更新日:、 作成日:
VBA エラー処理をする (On Errer GoTo)
はじめに
Excel VBA マクロでエラー処理をする方法を紹介します。
On Error GoTo ラベル名 から、ラベルの位置からエラー処理できます。
On Error Resume Next から、エラーを無視して処理を継続できます。
On Error GoTo 0 から、エラー処理を無効にできます。
エラー処理する方法
エラーが発生したときにできることは、次の通りです。
- キャッチする
- 無視する
- 中断してデバッグする (開発用)
キャッチする:通常はエラーをキャッチします。処理をそこで中断して、適切なエラー処理をすることです。意図しないエラーに対処するためにも、エラーをキャッチする必要があります。
無視する:無視するとは、エラーが発生していないかのように処理を継続させることです。ただし不正な値のままプログラムを動かすと、さらなるエラーが発生する危険性があります。意図したエラーだけを無視します。
中断してデバッグする:意図しないエラーは、エラー発生時に中断してデバッグできます。
エラー処理をしないときは、エラーメッセージが表示されマクロが終了します。
エラー処理をする (On Error GoTo)
「GoTo 文」を使用して、エラーが発生したときに指定したラベルに処理を移動できます。他の言語では Try-Catch です。
On Error GoTo ラベル名 のように入力します。エラーが発生したときに指定したラベルの位置に処理を移動します。
エラー処理のラベル名を付けるには ラベル名: のように入力します。
Sub 実行()
On Error GoTo Catch ' エラーが発生したら Catch へ移動する
' 処理
Exit Sub
Catch: ' エラーが発生したらここから処理が始まる
' エラー処理
End Sub
Catch: の前に Exit Sub または Exit Function を入力します。これはエラーが発生していないときにエラー処理を行わないように、そこで関数を抜けます。
キャッチできる範囲
On Error の行から、その関数を抜けるまでに発生するエラーをキャッチします。その前に発生したエラーはキャッチできないので、必ず関数の直下に入力します。
Sub 実行()
' キャッチできない
On Error GoTo Catch
' キャッチできる
End Sub
範囲内で別の関数を呼び出すと、その関数でエラー処理をしていなければ、そこで発生したエラーもキャッチできます。
スポンサーリンク
エラー処理の後始末をする (Finally)
正常処理とエラー処理の両方で、同じように後始末したいことがよくあります。その処理が Finally です。
VBA のエラー処理に Finally の機能はありませんが、上記のエラー処理を組み合わせて同じようなことができます。
Resume ラベル名 のように入力して、キャッチしたエラー処理の中から指定したラベルに処理を移動できます。Resume 後は On Error でエラー処理を上書きできます。
Sub 実行()
On Error GoTo Catch
' 正常な処理
Debug.Print("正常")
Finally:
On Error Resume Next
' Finally の処理
Debug.Print("Finally")
Exit Sub
Catch:
' エラー処理
Debug.Print("エラー")
Resume Finally ' Finally へ移動する
End Sub
Finally: の中でエラーを発生させないようにします。保険の意味で On Error Resume Next を入力しています。Resume Next については下記の「エラーを無視する」をご覧ください。
Catch: で発生するエラーを無視するには、次のように Catch2: を追加します。
Sub 実行()
On Error GoTo Catch
' 正常な処理
Debug.Print("正常")
Finally:
On Error Resume Next
' Finally の処理
Debug.Print("Finally")
Exit Sub
Catch:
' 必要ならエラー情報を取得する
Debug.Print(Err.Description)
Resume Catch2 ' エラー処理は Catch2 で行う
Catch2:
On Error Resume Next
' エラー処理
Debug.Print("エラー")
GoTo Finally
End Sub
Catch: ではエラー処理を行いません。発生したエラー情報だけを取得し、エラーが発生しないようにします。エラー処理は Catch2: で行います。
Catch2: でエラー処理を行います。Catch: から Resume で呼ばれるので、エラーを無視できます。
エラーを無視する (On Error Resume Next)
エラーを無視して処理を継続できます。
On Error Resume Next を入力します。エラーが発生したときは、次の行に処理を移動できます。
Sub 実行()
On Error Resume Next ' エラーが発生したら次の行へ移動する
' 処理
End Sub
変数に代入するときにエラーが発生したときは、変数の値は変更されません。
Sub 実行()
On Error Resume Next
Dim i As Integer
i = 1
i = "a" ' エラー、無視される
Debug.Print(i) ' 1
End Sub
この動作を利用して関数が正常に実行されるときは値が返され、エラーが発生したときは何も設定されないので次のようにエラー判定ができます。
Sub 実行()
On Error Resume Next
Dim fso As Object
' エラーが発生するかもしれない処理
Set fso = CreateObject("Hoge.Hoge")
' エラーが発生したときは Nothing のまま
If fso Is Nothing Then
' エラー処理
End If
Set fso = Nothing
End Sub
無視できる範囲
「エラー処理をする」と同じで On Error Resume Next の行から関数を抜けるまでです。
絶対にマクロを中断したくないときは、最初に呼び出される関数に入力します。これですべてのエラーを無視できます。ただし、その後に正常な処理ができる保証がないのでオススメしません。
エラー処理を無効にする (On Error GoTo 0)
On Error GoTo 0 を入力します。その関数内のエラー処理を無効にできます。
Sub 実行()
On Error Resume Next
' 無視する
On Error GoTo 0 ' 以降はエラー処理しない
Dim i As Integer
i = "a" ' エラー
End Sub
無効にできる範囲
「エラー処理をする」と同じで On Error GoTo 0 の行から関数を抜けるまでです。それを呼び出した関数のエラー処理は無効になりません。
Sub 実行()
On Error Resume Next
' 無視する
Call Tips ' Tips 関数で GoTo 0 をしているので、その中だけ無効になる
' 無視する
End Sub
Sub Tips()
On Error GoTo 0 ' この関数のエラー処理を無効にする
End Sub
エラー処理を上書きする
On Error GoTo や On Error Resume Next の範囲内で別のエラー処理を入力すると、上書きできます。
Sub 実行()
On Error Resume Next
' 無視する
On Error GoTo Catch ' Resume Next を上書きする
' キャッチする
Exit Sub
Catch:
' エラー処理
End Sub
範囲内で別の関数を呼び出したときに、その関数にエラー処理が入力されているときは、その範囲内だけが上書きされます。
Sub 実行()
On Error Resume Next
' 無視する
Call Tips ' Tips 関数でエラー処理しているので、その中だけ上書きされる
' 無視する
End Sub
Sub Tips()
On Error GoTo Catch ' 呼び出し元でエラー処理していても、この関数の Catch へ移動する
' キャッチする
Exit Sub
Catch:
End Sub
キャッチしたエラー処理の中では上書きできません。
Sub 実行()
On Error GoTo Catch
Dim i As Integer
i = "a" ' エラー、Catch へ移動する
Exit Sub
Catch:
On Error Resume Next ' エラー処理の中の On Error では上書きできない、意味のないコード
i = "a" ' エラー、無視されない
End Sub
スポンサーリンク