Я немного удивлен, что это работает без IsMacroType=true
.Это может зависеть от того, была ли вычислена ячейка.
Excel обычно запрещает UDF читать другие части листа, если только UDF не зарегистрирован как «эквивалент листа макроса» (с # встрока регистрации).
Функции, которые зарегистрированы как «эквиваленты листа макроса», имеют следующее поведение (см. в нижней части документацию от xlfRegister ):
Размещение символа # после кода последнего параметра в pxTypeText дает функции те же разрешения на вызовы, что и функции на листе макроса.Они следующие:
Функция может извлекать значения ячеек, которые еще не были рассчитаны в этом цикле пересчета.
Функцияможет вызывать любую из информационных функций XLM (класс 2), например, xlfGetCell.
Если знак числа (#) отсутствует: вычисление не вычисленной ячейки приводит к ошибке xlretUncalcedи текущая функция вызывается снова после вычисления ячейки;вызов любой информационной функции XLM, кроме xlfCaller, приводит к ошибке xlretInvXlfn.
Ваша ошибка в случае без IsMacroType=true
может быть последней из этих - вы читаетеотсчитанная ячейка, следовательно, получающая ошибку.
Побочные эффекты установки IsMacroType=true
для UDF не совсем ясны.Одним из эффектов является то, что функции, зарегистрированные как IsMacroType=true
и имеющие параметр, помеченный как AllowReference=true
, будут автоматически считаться энергозависимыми (даже если они зарегистрированы с помощью IsVolatile=false
).Другим побочным эффектом является то, что это влияет на последовательность пересчета, особенно если вы читаете невычисленные ячейки изнутри вашего UDF.
Вы также должны быть очень осторожны при чтении других ячеек из UDF относительно вашего ожидания того, что должнопересчитать, когда, поскольку вы как бы подрываете дерево зависимостей вычислений.В вашем примере ваш UDF читает ячейку A30
, но изменится ли ячейка A30 автоматически, чтобы ваша функция пересчитала?Конечно, вы не можете использовать инструменты отслеживания зависимостей Excel, чтобы понять, что ваша ячейка зависит от A30
.На самом деле вы предпочитаете иметь функцию, которая принимает явный параметр и называется =DoSomething(A30)
, чтобы все прояснить и избежать всех этих проблем.
Одна из причин, по которой вы можете пытаться прочитать Value2
, - это определитьформатирование ячейки вместо базового значения, которое хранит Excel, но это действительно опасно, поскольку оно не является частью дерева перерасчета и зависимости.
Поэтому я бы сказал, что вы видите неожиданное поведениезнак того, что вы идете в направлении, которое не нравится Excel.