2012-02-09 16 views
28

Esta publicación trata de .NET NaN & Los valores de Inifinite se vuelven a pasar a Excel 2010 VBA.Hasta el infinito y más allá en VBA

Uso un método C# que no está bajo mi control que (al parecer) puede devolver .NET NaN o Neg, Pos Infinity. Los resultados en VBA son extraños (es decir, más raros de lo normal), y la única forma en que me he encontrado para lidiar con la situación de forma segura es una comparación poco elegante de tres cuerdas "-1. # IND" o "-1. # INF" o "1. # INF".

¿Hay una manera mejor?

He documentado la parte extraña aquí si tiene curiosidad. (Los ejemplos son para NaN, pero es la misma historia de POS o infinito neg.)

double dVal = CSharpMethodReturningDouble() ' via .NET assembly/COM interop 
variant vVal = CSharpMethodReturningDouble() ' via .NET assembly/COM interop 

Si el método C# devuelve un Double.NaN, entonces tenemos (en la ventana immed):

?dVal    
-1.#IND    
?vVal     
-1.#IND    

el (en caja) la celebración de la variante de NaN positivo por numérico, escriba = doble

?IsNumeric(vVal) 
True 
?TypeName(vVal) 
Double 

las comparaciones en el (en caja) variante trabajo NaN, pero con resultados opuestos que se espera. Las comparaciones en los dobles (Sin Embalaje) causan excepciones de desbordamiento

?vVal=1   '<== NaN comparisons should always return false 
True    
?vVal=0   '<== that's not what you get with -1.#IND 
True    
?dVal=0   '<== strangely, the same comparison on the unboxed double fails 
(OverFlow Exc) 

operaciones en la caja) (variante causa excepciones de desbordamiento operaciones en el (sin embalaje) se duplica el trabajo (y devuelven -1. # IND, como era de esperar)

?vVal * 1.1  '<== even stranger, for arith ops its the boxed value that fails 
(Overflow Exc) 
?dVal * 1.1  '<== but the operation on the unboxed double goes through 
-1.#IND 

EsError, IsNumeric no ayudan:

?IsError(vVal) 
False    
?IsError(dVal) 
False    
?IsNumeric(vVal) 
True  
?IsNumeric(dVal) 
True    

siempre se puede utilizar la comparación de cadenas para probar:

?vVal = "-1.#IND" 
True 
?dVal = "-1.#IND" 
True 
+4

Ver: http://stackoverflow.com/q/2731445/50776 – casperOne

Respuesta

2

Dado que un campo Double.NAN representa un valor que no es un número, es muy probable que esté en el camino correcto usando una comparación de cadenas.

Si iba por el otro camino (es decir, pasando valores de VB), ByRef y ByVal son los sospechosos habituales.

La función IsNumeric() de VB no siempre es intuitiva. Por ejemplo, devolverá True si un código alfanumérico se convierte, por casualidad, en un número en notación científica.

1

Estoy de acuerdo con David en que su solución actual es aceptable. ¡Asegúrate de probar en instalaciones de idiomas extranjeros!

El ejemplo que usted da podría ser parte de la solución: un valor que es igual a 1 y a 0 al mismo tiempo, no es un número normal. Esa prueba puede distinguir los NaN de los números normales. Posiblemente puedas encontrar reglas similares como esta para encontrar +/- infinito.

0

Asegúrese de tener en cuenta la configuración regional actual. NaN puede ser "-1.#IND" o "-1,#IND" según la configuración del separador decimal.

Una forma de evitar esto puede ser la comparación InStr:

InStr(CStr(dVal), "#IND") <> 0 
Cuestiones relacionadas