現場の「なぜ動かない?」を撲滅する。プロが実装すべき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は「簡易的なツール」として軽視されがちだが、ユーザーにとっては業務を支える大切なインフラだ。エラーログを実装することは、単にログを残すことではない。「ユーザーが直面する未知の不安を、技術の力で解決可能な課題へと変換する」というエンジニアの責務を果たしているに過ぎない。
今日からあなたのコードにこのロガーを組み込んでほしい。それが、バグに追われる日々を終え、真に堅牢なシステムを構築するための第一歩となるはずだ。
何か技術的な壁にぶつかったら、いつでもここに戻ってきてほしい。我々の戦いは、まだ始まったばかりだ。
