例如,以下函数用于检查工作簿是否已打开:
Function BookOpen(Bk As String) As Boolean
Dim T As Excel.Workbook
Err.Clear
On Error Resume Next
Set T = Application.Workbooks(Bk)
BookOpen = Not T Is Nothing
Err.Clear
On Error GoTo 0
End Function
这两个Err.Clear
陈述是否必要?
答案 0 :(得分:16)
在这个例子中
Function BookOpen(Bk As String) As Boolean
Dim T As Excel.Workbook
Err.Clear
On Error Resume Next
Set T = Application.Workbooks(Bk)
BookOpen = Not T Is Nothing
Err.Clear
On Error GoTo 0
End Function
这些用法都不合适,因为On Error
会重置上一个错误,因此Err.Clear
是多余的。
在实际处理失败的陈述后,这是合适的。
Function BookOpen(Bk As String) As Boolean
Dim T As Excel.Workbook
On Error Resume Next
Set T = Application.Workbooks(Bk) ' this can fail...
' so handle a possible failure
If Err.Number <> 0 Then
MsgBox "The workbook named """ & Bk & """ does not exist."
Err.Clear
End If
BookOpen = Not T Is Nothing
End Function
如果On Error Resume Next
生效,程序将在发生错误后继续,就像没有发生任何事情一样。抛出没有异常,没有警告,这不是结构化错误处理(即它不像try
/ catch
块。如果您不进行严格的错误检查,您的程序可能会处于非常奇怪的状态。
这意味着你必须在之后检查错误。每一个。声明。那。能够。失败。准备写很多的If Err.Number <> 0 Then
项检查。请注意,这比看起来更难做到。
更好的是:避免使用像瘟疫一样有效On Error Resume Next
的长段代码。将操作分解为只执行一件事的较小的函数/子函数,而不是编写一个完成所有操作的大函数,但可以在中途失败。
简而言之:Err.Clear
使您的程序在On Error Resume Next
块中的语句失败后可预测。它将错误标记为已处理。这就是它的目的。
当然,在您的示例中,通过使用通常可接受的方式检查工作簿(即集合成员)是否存在,可以轻松避免错误处理。
Function BookOpen(Bk As String) As Boolean
Dim wb As Variant
BookOpen = False ' not really necessary, VB inits Booleans to False anyway
For Each wb In Application.Workbooks
If LCase(wb.Name) = LCase(Bk) Then
BookOpen = True
Exit For
End If
Next
End Function