在VBA中使用IFERROR

时间:2018-01-08 14:33:33

标签: vba excel-vba excel

我希望有人可以帮助我吗?我已经做了很多谷歌搜索,无法弄清问题是什么。我只涉足vba,所以我当然不是专家......

我正在尝试在工作中的巨大电子表格中自动执行某些计算,我想我可能错过了一些非常愚蠢的事情。基本上,其中一个计算是一个单元格与另一个单元格的简单划分。当它遇到错误时,我希望它返回0.这是不断跳过的代码:

Sheets("Bridge").Range("W" & SumIfInt) = Application.WorksheetFunction.IfError(Sheets("Bridge").Range("AA" & SumIfInt) / Sheets("Bridge").Range("D" & SumIfInt), 0)

我收到运行时错误6溢出

提前致谢

4 个答案:

答案 0 :(得分:8)

编程时,最好先通过检查它的可能性来避免错误,而不是先触发它然后处理它。在执行计算之前检查单元格是空还是零:

If IsEmpty(Sheets("Bridge").Range("D" & SumIfInt)) Or Sheets("Bridge").Range("D" & SumIfInt) = 0 Then
    Sheets("Bridge").Range("W" & SumIfInt) = 0
Else
    Sheets("Bridge").Range("W" & SumIfInt) = Sheets("Bridge").Range("AA" & SumIfInt) / Sheets("Bridge").Range("D" & SumIfInt)
End If

On Error Resume Next基本上说“如果遇到错误就忽略它”。这可能会导致各种意外问题,只能作为最后的手段使用。

同时查看VBA中的IsError功能。

答案 1 :(得分:4)

尝试此操作而不使用If错误功能。如下所述,您应该非常小心地使用On error resume。

警告:On error resume next将跳过其余代码的所有错误情况,除非存在On error goto 0。此外,如果您想捕获特定错误,可以使用if error = 'number' then来相应地处理它们。 Application.worksheetfunction.iserror最好在excel中使用,而不是在excel vba中使用。

    On error resume next
    Sheets("Bridge").Range("W" & SumIfInt) = Sheets("Bridge").Range("AA" & 
    SumIfInt) / Sheets("Bridge").Range("D" & SumIfInt)

    if err <>0 then
       Sheets("Bridge").Range("W" & SumIfInt) = 0
    end if
    On error goto 0

答案 2 :(得分:4)

SumIfInt的声明类型是什么?如果那个Integer,其最大合法值是32,767,因为Integer是16位类型 - 并且使用16位有符号整数类型来表示Excel工作表中的行号是实现运行时错误的好方法6&#34;溢出&#34;。

使用32位整数类型:

Dim SumIfInt As Long

如果Sheets("Bridge").Range("D" & SumIfInt)是一个非常小的值,那么使用它作为分母可能会导致结果溢出Integer,或者甚至可能是Long - 如果你应该使用Double浮点类型。

  

当遇到错误时,我希望它返回0。

更好的代码根本不会遇到错误。你应该担心的唯一错误是&#34;除以零&#34; - 实际上也是&#34;类型不匹配&#34;如果任何涉及的单元格可能包含错误值 - 在任何情况下,用On Error Resume Next推送地毯下的错误并不会向您展示如何避免将来出现这种情况。

最好的错误处理代码是首先避免引发可避免错误的代码。

Dim divisorValue As Variant 
divisorValue = Sheets("Bridge").Range("D" & SumIfInt)

If IsError(divisorValue) Or IsEmpty(divisorValue) Then
    ' return 0 and bail out
    Exit Function
End If

Dim divisor As Double
divisor = CDbl(divisorValue)

现在使用已知的divisor值。

关于对象管理的说明:您多次取消引用完全相同的对象引用 - 效率低下。

如果在Sheets("Bridge")(运行代码的工作簿)的编译时存在ThisWorkbook,那么从不需要以这种方式取消引用 - VBA为工作簿中的每个工作表创建一个全局范围的对象变量 - 在VBE的 Project Explorer (Ctrl + R)中选择它,调出其属性(F4),然后将其(Name)设置为有意义的内容,例如BridgeSheet。然后你可以这样做:

BridgeSheet.Range("D" & SumIfInt)

另一个提示:你塞进一条指令的次数越多,调试就越难,因为有更多可能的失败点。

考虑将所涉及的个人价值拉入他们自己的变量,然后验证它们,然后一旦你知道这样做就不会爆炸

答案 3 :(得分:1)

尽量避免首先创建错误 - 通常应使用On Error来处理意外错误 这背后的原因是,如果On Error Resume Next之后发生真正的错误,它将被忽略,你的总和将为0。 例如如果有人写了五百而不是一个 500 ,你只会得到一个0(远远的,但是......实际上,不远处 - 永远不会估计一个足够有才华的白痴)。

反正....

如果Sheets("Bridge").Range("D" & SumIfInt)为零或为空,您将得到除以0的错误 提供其他所有内容是正确的(没有文本,所有其他数字都存在),那么这是您需要检查的唯一数字:

Sub Test()

    Dim SumIfInt As Long
    SumIfInt = 2

    With ThisWorkbook.Sheets("Bridge")
        If .Range("D" & SumIfInt) = 0 Then
            .Range("W" & SumIfInt) = 0
        Else
            .Range("W" & SumIfInt) = .Range("AA" & SumIfInt) / .Range("D" & SumIfInt)
        End If
    End With

End Sub