错误处理子例程将:
运行到过程的末尾,在这种情况下,执行将在调用过程中恢复。
或者,使用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