Идентичные номера VBA не совпадают в операторе if

Прошу прощения, я понимаю, что об этом, возможно, уже спрашивали тысячу раз, но я пытался искать и не могу найти ситуацию, подобную моей. Я все еще учусь, и я никогда раньше не писал здесь, поэтому, пожалуйста, будьте нежны со мной.

Я работаю в Excel VBA. У меня есть две ячейки (PICKAmt и INVAamt, один и тот же лист), и каждая из них имеет одинаковый номер, например. 399,80.

  1. Даже после форматирования ячейки до 0,00 VBA по-прежнему читает их как 399,8, но также говорит, что они не совпадают.

  2. Они оба двойники

  3. Тот же расчет работал при тех же обстоятельствах на другом листе.

  4. Мой код говорит:

    Private Function INVACalc(ByVal INVAamt As Double, Holdcell As String, lastcell1 As String) As Double   
    Dim PICKAmt As Double  
    Dim APSDamt As Double  
    Dim lastcell3 As String  
    Dim SUND As String  
    Dim APIE As String
    
    Worksheets("GL").Activate  
    Range(lastcell1).Offset(0, 9).NumberFormat = "0.00"  
    Range(lastcell1).Offset(0, 9).Value = Application.WorksheetFunction.Sum(Range("AL:AL"))         'add up total of all lines  
    PICKAmt = Range(lastcell1).Offset(0, 9).Value  
    If PICKAmt = INVAamt Then    
       'do stuff  
    Else  
      'do something else  
    End if
    

Он идет прямо к Иному, как будто две суммы не идентичны, а они есть. В них нет лишних пробелов или символов. Единственная разница, которую я могу уловить между ними, заключается в том, что ячейка INVAAmt отформатирована как Custom, а ячейка PICKAmt отформатирована как Number, но опять же, этот же код прекрасно работает на других листах с таким же форматированием. Я в недоумении.


person Ursula    schedule 21.07.2021    source источник
comment
Вычтите одно число из другого, чтобы увидеть разницу. Не полагайтесь на форматированное значение. Если есть разница, она пойдет на Else.   -  person shahkalpeshp    schedule 21.07.2021
comment
Я так делал - разницы нет.   -  person Ursula    schedule 21.07.2021
comment
Вы имеете в виду, что debug.print(PICKAmt - INVAamt) или debug.print(INVAamt - PICKAmt) возвращает 0?   -  person shahkalpeshp    schedule 21.07.2021
comment
Вот это интересно... прошлой ночью я делал вычитание в самом листе, а не в коде, он пришел к 0. Сегодня утром, когда я увидел комментарий shahkalpeshp, я добавил строку в код и снова запустил ее, ожидая, что она быть чистым 0. Я получил следующее: -1.13686837721616E-13.... Я не ожидал, что   -  person Ursula    schedule 22.07.2021
comment
Любые предложения о том, как обойти это?   -  person Ursula    schedule 22.07.2021
comment
Либо If Format(PICKAmt,"0.00") = Format(INVAamt,"0.00") then, либо If Abs(PICKAmt-INVAAmt) < 0.001 тогда   -  person CDP1802    schedule 22.07.2021
comment
@ CDP1802 - сработал первый вариант. Я достаточно новичок, чтобы не понимать, ПОЧЕМУ это сработало, поэтому не стесняйтесь объяснять мне это. Спасибо :)   -  person Ursula    schedule 23.07.2021


Ответы (1)


Проблема заключается в том, как десятичные числа представляются в двоичном виде, как описано здесь. «Одно и то же» десятичное число может иметь более одного представления с плавающей запятой, например

Sub explain()
   Dim n As Double, m As Double, k As Double
   n = 0.6
   m = 0.3 + 0.3
   k = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
   Debug.Print Format(m - n, "0.000000000000000000")
   Debug.Print Format(k - n, "0.000000000000000000")   
End Sub

Первый результат 0.000000000000000000 второй 0.000000000000000111. Одним из решений является форматирование двойников как строк и сравнение строк.

If Format(PICKAmt,"0.00") = Format(INVAamt,"0.00") Then
person CDP1802    schedule 23.07.2021