当使用Application.Evaluate或ActiveSheet.Evaluate方法调用例程时,我在子例程中运行find循环时遇到一些问题。例如,在下面的代码中,我定义了一个子程序FindSub(),它在工作表中搜索字符串“xxx”。例程CallSub()使用标准Call语句和Evaluate来调用FindSub()例程。
当我运行Call FindSub时,一切都会按预期工作:每个匹配的地址都会打印到即时窗口,当代码完成时我们会收到“完成”的最终消息。但是,当我执行Application.Evaluate“FindSub()”时,只打印出第一个匹配的地址,并且我们永远不会到达“已完成”消息。换句话说,在Cells.FindNext行之后遇到错误,因为循环尝试评估它是否应该继续,并且程序执行停止而不会打印任何运行时错误。
我希望调用FindSub和Application.Evaluate“FindSub()”在这种情况下产生相同的结果。有人可以解释为什么他们不这样做,如果可能的话,还有办法解决这个问题吗?感谢。
注意:在这个例子中,我显然不需要使用Evaluate。这个版本被简化为只关注我在更复杂的情况下遇到的特定问题。
Sub CallSub()
Call FindSub
Application.Evaluate "FindSub()"
End Sub
Sub FindSub()
Dim rngFoundCell As Range
Dim rngFirstCell As Range
Set rngFoundCell = Cells.Find(What:="xxx", after:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not rngFoundCell Is Nothing Then
Set rngFirstCell = rngFoundCell
Do
Debug.Print rngFoundCell.Address
Set rngFoundCell = Cells.FindNext(after:=rngFoundCell)
Loop Until (rngFoundCell Is Nothing) Or (rngFoundCell.Address = rngFirstCell.Address)
End If
Debug.Print "Finished up"
End Sub
答案 0 :(得分:1)
原因很可能是Evaluate将您的功能视为UDF - 就像从工作表公式中调用它一样。 UDF对他们可以做的事情有很大的限制 - 特别是没有设置属性或调用其他功能 - 我想这里的一些东西已经违反了这些限制,尽管我无法完全区分这里做了什么。
在UDF中,由于不允许工作表公式抛出VB错误,因此会无提示地吞下错误。 (如果公式错误不断地抛出VB对话框,它会破坏Excel用户界面)
有关UDF限制的详细信息,请参阅http://support.microsoft.com/kb/170787。
编辑:好的,这里有一些关于您的问题的说明,我知道您的代码在评估过程中默默地出错。使用此代码:
Sub FindSub()
Dim rngFoundCell As Range
Dim rngFirstCell As Range
Set rngFoundCell = Cells.Find(What:="xxx", after:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not rngFoundCell Is Nothing Then
Set rngFirstCell = rngFoundCell
Do
Debug.Print "FOUND: " & rngFoundCell.Address
Set rngFoundCell = Cells.FindNext(after:=rngFoundCell)
Debug.Print "FIND NEXT: " & IIf(rngFoundCell Is Nothing, " NOTHING", " SOMETHING")
Loop Until (rngFoundCell Is Nothing) Or (rngFoundCell.Address = rngFirstCell.Address)
Debug.Print "ESCAPED LOOP"
End If
Debug.Print "Finished up"
End Sub
我在即时窗口中得到以下输出:
findsub
FOUND: $G$6
FIND NEXT: SOMETHING
FOUND: $D$11
FIND NEXT: SOMETHING
ESCAPED LOOP
Finished up
太好了。但是:
callsub
FOUND: $G$6
FIND NEXT: SOMETHING
FOUND: $D$11
FIND NEXT: SOMETHING
ESCAPED LOOP
Finished up
FOUND: $G$6
FIND NEXT: NOTHING
这里有三点需要注意,至少在我运行它时。
Loop Until
行,您处理或测试。问题是,如果rngFoundCell
为Nothing
,则第二次测试会抛出错误; VBA正在尝试处理完整表达式,在这种情况下无法评估rngFoundCell.Address
。当作为UDF运行时(即在Evaluate中),代码将立即退出而没有错误对话框。这就是为什么你没有在评估中看到“完成”的原因。答案 1 :(得分:0)
以下内容应该有效:
Call FindSub
Call Application.Run("FindSub")
对我而言.Evaluate
失败&什么也没做。
如果我使用Call Application.Run("FindSub()")
(使用parens),我会看到与您相同的行为(“部分”第二次调用)。
您也可以尝试Application.Evaluate "FindSub"