VBA Resume 关键字

示例

错误处理子例程将:

  • 运行到过程的末尾,在这种情况下,执行将在调用过程中恢复。

  • 或者,使用Resume关键字在同一过程中恢复执行。

该Resume关键字仅应在错误处理子例程内使用,因为如果VBA遇到Resume但未处于错误状态,则会引发运行时错误20“恢复无错误”。

错误处理子例程可以通过多种方式使用Resume关键字:

  • Resume单独使用时,将继续执行导致错误的语句。如果在执行此操作之前未真正处理该错误,则将再次引发相同的错误,并且执行可能会进入无限循环。

  • Resume Next导致错误的语句之后立即继续对语句执行。如果在执行此操作之前未真正处理错误,则允许执行以可能无效的数据继续执行,这可能导致逻辑错误和意外行为。

  • Resume [line label]继续在指定的行标签(或行号,如果您使用的是旧式行号)上执行。通常,这将允许在干净退出过程之前执行一些清理代码,例如确保在返回调用者之前关闭数据库连接。


关于错误继续

该On Error语句本身可以使用Resume关键字来指示VBA运行时有效地忽略所有的错误

如果在执行此操作之前未实际处理错误,则允许执行以可能无效的数据继续执行,这可能导致逻辑错误和意外行为

上面的强调不能足够强调。On Error Resume Next有效地忽略了所有错误并将它们推到地毯下面。在输入无效的情况下,由于运行时错误而崩溃的程序比继续使用未知/意外数据运行的程序要好-仅仅是因为该错误更容易识别。On Error Resume Next可以轻松隐藏错误

该On Error语句是过程范围的-这就是为什么在给定过程中通常只应有一个,单个这样的On Error语句的原因。

但是,有时无法完全避免错误情况,而跳转到错误处理子例程只是Resume Next感觉不对。在这种特定情况下,可以将已知可能失败的语句包装在两个On Error语句之间:

On Error Resume Next
[possibly-failing statement]
Err.Clear 'resets current error
On Error GoTo 0

该On Error GoTo 0指令将重置当前过程中的错误处理,以便导致该运行时错误的任何其他指令将在该过程中未处理,而是向上传递到调用堆栈,直到被活动的错误处理程序捕获为止。如果调用堆栈中没有活动的错误处理程序,它将被视为未处理的异常。

Public Sub Caller()
    On Error GoTo Handler
    
    Callee
    
    Exit Sub
Handler:
   Debug.Print"Error " &Err.Number& " in Caller."
End Sub

Public Sub Callee()
    On Error GoTo Handler
    
   Err.Raise1     'This will be handled by the Callee handler.
    On Error GoTo 0 'After this statement, errors are passed up the stack.
   Err.Raise2     'This will be handled by the Caller handler.    
    
    Exit Sub
Handler:
   Debug.Print"Error " &Err.Number& " in Callee."
    Resume Next
End Sub