学习Excel技术,关注微信公众号:
Excelperfect
好的应用程序应该能够捕获错误并进行相应的处理,而不是VBA弹出的错误消息。正如上文提到的,有两种方法处理运行时错误。对于可预见的错误,编写特定的代码来处理它们。对于不可预见的意外错误,则使用VBA错误处理语句来处理。
在VBA中,On Error语句用于错误处理。当代码运行时发生错误时,该语句将执行相应操作。
On Error语句有4种不同的使用方式:
1.On Error GoTo 0
代码停止运行在出现错误的行并显示错误消息。
2.On Error GoTo [标签]
当错误发生时,代码移至指定的行或标签处,不会显示错误消息。
3.On Error GoTo -1
清除当前错误。
4.On Error Resume Next
当错误发生时,代码移至下一行继续执行,不会显示错误消息。
On Error GoTo 0
这是VBA默认的处理错误的操作。
发生错误时,VBA将在出现错误的行上停止运行并显示错误消息。此时,需要用户干预代码才能继续。在这种情况下不会发生错误处理。
让我们看一个例子。在下面的代码中,我们没有使用任何On Error语句,因此VBA默认情况下将使用On Error GoTo 0操作。
Sub DefaultErrorHandle()
Dim x As Long
Dim y As Long
x = 6
y = 6 / 0
x = 7
End Sub
在代码中,使用了0作为除数,因此在运行代码时,将会出现如下图4所示的错误消息。
图4
发生错误时,会导致应用程序中止。如果应用程序已经提供给用户使用而出现错误,这是非常不友好的。可以使用On Error GoTO [标签]语句,让错误发生时执行标签处预先定义的操作,避免应用程序中止。
On Error GoTo [标签]
当发生错误时,会将错误发送到指定的标签,通常位于过程的底部。
如下面的代码:
Sub GotoLabel()
Dim x As Long
Dim y As Long
On Error GoTo errH
x = 6
y = 6 / 0
x = 7
Done:
Exit Sub
errH:
MsgBox "发生了错误: "& Err.Description
EndSub
运行代码的结果如下图5所示。
图5
运行上述VBA代码,代码执行到以0作为除数这一行时,发生错误,代码跳至On Error GoTo 语句指定的标签errH处。
On Error GoTo -1
这个语句用于清除当前发生的错误。如果又发生另一个错误,代码将在发生错误行停止。
如下面的代码所示:
Sub TwoErrors()
On Error GoTo errH
'产生"类型不匹配"错误
Error (13)
Done:
Exit Sub
errH:
'产生"应用程序定义"错误
Error (1034)
End Sub
代码中发生的第一个错误导致代码跳至标签errH处,而第二个错误会导致代码直接停止在错误行,如下图6所示。
图6
而在标签语句内添加的错误处理因前面的错误尚未清除而不会起作用,如下面的代码:
Sub TwoErrors()
On Error GoTo errH
'产生"类型不匹配"错误
Error (13)
Done:
Exit Sub
errH:
On Error GoTo errH_Two
'产生"应用程序定义"错误
Error (1034)
Exit Sub
errH_Two:
Debug.Print "发生另一错误: "& Err.Description
End Sub
运行代码后,会弹出错误消息框,单击“调试”按钮,会停止在错误行,如下图7所示。
图7
要清除已发生的错误,使用On Error GoTo -1。在下面的代码中,我们添加了该语句,这样第二个错误会导致代码跳至errH_Two标签处:
Sub TwoErrors()
On Error GoTo errH
'产生"类型不匹配"错误
Error (13)
Done:
Exit Sub
errH:
'清除错误
On Error GoTo -1
On Error GoTo errH_Two
'产生"应用程序定义"错误
Error (1034)
Exit Sub
errH_Two:
MsgBox "发生另一错误: "& Err.Description
End Sub
运行上述代码后的结果如下图8所示。
图8
On Error Resume Next
使用On Error Resume Next语句,告诉VBA忽略错误并继续执行。
下面的代码会正常执行而不会报错:
Sub ResumeNext()
On Error Resume Next
Dim x As Long
Dim y As Long
x = 6
y = 6 / 0
x = 7
End Sub
有些错误无关紧要,可以忽略不计而不会有什么问题。但是,这样做并不是很好,因为程序中存在的错误往往会以多种方式影响程序自身,最终可能会获得无用的结果,并且你也不知道程序到底发生了什么问题。
然而,在有些情形下On Error Resume Next却很有用,在正文中会提供具体的例子。使用On Error Resume Next语句的一个原则是,其所影响的代码应该尽可能的少,当不再需要该语句时应及时关闭它。