サイトについて      連絡先   検索

VBA エラー処理

はじめに

Excel VBA のエラーを処理する方法を紹介します。

On Error Resume Next でエラーを無視できます。

On Error GoTo ラベル名 でエラーをキャッチできます。

On Error GoTo 0 でエラー処理を無効にできます。

エラーを無視する

On Error Resume Nextと書くと、関数内でそれ以降のコードで発生したエラーを無視して処理を続行します。それより前のコードでエラーが発生したときは無視されません。


    Dim i As Integer
    i = "Tips" ' このエラーは無視されない

On Error Resume Next ' 以降のエラーを無視します

    i = 1
    i = "Tips" ' このエラーが無視されます。i の値は変化しません
    Debug.Print(i) ' 1

このため絶対にエラーでプログラムを中断したくないときは、関数の頭に書くことをオススメします。この関数から実行する別の関数にも適用されるので、マクロの実行で最初に実行される関数に書けば、すべての処理のエラーを無視できます。


Sub 実行()
On Error Resume Next

    ' 処理

End Sub

エラーを無視した時にプログラムが正常に動作しているかは注意が必要です。本来設定する必要のある値をエラーで無視されると、その後の処理で次のエラーが発生する原因にもなります。

プログラムを安全に動作させるためにはエラーが発生したら無視せずに終了することです。

エラーをキャッチする

On Error GoTo ラベル名と書くと、エラーが発生したとき指定したラベルの行に処理を飛ばします。

ラベル名:でエラー発生時に処理する行の名前を決めます。


On Error GoTo Catch ' エラーが発生したら Catch: の行まで処理を飛ばします
    Dim i As Integer
    i = 1
    i = "a" ' エラーが発生
    i = 2

    Exit Sub
    Exit Function

Catch: ' エラーが発生したときはこの後から処理を行います
    Debug.Print(i) ' 1

Catch: の前に Exit Sub または Exit Function があるのに注目してください。行ラベルの前で処理を抜けるようなことはありません。正常に処理が行われた時も Catch: 以降のコードは実行されます。このためエラーが発生したときだけ Catch: 以降のコードを実行したいときは、その前で処理を抜けるために Exit が必要になります。

エラー処理を無効にする

On Error GoTo 0と書くと、それ以降のコードにエラー処理が適用されなくなります。

途中まではエラー処理を無視して、特定の行以降はエラーを発生させたいときに使用します。


On Error Resume Next ' 以降のエラーを無視します

    Dim i As Integer
    i = 1
    i = "Tips"  ' このエラーは無視されます

On Error GoTo 0 ' 以降はエラー処理が行われません

    i = "Tips"  ' エラーが発生します

Finally

他のプログラミング言語には正常に処理が行われても、エラーが発生しても、必ず最後の後処理ができる Finally というものがあります。VBA でそれを再現するには次のようにします。


Public Function 関数 As Boolean
On Error GoTo Catch
    ' 通常の処理

    Debug.Print ("正常")
    関数 = True ' 正常に終了

Finally:
On Error Resume Next
    ' 正常でもエラーでも最後に必ずこの処理が実行される

    Debug.Print ("Finally")
    Exit Function ' ここで関数を抜ける

Catch:
    ' エラー処理

    Debug.Print ("エラー")
    関数 = False ' エラーが発生
    Resume Finally
End Function
Catch: でエラーが発生する処理を書かないでください。そこでエラーが発生すると必ずエラーメッセージが表示され処理が終了します。エラーの発生中に起きたエラーは処理できません。

Catch: で発生するエラーを無視するには次のようにしてできます。


Public Function 関数 As Boolean
On Error GoTo Catch
    ' 通常の処理

    Debug.Print ("正常")
    関数 = True ' 正常に終了

Finally:
On Error Resume Next
    ' 正常でもエラーでも最後に必ずこの処理が実行される

    Debug.Print ("Finally")
    Exit Function ' ここで関数を抜ける

Catch:
    ' ここでエラー情報を取得できますが、その処理でエラーが発生するとプログラムは終了します。
    Dim errDescription As String
    errDescription = Err.Description

    Resume Catch2

Catch2:
On Error Resume Next
    
    ' エラー処理
    Debug.Print (errDescription)
    関数 = False ' エラーが発生
    GoTo Finally
End Function

Catch: でエラー情報の取得だけを行いエラーが発生しないようにします。そこでResume ラベル名を実行すると、エラーの発生を終わらせてラベル名の行から処理を再開できます。

Catch2: のコードはResume ラベル名の後に呼ばれるので、もはやエラー発生中ではなく通常の処理になっています。このため On Error Resume Next でエラーを無視できます。

関連ページ