8

たとえば、次の関数は、ブックが開いているかどうかを確認するために使用されます。

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

この 2 つのErr.Clearステートメントは必要ですか。

4

1 に答える 1

17

この例では

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より良いのは、ペストのように効果があるコードの長いセクションを避けることです。すべてを実行するが途中で失敗する可能性がある大きな関数を作成するのではなく、操作を 1 つのことだけを実行する小さな関数/サブルーチンに分割します。

要するに、ブロック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
于 2013-10-20T12:53:11.283 に答える