On Error~ で実行エラーを判定に使用する

実行エラーが発生すると、メッセージが表示されてマクロ実行は中断されるのが通常の動作です。On Error ステートメントを使うとこの仕組みを無効にできます。つまり、実行エラーのメッセージを表示しないで実行を継続させられます。

実行エラー

実行エラーを避けるために予め確認をするのが正攻法ではありますが、面倒な確認を省いてトライ & エラーで手早く処理してしまうことが可能になります。

主なステートメントやオブジェクト

On Error GoTo 行ラベル

エラーハンドラー(エラー時の処理を指定する構文)です。エラーが発生すると、エラー処理ルーチン に遷移します。行ラベルにはエラー処理ルーチンの開始行をセットします。

On Error Resume Next

エラーハンドラー(エラー時の処理を指定する構文)です。エラーが発生しても、以降の処理を継続します。

On Error GoTo 0

エラーハンドラーの指定を無効にして、通常のエラー処理に戻します。

Resume

エラー処理ルーチン内から、エラーが発生した行に戻って処理します。

Err オブジェクト

エラーの発生時に、その情報がセットされるオブジェクトです。
Err.Number <> 0 で、何らかのエラーが発生したことを捕捉できます。
Err.Description は、エラーメッセージを取得できます。
Err.Clear でセットされた情報をクリアできます。

VBAコードサンプル

今回は、「TABLE_A」という名前のListObject(テーブル)を取得する例を 2パターン紹介します。

このListObjectは、どのワークシートにあるのか特定できないしどこにもないかもしれない、という前提です。

Set myTable = Worksheets(1).ListObjects("TABLE_A")をトライし、エラーになる(ワークシートにない)なら次のワークシートで再トライするという流れです。最後までエラーになる(どこにもない)場合はメッセージを表示します。

On Error GoTo 行ラベル → Resume で復帰

Sub errtest1()
    Dim i As Long: i = 1
    Dim myTable As ListObject
    
    On Error GoTo NoTable
    Set myTable = Worksheets(i).ListObjects("TABLE_A")
    On Error GoTo 0
    
    With myTable
        '-----------
        'テーブルの処理
        '-----------
    End With
    Exit Sub 'ここで終了
    
NoTable: 'エラー処理ルーチン
    If i < Worksheets.Count Then
        i = i + 1
        Resume 'エラー元の処理に戻る
    Else
        MsgBox "TABLE_Aが どのシートにもありません"
    End If
End Sub

NoTable: 行ラベル以降が、エラー処理ルーチンです。エラー時のみに実行させるため、通常処理はその前の Exit Subで必ず終了するようにします。

Resumeで、エラー処理ルーチンから元の処理に戻ります。これにより、Worksheets(1)がダメならWorksheets(2)…というトライを行っています。

On Error Resume Next → Err.Number で判定

Sub errtest2()
    Dim i As Long
    Dim myTable As ListObject
    
    On Error Resume Next
    For i = 1 To Worksheets.Count
        Err.Clear
        Set myTable = Worksheets(i).ListObjects("TABLE_A")
        If Err.Number = 0 Then Exit For
    Next i
    If Err.Number <> 0 Then
        MsgBox "TABLE_Aが どのシートにもありません"
        Exit Sub
    End If
    On Error GoTo 0 'Err.Numberは0にリセットされる
    
    With myTable
        '-----------
        'テーブルの処理
        '-----------
    End With
End Sub

Err.Number には、エラー時に0以外の数値が入ります。成功時に0に書き換わるのではないので判定前にErr.Clearで前回のエラーをリセットしておく必要があります。

On Error GoTo 0 ではErrオブジェクトがリセットされます。このため、Errオブジェクトを使った判定などは、On Error GoTo 0 より前で行う必要があります。

 

タイトルとURLをコピーしました