On Error基本
失敗しないVBAの第一歩は「エラーを捕まえて、落とさず、原因を残す」こと。On Errorはそのための基本機能です。初心者向けに、よく使う書き方・テンプレート・注意点を例題付きでまとめます。
何ができるか
- エラーを捕まえる: 例外的な事態でも処理を止めずに制御を移す
- 原因を記録する:
Err.NumberやErr.Descriptionでエラー内容が分かる - 後始末する: ファイルや接続を閉じてリソースリークを防ぐ
- ユーザーに知らせる: メッセージやログでトラブル対応が楽になる
基本の構文と意味
- On Error GoTo ラベル:
エラーが起きたら指定ラベルへジャンプ(最もよく使う)
Sub Sample_GoToHandler()
On Error GoTo ErrHandler
' ここに本処理
Dim x As Long
x = 10 / 0 ' ゼロ除算 → エラー発生
' 正常終了の出口(ジャンプされないようにExitを置く)
Exit Sub
ErrHandler:
MsgBox "エラー番号: " & Err.Number & vbCrLf & "内容: " & Err.Description
' 必要なら後始末
End Sub
VB- On Error Resume Next:
エラーが起きても次の行へ進む(雑に使うと危険。直後に必ず判定)
Sub Sample_ResumeNext()
On Error Resume Next
Worksheets("存在しない").Activate ' エラーでも止まらない
If Err.Number <> 0 Then
MsgBox "失敗しました: " & Err.Description
Err.Clear ' 使い終わったらクリア
End If
On Error GoTo 0 ' 以降は通常のエラー動作に戻す
End Sub
VB- On Error GoTo 0 / On Error GoTo -1:
- GoTo 0: 現在のエラー処理を解除(標準動作に戻す)
- GoTo -1: 現在のエラーをリセット(Errをクリアするのと同じ効果)
よく使うテンプレート
1) 最小構成の「安全なサブルーチン」
Sub SafeTemplate()
On Error GoTo ErrHandler
' 本処理
Dim f As Integer
f = FreeFile
Open "C:\temp\sample.txt" For Output As #f
Print #f, "ログを書き込みます"
' 正常終了
Close #f
Exit Sub
ErrHandler:
' 後始末(開いていれば閉じる)
If f <> 0 Then
On Error Resume Next
Close #f
On Error GoTo 0
End If
MsgBox "処理中にエラーが発生しました。" & vbCrLf & _
"番号:" & Err.Number & " / " & Err.Description
End Sub
VB- ポイント:
- Exit Sub で正常系はハンドラに落ちないようにする
- ハンドラでは後始末(CloseやRelease)を必ず行う
2) ログを残す(監査・保守向け)
Sub WithLogging()
On Error GoTo ErrHandler
' 本処理
Dim ws As Worksheet: Set ws = Worksheets("Report")
ws.Range("A1").Value = "OK"
Exit Sub
ErrHandler:
Dim logWs As Worksheet: Set logWs = Worksheets("Log")
Dim r As Long
r = logWs.Cells(logWs.Rows.Count, 1).End(xlUp).Row + 1
logWs.Cells(r, 1).Value = Now
logWs.Cells(r, 2).Value = Err.Number
logWs.Cells(r, 3).Value = Err.Description
logWs.Cells(r, 4).Value = "WithLogging"
MsgBox "エラーをログに記録しました。"
End Sub
VB- ポイント:
- ログは「いつ/どこで/何のエラー」を最低限残す
- 後から再現・修正がしやすくなる
3) Resumeで「ここから再開」する
Sub ResumePattern()
On Error GoTo ErrHandler
Dim v As Variant
' エラーが出そうな箇所
v = 10 / 0
MsgBox "ここは到達しない"
Exit Sub
ErrHandler:
' 原因に応じた代替処理
If Err.Number = 11 Then ' 11 = Division by zero
Err.Clear
v = 0 ' デフォルト値で代替
Resume Next ' 次の行から再開(MsgBoxへ)
Else
MsgBox "想定外のエラー: " & Err.Description
Resume ExitPoint
End If
ExitPoint:
End Sub
VB- ポイント:
Resume Nextは「次の行から再開」Resume ラベルは「任意の復帰点に戻る」- 使い所は限定的。まずは「後始末+ログ」で十分
Errオブジェクトの使い方
- よく使うプロパティ
- Err.Number: エラー番号(0ならエラーなし)
- Err.Description: 説明文
- Err.Source: 発生元(自作エラーで設定可能)
- クリア
- Err.Clear または On Error GoTo -1
- 自分でエラーを投げる
Sub RaiseErrorIfInvalid()
Dim path As String: path = "C:\no\such\file.txt"
If Dir(path) = "" Then
Err.Raise Number:=1001, Source:="Validation", _
Description:="ファイルが見つかりません: " & path
End If
End Sub
VB- ポイント:
- 明示的にエラーを投げると「異常系」を一本化できる
- 呼び出し元で
On Error GoToして後始末・ログを共通化
初心者がつまずくポイントと対策
- Resume Nextを垂れ流しにしない
- 直後に
If Err.Number <> 0 Thenで必ず判定し、Err.Clearする
- 直後に
- 正常系のExitを忘れる
- ハンドラ直前で
Exit Sub(またはExit Function)を置く
- ハンドラ直前で
- 後始末が漏れる
- ファイル/ADO接続/オブジェクトは、ハンドラで必ず
CloseやSet ... = Nothing
- ファイル/ADO接続/オブジェクトは、ハンドラで必ず
- ハンドラ内で別エラーが出る
- 後始末は短く、安全に。必要なら一時的に
On Error Resume Nextを使い、終わったらOn Error GoTo 0に戻す
- 後始末は短く、安全に。必要なら一時的に
- どこで落ちたか分からない
- 例外時に「手順名・日時・番号・内容」をログかメッセージに残す
練習問題(例題)
- 例1:ゼロ除算を捕まえ、代替値0で続行し、最後に「完了」メッセージを出す
- 例2:存在しないシート参照を捕まえ、ログシートに日時・番号・説明を追記
- 例3:ファイル書き込みで失敗時、ファイル番号を安全にCloseしてからエラーメッセージ

