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