【実務・中級編】VBAの「実行時エラー番号」をログに記録し、リモート環境でのトラブルシューティングを容易にする – Excel VBA解析バイブル

スポンサーリンク

現場の「なぜ動かない?」を撲滅する。プロが実装すべきVBAエラーログ設計の極意

業務自動化ツールを開発していると、必ず直面する壁がある。それは、「開発者のPCでは完璧に動くのに、ユーザーの環境でだけ謎の挙動を示す」という現象だ。

実行時エラーが発生した際、ユーザーから「なんかエラーが出た」とだけ報告を受けて時間を浪費した経験はないだろうか? その泥沼から脱却する唯一の方法は、エラーを「記憶」し、後の分析に耐えうる「記録」として残すことだ。

今日は、VBAというレガシーな環境であっても、現代のWeb開発と同等の「堅牢なエラーハンドリングとロギング」を実現するためのアーキテクチャを伝授する。

1. なぜ「On Error Resume Next」に逃げてはいけないのか

多くの初学者が「とりあえずエラーを無視する」ために`On Error Resume Next`を乱用するが、これはデバッグの可能性を自ら握りつぶす自殺行為だ。

真のエンジニアは、「エラーは発生するもの」と前提し、その発生箇所、番号、そして状況を即座に特定できる仕組みを構築する。

今回実装するロギングシステムは、以下の3点を徹底する。
1. 一元管理: エラーログの記録ロジックを共通化し、各プロシージャに散らばらせない。
2. コンテキストの保持: エラー番号だけでなく、どのプロシージャで何をしている時に起きたかを記録する。
3. 低負荷・高信頼: ファイルI/Oを安全に処理し、ログ書き込み自体がエラーを引き起こさないようにする。

2. 実装コード:プロダクションレベルの「ログ出力エンジン」

以下のコードは、標準モジュール(例: `modLogger`)に配置して使い回すことを前提としている。

Option Explicit

‘ ログファイルのパス(環境に合わせて変更してください)
Private Const LOG_FILE_PATH As String = “C:\Temp\App_Error.log”

”’

”’ エラー情報をログファイルに記録する共通プロシージャ
”’

Public Sub WriteErrorLog(ByVal procName As String, ByVal errNum As Long, ByVal errDesc As String)
Dim fileNum As Integer
Dim logMessage As String

‘ 書き出し用のメッセージを作成
logMessage = “[” & Now & “] ” & _
“Proc: ” & procName & ” | ” & _
“Error: ” & errNum & ” | ” & _
“Desc: ” & errDesc

‘ 安全なファイルI/O
fileNum = FreeFile
On Error Resume Next ‘ ログ書き込み中のエラーは無視する(アプリ本体を止めるべきではない)
Open LOG_FILE_PATH For Append As #fileNum
Print #fileNum, logMessage
Close #fileNum
On Error GoTo 0
End Sub

3. 実践:各プロシージャへの組み込み方

次に、個々の処理でどのようにこのロガーを呼び出すか。重要なのは「エラーハンドラの定型化」だ。

Public Sub ProcessData()
Const PROC_NAME As String = “ProcessData”

On Error GoTo ErrorHandler

‘ — 本来の処理 —
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(“非存在シート”) ‘ ここでエラーを発生させる
‘ ——————

Exit Sub

ErrorHandler:
‘ ログに出力
WriteErrorLog PROC_NAME, Err.Number, Err.Description

‘ ユーザーへのフィードバック
MsgBox “システムエラーが発生しました。” & vbCrLf & _
“ログを確認してください。” & vbCrLf & _
“エラーコード: ” & Err.Number, vbCritical
End Sub

4. 現場で生き残るための「4つの設計指針」

この実装を導入する際、以下のポイントを遵守してほしい。

① ログファイルのパスは環境変数から取得せよ

`C:\Temp`は書き込み権限がない場合がある。ユーザーの`Environ(“USERPROFILE”)`配下や、アプリと同じディレクトリに相対パスで設定するのが定石だ。

② ファイルI/Oの競合を考慮せよ

もし多人数がネットワークドライブ上のファイルを同時に開く可能性があるなら、ファイルが開けない場合のリトライ処理を組み込むべきだ。あるいは、ログを「共有データベース」に飛ばす設計へと昇華させる必要がある。

③ 開発環境と本番環境の切り替え

`#Const`ディレクティブを用いて、開発中は詳細なデバッグ情報を表示し、本番環境ではユーザーへの露出を最小限にするなどの工夫が、プロのツールには求められる。

④ 「なぜ」エラーが起きたかの文脈を追記せよ

単に `Err.Description` だけでは不十分な場合が多い。`ProcessData` 内のどのステップ(例:CSV読み込み時、API通信時)で止まったのか、変数の中身をダンプするログを追加すると、トラブルシューティングの速度は10倍になる。

最後に:エンジニアとしての矜持

VBAは「簡易的なツール」として軽視されがちだが、ユーザーにとっては業務を支える大切なインフラだ。エラーログを実装することは、単にログを残すことではない。「ユーザーが直面する未知の不安を、技術の力で解決可能な課題へと変換する」というエンジニアの責務を果たしているに過ぎない。

今日からあなたのコードにこのロガーを組み込んでほしい。それが、バグに追われる日々を終え、真に堅牢なシステムを構築するための第一歩となるはずだ。

何か技術的な壁にぶつかったら、いつでもここに戻ってきてほしい。我々の戦いは、まだ始まったばかりだ。

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