Как узнать, есть ли в ячейке ошибка в формуле в C # - PullRequest
22 голосов
/ 11 марта 2010

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

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

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

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

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

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

Ответы [ 2 ]

65 голосов
/ 11 марта 2010

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

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

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

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

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

  • -2146826281 = # DIV / 0!
  • -2146826246 = # N / A
  • -2146826245 = # GETTING_DATA
  • -2146826259 = # ИМЯ?
  • -2146826288 = # НУЛЬ!
  • -2146826252 = #NUM!
  • -2146826265 = #REF!
  • -2146826273 = # ЗНАЧЕНИЕ!

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

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, но принципы такие же, как и для C #. У вас не должно возникнуть проблем с переводом, но если у вас есть какие-либо проблемы, пожалуйста, спросите. (Я надеюсь, что когда-нибудь у меня будет время обновить эту статью для C #. Если это произойдет в какой-то момент, я отредактирую пост, добавив ссылку.)

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

12 голосов
/ 18 марта 2010

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

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

или

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...