2

I have a simple error checking problem. At the start of my sub I'm making sure that a range adds up to 100%. I do this by getting the value of a Cell "F3" using Range.value and storing it as a double. F3 contains a SUM formula that checks another range.

I can see that in the locals window the value of the double is 1 (because the values add up to 100%), however, the code still gets into the If statement below and exits the sub.

Sub dataCollection()

'Define sheets
Dim ipt As Worksheet
Set ipt = Sheets("Input form")

'Check that allocation is 100%
Dim alloc As Double
alloc = ipt.Range("F3").Value

If alloc <> 1 Then
    MsgBox "Error, allocation does not equal 100%"
    Exit Sub
End If

...

End Sub

Is this a problem with using a double in this way or something?

Vityata
  • 42,633
  • 8
  • 55
  • 100
James Baker
  • 331
  • 3
  • 8
  • 26

1 Answers1

3

Using double or any floating point number in computer languages is a well known problem. Thus, you should never compare double values. Or you should be careful, when doing so. In your case, use something like:

If Abs(alloc-1) > 0.000000001 Then

More reading here: Floating point inaccuracy examples

In general, to understand what is happening, try the following code in a new excel workbook:

Option Explicit

Public Sub TestMe()

    Dim cntSum      As Double

    Cells.Clear

    Cells(1, 1) = 0.3
    Cells(2, 1) = 0.2
    Cells(3, 1) = 0.2
    Cells(4, 1) = 0.2
    Cells(5, 1) = 0.1

    cntSum = Cells(1, 1) + Cells(2, 1) + Cells(3, 1) + Cells(4, 1) + Cells(5, 1)

    Debug.Print cntSum
    Debug.Print cntSum = 1
    Debug.Print cntSum - 1

End Sub

You will have the following in the console:

 1 
False
-1,11022302462516E-16 

It will mean that cntSum is 1 (first line), but it is not equal to 1 (second line) and the absolute difference between it and 1 is -1,11~E-16.

In Excel, a way to go around this is using the Currency format. Add this line:

Range("A1:A5").Style = "Currency"

after the Cells.Clear code and run it again. Now the result is different.

Vityata
  • 42,633
  • 8
  • 55
  • 100