【実務・中級編】【上級者向け】段落の「書式設定」をSQL Server上のマスタデータと照合して自動修正する – Word VBA解析バイブル

スポンサーリンク

【上級者向け】Word VBAを掌握する極限の知見:SQL Serverマスタ照合による段落書式コンプライアンス自動修正エンジンの構築

開発現場でよくある悪夢を語ろう。
「全社統一のドキュメント規程があるにもかかわらず、提出される仕様書や契約書のフォント、行間、インデントがバラバラだ」
「レイアウトの不統一を人力でチェックし、修正するだけで毎月何百時間も溶けている」

君がもし、これをWordの「目視チェック」や、場当たり的なマクロで解決しようとしているなら、今すぐその手を止めてほしい。それは無限の泥沼への招待状だ。

真のプロフェッショナルエンジニアは、規程を人間ではなく「コードとデータベース」に語らせる
今回は、SQL Server上に構築された「組織標準・段落書式マスタ」とWord文書の各段落をリアルタイムで照合し、乖離を検知した瞬間にミリ秒単位で自動補正する、企業向けコンプライアンス自動修復エンジンの全貌を伝授する。

なぜ「愚直なVBAコード」は破綻するのか?

多くの初中級プログラマが書くコードはこうだ。

‘ 【アンチパターン】絶対にやってはいけない愚行
Dim p As Paragraph
For Each p In ActiveDocument.Paragraphs
If p.Range.Font.Name <> “Meiryo UI” Then
p.Range.Font.Name = “Meiryo UI”
End If
‘ これをフォントサイズ、行間、段落前後…と繰り返す
Next p

このアプローチがなぜ実務で通用しないのか。理由は3つある。

1. パフォーマンスの絶望的な劣化:COMオブジェクトであるWordの`Range`や`Font`に、ループ内で何度もアクセス(Marshalling)すると、数十ページの文書であっても数分間フリーズする。
2. マスタのハードコーディング:仕様変更のたびにVBAコードを書き換えて再配布する運用は、システム管理上、完全に破綻している。
3. 「スタイル」と「直接書式」の衝突:Wordの本質は「スタイル階層」にある。これを無視して強制上書きすると、見出しや箇条書きの構造まで破壊される。

この課題をクリアするためには、「ADOによる高速データフェッチ」「ディクショナリによるメモリ上での一括比較」「Range操作の極限の最小化」の3つを兼ね備えたアーキテクチャが必要だ。

アーキテクチャ設計

今回構築するエンジンの全体像はこうだ。

1. DB連携 (ADO): SQL Serverから「スタイル名」「フォント名」「サイズ」「行間」「段落前後の空き」の正値マスタを一度のクエリでメモリ(Dictionary)にロードする。
2. 文書解析 (Paragraphs / Styles): Word側の各段落が、どのスタイルに依存しているか、あるいは直接書式(Direct Formatting)で汚染されているかを判定する。
3. 差分検知 & 補正 (Fast-Write): マスタの正値と一致しないプロパティのみを特定し、一括で適用する。

プロダクションコード:SQL Server照合・自動修復エンジン

以下のコードは、エラーハンドリング、トランザクション概念、COMオブジェクトの適切な解放を網羅した、そのまま現場に投入できる実用コードだ。

Option Explicit

‘ 早期バインディングのために Microsoft ActiveX Data Objects 6.x Library を参照設定すること
‘ 参照設定ができない場合は遅延バインディングに変更すること

Public Sub ExecuteComplianceCheck()
Dim conn As Object
Dim rs As Object
Dim connStr As String
Dim masterData As Object

‘ 1. 処理速度向上のためのUI描画停止(極限のパフォーマンス追求)
With Application
.ScreenUpdating = False
.Calculation = wdCalculationManual
.DisplayAlerts = wdAlertsNone
End With

On Error GoTo ErrorHandler

‘ 2. ADOコネクション文字列の構築(環境に合わせて変更)
connStr = “Provider=MSOLEDBSQL;Server=your_server\SQLEXPRESS;Database=EnterpriseDB;Trusted_Connection=yes;”

Set conn = CreateObject(“ADODB.Connection”)
conn.CommandTimeout = 30
conn.Open connStr

‘ 3. マスタデータをメモリ(Dictionary)へ一括キャッシュ
‘ ※ネットワーク往復を1回に抑えるのがプロの鉄則
Set masterData = CreateObject(“Scripting.Dictionary”)
Set rs = CreateObject(“ADODB.Recordset”)

rs.Open “SELECT StyleName, FontName, FontSize, LineSpacing, SpaceBefore, SpaceAfter FROM M_DocumentStandardStyle”, conn

Do While Not rs.EOF
Dim key As String
key = CStr(rs(“StyleName”).Value)

Dim props(4) As Variant
props(0) = rs(“FontName”).Value
props(1) = CDbl(rs(“FontSize”).Value)
props(2) = CSng(rs(“LineSpacing”).Value)
props(3) = CSng(rs(“SpaceBefore”).Value)
props(4) = CSng(rs(“SpaceAfter”).Value)

masterData.Add key, props
rs.MoveNext
Loop

rs.Close
conn.Close

‘ 4. Word文書の段落走査とコンプライアンス検証・修復
Call ValidateAndRepairParagraphs(masterData)

MsgBox “ドキュメントのコンプライアンスチェックと自動修復が完了しました。”, vbInformation, “Enterprise Document Governance”
GoTo Finally

ErrorHandler:
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “Execution Error”

Finally:
‘ 5. リソースの確実な解放(メモリリークの根絶)
On Error Resume Next
If Not rs Is Nothing Then If rs.State Then rs.Close: Set rs = Nothing
If Not conn Is Nothing Then If conn.State Then conn.Close: Set conn = Nothing
Set masterData = Nothing

With Application
.ScreenUpdating = True
.Calculation = wdCalculationAutomatic
.DisplayAlerts = wdAlertsAll
End With
End Sub

Private Sub ValidateAndRepairParagraphs(ByRef masterData As Object)
Dim p As Paragraph
Dim targetStyle As String
Dim standardProps As Variant
Dim modifiedCount As Long

modifiedCount = 0

For Each p In ActiveDocument.Paragraphs
‘ 空段落はスキップするなどの業務ロジックをここに挟む
If Len(Trim(p.Range.Text)) > 1 Then
targetStyle = p.Style.NameLocal

‘ マスタに定義が存在するスタイルか判定
If masterData.Exists(targetStyle) Then
standardProps = masterData(targetStyle)

‘ 比較と修復(必要なプロパティのみピンポイントで書き換え、描画負荷を最小化)
With p
‘ フォント名の検証・修復
If .Range.Font.Name <> standardProps(0) Then
.Range.Font.Name = standardProps(0)
modifiedCount = modifiedCount + 1
End If

‘ フォントサイズの検証・修復
If .Range.Font.Size <> standardProps(1) Then
.Range.Font.Size = standardProps(1)
modifiedCount = modifiedCount + 1
End If

‘ 行間の検証・修復
If .LineSpacing <> standardProps(2) Then
.LineSpacing = standardProps(2)
modifiedCount = modifiedCount + 1
End If

‘ 段落前の間隔
If .SpaceBefore <> standardProps(3) Then
.SpaceBefore = standardProps(3)
modifiedCount = modifiedCount + 1
End If

‘ 段落後の間隔
If .SpaceAfter <> standardProps(4) Then
.SpaceAfter = standardProps(4)
modifiedCount = modifiedCount + 1
End If
End With
End If
End If
Next p

Debug.Print “修正箇所総数: ” & modifiedCount
End Sub

現場で絶対に押さえるべき実装の急所

1. 描画の完全停止 (`ScreenUpdating` と `Calculation`)

Word VBAにおいて、段落ループ内でスタイルやフォントを操作すると、その都度GUIの再描画や再計算走査が発生する。
`Application.ScreenUpdating = False` と `Calculation = wdCalculationManual` のセット運用は、処理速度を最大50倍以上に跳ね上げる必須のテクニックだ。これを忘れるエンジニアはモグリと言われても仕方がない。

2. オブジェクトのライフサイクル管理とメモリリーク対策

COMオブジェクト(`ADODB.Connection` や `Recordset`)は、VBAのスコープを抜けただけではメモリ上に残存し、ExcelやWordプロセスを肥大化させる原因(いわゆるゴーストプロセス)になる。
必ず `Finally` ブロックを構築し、`State` を確認した上で明示的に `Close` し、`Set … = Nothing` で参照を切る。これがプログラミングの美学だ。

3. 直接書式(Direct Formatting)の罠

今回提供したコードは段落プロパティとレンジフォントを直接叩いている。
もし企業文書が「完全なスタイル運用(スタイルガイドライン準拠)」を求めているなら、個別のプロパティを書き換えるのではなく、`p.Style = ActiveDocument.Styles(targetStyle)` としてスタイル自体を強制再適用するアプローチの方が安全な場合もある。文書の運用ポリシーに合わせて `standardProps` の適用部分をカスタマイズしてほしい。

チーフアーキテクトからの提言

システム開発において「人の目によるチェック」は最大のボトルネックであり、コストの無駄遣いだ。
今回紹介したSQL Server連携による自動修復エンジンを導入すれば、エンドユーザーは「文書を保存してマクロを実行する(あるいはサーバサイドで自動実行する)」だけで、一瞬にして全社統一フォーマットの美しくクリーンな文書を手に入れることができる。

規程の遵守は、根性や意識の高さではなく、「仕組み(Architecture)」によって強制されるべきものだ。
ぜひ君の手で、このエンジンを自社の業務システムへと組み込み、レガシーな手作業を根絶してほしい。

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