I had a problem and Range.Find Method should do the work for it,
On Microsoft site ( Rang.Find Method ), found the code I thought I would need:
Set C = wsCountry.Range("G:G").Find(What:="BOSS", MatchCase:=True, LookAt:=xlWhole, LookIn:=xlValues, SearchDirection:=xlNext, SearchOrder:=xlByRows)
If Not C Is Nothing Then
firstAddress = C.Address
Do
If wsRep.Range("B:B").Find(What:=C.Offset(0, -5), LookIn:=xlValues) Is Nothing Then
wsUser.Range("SpecialPO").Find(What:="BOSS", MatchCase:=True, LookIn:=xlValues).Offset(0, 1) = wsUser.Range("SpecialPO").Find(What:="BOSS", MatchCase:=True, LookIn:=xlValues).Offset(0, 1) + 1
End If
Set C = wsCountry.Range("G:G").FindNext(C)
If C Is Nothing Then Exit Do
Loop While C.Address <> firstAddress
End If
Problem :
When trying to set the variable C for the second time using .FindNext, it will throw value "Nothing". Although the column has another 2 values as "BOSS"
(I found an extent content and probably I will be using another solution suggested by siddharthrout in Section 3 . Although I want to know why this solution didn't work as intended)
As always, many thanks in advance.
Question:
The following line is causing the error.
Loop While Not C Is Nothing And C.Address <> firstAddress
Error: Object Variable or With Block variable not set.
In VBA, the If/While etc. evaluate all parts of composite conditions (And, Or), unlike in eg C++ - ie, in VBA the And and Or are not short-circuited. So your first check for Is Nothing doesn't cause the second check on a member to not be performed, hence the Variable not Set error.
The solution is thus to test for Is Nothing separately before checking any members, via a nested If. This can't be done in the While, so it needs to be done separately before the end of the While loop, and you should store the result in a variable to test for in the While.
Even though the code you posted is from MSDN, it can still be wrong :)
To see this in action, run the following code in a VBA module:
Sub x()
Dim o As Range
Set o = Nothing
Do While Not o Is Nothing And o.Address = "whatever"
Call MsgBox("Made it!")
Loop
End Sub
When you call .Find on a range you create a find context. This is how .FindNext knows what to find next. When you 'interrupt' a Find/FindNext sequence with a second (unrelated) .Find (on an unrelated range eg), you mess with this context. The next time you want to continue your .FindNext on your original range, the context will be unusable and the .FindNext will start returning wrong results. Note that .Find isn't really a nice function to use; it'll actually change the default values in the user's Find dialog. This also hints to the fact that there's only one Find context in Excel, and it is shared with the user operated GUI (not nice, but what can you do).
See the below code for how this works. Select an empty sheet, fill it like such:
Column A Column B
a d
b e
c f
a d
b e
c f
Then run the code below; it'll show you "Didn't FindNext". Now comment out the second .Find on oSearchRangeB and run it again; it'll now return "Did FindNext".
Sub x()
Dim oSearchRangeA As Range
Set oSearchRangeA = ActiveSheet.Range("A:A")
Dim oSearchRangeB As Range
Set oSearchRangeB = ActiveSheet.Range("B:B")
Dim oFoundCell As Range
Set oFoundCell = oSearchRangeA.Find( _
What:="b", MatchCase:=True, LookAt:=xlWhole, LookIn:=xlValues, _
SearchDirection:=xlNext, SearchOrder:=xlByRows _
)
If Not oFoundCell Is Nothing Then
Dim oInterferingFoundCell As Range
Set oInterferingFoundCell = _
oSearchRangeB.Find(What:="f", LookIn:=xlValues)
Set oFoundCell = oSearchRangeA.FindNext(oFoundCell)
If oFoundCell Is Nothing Then
Call MsgBox("Didn't FindNext")
Else
Call MsgBox("Did FindNext")
End If
End If
End Sub
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.