Я обнаружил точную проблему, но я хочу, чтобы вы все проголосовали за то, что пытаетесь помочь мне разобраться в этом, и отдаете должное GSerg, потому что, хотя мне не повезло, он был мёртв с его предложением что
Excel предпочитает делать некоторые свойства диапазона недоступными на определенных этапах расчета.
Хорошая находка GSerg.
Проблема была с Обработчиками событий . Рабочая книга содержит ряд обработчиков событий, таких как Workbook_Open, Worksheet_Change и т. Д. Время от времени одно из действий, выполняемых этими обработчиками событий, приводит к пересчету некоторых ячеек в рабочей книге. Если во время выполнения макроса Excel запускает пересчет, все ячейки, содержащие этот UDF, приведут к ошибке. Это связано с тем, что по какой-то причине во время инициированного VBA пересчета свойство .HasFormula было недоступно. , как сказал @GSerg:
![Property Unavailable](https://i.stack.imgur.com/fflOo.png)
Предположительно - следующий бит - это недосмотр со стороны Excel, но как только макрос завершится, если будет выполнен пересчет, что приведет к ошибкам из-за неправильной работы UDF, Excel не будет пытаться снова запустить UDF. , Получившееся значение ошибки будет считаться возвращаемым значением вызова и не изменится, если не будет считать, что параметр этого UDF изменился. Excel будет кэшировать результат вызова пользовательской функции до тех пор, пока не будет изменена ячейка, к которой привязаны параметры.
Именно поэтому при пошаговом выполнении «Формула оценки» все будет работать до самого последнего шага, где он фактически не оценивает последний шаг, он просто показывает значение из электронной таблицы, как было рассчитано последним.
Решение
На самом деле было два возможных решения. Первое решение, которое я нашел, состояло в том, чтобы отключить автоматический расчет в начале обработчиков событий, а затем снова включить его. По какой-то причине, даже если макрос выполняется в то время, когда для вычисления задано значение xlCalculationAutomatic, это приведет к успешной повторной оценке UDF и доступному свойству.
Второе решение, которое я предпочитаю, потому что оно предотвращает случайное повторение этого события, заключается в использовании другого метода для проверки формулы:
Function CellIsFormula(ByRef rng As Range) As Boolean
CellIsFormula = Left(rng(1).Formula, 1) = "="
End Function
Свойство .Formula никогда не будет недоступно. Так что эта проблема никогда не возникает.