墓場まで持っていくVBAの流儀:エラーハンドリングとメモリ管理の深淵
Excel VBAは、現代のモダンな開発環境から見れば「化石」のように映るかもしれない。だが、数百万行のレガシーコードを抱え、システム間連携の狭間で悲鳴を上げる現場において、VBAほど「即応性と破壊力」を兼ね備えた武器は存在しない。
多くのエンジニアが犯す致命的な過ちは、エラーハンドリングを「とりあえず動けばいいもの」として扱うことだ。メモリリーク、ゾンビ化したExcelプロセス、そして原因不明のランタイムエラー。これらはすべて、お前たちの「エラーハンドリングの無知」から生じている。
今日は、VBAを掌握し、堅牢なシステムを構築するための「極限のエラーハンドリング」について説く。
—
1. エラーハンドリングの「三権分立」:On Error GoTo 0 と Resume の真意
多くのチュートリアルは `On Error Resume Next` を軽率に推奨するが、あれは「目隠しをして時速100キロで走る」ようなものだ。真のエンジニアは、以下の三原則を守る。
1. On Error GoTo 0: エラーハンドラを無効化し、デバッグ時にエラー箇所を特定可能にする。「エラーを無視する」のではなく「制御を戻す」ための必須コマンドだ。
2. On Error GoTo [ラベル]: 異常系への分岐点。必ずプロシージャの最後に配置する。
3. Resume [ラベル]: 復帰点。エラー箇所を補正して再試行するか、あるいは終了処理へ流し込むための舵取りだ。
実践的テンプレート:プロフェッショナルの定型
Public Sub SecureDataProcess()
‘ オブジェクトの事前宣言(メモリ管理の基本)
Dim ws As Worksheet
‘ エラーハンドリングの開始
On Error GoTo ErrHandler
Set ws = ThisWorkbook.Sheets(“Data”)
‘ メイン処理
‘ … ここにAPIコールやDB接続のロジック …
CleanExit:
‘ 終了処理:メモリ解放は必ずここを通る
Set ws = Nothing
On Error GoTo 0
Exit Sub
ErrHandler:
‘ ログ記録(イベントビューアやログファイルへ)
Debug.Print “Error: ” & Err.Number & ” – ” & Err.Description
‘ 致命的なエラー以外ならここで修正を試みる等の処理
‘ Resume Next ‘ 状況に応じて判断
Resume CleanExit
End Sub
—
2. メモリ最適化:オブジェクトを「死なせる」技術
VBAにおいて `Set obj = Nothing` を書かないのは、C言語で `free()` を忘れるのと同じ罪だ。特にExcelのCOMオブジェクトは、明示的に解放しない限り、裏側でプロセスが残り続け、いずれメモリリークを引き起こす。
- 循環参照を避ける: 親子関係にあるオブジェクトを相互に参照させると、参照カウントがゼロにならずメモリが永続的に確保される。
- API呼び出しの罠: Windows API (kernel32.dll 等) を呼ぶ際は、必ずエラーハンドラ内でハンドルの解放を記述せよ。OS側のリソースをリークさせると、Excelごとクラッシュする。
—
3. レガシー連携の極限:システム間通信の安全圏
VBAからWeb API(WinHttp.WinHttpRequest.5.1)を叩く際、最も恐ろしいのはタイムアウトと「半死のコネクション」だ。
Private Function FetchDataFromAPI(url As String) As String
Dim http As Object
On Error GoTo ErrHandler
Set http = CreateObject(“WinHttp.WinHttpRequest.5.1”)
With http
.Open “GET”, url, False
.SetTimeouts 5000, 5000, 5000, 5000 ‘ 極限まで短く設定し、無駄な待機を排除
.Send
If .Status = 200 Then
FetchDataFromAPI = .ResponseText
Else
Err.Raise 9999, , “API Error: ” & .Status
End If
End With
CleanExit:
Set http = Nothing
Exit Function
ErrHandler:
‘ ここで例外をキャッチし、呼び出し元へ適宜通知する
FetchDataFromAPI = “”
Resume CleanExit
End Function
—
最後に:エンジニアとしての矜持
VBAは、誰でも書けるがゆえに、誰でも壊せる。
君たちが記述するその1行が、企業の基幹業務を支えるのか、それとも数ヶ月後に爆発する時限爆弾になるのか。それは「エラーをどう処理したか」という細部に宿る。
`On Error GoTo 0` を書き忘れるな。
`Set = Nothing` を怠るな。
そして何より、エラーが発生した瞬間に「何が起きたか」を誰が見ても分かるようにログを吐け。
技術とは、魔法ではない。論理の積み重ねだ。その積み重ねこそが、伝説を創る。健闘を祈る。
