何时适当明确使用Err.Clear?

Fel*_*lix 7 excel vba excel-vba

例如,以下函数用于检查工作簿是否已打开:

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
Run Code Online (Sandbox Code Playgroud)

这两个Err.Clear陈述是否必要?

Tom*_*lak 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
Run Code Online (Sandbox Code Playgroud)

没有任何用途是合适的,因为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
Run Code Online (Sandbox Code Playgroud)

如果你On Error Resume Next有效,程序将在错误后继续,好像什么也没发生.抛出没有异常,没有警告,这不是结构化错误处理(即它不像try/ catchblocks).如果您不进行严格的错误检查,您的程序可能会处于非常奇怪的状态.

这意味着你必须在之后检查错误.每一个.声明.那.能够.失败.准备写了很多If Err.Number <> 0 Then检查.请注意,这比看起来更难.

更好的是:避免使用On Error Resume Next像瘟疫一样有效的长段代码.将操作分解为只执行一件事的较小的函数/子函数,而不是编写一个完成所有操作的大函数,但可以在中途失败.

简而言之:Err.ClearOn 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
Run Code Online (Sandbox Code Playgroud)