壊れないWord自動化の極意:『On Error Resume Next』の誘惑を断ち切り、プロのハンドリングを実装せよ
Word VBAにおいて、`On Error Resume Next` を「魔法の杖」だと思っていないか?
「エラーが出ても無視すればいい」という甘い考えで書かれたコードは、数ヶ月後の君自身を追い詰める技術的負債となる。特にWordは、カーソルの位置、選択範囲の消失、外部オブジェクトとの同期ズレなど、予測不可能な「実行時エラー」の温床だ。
今日は、場当たり的な修正ではなく、「エラーを制御下に置くための構造的設計」について伝授する。
—
1. なぜ『On Error Resume Next』は悪魔の囁きなのか
初心者ほど「エラーが怖いから」という理由で `Resume Next` を多用する。しかし、これはブレーキの壊れた車で高速道路を走るようなものだ。
- 状態の不整合: オブジェクトが取得できていないのに後続の処理が走り、予期せぬ場所(最悪の場合は別のドキュメント)を書き換える。
- デバッグの迷宮化: 根本原因(Root Cause)が隠蔽され、なぜ最終的にエラーが起きたのかが追跡不能になる。
プロのエンジニアは、「エラーを無視する」のではなく「エラーを予測し、安全に退避させる」という設計思想を持つ。
—
2. 堅牢なエラーハンドリング:『守備範囲の局所化』
エラーハンドリングは、全域に適用するのではなく、「外部要因が絡む不安定な処理」に対して局所的に適用するのが鉄則だ。
推奨される設計パターン:構造的ハンドリング
Public Sub SafeDocumentOperation()
Dim doc As Document
‘ 1. エラーを局所的に制御する
On Error GoTo ErrorHandler
‘ 外部ファイル操作やオブジェクトアクセスなど、失敗の可能性がある箇所
Set doc = Documents.Open(“C:\Target.docx”)
‘ 処理本体…
GoTo Cleanup ‘ 正常終了時はクリーンアップへ
ErrorHandler:
‘ 2. エラータイプに応じて振る舞いを変える
Select Case Err.Number
Case 5174 ‘ ファイルが見つからない等の具体的なエラーコード
MsgBox “対象ファイルが存在しません。パスを確認してください。”, vbCritical
Case Else
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End Select
Resume Cleanup
Cleanup:
‘ 3. オブジェクトの解放とエラー解除
If Not doc Is Nothing Then Set doc = Nothing
On Error GoTo 0 ‘ エラーハンドラをリセット
End Sub
—
3. Word VBA特有の「罠」を回避するテクニック
Wordのオブジェクトモデルは、`Selection` や `Range` が突然無効化されるという特異な性質を持つ。これらを防ぐための「実戦的設計」は以下の通りだ。
① `Selection` より `Range` を使え
`Selection` はユーザーの操作に依存し、非常に不安定だ。`Range` オブジェクトを明示的に作成し、そこにスコープを限定することで、エラーの発生確率を劇的に下げられる。
② 「オブジェクトが消滅した」エラーへの対処
データベース連携や別アプリとの連携時、Word側のオブジェクトが解放済みになることがある。これをハンドリングするには「明示的な型判定」が有効だ。
‘ プロダクションコードにおける安全なオブジェクトチェック
If Not myRange Is Nothing Then
‘ オブジェクトが有効な場合のみ処理
myRange.Text = “更新完了”
Else
‘ オブジェクトが消失した場合のロジックをここに記述
Err.Raise vbObjectError + 1001, “Process”, “Rangeオブジェクトが消失しました。”
End If
—
4. チーム開発で生き残るための「保守性」の定義
君が書いたコードは、半年後の君が保守する。そのための「3つの絶対ルール」を心に刻んでほしい。
1. エラーログを可視化する: `MsgBox` だけでは足りない。重要なツールであれば、テキストファイルやイベントログにエラー内容とタイムスタンプを書き出す機能を組み込め。
2. `On Error GoTo 0` を忘れるな: 複数のプロシージャを呼び出す際、エラーハンドラが重複して意図しない挙動にならないよう、各ブロックの出口で必ずリセットすること。
3. 「失敗した時の状態」を保証する: 関数が失敗した際、ファイルを開きっぱなしにしたり、無意味な空のドキュメントを残したりしてはいけない。`Cleanup` ラベルで必ず状態を初期化しろ。
—
最後に:エンジニアとしての矜持
「動けばいい」というコードは、エンジニアの仕事ではない。それは「爆弾」を仕掛けているのと同じだ。
Word VBAは、APIの深淵を覗くことができる強力な武器だ。その武器を正しく扱い、誰よりも安定したツールを構築すること。それこそが、君というエンジニアの価値を最大化させる唯一の道である。
さあ、コードを開け。まずはその場当たり的な `Resume Next` を一つずつ、適切な `GoTo` ハンドラに書き換えることから始めよう。
