这是一个非常奇怪的 VBA 怪癖。我很惊讶我从来没有碰到过这个。
Dim x As Long
x = 24 * 60 * 60 ' Overflow
x = 32767 + 1 ' Overflow.
x = 32768 + 1 ' Works fine!
所以看起来* 和+ 运算符在前两个示例中返回一个整数。果然,在*operator的帮助文件中(+operator类似):
结果 = number1 * number2
[...]
result 的数据类型通常与最精确表达式的数据类型相同。
默认情况下,您的文字 24、60 和 60 都是 Integer 类型,因此您的 *(或 +)运算符返回一个 Integer,它会溢出,因为结果大于 32,767。
但是,上面第三个示例中的文字 32,768 默认为 Long 类型(因为它太大而不能成为 Integer),因此 + 返回一个 Long;没有溢出。
帮助文件也这样说:
如果 [...] result 的数据类型是整数 variant 超出其合法范围 [...] 那么 result [...] 转换为 Long 变体。
强调我的。现在这个小规则听起来像是常识,任何人都会合理地假设它适用于你的情况。但是您的数字是整数类型,而不是 Variant/Integer,因此 VBA 不适用此规则!对我来说绝对没有意义,但这就是事实,这就是文档所说的。
解决方案:将* 运算符的参数之一设为比整数更精确的类型(例如 Long),问题就会消失。
x = CLng(24) * 60 * 60 ' Result is Long, works fine.
事实上,这可能就是我从未遇到过这个怪癖的原因,我养成了将所有整数变量声明为 Long 的习惯,除非特别担心使用 Long 而不是 Integer 会导致问题内存使用或执行时间(几乎从来没有这种情况)。当然,当您对小于 32,768 的文字进行操作时,这将无济于事,因为它们默认为整数类型。
您在 a comment 中询问 Variant/Integer 是什么。 Variant 基本上是任何其他数据类型的容器类型。在您使其包含整数的特定情况下:
Dim a As Variant ' a is now Empty
a = CInt(32767) ' a is now Variant/Integer
x = a + 1 ' works fine
但如上所述,一个普通的旧 Integer 会触发溢出错误:
Dim b As Integer
b = 32767
x = b + 1 ' overflow