実行エラーが発生すると、メッセージが表示されてマクロ実行は中断されるのが通常の動作です。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 より前で行う必要があります。
