Подтвердить что ты не робот

Как узнать, имеет ли ячейка ошибку в формуле в С#

В формуле Excel вы можете использовать =ISERR(A1) или =ISERROR(A1)

В макросе VBA вы можете использовать IsError(sheet.Cells(1, 1))

Но с помощью проекта VSTO Excel Addin я не нашел аналогичную функцию в Microsoft.Office.Interop.Excel API. Я только хочу знать, есть ли ошибка в ячейке, меня не интересует тип ошибки.

Мое текущее обходное решение - сделать это для всех существующих сообщений об ошибках.:

if (((Range)sheet.Cells[1, 1]).Text == "#N/A" || ...)

Есть ли лучший способ сделать это. Есть ли в API простая функция для этого?

4b9b3361

Ответ 1

Вы можете использовать метод WorksheetFunction:

Globals.ThisAddIn.Application.WorksheetFunction.IsErr(...)

или

[Your Excel Object].WorksheetFunction.IsErr(...)

IsErr семантически идентична функции рабочего листа Excel, только вместо ссылочного номера ячейки в фактическом значении - AFAIK.

Ответ 2

Работа с значениями CVErr в .NET - очень сложный вопрос. Проблема в том, что .NET(по праву) считает CVErr устаревшим в отношении обработки ошибок. Однако значения CVErr все еще используются в ячейках Excel, поэтому это довольно большое упущение для автоматизации Excel.

К счастью, есть обходной путь. Способ проверки значений CVErr - это проверка типа данных, хранящегося в ячейке. Если удерживаемое значение вводится как целое (Int32), тогда удерживаемое значение является CVErr. (Обратите внимание, что числовые значения, хранящиеся в ячейке, обычно типизируются как Двойные, только значения CVerr могут проходить через Integer.)

То есть, на самом простом уровне, чтобы проверить значение CVErr, все, что вам нужно сделать, это использовать следующую функцию:

bool IsXLCVErr(object obj)
{
    return obj is Int32;
}

Если вам нужно проверить определенное значение CVErr (например, # N/A), тогда вы должны сначала проверить, чтобы тип данных был Integer (Int32), а затем проверял определенное значение, хранящееся в ячейке, в соответствии с этой таблицей:

  • -2146826281 = # DIV/0!
  • -2146826246 = # N/A
  • -2146826245 = #GETTING_DATA
  • -2146826259 = #NAME?
  • -2146826288 = #NULL!
  • -2146826252 = #NUM!
  • -2146826265 = #REF!
  • -2146826273 = #VALUE!

Например, ваш код может выглядеть так:

enum CVErrEnum : Int32
{
    ErrDiv0 = -2146826281,
    ErrGettingData = -2146826245,
    ErrNA = -2146826246,
    ErrName = -2146826259,
    ErrNull = -2146826288,
    ErrNum = -2146826252,
    ErrRef = -2146826265,
    ErrValue = -2146826273
}

bool IsXLCVErr(object obj)
{
    return (obj) is Int32;
}

bool IsXLCVErr(object obj, CVErrEnum whichError)
{
    return (obj is Int32) && ((Int32)obj == (Int32)whichError);
}

Я написал подробную двухчастную статью об этом несколько лет назад:

Статьи написаны для VB.NET, но принципы точно такие же, как для С#. У вас не должно быть проблем с переводом, но если у вас возникнут проблемы, спросите пожалуйста. (В какой-то день я надеюсь, что у меня есть время, чтобы обновить эту статью для С#. Если это произойдет в какой-то момент, я отредактирую сообщение, чтобы включить ссылку.)

Надеюсь, это поможет!