Как узнать, имеет ли ячейка ошибку в формуле в С#
В формуле 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 простая функция для этого?
Ответы
Ответ 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, но принципы точно такие же, как для С#. У вас не должно быть проблем с переводом, но если у вас возникнут проблемы, спросите пожалуйста. (В какой-то день я надеюсь, что у меня есть время, чтобы обновить эту статью для С#. Если это произойдет в какой-то момент, я отредактирую сообщение, чтобы включить ссылку.)
Надеюсь, это поможет!