On Error の正しい使い方(止まっても安全に終わるエラー処理の型)
On Error Resume Next の乱用で起きる問題と、On Error GoTo を使ったエラー処理の基本の型を解説します。画面更新や計算方法を元に戻し、エラーの内容を記録する書き方です。
エラー処理が必要な理由
マクロがエラーで止まると、その時点で処理が途中のまま残ります。高速化のために画面更新や自動計算を止めていると、それも止まったままになり、利用者は「Excel がおかしくなった」と感じます。開いたブックが閉じられずに残ったり、途中までしか書き込まれていないデータが保存されたりすることもあります。
エラー処理の目的は、エラーを隠すことではなく、「止まったときに後片付けをして、何が起きたかを分かるようにする」ことです。
On Error Resume Next の注意点
On Error Resume Next は、エラーが起きても次の行へ進む命令です。手軽なため多用されがちですが、エラーが起きても気づけないので、間違った結果のまま処理が終わる危険があります。使うのは「エラーになるかもしれない1行」だけにして、その直後に On Error GoTo 0 で元に戻すのが原則です。
' よい例:シートがあるかを確認する1行だけで使う
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("集計")
On Error GoTo 0 ' すぐに通常のエラー処理に戻す
If ws Is Nothing Then MsgBox "集計シートがありません": Exit Sub基本の型:On Error GoTo
処理の最初に On Error GoTo でエラー時の飛び先を指定し、最後に後片付けの部分を置きます。正常に終わったときもエラーのときも、必ず後片付けを通るように書くのがポイントです。
Sub MainProcess()
Dim src As Workbook
On Error GoTo ErrHandler
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set src = Workbooks.Open(ThisWorkbook.Path & "\元データ.xlsx", ReadOnly:=True)
' ……本来の処理……
Finally: ' 正常時もエラー時もここを通る
On Error Resume Next
If Not src Is Nothing Then src.Close SaveChanges:=False
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
MsgBox "エラーが発生しました" & vbCrLf & _
"番号:" & Err.Number & vbCrLf & "内容:" & Err.Description, vbCritical
Resume Finally ' 後片付けへ
End Subコードのポイント
エラー時は ErrHandler でメッセージを表示したあと、Resume Finally で後片付けの部分に移ります。後片付けの中では、ブックが開いていない場合などに再びエラーにならないよう、On Error Resume Next を使っています(ここは後片付けだけなので、エラーを無視しても問題ありません)。
Exit Sub を後片付けの最後に置くことで、正常に終わったときに ErrHandler の部分まで進まないようにしています。
エラーを記録する
利用者が多いマクロでは、エラーの内容を「ログ」シートやテキストファイルに記録しておくと、あとから原因を調べやすくなります。日時、マクロ名、エラー番号、エラー内容、処理中だったデータ(何行目か、どのファイルか)を残しておくのがおすすめです。メッセージを見た利用者から「エラーが出ました」とだけ連絡が来ても、記録があればすぐに原因にたどり着けます。
- 日時とマクロ名
- Err.Number と Err.Description
- 処理中のファイル名・行番号などの手がかり
※エラー処理の書き方には複数の流儀があります。チーム内で型をそろえておくと保守しやすくなります。