はじめに
ExcelVBAでは、エラーに対してどのように対処するかをプログラミングで制御できます。
ExcelVBAでのエラー処理は、On Errorステートメントで行います。主な機能は以下のようになります。
On Errorステートメント | 機 能 |
---|---|
On Error Resume Next | エラーを無視して次の処理へ進む |
On Error GoTo ラベル | エラーが発生したらラベル位置へジャンプ |
On Error GoTo 0 | 設定したエラー処理を無効化する |
例を見ていきましょう。ここでは以下のようなシートの表で、D列に B列をC列で割った値を代入する事を想定しています。

エラーを無視して次へ
プロシージャの途中で、On Error Resume Next とすると、その後エラーが発生しても無視して次に進むようになります。
On Error Resume Next の効果は、On Error GoTo 0で設定を解除するか、そのプロシージャの最後まで続きます。(On Error GoTo 0 については後述します。)
'On Error Resume Next
Sub macro1()
Dim i As Long
On Error Resume Next 'エラーを無視して次へ
For i = 2 To 7
Cells(i, "D") = Cells(i, "B") / Cells(i, "C")
Next i
End Sub
結果は以下のように割り算が出来る時のみD列に値が入り、割り算ができないセルは無視されます。
エラー表示はされません。
尚、On Error Resume Next の効果はプロシージャが終了した時点でなくなります。

エラーが発生したらラベルへ飛ぶ
'On Error GoTo ラベル, Resume Next
Sub macro2()
Dim i As Long, cnt As Long
On Error GoTo ERR_LABEL 'ラベルへジャンプ
cnt = 0
For i = 2 To 7
Cells(i, "D") = Cells(i, "B") / Cells(i, "C")
Next i
If cnt > 0 Then MsgBox cnt & "個のエラーがあります。"
Exit Sub
ERR_LABEL:
cnt = cnt + 1
Resume Next
End Sub

On Error GoTo ラベル を使用すると、エラーが発生した際にラベルにジャンプします。ラベルにジャンプした後で、Resume Next でエラー箇所の次に戻ります。
上記のプログラムでは、エラーが発生した時、ERR_LABEL:に進んだ後、カウンタ変数をインクリメントしてFor文内部に戻ります。結果、エラーの回数をカウントして最後にメッセージボックスで表示します。
ラベルの前に Exit Sub を忘れないようにしましょう。
Errオブジェクト
VBAではエラーが発生すると、Errオブジェクトにその内容が入るので、プロパティで確認できます。
プロパティはエラー番号を示す Numberプロパティ。内容を説明する Description プロパティがよく使われます。
'Errオブジェクト
Sub macro3()
Dim i As Long
On Error GoTo ERR_LABEL 'ラベルへジャンプ
For i = 2 To 7
Cells(i, "D") = Cells(i, "B") / Cells(i, "C")
Next i
Exit Sub
ERR_LABEL:
MsgBox i & "行目" & vbCrLf & _
" エラー番号: " & Err.Number & vbCrLf & _
" " & Err.Description
Resume Next
End Sub

実行すると上記のように3回メッセージボックスが表示され、エラーが起こった行、エラー番号、エラーの説明が表示されます。
エラー番号で分岐
'エラー番号で分岐
Sub macro4()
Dim i As Long
On Error GoTo ERR_LABEL 'ラベルへジャンプ
For i = 2 To 7
Cells(i, "D") = Cells(i, "B") / Cells(i, "C")
Next i
Exit Sub
ERR_LABEL:
Select Case Err.Number
Case 13
MsgBox i & "行目でエラーです。" & vbCrLf & _
"C列,D列の値を確認してください。"
Case 6
MsgBox i & "行目でエラーです。" & vbCrLf & _
"D列の値を確認してください。"
Case Else
MsgBox i & "行目" & vbCrLf & _
" エラー番号: " & Err.Number & vbCrLf & _
" " & Err.Description
End Select
End Sub

このプログラムでは、エラー番号で処理を分岐するため、エラー内容によるメッセージを表示できるようになります。
On Error 処理を中断する
On Error 処理は、プロシージャの最後に無効となりますが、手動で処理を中断させるには
On Error GoTo 0
とします。こうするとプロシージャの最後でなくても途中で効力を無効化させることができます。
'On Error GoTo 0
Sub macro5()
Dim i As Long
For i = 2 To 7
On Error GoTo ERR_LABEL 'ラベルへジャンプ
If Cells(i, "B") = "" And Cells(i, "C") = "" Then
'エラー制御を戻す
On Error GoTo 0
End If
Cells(i, "D") = Cells(i, "B") / Cells(i, "C")
Next i
Exit Sub
ERR_LABEL:
MsgBox i & "行目" & vbCrLf & _
" エラー番号: " & Err.Number & vbCrLf & _
" " & Err.Description
Resume Next
End Sub
今回のプログラムでは、B列とC列が空白の時に、エラー制御を外してエラーが発生するようにしています。
ケースによっては、エラーをカバーするだけでなくキチンとエラーを発生させるのも1つの考え方でしょう。
On Error GoTo 0 を使うケースは少ないかもしれません。
まとめ
プログラマーであれば、エラーがでないようにコードを書くのは当然ですが、時にはエラーをきっかけに処理を分岐させるような手法もあります。このようなケースでは、Errオブジェクトが必須の機能となります。
コメント