运行时错误 20 恢复没有错误

不正确的代码

Sub DoSomething()
    On Error GoTo CleanFail
    DoSomethingElse

CleanFail:
    Debug.Print Err.Number
    Resume Next
End Sub

为什么这不起作用?

如果 DoSomethingElse 程序引发错误,执行跳转到 CleanFail 行标签,打印错误号,Resume Next 指令跳回到紧跟错误发生线之后的指令,在这种情况下是 Debug.Print 指令:错误处理子程序在没有错误上下文的情况下执行,当达到 Resume Next 指令时,会引发运行时错误 20,因为无处可去。

正确的代码

Sub DoSomething()
    On Error GoTo CleanFail
    DoSomethingElse

    Exit Sub    
CleanFail:
    Debug.Print Err.Number
    Resume Next
End Sub

为什么这样做?

通过在 CleanFail 行标签之前引入 Exit Sub 指令,我们将 CleanFail 错误处理子程序与过程体的其余部分隔离开来 - 执行错误处理子程序的唯一方法是通过 On Error 跳转; 因此,没有执行路径到达错误上下文之外的 Resume 指令,这避免了运行时错误 20。

其他说明

这与运行时错误 3 非常相似 :没有 GoSub 返回 ; 在这两种情况下,解决方案是确保正常的执行路径不能在没有显式跳转的情况下进入子程序(由线标签标识)(假设 On Error GoTo 被认为是显式跳转 )。