weird IF statement error " Conversion from string "FAIL" to type 'Long' is not valid." - vb.net

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

Related

Is it possible to create an extension method that can be used in an sql query?

I have an application that draws elements from a database when a search button is clicked. I need to update it so that I can find elements that have a specific Substring exactly 6 places into the string. For example, I need to find 111-2233-44-555 by looking for 33 at the 6th and 7th places. My first instinct was to create an extension method for the string class so that I could say something like this:
Dim example As String = "111-2233-44-555"
If example.HasYear(33) Then
'Do Something'
End If
And this worked perfectly. Here's the method I made:
Public Module StringExtensionMethods
''' <summary>
''' Finds the year in a competition number of format XXX-XXXX-XX-XXX
''' </summary>
''' <param name="pstrCompNum">The competition number to find the year in</param>
<Extension()>
Public Function HasYear(ByVal pstrCompNum As String, ByVal pstrCompYear As String) As Boolean
Try
Dim testString As String = pstrCompNum
Debug.Print(testString)
Dim testSubstring As String = testString.Substring(6, 2)
If testSubstring.Equals(pstrCompYear) Then
Return True
End If
Return False
Catch ex As Exception
Throw ex
End Try
End Function
End Module
But a problem arises when I try to use this method in an SQL query. Rightfully so, since HasYear() isn't related to SQL in any way whatsoever. Here's the query I want to execute:
Dim o = From c In myContext.Competitions.Include("CodeJusticeBranches").Include("CodeJusticeLocations").Include("CodeCompetitionTypes").Include("CodePositionTypes").Include("CompetitionPositions") _
Where (pstrCompNum Is Nothing OrElse c.comp_number = pstrCompNum) _
And (pstrCompYear Is Nothing OrElse c.comp_number.HasYear(strYear) = True) _
And (pstrCompTypeId Is Nothing OrElse c.CodeCompetitionTypes.code_ct_id = CInt(pstrCompTypeId)) _
And (pstrBranchId Is Nothing OrElse c.CodeJusticeBranches.code_branch_id = CInt(pstrBranchId)) _
And (pstrPosTypeId Is Nothing OrElse c.CodePositionTypes.code_pos_type_id = CInt(pstrPosTypeId)) _
Order By c.comp_number _
Select c
I get the error LINQ to Entities does not recognize the method 'Boolean HasYear (System.String, System.String)' method, and this method cannot be translated into a store expression.
So what I'm looking for is essentially a way to make an extension method that can be used in an SQL query. Any ideas?
Don't include custom functions in your LINQ. It must be convertable to SQL so your extension method doesn't qualify. Just execute your query with supported where clauses, then tack on your custom queries after.
Dim o = (
From c In myContext.Competitions.Include("CodeJusticeBranches").Include("CodeJusticeLocations").Include("CodeCompetitionTypes").Include("CodePositionTypes").Include("CompetitionPositions")
Where (pstrCompNum Is Nothing OrElse c.comp_number = pstrCompNum) _
And (pstrCompTypeId Is Nothing OrElse c.CodeCompetitionTypes.code_ct_id = CInt(pstrCompTypeId)) _
And (pstrBranchId Is Nothing OrElse c.CodeJusticeBranches.code_branch_id = CInt(pstrBranchId)) _
And (pstrPosTypeId Is Nothing OrElse c.CodePositionTypes.code_pos_type_id = CInt(pstrPosTypeId))
Order By c.comp_number Select c).ToList().
Where(Function(c) c.pstrCompYear Is Nothing OrElse c.comp_number.HasYear(strYear))
I like what #djv posted, but I've decided to try out Andrew Morton's suggestion, to just omit the HasYear() altogether. I ended up using this:
Dim k = From c In myContext.Competitions.Include("CodeJusticeBranches").Include("CodeJusticeLocations").Include("CodeCompetitionTypes").Include("CodePositionTypes").Include("CompetitionPositions") _
Where (pstrCompNum Is Nothing OrElse c.comp_number = pstrCompNum) _
And (pstrCompYear Is Nothing OrElse c.comp_number.Substring(6, 2) = pstrCompYear) _
And (pstrCompTypeId Is Nothing OrElse c.CodeCompetitionTypes.code_ct_id = CInt(pstrCompTypeId)) _
And (pstrBranchId Is Nothing OrElse c.CodeJusticeBranches.code_branch_id = CInt(pstrBranchId)) _
And (pstrPosTypeId Is Nothing OrElse c.CodePositionTypes.code_pos_type_id = CInt(pstrPosTypeId)) _
Order By c.comp_number _
Select c
Notice the line And (pstrCompYear Is Nothing OrElse c.comp_number.Substring(6, 2) = pstrCompYear)
This solved my problem very simply.

Adding another condition to this conditional if statement

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

Select case statement- working with variables VB.NET

Good day! I'm new to this control structure so what I'm trying to figure out are the ways to get values of input1 and input2 FROM EACH CASES( Case "String1" and Case "String2") and use it in Case "String3".
Code:
Dim input1 As String
Dim input2 As String
Select Case sampleVariable
Case "String1"
input1 = "Some value"
Case "String2"
input2 = "Some value"
Case "String3"
MsgBox(input1 & input 2)
End Select
Thank you.
Essentially, a select statements is like a shorthand for a significant amount of IF...THEN...ELSEIF...END If statements. All it really does is make the code easier to read if you have a significant amount of IF statements or conditions that need to be tested against a single instance. Mostly Select statemnts will be used to determine the outcome of some dialogue box, or other which predefined outcome was chosed by the user. if you were to write out your select statement, it would look like this:
If sampleVariable.Equals("String1") Then
input1 = "Some value"
ElseIf sampleVariable.Equals("String2") Then
input2 = "Some value"
ElseIf sampleVariable.Equals("String3") Then
MsgBox(input1 & input2)
End if
The reason you can't access the values that you are setting from the first two statements in the third case, is because the value assignment is hiding in an enclosed block. To see this more clearly, take a look at this:
Dim checkValue As Boolean
If checkValue Then
Dim hiddenVariable As String = "Hello World"
End If
MsgBox(hiddenVariable)
Using the above example, my hiddenVarible is declared and instantiated within the If block. This would work out fine as long as checkValue were always true. However if checkValue were false then hiddenVariable would never declared and you would probably receive an exception about a NullReference exception. In fact, Visual Studio won't even compile that under default settings.
The same type of thing is happening to your code as well. while you have declared input1 and input2 in the beginning, you haven't instantiated them with any values. So if case #3 is the outcome of you select statement, then you are essentially calling out MsgBox(Nothing & Nothing). The settings of values from your first two case statements never happen because the case statement didn't evaluate to true.
Now looking at the code, I'm not sure why you're going through about it this way since you are assigning string literals to your variables. I'm going to put down a few alternative options for you to choose from.
Adding some checks to case #3 for Nothing values:
Dim input1 As String
Dim input2 As String
Select Case sampleVariable
Case "String1"
input1 = "Some value"
Case "String2"
input2 = "Some value"
Case "String3"
If IsNothing(input1) OrElse IsNothing(input2) Then
MsgBox("At least one of the input values has no value")
Else
MsgBox(input1 & input2)
End If
End Select
Use the classic IF...THEN...END IF blocks:
Dim input1 As String = String.Empty
Dim input2 As String = String.Empty
If sampleVariable.Equals("String1") Then
input1 = "Some value"
ElseIf sampleVariable.Equals("String2") Then
input2 = "Some value"
ElseIf sampleVariable.Equals("String3") Then
MsgBox(input1 & input2)
End if
Assign the values upfront and forget the select statement because it really isn't doing anything:
Dim input1 As String = "Some value"
Dim input2 As String = "Some value"
If sampleVariable.Equals("String3") Then MsgBox(input1 & input2)
I hope this get you towards what ever answer you were looking for. H
owever if you were to give more background on what you are trying to do exactly and why you were trying to accomplish it this way, we may be able to help better.
I don't understand what you trying to do, but first what come in mind:
Dim input1 As String
Dim input2 As String
If sampleVariable.Equals("String1") = True Then
input1 = "Some value"
End if
If sampleVariable.Equals("String2") = True Then
input2 = "Some value"
End if
If sampleVariable.Equals("String3") = True Then
MsgBox(input1 & input2)
End if

How to include a number and string in select case statement

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

Setting value to a not-existing array item?

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