今回はエラー処理についてご説明します。
例外処理とも言いますが、ツールを作る上で必ずと言って良いほどエラーが発生します。
例えば、ダイアログボックスを開いてファイル選択をする場合に、キャンセルもしくは×ボタンで閉じた場合には、ファイルパスを取得出来ずエラーとなります。
他にも割り算の計算で、計算しきれない計算が発生した場合など、事例を挙げるとキリがないくらい発生します。
そのため、必ずエラー処理を行います。
1.よく起こるエラー例
コーディングをしていてよく起こるエラーの一例です。
基本的に「No(ノー)」を想定していない場合にエラーが発生します。
- 空白を想定していない処理
- 最終行を取得して範囲指定した場合に、データがない想定をしていない処理
- 0で割り算を想定していない処理
- ダイアログでキャンセル、×ボタンで閉じられることを想定していない処理
- 自動処理でファイルを自動取得する際にファイルが存在しないことを想定していない処理
- 数値型の変数に文字列を代入した時の処理
2.エラー処理の方法
エラー処理は「On Error ステートメント」を使用します。
エラーが発生するコードの前に記載する事で、エラーを無視したり、指定した場所にスキップしたりして回避する事ができます。
3.エラーを無視する
「On Error Resume Next」で無視する
「On Error Resume Next」を使用すると、エラーが発生しても無視して次のコードから実行されます。
注意として、安易に使用するとエラーの発見が出来ない等の原因になります。
次のコードは0で割り算した場合に起こるエラーです。
Sub Sample1()
Dim i As Long
For i = 10 To 0 Step -1
Cells(i + 1, 1) = 100 / i
Next i
End Sub
上記のコードのエラーを無視する場合には次のように記載します。
Sub Sample2()
Dim i As Long
On Error Resume Next
For i = 10 To 0 Step -1
Cells(i + 1, 1) = 100 / i
Next i
End Sub
「On Error Resume Next」を解除する
「On Error Resume Next」を記述すると、それ以降のエラーを無視してしまうので、エラー回避の処理が終了した場合は、「On Error GoTo 0」で解除する事ができます。
Sub Sample3()
Dim i As Long
On Error Resume Next
For i = 10 To 0 Step -1
Cells(i + 1, 1) = 100 / i
Next i
On Error GoTo 0
End Sub
4.「On Error GoTo」でエラーをスキップする
「On Error GoTo ラベル名」を使用すると、記述以降のコードでエラーが発生すると、「ラベル名:」と書いたコードまで処理をスキップします。
ここで注意することは、エラーが発生しなかった場合に「ラベル名:」以降のコードを通過しないように「Exit Sub」などでプロシージャを離脱する処理を組み込みます。
Sub Sample4()
Dim i As Long
Dim n As Long
n = 1
On Error GoTo ErrLabel 'エラー発生時のラベル名指定
For i = 10 To 0 Step -1
Cells(i + 1, 1) = 100 / i
n = n + 1
Next i
Exit Sub 'エラーが発生しなかった場合、ここで離脱
ErrLabel: 'エラー発生時にここまでスキップ
MsgBox n & "回目でエラーが発生しました。"
End Sub
「Exit Sub」がないと、エラーが発生しなかった場合でもメッセージボックスが処理されます。
また、「On Error GoTo ラベル名」も解除しないとエラー発生時にスキップしてしまうため、エラー処理を「On Error GoTo 0」で解除する必要がありますので、便宜対応した方が良いです。
5.エラー処理を繰り返し行う
「On Error GoTo ラベル名」は1度エラー処理を行うと、以降エラーが発生しても回避してくれません。
ループ中に複数回エラーが発生する可能性のある処理を行う際には、エラー処理を繰り返し行える処理を組み込む必要があります。
繰り返しエラー処理を行うには「Resumeステートメント」を使用します。
「Resume」を記載した場合、エラーが発生した行のコードに戻って処理が継続されます。
また、「Resume Next」と記載した場合は、「Resume Next」が書かれた次の行から処理を開始します。
Sub Sample5()
Dim i As Long
Dim n As Long
On Error GoTo ErrLabel 'エラー発生時のラベル名指定
For n = 1 To 10
For i = 10 To 0 Step -1
Cells(i + 1, 1) = 100 / i
Next i
Next n
Exit Sub 'エラーが発生しなかった場合、ここで離脱
ErrLabel: 'エラー発生時にここまでスキップ
Resume Next 'エラーが発生した次のコードから処理が継続される
End Sub
上記コードの「Resume Next」を「Resume」とした場合無限ループになるのでご注意ください。
6.エラーの種類を取得する
エラーの種類を取得する事で、エラーの種類に合わせて処理を変更する事が可能です。
エラーの種類は「Errオブジェクト」で取得出来ます。
プロパティ | 説明 |
Number | エラーの種類の番号 |
Description | エラーの種類の説明 |
Source | エラーが発生したオブジェクト/アプリケーション |
Sub Sample6()
Dim i As Long
On Error GoTo ErrLabel 'エラー発生時のラベル名指定
For i = 10 To 0 Step -1
Cells(i + 1, 1) = 100 / i
Next i
Exit Sub 'エラーが発生しなかった場合、ここで離脱
ErrLabel: 'エラー発生時にここまでスキップ
MsgBox Err.Number & vbCrLf & _
Err.Description & vbCrLf & _
Err.Source
End Sub
7.エラーの種類で処理方法を変更する
エラーの種類によって処理方法を変更したい場合は、「IF」か「Select Case」で分岐処理を行います。
次のコードはメイン処理でエラーが発生した場合に、エラーの番号でエラー処理を分岐します。
※次のコードは実行しても動きません。
Sub Sample7()
On Error GoTo ErrLabel 'エラー発生時のラベル名指定
メイン処理
Exit Sub 'エラーが発生しなかった場合、ここで離脱
ErrLabel: 'エラー発生時にここまでスキップ
Select Case Err.Number
Case エラー番号1
MsgBox "エラー処理1"
Case エラー番号2
MsgBox "エラー処理2"
Case エラー番号3
MsgBox "エラー処理3"
End Sub