VBA 中涉及两个整数和一个长整数的溢出错误
Posted
技术标签:
【中文标题】VBA 中涉及两个整数和一个长整数的溢出错误【英文标题】:Overflow error in VBA involving two integers and a Long Integer 【发布时间】:2017-10-30 21:03:28 【问题描述】:我不会在 VBA 中编写代码,但我需要调试其中编写的代码。当我运行代码时,我收到了一个溢出错误,我在网上查看了该错误。我在调试器中使用断点来查找导致错误的代码行。
这是行:
lngInt = nIntA * nIntB
调试器说 nIntA(一个整数)= 4,851,nIntB(另一个整数)= 10。lngInt 是一个长整数,如果我没看错的话:
dim lngInt As Long
nIntA 和 nIntB 初始化为:
Public nIntA As Integer
Public nIntB As Integer
如果有帮助,两者都是从 Access 表单中设置的。
这似乎没有给我一个问题,所以我假设这是 VBA 中的一个怪癖。什么可能导致错误?
提前谢谢你!
【问题讨论】:
Integer * Integer
给出Integer
,所以4851 * 10
在隐式转换为Long
以存储在lngInt
之前给出Overflow
。使用lngInt = CLng(nIntA) * CLng(nIntB)
或者简单地改变声明Public nIntA As Long
和Public nIntB As Long
无论如何,您的 16 位 Integer
变量在内部是在 32 位上计算的,就像 Long
整数一样,那么为什么不声明它们 As Long
呢?这不是“VBA 怪癖”,而是表达式赋值的工作原理:表达式需要在其结果被赋值之前被评估,Integer * Integer
将是Integer
。不要责怪这门语言,VBA 的“怪癖”比人们想象的要少得多——无论如何,它比 javascript 数学要少得多。
【参考方案1】:
Integer
类型已过时。您可以随心所欲地声明和使用 16 位整数,VBA 运行时将强制执行其限制,但在内部它无论如何都(默默地)转换为 32 位整数,所以为什么不直接使用 Long
(32 位) 首先是整数?
也就是说,这与“VBA 怪癖”无关,而是与基础有关:
foo = [expression]
在运行时可以执行foo
的分配之前,需要评估[expression]
。 “怪癖”是 VBA 不关心 foo
的类型,直到 之后 [expression]
被评估,因为无论如何它都必须(隐式)将其转换为该类型:
Dim foo As Double
foo = 2 + 2
2 + 2
是否应该自行评估为Double
?它没有,也不需要。 2 + 2
的计算结果为 4
,由于两个操作数都是 Integer
,因此结果将是 Integer
,因此赋值为:
Dim foo As Double
foo = CDbl((2 + 2))
现在,如果您有两个 Integer
值相乘,并且总数溢出类型,根据规范,您会得到 overflow 错误。
Dim foo As Long
foo = 32000 * 2
因为那仍然是:
Dim foo As Long
foo = CLng((32000 * 2))
注意内括号:(32000 * 2)
被评估为 Integer
之前结果可以转换为 Long
,并且该转换的结果分配给 foo
。 p>
如果其中一个操作数是 Long
,则结果将是 Long
- 因为两个操作数都是 Integer
,所以结果将是 Integer
。
如果您想要时髦的表达式和令人难以置信的隐式转换,请尝试使用 Javascript。 VBA 在这里一点也不“古怪”。
【讨论】:
@YowE3K MSDN states it rather plainly - 另见this answer 关于这个主题。 所以你的意思是我应该将两个 IntA 和 IntB 声明为 Long 整数,这样它们的乘积就不会导致溢出? @JoubertLucas 表达式将计算为其操作数使用的最宽类型,因此两者之一需要是 long 才能使表达式计算为 long,是的。以上是关于VBA 中涉及两个整数和一个长整数的溢出错误的主要内容,如果未能解决你的问题,请参考以下文章