4

In Excel 1234 > qwer = false, but 1234 < qwer = true. Having worked with nullable types in C# I would expect both statements to return false like when comparing values to nulls.

What is rationale behind that? Is it documented somewhere?

My first thought was that Excel internally converts numbers to strings and then compares strings, but then:

'129 < '11a = false - when left part is entered as text

129 < '11a = true - when left part is entered as a number

In VBA variant type comparison works the same way as on spreadsheets

Sub CompareNumberAndText()
    Dim a, b, c

    at = "129"
    an = 129
    b = "11a"
    ct = at < b 'false
    cn = an < b 'true
End Sub

I am developing a library with a type similar to Excel cell and wanted to make behavior as close to Excel as possible, but these Excel comparison results are counter-intuitive. I would throw an error or return false in this case.

I could imagine a hypothetical situation when in column A I calculate some value by dividing two numbers, e.g. P/E ratio, but for negative E I put "n.m.". Then in column B I check if P/E > some_value, I will get true for n.a. If the exercise is to find expensive stocks, then showing ones with negative earnings makes some (but very little) sense and could be useful for further manual one-by-one analysis when there are 20 stocks. But if there are 2000 ones and I calculate some aggregates, this could go unnoticed.

V.B.
  • 6,236
  • 1
  • 33
  • 56

2 Answers2

2

You can refer to Comparing Strings by Using Comparison Operators

According to this for your string comparison at < b, the ASCII value of first character 1 is 49 and same for at and b, however the for the second character the ASCII value of 2 is more than the ASCII value of 1, hence the expression at < b return false

Also as explained in greater detail in Comparison Operators (Visual Basic), if you defined the primitive types of the variables the behavior get changed, see below

Case-1:

Sub CompareNumberAndText()
    Dim at As String, b As String, c As String, an As Integer

    at = "120"
    an = 2
    b = "1"
    c = "3"
    ct = at < b 'false
    cn = an < b 'false
    kl = an < c 'true
End Sub

Case-2:

Sub CompareNumberAndText()
    Dim at As String, b As String, an As Integer

    at = "120"
    an = 2
    b = "1a"
    ct = at < b 'false
    cn = an < b 'error
End Sub

In Case-1 above the string b and c are converted to double and then compared to the value of an and results in proper boolean values as a result, however in Case-2 the program fails to convert the variable b to a double value and throws an error Run Time Error - 13, Type Mismatch.

AKS
  • 18,983
  • 3
  • 43
  • 54
  • You do not explain here why number < text = true for variant types. In case 2 you define types as string and integer and the error is expected, but why if we remove types in Dim (make all of them variant) we will get true for both comparisons in case 2? – V.B. Sep 08 '13 at 09:48
  • I couldn't find any plausible documentation for this in VBA, however it totally imitates the behavior shown in older versions of python (check http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int). I am not sure whether the same reasoning could be applied here too for string to integer comparison. – AKS Sep 08 '13 at 17:32
  • OMG, Python 2 is also counter intuitive! Thanks for the link! Wondering what was in minds of the people who did this, why not just an error!!? – V.B. Sep 08 '13 at 17:47
  • Same thought here, the first comment on the selected answer reflects the same frustration. At least, they changed it in later versions :) – AKS Sep 08 '13 at 17:51
1

Duplicating the way Excel treats comparisons is not a trivial exercise - you need to investigate Unicode collating sequences and locales. For some discussion of the problems see this blog post on sorting and comparing the Excel way

Charles Williams
  • 23,121
  • 5
  • 38
  • 38