Excel VBA:エラー処理とデバッグの基本
音声
目次
よくある実行時エラー(1004・91・9)
代表的な実行時エラーと原因・対処を短くまとめます。
- 1004はApplication-defined or object-defined errorであり、存在しないシートの参照、保護シートへの書き込み、誤ったRange指定などで発生しやすいです。
- 91はオブジェクト変数またはWithブロック変数が設定されていない状態であり、Setのし忘れや取得に失敗してNothingになっていることが原因です。
- 9はインデックスが有効範囲にない状態であり、Worksheets("名前")の誤字やWorksheets(5)が存在しないなどで発生します。
対処の基本は、エラー行を特定して「何を参照しようとしたか」を確認することです。VBEのステップ実行(F8)で直前の変数状態を見て、イミディエイトやDebug.Printで値を出していくと再現条件が絞れます。
最小マクロ: エラーになりやすい参照(シート名)をわざと含めた最小例です。
Option Explicit
Sub MinimalMacro()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data") ' 存在しなければ実行時エラー 9 になりやすい
ws.Cells(1, 1).Value = "行1"
Debug.Print ws.Cells(1, 1).Address
End Sub
On Error Resume Next の使い方
エラーが起きても次の行へ進める命令です。「失敗しても問題ない」処理(例:存在しないものを消そうとする、任意シートがあれば参照したい等)に限定して使います。
ポイントは次の3つです。
- 影響範囲を最小にして、必要な行だけにかけます。
- Err.Number をすぐ確認し、必要なら Err.Clear します。
- 処理が終わったら必ず On Error GoTo 0 で通常状態に戻し、戻し忘れを避けます。
例(存在すれば削除し、なければ何もしない)です。
Option Explicit
Sub DeleteTempSheetIfExists()
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("Temp") ' 無ければここでエラーになり得る
On Error GoTo 0
If ws Is Nothing Then
Debug.Print "Tempシートは存在しません"
Exit Sub
End If
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End Sub
On Error GoTo での基本形
エラー発生時に指定ラベルへジャンプし、共通の後片付け(設定の復元)やログ出力を行う定番パターンです。構造は次の形にすると崩れにくいです。
- 先頭で
On Error GoTo ErrHandlerを書きます。 - 本体処理の後に、正常終了用として
Exit Subを置きます。 ErrHandler:で Err情報を取得してログ出力や復旧を行い、必要に応じてResume/Resume Next/Exit Subを使います。
基本形(エラー情報を Debug.Print へ出し、後で必ず終了する例)です。
Option Explicit
Sub ReadCellWithHandler()
On Error GoTo ErrHandler
Dim v As Variant
v = ThisWorkbook.Worksheets("Data").Range("B1").Value ' 参照が壊れていると1004/9などになり得る
MsgBox "B1=" & v
Exit Sub
ErrHandler:
Debug.Print "Err=" & Err.Number & " / " & Err.Description
MsgBox "エラーが発生しました。Err=" & Err.Number, vbExclamation
Exit Sub
End Sub
ブレークポイントとステップ実行(F8)
VBEのコード行左の余白をクリックするとブレークポイントを置けます。実行するとその行の手前で停止し、F8で1行ずつ進められます。
よく使う観察手段は以下です。
- マウスオーバーで変数値を確認できます。
- Locals(ローカル)ウィンドウでスコープ内変数を一覧表示できます。
- ウォッチ式で特定の式を監視できます。
外部参照(Worksheets取得、Range指定、ファイル操作など)の直後や、ループに入る直前にブレークポイントを置くと、1004・91・9の原因となる「参照先が想定と違う」状況を早期に見つけられます。
イミディエイトと Debug.Print
イミディエイトウィンドウ(Ctrl+G)は、式の即時評価と簡易ログ確認に使います。Debug.Print は処理の流れと変数の中身を軽量に出せるため、MsgBoxを繰り返す方法よりデバッグに向きます。
例です。
- イミディエイトで
? ThisWorkbook.Nameのように評価します。 - ループ内で
Debug.Print "i=" & iのように経過ログを出します。 - エラーハンドラで
Err.Numberを出して、発生条件を絞ります。
注意(ここだけ)
On Error Resume Nextを使った場合は、処理が終わった時点でOn Error GoTo 0に戻さないと、以降のエラーが握りつぶされて原因追跡が困難になります。
要約
1004はRangeやシート参照の不整合が原因になりやすく、91はNothing(Set忘れや取得失敗)が典型で、9はコレクションの範囲外参照が起きやすいです。
On Error Resume Next は短い範囲に限定し、Errの確認と On Error GoTo 0 への戻しを徹底するのがポイントです。
On Error GoTo は、エラー時のログ出力、復旧、後片付けを一箇所にまとめる基本形として有効です。
ブレークポイントとF8のステップ実行を使うと、エラー直前の状態(参照先や変数)を確認できます。
イミディエイトと Debug.Print は、即時評価と軽量ログによって原因の切り分けを高速化できます。