30 Stimmen

Bis ins Unendliche und darüber hinaus in VBA

In diesem Beitrag geht es um .NET NaN's & Inifinite values getting passed back to Excel 2010 VBA.

Ich verwende eine C#-Methode, auf die ich keinen Einfluss habe und die (anscheinend) .NET-NaNs oder Neg,Pos Infinity zurückgeben kann. Die Ergebnisse in VBA sind seltsam (d.h. seltsamer als üblich), und der einzige Weg, den ich gefunden habe, um mit der Situation sicher umzugehen, ist ein uneleganter Dreifach-Zeichenfolgenvergleich "-1.#IND" oder "-1.#INF" oder "1.#INF".

Gibt es einen besseren Weg?

Ich habe den merkwürdigen Teil hier dokumentiert, falls Sie neugierig sind. (Die Beispiele sind für NaN, aber es ist die gleiche Geschichte für pos oder neg Unendlichkeit).

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

Wenn die C#-Methode ein double.NaN zurückgibt, dann haben wir (im Fenster immed):

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

Die (umrahmte) Variante mit dem NaN-Test ist positiv für numerisch, Typ = double

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

Vergleiche mit der (umrahmten) Variante NaN funktionieren, allerdings mit den entgegengesetzten Ergebnissen, die man erwarten würde. Vergleiche mit den (unboxed) Doubles führen zu Überlaufausnahmen

?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)

Operationen auf der (geboxten) Variante führen zu Überlaufausnahmen Operationen mit den (unboxed) Doubles funktionieren (und geben erwartungsgemäß -1.#IND zurück)

?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 

IsError und IsNumeric helfen nicht weiter:

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

Sie können immer einen String-Vergleich zum Testen verwenden:

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

2voto

David Healy Punkte 83

Da ein Double.NAN-Feld einen Wert darstellt, der keine Zahl ist, sind Sie sehr wahrscheinlich auf dem richtigen Weg, wenn Sie einen Zeichenfolgenvergleich verwenden.

Wenn Sie den umgekehrten Weg gehen würden (d.h. Werte aus VB heraus übergeben), sind ByRef und ByVal die üblichen Verdächtigen.

Die Funktion IsNumeric() von VB ist nicht immer intuitiv. Zum Beispiel gibt sie True zurück, wenn ein alphanumerischer Code zufällig eine Zahl in wissenschaftlicher Notation ist.

1voto

Ich stimme mit David überein, dass Ihre derzeitige Problemlösung akzeptabel ist. Testen Sie sie jedoch unbedingt bei fremdsprachigen Installationen!

Das Beispiel, das Sie anführen, könnte Teil der Lösung sein: Ein Wert, der gleichzeitig 1 und 0 ist, ist keine normale Zahl. Dieser Test kann NaNs von normalen Zahlen unterscheiden. Möglicherweise können Sie ähnliche Regeln wie diese finden, um +/-Unendlichkeit zu finden.

0voto

apan Punkte 1

Achten Sie darauf, dass Sie den aktuellen Standort berücksichtigen. NaN kann sein "-1.#IND" o "-1,#IND" je nach Einstellung des Dezimaltrennzeichens.

Eine Möglichkeit, dies zu vermeiden, kann der InStr-Vergleich sein:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X