プログラミングを作成する上で、少なくとも実行できない場合がただあります。それらを修正しながら、実行可能なプログラムを作り上げることになります。プロシージャ内に実行できないコードが記述されていた場合は、「実行時エラー」が発生します。また、問題なく動作できるプロシージャを作成しても、ユーザの操作やExcelの状態によっても実行時エラーが発生することがあります。
VBEでは、実行時エラーが発生した場合、プロシージャの処理が中断されて、エラーの原因がダイアログボックスで表示されます。このとき、「終了」ボタンをクリックすると、プロシージャは強制的に終了できます。また、「デバッグ」をクリックすると、実行時エラーの原因となるステートメントが黄色で反転表示されます。
上の例では、変数の強制宣言「Option Explicit」が設定されているのに、プロシージャ内で変数を宣言していないのでエラーメッセージが表示されています。プロシージャの実行前に発生するエラーをコンパイルエラーと呼びます。
実行時エラーが発生してもプロシージャが中断されないようにするには、実行時エラーに対する処理を記述することで回避することができます。実行時エラーに対する処理をエラートラップといい、堅牢なアプリケーションを作成するには不可欠なものです。なるべく、エラートラップを記述して、無用なエラーを回避するように努めます。
エラートラップを作成するには、いくつかのステートメントを利用します。これらを1つずつ紹介します。
このステートメントを使うと、発生した実行時エラーを無視して次のステートメントを実行できます。よって、On Error Resume
Nextステートメントが実行されてからプロシージャの終了までがエラートラップとなります。
例えば、下のプロシージャのようなカラーインデックスの番号をユーザに求めた場合、ユーザが数字ではなく文字で入力してしまうケースも考えられます。
Sub 項目色()
Dim ChgColor As Integer
ChgColor = InputBox("カラーインデックス番号を入力しましょう")
Range("B2:F2").Interior.ColorIndex = ChgColor
End Sub
変数は整数型と指定してありますので、それ以外のデータ型であれば実行時エラーが発生します。
このような実行時のエラーを回避するために以下のように記述します。
Sub 項目色()
Dim ChgColor As Integer
On Error Resume Next
ChgColor = InputBox("カラーインデックス番号を入力しましょう")
Range("B2:F2").Interior.ColorIndex = ChgColor
End Sub
上の例では3行目にOn Error Resume
Nextステートメントを追加することで、間違ったデータ型を入力されても強制的にプロシージャが終了され、実行時のエラーのメッセージは表示されません。この場合、エラートラップは、On Error
Resume NextステートメントからEnd Subまでの範囲となります。
On Error Resume
Nextステートメントは、発生した実行時エラーを無視しても、そのあとのコードが問題なく実行できる場合や実行結果に不具合が生じない場合に使用します。
長いプロシージャを作成した場合、特定の場所だけエラートラップの処理を記述することがあります。もし、On Error Goto
0ステートメント以降のコードに問題があった場合、実行時エラーが発生するためにその場所を特定できます。
On Error Goto
0ステートメントを使って、エラートラップの途中で無効にするように設定します。
Sub 項目色()
Dim ChgColor As Integer
On Error Resume Next
ChgColor = InputBox("カラーインデックス番号を入力しましょう")
On Error GoTo 0
Range("B2:F2").Interior.ColorIndex = ChgColor
End Sub
この例では、変数に代入するする処理で実行時エラーが発生されても無視されますが、背景色が指定される処理では実行時エラーが発生され、処理が中断されます。
カラーインデックスの番号は「56」まであります。最初から文字列など整数型でない場合はすぐに処理が中断されますが、例えば「58」と入力されると整数型ですからエラーは発生しません。しかし、その数字は有効範囲外ですから実行時エラーを発生させる必要があります。このような場合に、On
Error Goto 0ステートメントを使います。
エラートラップの記述によって、実行時エラーのメッセージが回避されプロシージャを終了しますが、ユーザは何故何も実行されないで終了したのか分からない場合があります。その場合、実行が終了された理由をユーザにメッセージとして表示させる必要があります。
On Error Gotoステートメントを使うと、実行時エラーが発生したときに別の処理を実行することができます。このような処理をエラー処理ルーチンと呼びます。その例を下に記述します。
Sub 項目色()
Dim ChgColor As Integer
On Error Resume Next
ChgColor = InputBox("カラーインデックス番号を入力しましょう")
On Error GoTo ErrorChgColor
Range("B2:F2").Interior.ColorIndex = ChgColor
Exit Sub
ErrorChgColor:
MsgBox ChgColor & "番は範囲外の数値です。" & Chr(10) & _
"処理を終了しますので、再度実行してください。"
End Sub
On Error Goto
の次には、エラーが発生した場合どの箇所にジャンプするのかラベル名を記述します。上の例では、ErrorChgColorというラベルにジャンプするようにしています。また、すべてが正しく処理された場合は、強制的にプロシージャが終了されるようにExit
Subを記述します。
ErrorChgColorがラベルであることは「:」で指定されます。そして、その下に記述されているMsgBoxからがエラー処理ルーチンとなります。つまり、エラーが発生したら「○番は範囲外の数値です。処理を終了しますので、再度実行してください」というメッセージを表示されるように設定されています。
※上の図は入力ボックスに「69」という数値を入れた時、エラー処理ルーチンが実行された例です。
On Error Goto ErrorChgColorの意味は、実行時エラーが発生した場合はErrorChgColorという行ラベルにジャンプしてそれを処理しなさいということになります。
では、これまでの例をもう少し使いやすくしてみます。データ型が整数であれば処理をしてくれますが、誤って文字列が入力されたときは、単にプロシージャが終了されるだけです。そこで、整数以外のデータが入力された場合は、メッセージを表示し、その後に再度入力ボックスを表示するように作り直します。ようするにプロシージャをエラー発生時前に戻すことで実現できます。Resumeステートメントは、エラー処理ルーチンから実行時エラーが発生したステートメントへ制御を戻すことができます。ただし、Resumeステートメントは、エラー処理ルーチン内だけで利用できるものです。以下に例を記述します。
Sub 項目色()
Dim ChgColor As Integer
On Error GoTo ErrorInputbox
ChgColor = InputBox("カラーインデックス番号を入力しましょう")
On Error GoTo ErrorChgColor
Range("B2:F2").Interior.ColorIndex = ChgColor
Exit Sub
ErrorInputbox:
MsgBox "整数で入力してください。" & Chr(10) & _
"入力しなおしてください。"
Resume
ErrorChgColor:
MsgBox ChgColor & "番は範囲外の数値です。" & Chr(10) & _
"処理を終了しますので、再度実行してください。"
End Sub
上の例では、入力ボックス内に整数以外が入力された場合は、ErrorInputboxの行ラベルへジャンプして、「整数で入力してください。入力しなおしてください。」というメッセージを表示させ、再度入力ボックスが表示される処理に戻しています。
エラー処理ルーチン内で実行時エラーが発生した場合、実行時エラーが発生したステートメントの次のステートメントの処理を行うには、Resume Nextステートメントを使います。このステートメントもエラー処理ルーチン内だけの利用となります。
Sub 項目色()
Dim ChgColor As Integer
On Error GoTo ErrorInputbox
ChgColor = InputBox("カラーインデックス番号を入力しましょう")
On Error GoTo ErrorChgColor
Range("B2:F2").Interior.ColorIndex = ChgColor
Exit Sub
ErrorInputbox:
ChgColor = 4
Resume Next
ErrorChgColor:
MsgBox ChgColor & "番は範囲外の数値です。" & Chr(10) & _
"処理を終了しますので、再度実行してください。"
End Sub
上の例を説明すると、もし整数以外が入力されたらErrorInputboxの行ラベルにジャンプします。そのときの処理は、変数に「4」を代入してOn Error Goto
ErrorChgColorのエラー処理ルーチンに戻し、処理を実行します。
こうすることで、整数以外のデータが入力された場合は、ColorIndexには「4」を入れて、指定されたセル範囲を塗りつぶすことになります。つまり、ちゃんと有効範囲内の整数値が入力されなかったら、強制的に「4」という数字を入れてセルを塗りつぶすこととなります。
このように、VBAでプロシージャを作成する場合は、ユーザが予期しないことを実行することを想定して、その場合のエラー処理を記述しておく必要があります。
エラー処理の記述は、プロシージャが完成した後に付加した方が効率的です。また、ユーザの間違いそうな操作をある程度想定することも大事でしょう。