2010-03-11 12 views
21

En una fórmula de Excel puede utilizar =ISERR(A1) o =ISERROR(A1)¿Cómo saber si una célula tiene un error en la fórmula en C#

En una macro de VBA puede utilizar IsError(sheet.Cells(1, 1))

Pero el uso de un proyecto VSTO Excel Addin No encontré una función similar en la API Microsoft.Office.Interop.Excel. Solo quiero saber si hay un error en la celda, no estoy realmente interesado en el tipo de error.

Mi solución actual es hacer esto para todos los mensajes de error existentes .:

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

¿Hay una mejor manera de hacer esto. ¿Hay una función simple en la API para eso?

+0

'(sheet.Cells [1,1] as Range) .Text' se ve mejor. –

+0

Se ve mejor, pero si por alguna razón Cells [1,1] no es de tipo Range, entonces tendremos una NullReferenceException en lugar de una InvalidCastException. Prefiero obtener un tipo de excepción más preciso que mejorar la legibilidad en este caso. – Pascal

Respuesta

12

se puede utilizar el WorksheetFunction método:

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

o

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

El IsErr es semánticamente idéntica a la función de hoja de cálculo de Excel, sólo que en lugar de la pasada de referencia de la celda en el valor real - que yo sepa .

+2

Nota rápida: 'WorksheetFunction.IsErr' devolverá valores falsos para # N/A, por diseño. Por lo tanto, para usar este enfoque, uno debería usar 'WorksheetFunction.IsError' en su lugar. Si necesita recoger un valor CVErr * particular *, puede recoger valores # N/A usando 'WorksheetFunction.IsNA', pero para cualquier otro tipo CVErr en particular, debe usar el enfoque que he delineado abajo. –

+0

¡Gracias por la aclaración, Mike! – code4life

+0

Por alguna razón, la WorksheetFunction.IsError() no funciona para mí, pero la otra solución (prueba para 'is Int32') funciona. – earcam

58

El tratamiento de los valores CVErr en .NET es un tema muy complicado. El problema es que .NET (por derecho) considera CVErr como obsoleto con respecto al manejo de errores. Los valores de CVErr, sin embargo, todavía se usan en las celdas de Excel, por lo que esta es una omisión bastante grande para la automatización de Excel.

Afortunadamente, hay una solución. La forma de verificar valores CVErr es examinar el tipo de datos que posee la celda. Si el valor retenido se escribe como un Entero (Int32), entonces el valor retenido es un CVErr. (Tenga en cuenta que los valores numéricos almacenados en una celda normalmente se escriben como Double, solo los valores CVerr pueden aparecer como Integer).

Es decir, en el nivel más simple, para probar un valor CVErr, todo lo que necesita hacer es utilizar la siguiente función:

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

Si necesita comprobar un valor CVErr específica (por ejemplo, # N/a), entonces en primer lugar comprobar para asegurarse de que el tipo de datos es un entero (Int32) y luego verifique el valor específico que tiene la celda, según esta tabla:

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

Por ejemplo, el código podría tener este aspecto:

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); 
} 

Me escribió un detallado artículo en dos partes sobre esto hace unos años:

Los artículos están escritos para VB.NET, pero los principios son exactamente los mismos que para C#. No debería tener problemas para traducir, pero si tiene algún problema, solicítelo. (Algún día espero tener el tiempo para actualizar este artículo para C#. Si eso sucede en algún momento, editaré la publicación para incluir un enlace.)

Espero que esto ayude!

+10

Este tipo es la respuesta que hace que las personas deseen TENER una función de 'supervoto de un día' – AakashM

+0

Gracias Mike, esta es la información que he estado buscando todo el día. estaba obteniendo un número extraño de filas devueltas y no se dio cuenta de que VBA trata las células con un CVErr de manera diferente a .net (que solo las considera como un valor Int. –

+0

Me alegro de que esto haya sido útil. Cuando intenté este problema hace algunos años, realmente me dio un vuelco. Es un problema aparentemente imposible de resolver. Así que una vez que descubrí cómo manejarlo, solo tuve que escribirlo. –

Cuestiones relacionadas