【问题标题】:When is it appropriate to explicitly use Err.Clear?什么时候适合显式使用 Err.Clear?
【发布时间】:2013-10-20 12:35:38
【问题描述】:

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

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 语句是否必要?

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    在这个例子中

    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 &lt;&gt; 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
    

    【讨论】:

    • 如果你删除Err.Clear,你的代码会发生什么?
    • 程序将继续运行并且错误仍然存​​在,直到下一个On Error 语句。当代码变得更复杂时,不清除您已处理的错误可能会导致难以发现的错误。
    • 任何On Error 语句都会清除Err 对象。所以除非你做一个具体的检查If Err.Number你不会有问题。
    猜你喜欢
    • 2011-09-13
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 2019-09-17
    • 2019-08-25
    相关资源
    最近更新 更多