【テクニカル・上級編】エラーハンドリングの基本形:On Error GoTo 0とResumeの正しい理解 – Excel VBA解析バイブル

スポンサーリンク

墓場まで持っていく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` を怠るな。
そして何より、エラーが発生した瞬間に「何が起きたか」を誰が見ても分かるようにログを吐け。

技術とは、魔法ではない。論理の積み重ねだ。その積み重ねこそが、伝説を創る。健闘を祈る。

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