エラー処理のステートメント
エラー処理のステートメントには6種類あります。
ステートメント | 内容 |
On Error Goto 行ラベル | エラーが発生した際の処理を用意しておき、実際にエラーが発生するとその処理に遷移する。 |
On Error Goto 0 | エラーが発生すると、エラー発生源の処理を無効にして処理を中断する。 |
On Error Resume Next | エラーが発生してもエラーを無視して処理を続ける。 |
Resume | エラーが発生するとエラー時用の処理を実行して、エラーが発生した行に戻る。 |
Resume Next | エラーが発生するとエラー時用の処理を実行して、エラーが発生した行の次の行に戻る。 |
Resume 行ラベル | エラー発生時に指定した行ラベルに処理を移す。 |
エラー処理のステートメントを使う理由
VBAでのエラーには主に3つあります。
コンパイルエラー、実行時エラー、論理エラー、の3つです。
それらのエラーの中で、エラー処理のステートメントは2つ目の実行時エラーが発生したときにエラーをどう扱うかについて記述します。
On Error Gotoステートメント
On Error Gotoステートメントはエラーが発生すると行ラベルに処理が移動します。
行ラベルとは、エラー発生時に処理を移す位置の名前で、コロン(:)を付けることで行ラベルと認識されます。
「On Error Goto 」の後ろに同じ行ラベル名を書いておくと、エラー発生時に処理が移ります。
On Error Gotoステートメントは、エラーが発生する可能性がある行よりも前に書いておく必要があります。
以下の2つはどちらもSetステートメントの行でエラーが発生する処理ですが、On Error Gotoステートメントの位置が異なります。
1つ目のコードはエラー発生行より前にOn Error Gotoステートメントを書いているためエラーが発生すると行ラベルに処理が移りますが、2つ目のコードはエラー発生行より後に書いているため、行ラベルに処理が移らず、実行時エラーとしてエラーダイアログが表示されます。
1 2 3 4 5 6 7 8 9 |
Sub OnErrorGotoTest1() On Error GoTo ERR_LABEL Dim r As Range Set r = Range("A1").Offset(-1, 0) '// エラー発生時にERR_LABELに移る Exit Sub ERR_LABEL: Debug.Print Err.Number & " "; Err.Description End Sub |
実行結果
1004 アプリケーション定義またはオブジェクト定義のエラーです。
1 2 3 4 5 6 7 8 9 |
Sub OnErrorGotoTest2() Dim r As Range Set r = Range("A1").Offset(-1, 0) '// エラー発生時にERR_LABELに移らない On Error GoTo ERR_LABEL Exit Sub ERR_LABEL: Debug.Print Err.Number & " "; Err.Description End Sub |
エラー発生時に以下のダイアログが表示されます。
On Error Goto 0ステートメント
On Error Goto 0ステートメントには大きく分けると2つの機能があります。
1つはErrオブジェクトの情報をクリアです。
もう1つはエラー発生時に「On Error Goto 行ラベル」で行ラベルに処理が移らなくなります。
本などでは「エラー発生時の処理を無効にする」などとよく分からない説明がされていることがありますが、Errオブジェクトがクリアされて行ラベルにジャンプしなくなる、と考えた方が分かりやすいと思います。
以下のコードはエラー発生で行ラベルに処理が移動したあとにErrオブジェクトを使ってエラー情報を出力しています。
そのあとにOn Error Goto 0を実行すると、Errオブジェクトの内容がなくなり、エラー無しの0が出力されます。
Resume Nextでエラー発生行の次の行の7行目に移動します。
7行目は5行目と同じ処理のためまたエラーが発生しますが、「On Error Goto ERR_LABEL」のエラー処理が「On Error Goto 0」で無視されるようになったため、行ラベルに処理が移らず、エラーダイアログが表示されます。
処理の順番はコメントの番号の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Sub OnErrorGoto0Test() On Error GoTo ERR_LABEL Dim r As Range Set r = Range("A1").Offset(-1, 0) '// 1. エラー発生行(ERR_LABELへ遷移) Set r = Range("A1").Offset(-1, 0) '// 6. エラー発生行(エラーダイアログ表示) Exit Sub ERR_LABEL: '// 2. エラー発生時のエラー情報を出力 Debug.Print Err.Number & " "; Err.Description '// 3. エラーを無効化(エラー情報が消去) On Error GoTo 0 '// 4. エラー発生時のエラー情報は出力されず、0が出力される Debug.Print Err.Number & " "; Err.Description '// 5. エラー発生行の次の行に移動 Resume Next End Sub |
実行結果
1004 アプリケーション定義またはオブジェクト定義のエラーです。
0
On Error Resume Nextステートメント
On Error Resume Nextステートメントは実行時エラーが発生してもエラーを無視して処理が継続します。
エラーを無視していてもErrオブジェクトにはエラー情報は登録されているため確認することは可能です。
以下のコードはエラーが発生しても処理が継続するサンプルです。
処理は継続しますがErrオブジェクトにはエラー情報が登録されています。
1 2 3 4 5 6 7 8 |
Sub OnErrorGotoResumeNextTest() On Error Resume Next Dim r As Range Set r = Range("A1").Offset(-1, 0) '// エラー発生が無視され処理が継続する Debug.Print Err.Number & " "; Err.Description End Sub |
実行結果
1004 アプリケーション定義またはオブジェクト定義のエラーです。
Resume、Resume Next、Resume 行ラベル
Resumeステートメントは「On Error Goto 行ラベル」でエラー発生時に行ラベルに処理が移ったあとの処理として利用します。
エラー処理が終わったあとにエラー発生行か、エラー発生行の次の行か、指定した行ラベルかに処理を移します。
それぞれの内容は最初に書いたとおりです。
ステートメント | 内容 |
Resume | エラーが発生するとエラー時用の処理を実行して、エラーが発生した行に戻る。 |
Resume Next | エラーが発生するとエラー時用の処理を実行して、エラーが発生した行の次の行に戻る。 |
Resume 行ラベル | エラー発生時に指定した行ラベルに処理を移す。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub ResumeTest1() On Error GoTo ERR_LABEL Dim r As Range Set r = Range("A1").Offset(-1, 0) '// エラー発生時にERR_LABELに移る Exit Sub ERR_LABEL: Debug.Print Err.Number & " "; Err.Description Resume Next End Sub |