枯れた技術を極限まで駆動する:VBA×外部JSONによる「動的置換アーキテクチャ」の設計思想
Word VBAにおける`Find`オブジェクトは、古くから存在するがゆえに、多くのエンジニアが「その場の思いつき」で実装し、メモリリークやパフォーマンス低下を招いている。
本稿では、VBAをただの自動化ツールとしてではなく、「外部ソースと疎結合された堅牢な置換エンジン」へと昇華させるためのアーキテクチャを提示する。ハードコーディングされた置換ルールは、技術的負債の温床だ。JSONを外部辞書として取り込み、Wordを再起動することなく置換ロジックを更新し続けるための「極限の設計」を解説する。
—
1. なぜ「外部JSON」なのか:疎結合の必然性
VBAコード内に置換表を配列として持つのは素人の所業だ。保守のたびにコンパイルが必要な環境は、CI/CDとは無縁の「レガシーの呪縛」そのものである。
外部JSONを利用する目的は以下の3点に集約される。
- 動的更新: Wordを閉じることなく置換ルールを差し替える。
- 構造化データの活用: 単なる「検索・置換」を超えた、属性(正規表現フラグ、ワイルドカード指定等)の付与。
- 保守性の分離: ビジネスロジック(VBA)と辞書データ(JSON)の責任分界点を明確にする。
—
2. 核心技術:VBAでのJSON解析戦略
VBAには標準でJSONパーサーが存在しない。Microsoft Script Controlや`FileSystemObject`による力技も存在するが、現代のエンジニアであれば`VBA-JSON`(Tim Hall氏作)を採用すべきだ。もし外部ライブラリの持ち込みが禁じられている閉域網環境であっても、最低限、自作の簡易パーサーをクラスモジュールとして実装し、グローバルスコープを汚染しない設計を徹底すること。
—
3. 実装:メモリを制御し、Findを駆動する
以下は、メモリリークを回避しつつ、高速に置換を繰り返すためのエンジン設計例だ。
‘ @class ReplaceEngine
‘ WordのFindオブジェクトは、参照を保持し続けるとメモリを解放しにくい。
‘ 処理の都度オブジェクトを明示的にクリアする設計が不可欠である。
Option Explicit
Public Sub RunBatchReplace(ByVal jsonPath As String)
Dim fso As Object
Dim jsonText As String
Dim dict As Object
Dim key As Variant
‘ 1. ファイルシステムへのアクセスは最小限に
Set fso = CreateObject(“Scripting.FileSystemObject”)
jsonText = fso.OpenTextFile(jsonPath, 1).ReadAll
‘ 2. JSON解析 (VBA-JSONライブラリ利用を想定)
Set dict = JsonConverter.ParseJson(jsonText)
‘ 3. WordのFindオブジェクトを最適化する
Dim rng As Range
Set rng = ActiveDocument.Content
‘ 4. ループ処理:オブジェクトの明示的解放を意識
For Each key In dict.Keys
ExecuteFind rng, key, dict(key)
Next
Set rng = Nothing
Set dict = Nothing
Set fso = Nothing
End Sub
Private Sub ExecuteFind(ByRef rng As Range, ByVal findText As String, ByVal replaceText As String)
With rng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = findText
.Replacement.Text = replaceText
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True ‘ ここをTrueにすることで正規表現的な挙動が可能
.Execute Replace:=wdReplaceAll
End With
End Sub
—
4. チーフアーキテクトからの助言:極限のパフォーマンスを引き出すために
A. オブジェクトの明示的解放(Nothingへの固執)
WordのCOMインターフェースは、バックグラウンドでインスタンスを維持しがちだ。`Set rng = Nothing` を忘れることは、長時間のバッチ処理においてメモリの断片化を招く。特にループ内で`Range`を再生成する場合は、必ず参照をリセットすること。
B. Findオブジェクトの初期化
`.ClearFormatting` と `.Replacement.ClearFormatting` を毎回の検索直前に行うのは、Wordのバグ(前回の検索設定が残存し、意図せぬ置換が走る)を回避するための「呼吸」のようなものだ。これを省略する者は、必ずいつか重大な置換ミスを犯す。
C. 大規模文書における高速化
もし対象文書が数万ページに及ぶ場合、`Find` を全文書に対して一度に投げるのは非効率だ。`Paragraph`単位や`Section`単位でイテレートし、各セグメント内で`Find`を完結させることで、Wordのメモリ保持量を一定に保つことができる。
—
結論:技術は「仕組み」に宿る
Word VBAは「枯れた技術」ではない。「磨き上げられたエンジニアリングが適用されていない、未開のフィールド」である。
今回提示した「JSON駆動型置換エンジン」は、単なるコードの断片に過ぎないが、これを基盤として、辞書の動的読み込み、履歴ログの生成、エラーリカバリーのロジックを積み上げていくことで、それは「ツール」から「システム」へと進化する。
VBAを書くことに恥じる必要はない。コードの質が、そのエンジニアの矜持を決めるのだ。さあ、今すぐレガシーなコードをリファクタリングし、真の自動化を実現せよ。
