原因很可能是 Evaluate 将您的函数视为 UDF - 就好像它是从工作表公式中调用的一样。 UDF 对它们可以执行的操作有严格的限制 - 特别是不能设置属性或调用其他函数 - 我想这里的某些内容已经违反了这些限制,尽管我无法准确地隔离这里所做的事情。
在 UDF 内部,错误会被悄悄吞掉,因为工作表公式不允许引发 VB 错误。 (如果公式错误不断引发 VB 对话框,则会破坏 Excel 用户界面)
See http://support.microsoft.com/kb/170787 http://support.microsoft.com/kb/170787有关 UDF 限制的详细信息。
EDIT:好的,这是对您的问题的一些澄清,我知道您的代码在评估过程中在哪里默默地出错。使用此代码:
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
这里有三件事值得注意,至少当我运行它时。
- 该函数被调用两次。这是 Evaluate 的一个已知问题,与 Excel 如何处理工作表上的计算有关。这就是为什么 Evaluate 永远不能用在记录数据的函数上 - 因为它可以在单个 Evaluate 中被多次调用。
- 在第二次循环中,“查找下一个”无法找到另一个单元格。这是一个谜,但 Evaluate 不应该真正用于运行在工作表中运行的函数,因此在某种程度上,这是未定义的行为,不能真正被视为错误。评估意味着运行一个公式,其中所有单元格引用都在公式中明确映射。我自己的理论是“查找下一个”不起作用,因为您试图使用不是活动单元格的单元格引用,而“评估”则试图消除这种非法活动。
- 你的虫子。上
Loop Until
行,您处理 Or 测试。问题是,如果rngFoundCell
is Nothing
,第二次测试会抛出错误; VBA 正在尝试处理完整的表达式rngFoundCell.Address
在这种情况下无法进行评估。当作为 UDF 运行时(即在 Evaluate 中),代码将立即退出,不会出现错误对话框。这就是为什么您在评估中看不到“完成”的原因。