Nested Loop Issue - vb.net-2010

I get the below error when run the code , I made nested loop between two tables when the code started the loop started but when it end in table 2 the below error appears
Operator '=' is not defined for string "9" and type 'DBNull'.
Do While Not rs1.EOF()
Do While Not rs2.EOF()
If rs1("Number").Value = rs2("CDNumber").Value Then
rs1("Matched").Value = "Yes"
rs1.Update()
rs2.MoveFirst()
rs1.MoveNext()
End If
rs2.MoveNext()
Loop
Loop

I believe this error arises because, at some point, your loop tries to compare a string and a null value. I don't believe this is a valid comparison. Check your data set for NULL values.
It likely happens at line: If rs1("Number").Value = rs2("CDNumber").Value Then
Relevant Link:
VB.Net DBNull and String error

Try the code below:
It is always wise to check data used in a calculation for NULL. for example:
IIF(IsDBNull(MyValue),0,MyValue)
If MyValue is null, zero is returned, if not, the value of MyValue is returned
Do While Not rs1.EOF()
Do While Not rs2.EOF()
If
IIF(IsDBNull(rs1("Number").Value),0,rs1("Number").Value) =IIF(IsDBNull(rs2("CDNumber").Value),0,rs2("CDNumber").Value) Then
rs1("Matched").Value = "Yes"
rs1.Update()
rs2.MoveFirst()
rs1.MoveNext()
End If
rs2.MoveNext()
Loop
Loop
Solution 2: Adding the extra validation using If condition for IsDbNull values.
Do While Not rs1.EOF()
Do While Not rs2.EOF()
If NOT IsDbNull(rs1("Number")) And Also NOT IsDbNull(rs2("CDNumber")) Then
If IIF(IsDBNull(rs1("Number").Value),0,rs1("Number").Value) =IIF(IsDBNull(rs2("CDNumber").Value),0,rs2("CDNumber").Value) Then
rs1("Matched").Value = "Yes"
rs1.Update()
rs2.MoveFirst()
rs1.MoveNext()
End If
End If
rs2.MoveNext()
Loop
Loop
Solution 3: Using only If condition for IsDbNull values.
Do While Not rs1.EOF()
Do While Not rs2.EOF()
If rs1("Number").Value = rs2("CDNumber").Value Then
rs1("Matched").Value = "Yes"
rs1.Update()
rs2.MoveFirst()
rs1.MoveNext()
End If
rs2.MoveNext()
Loop
Loop

Related

VBA If Statement within For (Else Running even when If condition is met)

I'm pretty new to VBA and having issues with a Else statements running even when If conditions are met.
Pretty sure this is due to the If statement being within a For & Next
For iCnt = 1 To Len(Firstname)
If IsNumeric(Mid(Firstname, iCnt, 1)) Then
MsgBox "The Firstname cannot contain Numeric values"
ElseIf Len(Firstname) > 100 Then
MsgBox "The Firstname exceeds the character limit (100)"
Else
Sheet3.Cells(lRow, 2).Value = Me.Firstname.Value
End If
Next iCnt
Please any suggestions how to fix this?
Really you only want the first condition to exist in that FOR loop. The rest of it should be tested afterwards and only if that first condition never trips.
Consider instead:
Dim nameHasNumbers as boolean: nameHasNumbers = False
For iCnt = 1 To Len(Firstname)
If IsNumeric(Mid(Firstname, iCnt, 1)) Then
'number found toggle flag and exit the loop
nameHasNumbers = True
exit For
End If
Next iCnt
'Now alert the user or update the name cell
If nameHasNumbers Then
MsgBox "The Firstname cannot contain Numeric values"
ElseIf Len(Firstname) > 100 Then
MsgBox "The Firstname exceeds the character limit (100)"
Else
Sheet3.Cells(lRow, 2).Value = Me.Firstname.Value
End If
For each letter in the name you are going to get the Else to happen. Need to restructure the whole thing. I would put the checking into a function and then based on that result do your other work. If you need a message to inform the user of the reason for the name being invalid add that to the function. Your function can then do other testing on other conditions without affecting your calling code.
Private Function IsValidName(ByVal value As String) As Boolean
If Len(value) > 100 Then
IsValidName = False
Exit Function
Else
Dim charCounter As Long
For charCounter = 1 To Len(value)
If IsNumeric(Mid(value, charconter, 1)) Then
IsValidName = False
Exit Function
End If
Next
IsValidName = True
End If
End Function
When you want to check whether a string includes a digit, you can compare it to a Like pattern which matches a digit: FirstName Like "*[0-9]*"
That approach is simpler than looping through the string checking whether each character is a digit. And since it does not require the For loop, it should be easier to avoid the logic error in your code sample. (As long as the string length did not exceed 100 characters, it wrote a value to Sheet3.Cells(lRow, 2).Value again for each and every non-numeric character contained in FirstName.)
If FirstName Like "*[0-9]*" Then
MsgBox "The Firstname cannot contain Numeric values"
ElseIf Len(FirstName) > 100 Then
MsgBox "The Firstname exceeds the character limit (100)"
Else
Sheet3.Cells(lRow, 2).Value = Me.FirstName.Value
End If

How to trigger a command only when the for loop is over?

I have a for loop with an If condition inside, and I want to trigger a command only when the loop is over and the If condition wasn't triggered.
You'll need to keep a flag. Set it to false by default and when the if statement gets executed you set the flag to true.
Dim didIfExecute As Boolean = False
For ...
If ... Then
didIfExecute = True
End If
Next
If Not didIfExecute Then
...
End If
You could use Return for it. Return immediately exits the function. Here is a example:
Dim a As Byte
For a = 10 To 20
Console.WriteLine("value of a: {0}", a)
If a= "20" Then
CoolFunction()
Return
End If
Next
MsgBox("u will never see this msg! maybe if you edit the if condition...")
If the If condition got triggered then it will not execute the code which is under the loop. If the If condition don't get triggered then everything what is under the loop will be executed.
You could also use a Boolean for it. This would not "kill" everything that is under the Loop.
Dim a As Byte
Dim EvenTriggered As Boolean = False
For a = 10 To 20
Console.WriteLine("value of a: {0}", a)
If a= "20" Then
CoolFunction()
EventTriggered = True
End If
Next
If EventTriggered = False Then
MsgBox("u will never see this msg! maybe if you edit the if condition...")
End IF

How to add an if statement inside a for loop in VBA?

For a = 1 to 10
if a = dumm then next a 'this statement should avoid running the subsequent codes if the if statement is true (similar to continue in c++
end if
'statements that need to run when the if statement is not true
next a
Why does this code not work?? It throws compile error: Next without for
Why does this code not work?? It throws compile error: Next without for
Because you have a next without a corresponding For. For/Next and For Each/Next must be paired, you can't open a For loop without a Next and you can't use Next without `For.
Simply:
if a = dumm then a = a + 1
This increments your a value within the loop. I'm unclear as to why you think this isn't applicable, because whether you increment a and then run the code, or skip to the next a (which is functionally equivalent to incrementing it via +1), the result should be same
Or, you could add a label and a GoTo statement:
For a = 1 to 10
if a = dumm then
GoTo MyLabel
end if
'statements that need to run when the if statement is not true
MyLabel:
next a
Or, and my preference, just use proper boolean expressions:
For a = 1 to 10
if not a = dumm Then
'statements that need to run when the if statement is not true
end if
Next
If you don't want to continue the loop at all, then either add an Exit statement,
For a = 1 to 10
if a = dumm Then Exit For
'statements that need to run when the if statement is not true
Next
or use a Do/While loop with proper escape conditions:
a = 1
Do
'statements go here...
a = a + 1
Loop While a <= 10 and Not a = dumm

Dealing with Empty Cells in VBA for Access

I have the following code which is supposed to step through an array of fields and create two new arrays to add to a new recordset:
For Each Field In SDSRecordsets(i)
Debug.Print (j)
Debug.Print (Field.Value)
fieldNames(j) = Field.Name
If Field.Value = Null Then
values(j) = ""
Else
values(j) = Field.Value
End If
j = j + 1
Next
The first time this loop runs, the Debug.Print lines print out 0 and then the string value in the first cell as it should. It then runs through the rest of it with no problems. The second time, it tries to add an empty cell. The first Debug.Print prints out 1, as it should, and the second prints out Null, also doing as it should. However, I then get a compile error on the line:
values(j) = Field.Value
Can anyone explain why it is reaching this line, because the way I see it, the If statement must be evaluating Null = Null as false for this to happen.
I've also tried doing this with:
If Not IsEmpty(Field.Value) Then
But that doesn't work either.
Use the Nz function:
For Each Field In SDSRecordsets(i)
Debug.Print (j)
Debug.Print (Field.Value)
fieldNames(j) = Field.Name
values(j) = nz(Field.Value,"")
j = j + 1
Next
Also you can use isnull([expr]) function, the direct comparison with null will not work

Find value in a vba dynamic table

I have a dynamic table of strings that I defined in vba (I precise that it is not an XL table) and I want to check if a specific value is present in this table. Here is a portion of my function:
Dim tableOfSizes() As String
sizeTable(0)=size1
sizeTable(1)=size2
sizeTable(2)=size3
'size2 and size3 are optional parameters of the function
If instr(tableOfSizes, "Medium") <> 0 Then
' Action if "Medium" is found in the table
End If
but it seems that instr do not work for tables, or at least, for dynamic tables. Is that the problem?
For 1D-array you can use following approaches.
Way №1 Filter function
If UBound(Filter(tableOfSizes, "Medium")) <> -1 Then
' Action if "Medium" is found in the table
End If
Way №2 (for Excel-VBA) Application.Match
If Not IsError(Application.Match("Medium", tableOfSizes, 0)) Then
' Action if "Medium" is found in the table
End If
For multi-dimmension arrays you can use following function:
Function contains(arr, elem) As Boolean
Dim a
contains = False
For Each a In arr
If a = elem Then
contains = True
Exit Function
End If
Next
End Function
and then:
If contains(tableOfSizes, "Medium") Then
' Action if "Medium" is found in the table
End If