Прерывистый «InteropServices.COMException / ForwardCallToInvokeMember» доступ к Value2 в ячейке Range - PullRequest
0 голосов
/ 10 июля 2019

В моем последнем вопросе: Исключение ExcelDNA, вызывающее исключение при доступе к Range.Value2

Я обвинил ExcelDNA по причине, по которой Value2 генерировал исключение COMException.Но я не уверен, что это так.

Я отключил флаг IsMacroType, который полностью останавливает возникновение COMException, и заметил, что иногда Range.Value2 вообще не выдает исключение.

Так что иногда это работает, а иногда нет.Мой вопрос заключается в том, что может вызвать range.Value2 для создания прерывистых COMExceptions?

Это раздражает, потому что трассировка стека не дает мне полезной информации, а IsMacroType полностью решает проблему.

Я подозреваю, что если ячейка постоянно меняется, к моменту доступа к Value2 эта ячейка может стать недействительной, но это предположение, и я не уверен, как работает Excel.

Но также это не имеет смысла, поскольку в коде нет нескольких потоков.

Сталкивались ли вы с этой проблемой?

Это код:

var valueCell = (Range)row.Cells[1, 30];
if (valueCell .Value2 != null)
{
     //do something
}

Серьезно, Value2 не может вычислить оператор if

1 Ответ

1 голос
/ 10 июля 2019

Я немного удивлен, что это работает без 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.

...