Причина, скорее всего, в том, что Evaluate видит вашу функцию как UDF - как если бы она была вызвана из формулы рабочего листа. UDF имеют серьезные ограничения на то, что они могут делать - в частности, не устанавливать свойства или вызывать другие функции - и я предполагаю, что что-то здесь нарушило эти ограничения, хотя я не могу точно выделить, что здесь сделано.
Внутри UDF ошибки проглатываются молча, потому что формуле листа не разрешено генерировать ошибки VB. (Это нарушило бы пользовательский интерфейс Excel, если ошибка формулы постоянно вызывала диалоги VB)
Подробнее об ограничениях 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
Здесь есть три примечания, по крайней мере, когда я запускаю их.
- Функция вызывается дважды. Это известная проблема с Evaluate, связанная с тем, как Excel обрабатывает свои вычисления на листе. Вот почему Evaluate никогда не следует использовать для функций, которые записывают данные - потому что он может вызываться несколько раз в одном Evaluate.
- Во втором цикле Find Next не может найти другую ячейку. Это загадка, но на самом деле Evaluate не должен использоваться для запуска функций, которые бегают по листу, поэтому, в некотором смысле, это неопределенное поведение и его нельзя считать ошибкой. Evaluate предназначен для запуска формулы, где все ссылки на ячейки отображаются в формуле явно. Моя собственная теория заключается в том, что Find Next не работает, потому что вы пытаетесь использовать ссылку на ячейку, которая не является активной ячейкой, а Evaluate пытается уничтожить такую незаконную деятельность.
- Ваш баг. В строке
Loop Until
вы обрабатываете тест Or. Проблема в том, что если rngFoundCell
равно Nothing
, второй тест выдаст ошибку; VBA пытается обработать полное выражение, и rngFoundCell.Address
не может быть вычислено в этом случае. Код будет немедленно завершен без диалогового окна с ошибкой при запуске в качестве пользовательской функции (т. Е. В Evaluate). Вот почему вы не видите "Закончено" внутри Evaluate.