エラー処理2012.11.10 [更新日]2024.11.30
VBAでのエラー制御についてまとめたメモです。
※サンプルコードがエラーで中断される場合
・VBEのオプション設定を変更 参照
・プロジェクトをロックする 参照
ブックファイルを配布の際に、プロジェクトをロックしておくと、ユーザーのVBE設定にかかわらず、On Errorステートメントが有効になる。
Excelマクロ管理ツール
On Errorステートメント
エラー発生時にステートメント実行位置を制御する。
エラー処理ルーチンを無効にするときにも使用できる。
Exit Subなどで、そのプロシージャを抜けた場合、エラー処理ルーチンは無効になる。
構文1:On Error GoTo line
引数[line]に指定した行から始まる、エラー処理ルーチンを有効にする。
引数[line]には任意の行ラベルまたは行番号を必ず指定。
実行時エラーが発生すると、[line]に指定したルーチンにプログラムの制御が移る。
指定する行は、On Errorステートメントと同じプロシージャ内に存在しなければならない。
構文2:On Error Resume Next
実行時エラーが発生してもプログラムを中断せず、エラーの次のステートメントから実行を継続する。
オブジェクトを伴うエラーは、Errオブジェクトで原因を探ることができるため、このステートメントを使用すると良い。
構文3:On Error GoTo 0
On Error GoTo line や On Error Resume Next を無効にする。
サンプルコード
エラー発生時の On Errorステートメントの Resume Next と GoTo line の動作の違いを確認する。
Sub OnErrorステートメントの動作の違い() Dim i As Long Dim dblResult As Double '--------------------------------------- ' On Error Resume Next '--------------------------------------- ' エラーが発生した場合 無視して次に進む On Error Resume Next dblResult = 100 / i ' i = 0 のため 100 を 0 で除算することでエラーが発生する On Error GoTo 0 MsgBox dblResult, , "On Error Resume Next" ' 結果「1.#INF」: 0 除算により結果が誤った形式で表示される '--------------------------------------- ' On Error GoTo ライン '--------------------------------------- ' エラーが発生した場合 指定の行または行ラベルに制御を移す On Error GoTo LBL_ERROR dblResult = 100 / i ' 100 を 0 で除算しエラーが発生すると LBL_ERROR に制御を移す On Error GoTo 0 MsgBox dblResult, , "On Error Goto ライン" ' 結果「5」 Exit Sub '--------------------------------------- ' エラー発生時の行ラベル '--------------------------------------- LBL_ERROR: i = 20 ' i に 20 を代入 Resume ' エラーが発生箇所に制御を戻す End Sub
VBAコードをカラーで印刷・Web掲載するためのツールはこちら
Resumeステートメント
エラー処理の最後に記述し、プログラムの再開位置を指定する。
構文1:Resume [0]
[0]は省略可能。
エラーの原因となったステートメントからプログラムを再開する。
構文2:Resume Next
エラーの原因となったステートメントの、次のステートメントからプログラムを再開する。
構文3:Resume line
引数[line]に指定した行からプログラムを再開する。
サンプルコード
Resumeステートメントの Resume Next 、 Resume 0 、 Resume line の動作の違いを確認する。
Sub Resumeステートメントの動作の違い() Dim i As Long Dim dblResult As Double '--------------------------------------- ' Resume Next '--------------------------------------- i = 0 On Error GoTo LBL_ERROR_A dblResult = 100 / i ' 100 を 0 で除算しエラーが発生すると LBL_ERROR_A に制御を移す On Error GoTo 0 MsgBox dblResult, , "Resume Next" ' 結果「1.#INF」: 0 除算により結果が誤った形式で表示される '--------------------------------------- ' Resume 0 '--------------------------------------- i = 0 On Error GoTo LBL_ERROR_B dblResult = 100 / i ' 100 を 0 で除算しエラーが発生すると LBL_ERROR_B に制御を移す On Error GoTo 0 MsgBox dblResult, , "Resume 0" ' 結果「5」 '--------------------------------------- ' Resume ライン '--------------------------------------- i = 0 On Error GoTo LBL_ERROR_C dblResult = 100 / i ' 100 を 0 で除算しエラーが発生すると LBL_ERROR_C に制御を移す On Error GoTo 0 MsgBox dblResult, , "Resume ライン" ' (メッセージは表示されない) LBL_RESUME_LINE: MsgBox "終了" Exit Sub '--------------------------------------- ' エラー発生時の各行ラベル '--------------------------------------- LBL_ERROR_A: i = 20 ' i に 20 を代入 Resume Next ' エラー発生箇所の次のステートメントに制御を移す LBL_ERROR_B: i = 20 ' i に 20 を代入 Resume 0 ' エラー発生箇所に制御を移す LBL_ERROR_C: i = 20 ' i に 20 を代入 Resume LBL_RESUME_LINE ' LBL_RESUME_LINE に制御を移す End Sub
Errオブジェクト
コードの実行時にエラーが発生した場合に、エラーに関する情報がErr.オブジェクトに格納される。
主なメンバ | タイプ | 説明 |
---|---|---|
Number | プロパティ | エラー発生時にエラー番号が設定される |
Source | プロパティ | エラー発生元のオブジェクトまたはアプリケーションの名前が設定される |
Description | プロパティ | エラー発生時にエラーに関連する説明の文字列をが設定される |
Clear | メソッド | Errオブジェクトのすべてのプロパティの設定値をクリアする |
Raise | メソッド | 実行時エラーを生成する |
サンプルコード
Errオブジェクトの動作確認
Sub Errオブジェクトの動作確認1() '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source '--------------------------------------- ' エラーを発生させる '--------------------------------------- On Error Resume Next Dim dblResult As Double dblResult = 100 / 0 ' 100 を 0 で除算することでエラーが発生する '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source '--------------------------------------- ' エラー情報クリア '--------------------------------------- Err.Clear '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
コード実行結果
Errオブジェクトの各プロパティは、エラー処理ルーチン内の次のステートメントの後で
0 または長さ 0 の文字列 ("") にリセットされる。
・Resume Next
・GoTo 0
・GoTo ライン
サンプルコード
Errオブジェクトのリセット確認① On Error Resume Next
Sub Errオブジェクトのリセット確認1() '--------------------------------------- ' エラーを発生させる '--------------------------------------- On Error Resume Next Dim dblResult As Double dblResult = 100 / 0 ' 100 を 0 で除算することでエラーが発生する '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source On Error Resume Next ' エラー情報がリセットされる '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
コード実行結果
サンプルコード
Errオブジェクトのリセット確認② Resume Next
Sub Errオブジェクトのリセット確認2() '--------------------------------------- ' エラーを発生させる '--------------------------------------- On Error GoTo LBL_ERROR Dim dblResult As Double dblResult = 100 / 0 100 を 0 で除算しエラーが発生すると LBL_ERROR に制御を移す '--------------------------------------- ' エラー情報確認② '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source Exit Sub LBL_ERROR: '--------------------------------------- ' エラー情報確認① '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source Resume Next ' エラー情報がリセットされる(エラー発生箇所の次のステートメントに制御を移す) End Sub
コード実行結果
サンプルコード
Errオブジェクトのリセット確認③ On Error GoTo 0
Sub Errオブジェクトのリセット確認3() '--------------------------------------- ' エラーを発生させる '--------------------------------------- On Error Resume Next Dim dblResult As Double dblResult = 100 / 0 ' 100 を 0 で除算することでエラーが発生する '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source On Error GoTo 0 ' エラー情報がリセットされる '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
コード実行結果
サンプルコード
Errオブジェクトのリセット確認④ On Error GoTo ライン
Sub Errオブジェクトのリセット確認4() '--------------------------------------- ' エラーを発生させる '--------------------------------------- On Error Resume Next Dim dblResult As Double dblResult = 100 / 0 ' 100 を 0 で除算することでエラーが発生する '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source On Error GoTo LBL_NEXT ' エラー情報がリセットされる LBL_NEXT: '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
コード実行結果
次のステートメントではErrオブジェクトの各プロパティはリセットされない。
・End Sub
・End Function
・End Property
・Exit Sub
・Exit Function
・Exit Property
サンプルコード
Errオブジェクトのリセット確認⑤
Sub Errオブジェクトのリセット確認5() '--------------------------------------- ' エラー発生プロシージャを呼び出す '--------------------------------------- Call エラー発生 '--------------------------------------- ' エラー情報確認② '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
Private Sub エラー発生() On Error Resume Next Dim dblResult As Double dblResult = 100 / 0 ' 100 を 0 で除算することでエラーが発生する '--------------------------------------- ' エラー情報確認① '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
コード実行結果
Errオブジェクトの Raise メソッドは、実行時エラーを発生させる。
構文:Err.Raise Number, [Source], [Description], [HelpFile], [HelpConText]
Number(エラー番号)の 0 から 512 はシステム エラー用に予約されており、513 から 65535 は、ユーザー定義エラーに使用できる。
[参考]Microsoft Learn Challenge Raise メソッド
Microsoft Learn Challenge トラップ可能なエラー
サンプルコード
Err.Raise メソッドの動作確認① 実行時エラーの発生を確認する。
Sub ErrRaiseメソッドの動作確認1() On Error Resume Next ' エラー番号 91 のエラーを発生させる Err.Raise 91 '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
コード実行結果
サンプルコード
Err.Raise メソッドの動作確認② 呼出先のプロシージャでの実行時エラーの発生を確認する。
Sub ErrRaiseメソッドの動作確認2() On Error GoTo LBL_ERROR ' 処理Aを呼び出す Call 処理A Exit Sub LBL_ERROR: '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
Private Sub 処理A() ' エラー番号 513 (ユーザー定義)のエラーを発生させる Err.Raise 513, "処理A", "Raiseメソッド動作確認2" End Sub
コード実行結果
サンプルコード
Err.Raise メソッドの動作確認③ 呼出先のプロシージャの更に呼出先のプロシージャでの実行時エラーの発生を確認する。
Sub ErrRaiseメソッドの動作確認3() On Error GoTo LBL_ERROR ' 処理Bを呼び出す Call 処理B Exit Sub LBL_ERROR: '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
Private Sub 処理B() ' 処理Cを呼び出す Call 処理C ' エラー番号 513 (ユーザー定義)のエラーを発生させる Err.Raise 513, "処理B", "Raiseメソッド動作確認3" End Sub
Private Sub 処理C() ' エラー番号 514 (ユーザー定義)のエラーを発生させる Err.Raise 514, "処理C", "Raiseメソッド動作確認3" End Sub
コード実行結果
サンプルコード
ErrRaiseメソッドを用いたエラー制御例
Sub ErrRaiseメソッドを用いたエラー制御例() On Error GoTo LBL_ERROR ' 処理Dを呼び出す Call 処理D ' エラー番号 515 (ユーザー定義)のエラーを発生させる Err.Raise 515, "呼出元", "ErrRaiseメソッドを用いたエラー制御例" Exit Sub LBL_ERROR: '--------------------------------------- ' エラー情報確認 '--------------------------------------- MsgBox "エラー番号:" & Err.Number & vbLf & _ "エラー説明:" & Err.Description & vbLf & _ "エラーソース:" & Err.Source End Sub
Private Sub 処理D() On Error GoTo LBL_ERROR ' 処理Eを呼び出す Call 処理E ' 2分の1の確率で実行時エラーを発生させる If WorksheetFunction.RandBetween(0, 1) = 1 Then Dim i As Long i = "サンプル" End If Exit Sub LBL_ERROR: If Err.Source = "VBAProject" Then Err.Source = "処理D" ' エラーオブジェクトの情報に基づきエラーを発生させる Err.Raise Err.Number, Err.Source, Err.Description End Sub
Private Sub 処理E() On Error GoTo LBL_ERROR ' 2分の1の確率で実行時エラーを発生させる If WorksheetFunction.RandBetween(0, 1) = 1 Then Dim dblResult As Double dblResult = 100 / 0 End If Exit Sub LBL_ERROR: If Err.Source = "VBAProject" Then Err.Source = "処理E" ' エラーオブジェクトの情報に基づきエラーを発生させる Err.Raise Err.Number, Err.Source, Err.Description End Sub
コード実行結果
上記のエラー制御では、
処理を開始する呼出元プロシージャ「ErrRaiseメソッドを用いたエラー制御例」に、エラー時に情報を確認するコードを準備している。
そして呼出先プロシージャ「処理D」や「処理E」では、エラー発生時にErrオブジェクトのプロパティにプロシージャ名を設定し Err.Raise メソッドを実行している。
この仕組みで Err.Raise メソッドを実行すると、結果として呼出元のエラー情報確認コードに制御が移る。
このような仕組みを構築することにより、エラー発生箇所やエラー内容を特定をしやすくなる。