VBAには他言語のような Try...Catch...Finally 構文や標準のコールスタック取得機能が用意されていないため、エラー発生時にどの経路で呼び出されたかを把握するには少し工夫が必要です。
独自のエラー処理用クラスを組むほどではないものの、簡易的なデバッグ用として「エラー発生時に呼び出し元の関数名を Err.Source へ連結して再スロー(Err.Raise)する」ことで、擬似的なコールスタックを残すテクニックを紹介します。
実装のポイント
- 呼び出し履歴を追跡したいプロシージャ(メソッド・プロパティ)に
On Error GoTo ExceptionHandlingを記述します。 - 正常終了時にエラー処理ラベルへ突入しないよう、必ず
Exit Subを配置します。 - エラー発生時は
Err.Sourceに自身のプロシージャ名を追記し、Err.Raiseで上位の呼び出し元へエラーを再送出します。
サンプルコード
' 呼び出し元(トップレベル)
Sub main()
On Error GoTo ExceptionHandling
' 処理の呼び出し
Call funcA
' 正常終了時
Exit Sub
ExceptionHandling:
' 例外情報の出力
Dim s As String
s = "Err.Number: " & Err.Number & vbCrLf _
& "Err.Source: " & Err.Source & vbCrLf _
& "Err.Description: " & Err.Description & vbCrLf _
& "Err.HelpContext: " & Err.HelpContext & vbCrLf _
& "Err.HelpFile: " & Err.HelpFile & vbCrLf _
& "Err.LastDllError: " & Err.LastDllError
Debug.Print s
End Sub
Sub funcA()
On Error GoTo ExceptionHandling
Call funcB
Exit Sub
ExceptionHandling:
' 呼び出し元にプロシージャ名を付加して再スロー
Err.Source = Err.Source & "->funcA"
Err.Raise Err.Number, Err.Source, Err.Description
End Sub
Sub funcB()
On Error GoTo ExceptionHandling
Call funcC
Exit Sub
ExceptionHandling:
Err.Source = Err.Source & "->funcB"
Err.Raise Err.Number, Err.Source, Err.Description
End Sub
Sub funcC()
On Error GoTo ExceptionHandling
' テスト用に0除算エラーを意図的に発生させる
Dim a As Integer
a = 100 / 0
Exit Sub
ExceptionHandling:
Err.Source = Err.Source & "->funcC"
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Sub
イミディエイトウィンドウの出力結果
Err.Number: 11
Err.Source: VBAProject->funcC->funcB->funcA
Err.Description: 0 で除算しました。
Err.HelpContext: 1000011
Err.HelpFile: C:\Program Files\...\VbLR6.chm
Err.LastDllError: 0
出力結果の Err.Source を確認すると、エラーが発生した funcC から funcB、funcA を経由してトップレベルの main まで渡ってきたコール履歴が一目で確認できます。
この記事の更新履歴
この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。
2026年9月11日
- 変更各プロシージャで正常終了時にエラーハンドラへ流れ込まないようExit Subを追加しました。
- 変更本文中の誤字(fancC)をfuncCに修正しました。
- 変更崩れていたHTMLの段落タグを整形し、VBAコードブロックとして見やすく整理しました。
