我遇到了问题,Range.Find方法应该为它做好工作,
在Microsoft网站(Rang.Find Method)上,找到了我认为需要的代码:
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
问题:
当尝试使用.FindNext第二次设置变量C时,它将抛出值&#34; Nothing&#34;。虽然该列还有另外两个值为&#34; BOSS&#34;
(我发现了一个范围内容,我可能会使用siddharthrout在Section 3中建议的其他解决方案。虽然我想知道为什么这个解决方案没有按预期工作)
一如既往,非常感谢。
答案 0 :(得分:0)
问题:
以下行导致错误。
Loop While Not C Is Nothing And C.Address <> firstAddress
错误:未设置对象变量或块变量。
在VBA中,If / While等评估复合条件的所有部分(和,或),与例如C ++ - 即,在VBA中,And和Or不会短路。因此,首次检查Is Nothing是否会导致对成员的第二次检查无法执行,因此变量未设置错误。
因此,解决方案是在通过嵌套的If检查任何成员之前单独测试Is Nothing。这不能在While中完成,因此需要在While循环结束之前单独完成,并且您应该将结果存储在变量中以在While中进行测试。
即使您发布的代码来自MSDN,它仍然可能是错误的:)
要查看此操作,请在VBA模块中运行以下代码:
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
当你在一个范围上调用.Find时,你会创建一个查找上下文。这就是.FindNext知道接下来要找什么的方法。当你中断&#39;一个Find / FindNext序列与第二个(无关的).Find(在一个不相关的范围,例如),你搞乱这个上下文。下次要在原始范围上继续.FindNext时,上下文将无法使用,.FindNext将开始返回错误的结果。请注意,.Find并不是一个很好用的功能;它实际上会更改用户的“查找”对话框中的默认值。这也暗示了Excel中只有一个查找上下文,它与用户操作的GUI共享(不好,但你能做什么)。
请参阅以下代码了解其工作原理。选择一个空白纸,填写如下:
Column A Column B
a d
b e
c f
a d
b e
c f
然后运行下面的代码;它会告诉你&#34;没有找到下一个&#34;。现在注释掉第二个.Find on oSearchRangeB并再次运行它;它现在返回&#34; FindNext&#34;。
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