如果我在即时窗口中键入以下内容,则会收到运行时错误“6”:溢出。
MsgBox 24 * 60 * 60
为什么是这样?
这也失败了:
Dim giveTime As Long
giveTime = 24 * 60 * 60
为什么是这样?giveTime
被声明为 Long 类型,因此 24 × 60 × 60 = 86400 应该很合适。
如果我在即时窗口中键入以下内容,则会收到运行时错误“6”:溢出。
MsgBox 24 * 60 * 60
为什么是这样?
这也失败了:
Dim giveTime As Long
giveTime = 24 * 60 * 60
为什么是这样?giveTime
被声明为 Long 类型,因此 24 × 60 × 60 = 86400 应该很合适。
这是一个非常奇怪的 VBA 怪癖。我很惊讶我从来没有碰到过这个。
Dim x As Long
x = 24 * 60 * 60 ' Overflow
x = 32767 + 1 ' Overflow.
x = 32768 + 1 ' Works fine!
所以看起来*
and+
运算符在前两个示例中返回一个整数。果然,在运算符的帮助文件中*
(运算符类似+
):
结果= number1 * number2
[...]
结果的数据类型通常与最精确表达式的数据类型相同。
默认情况下,您的文字 24、60 和 60 都是 Integer 类型,因此您的*
(or +
) 运算符返回一个 Integer,它会溢出,因为结果大于 32,767。
但是,上面第三个示例中的文字 32,768 默认为 Long 类型(因为它太大而不能成为 Integer),因此+
返回 Long;没有溢出。
帮助文件也这样说:
如果 [...] result的数据类型是超出其合法范围的整数变体[...] 那么result将 [...] 转换为 Long 变体。
强调我的。现在这个小规则听起来像是常识,任何人都会合理地假设它适用于你的情况。但是您的数字是整数类型,而不是 Variant/Integer,因此 VBA 不适用此规则!对我来说绝对没有意义,但这就是事实,这就是文档所说的。
解决方案:使您的*
运算符的参数之一是比整数更精确的类型(例如 Long),问题就会消失。
x = CLng(24) * 60 * 60 ' Result is Long, works fine.
事实上,这可能就是我从未遇到过这个怪癖的原因,我养成了将所有 Integer 变量声明为 Long 的习惯,除非特别担心使用 Long 而不是 Integer 会导致内存使用问题或执行时间(几乎从来没有这种情况)。当然,当您对小于 32,768 的文字进行操作时,这将无济于事,因为它们默认为整数类型。
您在评论中询问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
在每个数字之后,放置#。它将每个数字定义为双精度数。可以将其想象为,每个数字都作为临时变量放入内存中进行计算。如果您定义每个数字,它将为计算留出足够的空间。
例如:
暗淡 x 长
x = 24# * 60# * 60#
或 24&' 表示长