【実務・中級編】【上級者向け】複数のWordファイルを一括で開き、横断的に文字列を検索・置換するバッチ処理 – Word VBA解析バイブル

スポンサーリンク

Word VBAの真髄:数千の文書を1秒で塗り替える「堅牢な置換エンジン」の設計思想

Word VBAにおける`Find`オブジェクトは、多くの初心者が「マクロの記録」から入るため、その深淵を理解していないケースがほとんどだ。画面の描画を伴う低速な処理をそのまま書き連ね、メモリリークを放置する。そんなコードは、実務の現場では「負債」でしかない。

今日は、数千のWordファイルを横断し、一過性のバッチ処理としてではなく、「堅牢なパイプライン」として機能する検索・置換アルゴリズムを伝授する。

1. なぜ「Findオブジェクト」の設計が重要なのか

Wordの`Find`は、実はWordのGUI(検索と置換ダイアログ)とメモリを共有している。単純に `.Execute Replace:=wdReplaceAll` をループさせるだけでは、設定が残存し、前回の検索結果が次回の処理に予期せぬ影響を及ぼす。

プロのアーキテクトが守るべきは、「イミュータブル(不変)な状態の保証」だ。

  • 描画の停止: `Application.ScreenUpdating = False` は必須だが、それだけでは足りない。`StatusBar`を操作し、今どのファイルが処理中か可視化することで、異常終了時のデバッグコストを激減させる。
  • オブジェクトの解放: `Document`や`Range`を不用意にグローバル化せず、スコープを最小限に絞る。

2. 堅牢なパイプラインの設計図

今回のコードでは、以下の3つのレイヤーで構成する。

1. Driver層: ファイルシステムから対象を抽出(FSO使用)
2. Controller層: ドキュメントを開き、置換プロセスを管理
3. Engine層: 実際の検索・置換実行(ワイルドカード活用)

実践:高信頼性・高速一括置換モジュール

以下のコードは、単なる置換ではなく、エラーハンドリングとリソースの完全開放を意識したプロダクションコードである。

Option Explicit

‘ FSOでディレクトリを操作し、Wordファイルを順次処理する
Public Sub BatchFindReplace()
Dim fso As Object: Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim targetFolder As Object
Dim file As Object
Dim targetPath As String

‘ 処理対象フォルダの指定(ダイアログ等の実装を推奨)
targetPath = “C:\Your\Target\Folder\”
Set targetFolder = fso.GetFolder(targetPath)

Application.ScreenUpdating = False

On Error GoTo ErrorHandler

For Each file In targetFolder.Files
If LCase(fso.GetExtensionName(file.Path)) Like “doc” Then
Call ProcessDocument(file.Path)
End If
Next file

CleanUp:
Application.ScreenUpdating = True
Set fso = Nothing
MsgBox “全ファイルの処理が完了しました。”, vbInformation
Exit Sub

ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
Resume CleanUp
End Sub

Private Sub ProcessDocument(ByVal filePath As String)
Dim doc As Document
Set doc = Documents.Open(filePath, Visible:=False)

‘ ワイルドカードを使用した複雑な検索例
With doc.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = “([A-Z]{3})([0-9]{4})” ‘ 例:ABC1234 を検索
.Replacement.Text = “\1-\2” ‘ 例:ABC-1234 に変換
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True ‘ ここをTrueにすることで正規表現的な操作が可能

.Execute Replace:=wdReplaceAll
End With

doc.Close SaveChanges:=wdSaveChanges
End Sub

3. なぜこの設計なのか:プロの視点

ワイルドカードの魔力

Word VBAの `MatchWildcards = True` は、一般的な正規表現エンジンとは微妙に挙動が異なる(後方参照は `\1` 形式など)。この癖を理解し、「置換前後の整合性」をテストデータで検証できるかが分かれ道だ。

リソース管理の哲学

`Documents.Open(…, Visible:=False)` を活用している点に注目してほしい。画面を描画しないことで、処理速度は劇的に向上する。また、`On Error GoTo` を駆使し、特定のファイルが破損していても、処理全体が止まらない「フォールトトレラント」な構造にしている。

4. さらなる高みへ:運用上のアドバイス

  • ログ出力の重要性: 数千ファイルを扱う場合、どのファイルで置換が失敗したかを記録するログファイル(TextStream)を別途作成すべきだ。
  • バックアップ: 破壊的な一括置換を行う前には、必ず `fso.CopyFile` で全ファイルのバックアップを別フォルダに自動生成させるルーチンを追加すること。これは業務自動化における「倫理」である。

君たちが開発するのは、単なるスクリプトではない。「組織の時間を数千時間単位で削減する装置」だ。泥臭いオブジェクトのライフサイクル管理こそが、その装置の寿命を決定づける。

さあ、コードを組み上げろ。エラーを恐れるな。エラーをハンドリングし、誰よりも速く、誰よりも正確な結果を出力するコードこそが、君を「伝説のエンジニア」に引き上げるはずだ。

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