I have this if statement right here:
If lbl1.Text <> "Good" Or lbl2.Text <> "Good" Or lbl3.Text <> "Good" Then
MsgBox("Something.")
Exit Sub
End If
This works fine, but I also need to attach another condition to it, but for some reason I am drawing a blank on it. I need it to also pass that it is ok for lbl2 & lbl3 to be an empty string. In order words, if lbl1.text = "Good" then it is ok for lbl2 & lbl3 to be empty, therefore it will not exit sub.
If you look at it from the other way around, what you're saying is that if any one of the labels says "Good", then don't enter this statement, so, you could say enter this statement if that is not the case.
In other words:
If Not(lbl1.Text = "Good" Or lbl2.Text = "Good" Or lbl3.Text = "Good") Then
MessageBox.Show("Something.")
End If
Hope that does the trick!
What about a statement like this?
If Not ((lblA.Text = "Good" OrElse lblA.Text = String.Empty) AndAlso _
(lblB.Text = "Good" OrElse lblB.Text = String.Empty) AndAlso _
(lblC.Text = "Good" OrElse lblC.Text = String.Empty)) Then
MessageBox.Show("Something.")
End If
Related
I have a form with 3 text boxes, txt_customeracc, txt_customername, txt_customercontact
These 3 text boxes are optional and by default the text boxes will have "N/A" displaying on form load, but if a user enters information into one of them I want them to enter the information in the other two boxes also.
The code I am using is below
If txt_customername.Text <> "" Or txt_customername.Text <> "N/A" Or
txt_customercontact.Text <> "" Or txt_customercontact.Text <> "N/A" And
txt_customeracc.Text = "" Or txt_customeracc.Text = "N/A"
Then error1 += vbNewLine & "Please enter a correct Customer Account Number"
So from the above code I am expecting that if a user enters information in either the txt_customername or the txt_customercontact text boxes but not in the txt_customeracc box the warning should then appear but currently the warning message is displaying regardless of whether information is or isn't entered in any of the boxes. Can anyone tell me what I am doing wrong?
What is operator precedence ?
Your main problem here is that you have an issue with operator precedence. What is that ?
It is exactly the same issue as when doing calcuations, multiplication comes first, then comes addition. Well in VB .NET, And operator comes before Or, so what you have written in your code is evaluated as follow :
If txt_customername.Text <> "" Or
txt_customername.Text <> "N/A" Or
txt_customercontact.Text <> "" Or
(txt_customercontact.Text <> "N/A" And txt_customeracc.Text = "") Or
txt_customeracc.Text = "N/A"
Then
error1 += vbNewLine & "Please enter a correct Customer Account Number"
End If
Since this is not really what you want, let's build this together :
if customername OR customercontact is filled up
AND
customeracc is empty
That would give us :
if (
(txt_customername.Text <> "" Or txt_customername.Text <> "N/A") 'CustomerName is filled up
Or
(txt_customercontact.Text <> "" Or txt_customercontact.Text <> "N/A") 'Customer Contact is filled up
)
And
(txt_customeracc.Text = "" Or txt_customeracc.Text = "N/A") 'Customer account is empty
Then
'Do whatever
End If
Make it better, call a function
Another problem here is readability, this code may have errors because it's hard to read, so hard to debug.
What we can do is build a function that will check if a textbox is empty :
Private Function IsEmpty(Tb As Textbox) As Boolean
'Here we return true if tb.Text is empty or contains "N/A"
Return Tb.Text = "" Or Tb.Text = "N/A"
End Function
So that would make this a bit more readable :
if (Not IsEmpty(txt_customername) Or Not IsEmpty(txt_customercontact)) 'CustomerName or Customer Contact is filled up
And IsEmpty(txt_customeracc) 'Customer account is empty
Then
'Do whatever
End If
Make it better (2), Compare the strings
As stated by zaggler in his comment, here we don't use String Comparison. What if a user starts typing, then decides to put it back to N/A and writes it lowercase ("n/a") ? Well, we will make a mistake, believing that he did fill up the Textbox and you will end up searching for user "n/a" in your database, which is not a very good idea...
So let's compare the String, make our function even better :
Private Function IsEmpty(Tb As Textbox) As Boolean
'Here we return true if tb.Text is empty or contains "N/A" (or "n/a")
Return Tb.Text = "" Or (String.Compare(Tb.Text, "N/A", True) = 0)
End Function
Note
You can see here the advantage of functions. I wrote it because I didn't want to change to String.Compare() six times... Whenever you have the same code twice, it should be a function...
If you want to give the user a proper error message telling him what he has missed to fill out you have to split the if statement into several parts.
First check if all text boxes contain any valid data.
If not you can skip further checks directly.
If one textbox contains data check each and set error accordingly.
If (txt_customername.Text = "" OrElse txt_customername.Text = "N/A") AndAlso
(txt_customercontact.Text = "" OrElse txt_customercontact.Text = "N/A") AndAlso
(txt_customeracc.Text = "" OrElse txt_customeracc.Text = "N/A") Then
'No Error exit sub
Exit Sub
End If
'This part is only reached if one textbox contains data
If (txt_customername.Text = "" OrElse txt_customername.Text = "N/A") Then
error1 += vbNewLine & "Please enter a correct Customer Name"
End If
If (txt_customercontact.Text = "" OrElse txt_customercontact.Text = "N/A") Then
error1 += vbNewLine & "Please enter a correct Customer Contact"
End If
If (txt_customeracc.Text = "" OrElse txt_customeracc.Text = "N/A") Then
error1 += vbNewLine & "Please enter a correct Customer Account Number"
End If
As you can see I also recommend using short circuit OrElse and AndAlso which gives a littttttttle performance.
You could count the number of filled fields.
Dim numberFilled As Integer = 0
If txt_customername.Text <> "" And txt_customername.Text <> "N/A" Then
numberFilled += 1
End If
If txt_customercontact.Text <> "" And txt_customercontact.Text <> "N/A" Then
numberFilled += 1
End If
If txt_customeracc.Text <> "" And txt_customeracc.Text <> "N/A" Then
numberFilled += 1
End If
If numberFilled = 1 Or numberFilled = 2 Then
error1 += vbNewLine & "Please enter a correct Customer Account Number"
End If
Personally I would have a function IsValueEmpty that would check:
Function IsValueEmpty(ByVal value As String) As Boolean
If String.IsNullOrEmpty(value) Or value = "N/A" Then
Return True
End If
Return False
End Function
Could also Trim.
You could have the relevant message part stored in the Tag property of each textbox and use Linq :
Dim customerTextBoxes = {txt_customeracc, txt_customername, txt_customercontact}
Dim messages = Aggregate customerTextBox In customerTextBoxes
Where customerTextBox.Text = "" OrElse customerTextBox.Text = "N/A"
Select $"Please enter a correct {customerTextBox.Tag}")
Into ToArray
Then just check it's length against the initial one and if they're not equal aggregate the message for display
If customerTextBoxes.Length <> messages.Length Then error1 = String.Join(Environment.NewLine, messages)
I'm basically running through rows in a table. I'm checking each row to see if at least 1 of the columns im interested is = "pass" and that the rest = either "pass" or "N/A".
But im getting an error:
"An exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll but was not handled in user code
Additional information: Conversion from string "FAIL" to type 'Long' is not valid."
The statuses can either be "PASS", "FAIL", OR "N/A" in the DB is you're wondering where the FAIL came from.
Here's the code:
Private Function HasAuditPassed(activeLotId As String) As Boolean
Dim sql = String.Format("SELECT STEPID, CAVITYPAIRASTATUS,CAVITYPAIRBSTATUS,CAVITYPAIRCSTATUS,CAVITYPAIRDSTATUS FROM " & _
"TB_BL_AMMSSTEPSTATUS WHERE AUDITLOT = '{0}'", activeLotId)
Dim dynaset = DB.CreateDynaset(sql, DBWrapper.DynasetOptions.ORADYN_READONLY)
Do Until dynaset.EOF
Dim cavityPairAStatus = dynaset.GetFieldData(Of String)("CAVITYPAIRASTATUS")
Dim cavityPairBStatus = dynaset.GetFieldData(Of String)("CAVITYPAIRBSTATUS")
Dim cavityPairCStatus = dynaset.GetFieldData(Of String)("CAVITYPAIRCSTATUS")
Dim cavityPairDStatus = dynaset.GetFieldData(Of String)("CAVITYPAIRDSTATUS")
If (cavityPairAStatus Or cavityPairBStatus Or cavityPairCStatus Or cavityPairDStatus) = "PASS" And
(cavityPairAStatus And cavityPairBStatus And cavityPairCStatus And cavityPairDStatus) = ("PASS" Or "N/A") Then
Return True
End If
Loop
Return False
End Function
Sadly, you can't do if statements that way. You have to write the entire statement out because VB .Net does not handle string comparison that way. So a statement that would be the equivalent and work would be much longer and look like this:
If (cavityPairAStatus = "PASS" OrElse cavityPairBStatus = "PASS" OrElse
cavityPairCStatus = "PASS" OrElse cavityPairDStatus = "PASS")
And (cavityPairAStatus = "PASS" OrElse cavityPairAStatus = "N/A" AndAlso
cavityPairBStatus = "PASS" OrElse cavityPairBStatus = "N/A" AndAlso
cavityPairCStatus = "PASS" OrElse cavityPairCStatus = "N/A" AndAlso
cavityPairDStatus = "PASS" OrElse cavityPairDStatus = "N/A") Then
Return True
End If
A few more elegant solutions with creating lists are below, and can be used to help out readability some if you have to write statements like this repeatedly.
There are a couple of issues here. You can't write a If stytement in this style and you can't use binary operators (And and Or) with String.
Your If statement should be something like this:
If (cavityPairAStatus = "PASS" OrElse cavityPairBStatus = "PASS" OrElse …
If you want something a little more elegant you may consider something like this:
Dim values = {cavityPairAStatus, cavityPairBStatus, cavityPairCStatus, cavityPairDStatus}
If values.Any(Function(v) v.Equals("PASS")) AndAlso values.All(Function(v) v.Equals("PASS") OrElse v.Equals("N/A")) Then
…
End If
The way IF statement you have used is incorrect.
To compare so many conditions you need to write them separately.
Instead of using IF condition here I would suggest you to use a list.
Here's the sample code
Dim cavityPairStatus As New List(Of String)
cavityPairStatus.Add(dynaset.GetFieldData(Of String)("CAVITYPAIRASTATUS"))
cavityPairStatus.Add(dynaset.GetFieldData(Of String)("CAVITYPAIRBSTATUS"))
cavityPairStatus.Add(dynaset.GetFieldData(Of String)("CAVITYPAIRCSTATUS"))
cavityPairStatus.Add(dynaset.GetFieldData(Of String)("CAVITYPAIRDSTATUS"))
If cavityPairStatus.Contains("PASS") OrElse cavityPairStatus.Contains("N/A") Then
Return True
End If
For some reason the below query doesn't seem to work. Can anyone advise why it is behaving different to what I expect.
Basically if the combobox.text or textbox.text stated are both blank then a message should show. If one of them are selected then present the current datetime.
If String.IsNullOrEmpty(lbx_Aux_Codes.Text) OrElse String.IsNullOrEmpty(com_Work_Item.Text) Then
MessageBox.Show("Please Select a Task or Work Item")
Else
StartTime = DateTimeLog()
MessageBox.Show(StartTime)
End If
Any help is appreciated.
change OrElse to AndAlso
Your code should look like this
If String.IsNullOrEmpty(lbx_Aux_Codes.Text) AndAlso String.IsNullOrEmpty(com_Work_Item.Text) Then
MessageBox.Show("Please Select a Task or Work Item")
Else
StartTime = DateTimeLog()
MessageBox.Show(StartTime)
End If
OrElse or Or will return true if one is true so if you want that message to pop only when both are empty, since you want to proceed with else if one is filled, then use And instead.
I think it is better to use AndAlso for this requirement. OrElse serves a different "short-circuiting" purpose. You may check this out: Or versus OrElse and use an ElseIf for your second criteria:
If String.IsNullOrEmpty(lbx_Aux_Codes.Text) AndAlso String.IsNullOrEmpty(com_Work_Item.Text) Then
MessageBox.Show("Please Select a Task or Work Item")
ElseIf String.IsNullOrEmpty(lbx_Aux_Codes.Text) Or _
String.IsNullOrEmpty(com_Work_Item.Text) Then
StartTime = DateTimeLog()
MessageBox.Show(StartTime)
End If
I'm trying to find a way to only allow a user to input ".32" or "Not Used" into my datagridviewcell. Right now my code stands as below. When I run the code all it does is change everything to "Not Used". Even if I type in ".32" it will change it to "Not Used". Is there anyway to fix this? I appreciate any help or suggestions anyone can give.
If (e.ColumnIndex = 6) Then ' This specifies the column number
Dim cellData = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString
If cellData Is Nothing OrElse IsDBNull(cellData) OrElse cellData.ToString = String.Empty Then
MessageBox.Show("Cannot Be Empty") ' This will prevent blank datagridviewcells
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "Not Used"
End If
Select Case cellData
Case 0.32
DataGridViewSize.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = 0.32
Case Else
DataGridViewSize.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "Not Used"
End Select
End If
I think it no necessary to use select string
Better you change to Dim cellData = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
Please take a look at the following code:
Try
Dim Reader As New System.IO.StreamReader(PositionsFileName)
Do While Reader.Peek() <> -1
Dim Positions() As String = Reader.ReadLine().Split("|")
If (Positions(0) Is Nothing) Or (Positions(1) Is Nothing) Or (Positions(2) Is Nothing) Then
' something
End If
Loop
Catch ex As Exception
ex.Source = Nothing
End Try
I am reading a file and expecting format something|something1|something2. I am trying to make it set "Nothing" to the array index which does not exists (the file format is broken), so that the If statement goes smoothly, but it seem I am doing it wrong. Can you give me some hints?
If you do Split("|") and there are only 2 items (for example, something|something1), Positions(2) will not be Nothing, it will just not be there. So your code will raise an exception, something about index out of bounds of the array.
If you need Positions(2) contain Nothing in this case, you code can look like this:
Dim Positions(2) As String
Dim tmpArray() As String = Reader.ReadLine().Split("|")
For i = 0 To UBound(Positions)
If i <= UBound(tmpArray) Then
Positions(i) = tmpArray(i)
Else
Positions(i) = Nothing
End If
Next
I assume that you only have three "Somethings" per valid line. If so, try writing your Positions() assignment like this:
Dim Positions() As String = Reader _
.ReadLine() _
.Split("|") _
.Concat(Enumerable.Repeat("Nothing", 3)) _
.Take(3) _
.ToArray()
This will ensure that you have three items every time. No need to check for nothings.
Just check positions.length after the split. Also, if you want to check for cases like "||Something2|Something3", the first position will be "" not Nothing. The orelse is a shortcircuit that will keep the latter condtitions from being evaulated if an earlier condition is met.
If Positions.length < 3 OrElse Positions(0) = "" OrElse Positions(1) = "" OrElse Positions(2) = "" Then
' something
End If