在Excel VBA中允许整数溢出是否可行?

3
相当简单,但是我在谷歌上找不到任何相关信息。这是我想要发生的事情的一个例子:
Function myFunc()
    Dim a As Integer
    Dim b As Integer
    Dim c As Integer

    a = 20000
    b = 15000
    c = a + b

    myFunc = c
End Function

我希望我的函数myFunc()在发生溢出时不会抛出异常,而是返回-30536。我知道我可以编写一个能够实现此功能的函数,但我已经为这个项目编写了许多代码,并且假设允许溢出,因此我希望有一个快速解决方案。
编辑:我不需要帮助来解决类型转换引起的溢出问题。我已经有一个解决方案;我只想避免更改数百个加法和减法操作。我有点沮丧的是VBA似乎竭尽全力禁用溢出功能--它应该让用户决定是否要使用它。

为什么不使用Long类型呢? - Alexander Bell
我正在翻译一些 C 代码,它在角度计算中严重依赖于溢出。它将角度存储为 2 字节整数。 - TylerKehne
几乎是这篇文章的副本。 - MikeDub
3个回答

2

我建议编写 MyFunc 以 Long 类型进行数学运算,并测试整数“溢出”并进行调整。

Function MyFunc(a As Integer, b As Integer) As Integer
    Dim sum As Long
    Const Mask As Integer = -1

    sum = CLng(a) + CLng(b)
    If sum > 32767 Then
        sum = sum - 65536
    ElseIf sum < -32768 Then
        sum = sum + 65536
    End If
    MyFunc = sum
End Function

测试一下

Sub zx()
    Debug.Print MyFunc(20000, 15000)

End Sub

是的,基本上我最终采用了这种方法,使用单独的加法和减法函数。虽然不是我所希望的,但至少它能够工作。 - TylerKehne
你可以只使用一个函数,通过取反参数来实现,例如 a-b = MuFunc(a, -b) - chris neilsen
是的,针对那种边缘情况。 - chris neilsen

0
为了防止在您的Excel VBA代码中发生整型溢出,您可以使用自定义函数来执行从整型到长整型的类型转换,如下所示:
Sub TestIntegerConversion()
    Debug.Print myFuncLong(20000, 15000)
End Sub

Function myFuncLong(a As Integer, b As Integer) As Long
    myFuncLong = CLng(a) + CLng(b)
End Function

或者不使用自定义函数,采用这样简单的形式:

Sub PreventOverflow()
    Dim a As Integer
    Dim b As Integer
    a = 20000
    b = 15000

    Debug.Print CLng(a) + CLng(b)
End Sub

或者,您可以编写自己的自定义函数,该函数应实现“溢出数学”(您必须以纯数学符号指定如何从35000获取数字-30536),并将结果作为LongString返回。 可能的实现如下所示(注意:溢出异常编号为6)

Sub OverflowCustomMath()
    Dim a As Integer
    Dim b As Integer
    Dim c As Long
    a = 20000
    b = 15000

On Error GoTo Err:
    Debug.Print a + b
Err:
    If (Err.Number = 6) Then
        'apply your custom overflow math, as for e.g.
        Debug.Print CLng(a) + CLng(b)
    End If
End Sub

希望这可以帮到你。


错失了重点。来自 OP _我希望 myFunc() 返回 -30536_。 - chris neilsen
@chrisneilsen 感谢您的评论:请查看扩展答案。最好的问候, - Alexander Bell
错误处理很有趣,但它是否与函数本身绑定?我希望它适用于所有模块。 - TylerKehne
您可以将溢出错误处理添加到任何函数或子程序中(我猜这就是您所说的“所有模块”)。例如,您可以创建一个全局函数并将其放置在代码模块中,以使其从任何工作表模块等处普遍访问。希望这可以帮助到您。最好的问候。 - Alexander Bell

0

使用典型的VBA错误处理程序,但测试适用于您的情况。

            Option Explicit

            Sub test()
                MsgBox myFunc
            End Sub

            Function myFunc()
            On Error GoTo Local_err
                Dim a As Integer
                Dim b As Integer
                Dim c As Integer

                a = 20000
                b = 15000
                c = a + b

                myFunc = c
Local_exit:
                Exit Function
Local_err:
                If Err = 6 Then
                    myFunc = -30536
                Else
                    MsgBox Err & " " & Err.Description
                    '  myFunc = whatever error value to return
                End If
                Resume Local_exit
            End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接