Подтвердить что ты не робот

До бесконечности и дальше в VBA

Это сообщение о значениях .NET NaN и Inifinite, которые передаются обратно в Excel 2010 VBA.

Я использую метод С#, который не под моим контролем, который (по-видимому) может вернуть .NET NaN или Neg, Pos Infinity. Результаты в VBA выглядят странно (т.е. Более странно, чем обычно), и единственный способ, с помощью которого я справился с ситуацией, - это неэлегантное сравнение трех строк: "-1. # IND" или "-1. # INF" или "1. # INF".

Есть ли лучший способ?

Я записал здесь странную часть, если вам интересно. (Примеры для NaN, но это одна и та же история для pos или neg infinity.)

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

Если метод С# возвращает double.NaN, то мы имеем (в непосредственном окне):

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

Вариант (в штучной упаковке), содержащий тесты NaN, положительные для числовых, тип = double

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

Сравнение на (в штучной) версии NaN, но с противоположными результатами, которые вы ожидаете. Сравнения в (unboxed) дублированиях вызывают исключения переполнения

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

Операции над вариантом (в коробке) вызывают исключения переполнения Операции над (unboxed) удваивают работу (и возвращают -1. # IND, как ожидалось)

?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, IsNumeric не помогает:

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

Всегда можно использовать сравнение строк для тестирования:

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

Ответ 1

Так как поле Double.NAN представляет значение, которое не является числом, вы, скорее всего, на правильном пути, используя сравнение строк.

Если вы идете в другую сторону (т.е. передавая значения из VB), ByRef и ByVal являются обычными подозреваемыми.

Функция VB IsNumeric() не всегда интуитивно понятна. Например, он вернет True, если буквенно-цифровой код, случайно, будет номером в научной нотации.

Ответ 2

Я согласен с Дэвидом в том, что ваше текущее решение приемлемо. Обязательно протестируйте на иностранных языках, хотя!

Пример, который вы дадите, может быть частью решения: значение, равное 1 и 0 одновременно, не является нормальным числом. Этот тест может отличать NaN от нормальных чисел. Возможно, вы найдете подобные правила, чтобы найти +/- бесконечность.

Ответ 3

Удостоверьтесь, что вы учитываете текущий язык. NaN может быть "-1.#IND" или "-1,#IND" в зависимости от настроек разделителя.

Одним из способов избежать этого может быть сравнение InStr:

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