Excel VBA 逆引き集 | On Error基本

Excel VBA
スポンサーリンク

On Error基本

失敗しないVBAの第一歩は「エラーを捕まえて、落とさず、原因を残す」こと。On Errorはそのための基本機能です。初心者向けに、よく使う書き方・テンプレート・注意点を例題付きでまとめます。


何ができるか

  • エラーを捕まえる: 例外的な事態でも処理を止めずに制御を移す
  • 原因を記録する: Err.NumberErr.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接続/オブジェクトは、ハンドラで必ず CloseSet ... = Nothing
  • ハンドラ内で別エラーが出る
    • 後始末は短く、安全に。必要なら一時的に On Error Resume Next を使い、終わったら On Error GoTo 0 に戻す
  • どこで落ちたか分からない
    • 例外時に「手順名・日時・番号・内容」をログかメッセージに残す

練習問題(例題)

  • 例1:ゼロ除算を捕まえ、代替値0で続行し、最後に「完了」メッセージを出す
  • 例2:存在しないシート参照を捕まえ、ログシートに日時・番号・説明を追記
  • 例3:ファイル書き込みで失敗時、ファイル番号を安全にCloseしてからエラーメッセージ

タイトルとURLをコピーしました