简体   繁体   中英

Excel Vba Method Range.Find

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.

Answer to original question

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

Answer to updated question

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM