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