奇怪的比较方式

Posted

技术标签:

【中文标题】奇怪的比较方式【英文标题】:Strange ways comparisons occur 【发布时间】:2015-02-16 23:39:47 【问题描述】:

我在这里看到这个问题时遇到了一些奇怪的事情:Issue with VBA Excel number formatting 我想我可以扩展它,看看是否有人可以解释。

假设我有一个 Excel 文档,在 A 列中有 5 个单元格,所有单元格的值都是 1234

第一个用格式字符串"000000000"格式化 第二个使用 Excel 的“数字”格式进行格式化 第三个被格式化为 Excel 的“常规”格式 第四个被格式化为“文本” 第五个被格式化为“文本”但实际上是字符串"000001234"

因此,excel表格是这样的

     A    |
----------+-
 000001234|
   1234.00|
      1234|
1234      |
000001234 |

现在我运行以下代码,稍微基于上面提到的问题。

Sub test3()
    Dim rng As Range
    Dim cl As Range
    Set rng = Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row)

    For Each cl In rng.Cells
        If 1234 = "000001234" Then
            cl.Offset(0, 1).Value = "A"
        End If
        If 1234 = cl.Value Then
            cl.Offset(0, 2).Value = "B"
        End If
        If "000001234" = cl.Value Then
            cl.Offset(0, 3).Value = "C"
        End If
    Next cl

End Sub

输出如下

     A    | B | C | D |
----------+---+---+---+-
 000001234| A | B |   |
   1234.00| A | B |   |
      1234| A | B |   |
1234      | A | B |   |
000001234 | A | B | C |

B 列很有意义。 VBA 可以像比较数字一样比较字符串,并且通过扩展列 C 也很有意义,在每种情况下,我们要么将数字与前 3 行中的数字进行比较,要么进行类似的字符串比较最后 2 行。

但是D 专栏让我明白了,基本上是我的问题。

如果1234 = "000001234"1234 = cl.Value 那么为什么不是"000001234" = cl.Value 在所有情况下都不是?

【问题讨论】:

【参考方案1】:

cl.Value 的类型是 vbDouble(前 3 个样本行)或 vbString(其他两个),请参阅 VarType() function。但在比较过程中,有类型转换。 因此

将值与数字1234 进行比较总是会成功,因为cl.Value 中的双精度和字符串在比较之前会转换为数字(整数)。在转换为数字期间,前导零变得无关紧要。 将值与字符串"000001234" 进行比较仅在字符串000001234 的情况下才会成功,因为cl.Value 在比较之前已转换为字符串,因此对于您的第一个示例行"000001234" <> "1234"(请参阅cl.Value 会发生什么:@987654330 @ → 1234"1234")。对于其他行,类似:1234.001234"1234",这又不等于 "000001234" 等。

【讨论】:

以上是关于奇怪的比较方式的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的 Python 日期比较行为

为啥 C++11 包含一个关于比较 void 指针的奇怪子句?

php中的字符串比较奇怪的行为

比较未定义和错误的非常奇怪的行为

在 C++ 中比较时有些奇怪

javascript奇怪的字符串比较[重复]