「マクロの記録」を卒業しよう。JSONで制御する、プロ仕様のWord表生成エンジン構築術
こんにちは。エンジニアの道へようこそ。
もし君が今、「マクロの記録」ボタンを押し、生成された膨大なコードを眺めながら「これをどうやって実務で使いやすくしようか……」と頭を抱えているとしたら、おめでとう。君は今、「ただの操作自動化」から「ソフトウェア開発」への入り口に立っています。
今日のテーマは、Word VBAにおける最高峰の設計思想の一つ、「データとロジックの分離」です。
具体的には、表のレイアウト(列幅、色、フォント、テキスト)をVBAの中に書き込むのではなく、外部のJSONファイルに切り出し、それを読み込んで表を動的に組み立てる「テンプレートエンジン」の作り方を伝授します。
これこそが、プロの業務自動化エンジニアが実践している「メンテナンス性の高いコード」の正体です。
なぜ、VBAの中に「設定」を書いてはいけないのか?
初学者が陥りやすい罠があります。それは、以下のようにコードの中に直接「列の幅」や「文字の色」を書き込んでしまうことです。
' ❌ アンチパターン:ハードコーディング
With myTable.Cell(1, 1).Range
.Font.Size = 12
.Font.Bold = True
.Text = "氏名"
End With
myTable.Columns(1).Width = CentimetersToPoints(4)
これの何が問題か分かりますか?
もし、明日クライアントから「列の幅をあと5mm広げてほしい」と言われたらどうでしょう? 君はプログラムのコードを書き換え、テストし、再度配布するという大仕事に追われることになります。
これを、「設定ファイル(JSON)を書き換えるだけで、プログラム本体には一切触れずに済む」状態に変える。これが、今回僕たちが目指すゴールです。
1. 設計図(JSON)を定義する
まずは、Wordの表がどうあるべきかを記述した「設計図」を作ります。JSONは、階層構造を持てるため、複雑なレイアウト定義に最適です。
config.json
{
"table_settings": {
"border_style": 1,
"auto_fit": false
},
"columns": [
{ "id": 1, "width_cm": 4, "header": "日付", "font_size": 10, "bold": true },
{ "id": 2, "width_cm": 6, "header": "項目名", "font_size": 11, "bold": true },
{ "id": 3, "width_cm": 5, "header": "備考", "font_size": 10, "bold": false }
]
}
このように、「何を表示するか」と「どう見せるか」を分離しておくのです。
2. 実装:動的生成エンジン
さて、ここからが本番です。VBAでJSONを扱うには、本来は外部ライブラリ(VBA-JSONなど)を使うのが定石ですが、今回は「概念を理解すること」に集中するため、「設定情報を格納したDictionaryオブジェクト」をシミュレートする形で、エンジンの核となるロジックを書いていきましょう。
※実務では `JsonConverter` ライブラリを導入して、このDictionary部分をJSONから自動生成するようにしてください。
Option Explicit
''' <summary>
''' 表の動的生成メインルーチン
''' </summary>
Sub GenerateDynamicTable()
Dim doc As Document
Set doc = ActiveDocument
' 1. 本来はここでJSONをパースしてDictionaryに格納する
' ここでは学習用に、JSONから読み込んだと仮定した設定データを作成
Dim config As Object
Set config = GetMockJsonConfig()
' 2. パフォーマンス向上のための定石:画面更新を停止
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
' 3. 表の作成(行数はデータ量に応じて決めるが、ここでは例として3行)
Dim rowCount As Integer: rowCount = 3
Dim colCount As Integer: colCount = config("columns").Count
Dim targetTable As Table
Set targetTable = doc.Tables.Add(Range:=doc.Range(doc.Content.End - 1), _
NumRows:=rowCount, _
NumColumns:=colCount)
' 4. 表の基本設定(枠線など)
With targetTable
.Borders.InsideLineStyle = wdLineStyleSingle
.Borders.OutsideLineStyle = wdLineStyleSingle
' 5. 列ごとの動的適用(ここがエンジンの心臓部)
Dim i As Integer
Dim colData As Object
For i = 1 To colCount
' JSON(Dictionary)から列の設定を取り出す
Set colData = config("columns")(i)
' --- 列幅の設定 ---
' CentimetersToPoints を使うことで、直感的な数値管理が可能に
.Columns(i).PreferredWidthType = wdPreferredWidthPoints
.Columns(i).PreferredWidth = Application.CentimetersToPoints(colData("width_cm"))
' --- ヘッダー行の設定 ---
With .Cell(1, i).Range
.Text = colData("header")
.Font.Size = colData("font_size")
.Font.Bold = colData("bold")
End With
Next i
End With
' 6. 後処理
Application.ScreenUpdating = True
MsgBox "表の生成が完了しました!", vbInformation
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub
''' <summary>
''' JSONの代わりとなる設定データを作る関数(モック)
''' </summary>
Private Function GetMockJsonConfig() As Object
' 本来は JSON Parser を使ってファイルを読み込む
' ここでは Dictionary を使って「JSONっぽさ」を再現
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim cols As Object
Set cols = CreateObject("Scripting.Dictionary")
' Column 1
Dim c1 As Object: Set c1 = CreateObject("Scripting.Dictionary")
c1("width_cm") = 4: c1("header") = "日付": c1("font_size") = 10: c1("bold") = True
cols.Add 1, c1
' Column 2
Dim c2 As Object: Set c2 = CreateObject("Scripting.Dictionary")
c2("width_cm") = 6: c2("header") = "項目名": c2("font_size") = 11: c2("bold") = True
cols.Add 2, c2
' Column 3
Dim c3 As Object: Set c3 = CreateObject("Scripting.Dictionary")
c3("width_cm") = 5: c3("header") = "備考": c3("font_size") = 10: c3("bold") = False
cols.Add 3, c3
dict.Add "columns", cols
Set GetMockJsonConfig = dict
End Function
3. ここがプロの視点:陥りやすい罠と回避策
このコードを書く際に、君が絶対に覚えておくべき「設計の重み」が3つあります。
① `Selection` を使うな、`Range` を使え
「マクロの記録」を見ると、必ず `Selection.Typecast…` のようなコードが出てきます。しかし、`Selection`(選択範囲)は、ユーザーが今どこをクリックしているかに依存する「不安定なオブジェクト」です。
プロは必ず `Table` や `Range` オブジェクトを直接操作します。これにより、「画面を動かさずに、裏側で高速に処理する」ことが可能になります。
② `Application.ScreenUpdating` の魔法
表の生成は、Wordにとって非常に負荷の高い作業です。列幅を変えるたびに、Wordは「画面をどう描き直すべきか」を計算します。
`Application.ScreenUpdating = False` を一行入れるだけで、描画の計算をスキップし、処理速度が劇的に向上します。これは「お作法」ではなく、「マナー」です。
③ オブジェクトのライフサイクル
大量のデータを流し込む際、`Cell(r, c).Range` をループの中で何度も呼び出すと、動作が極端に重くなります。
大規模な表を作るなら、一度 `Table` オブジェクトを変数に格納し、そのプロパティを介してアクセスする。この「オブジェクトへの最短距離」を意識することが、パフォーマンスエンジニアへの第一歩です。
まとめ:君はもう、一段上のステージにいる
今回の実装で君が手に入れたのは、単なる「表を作るマクロ」ではありません。
「設定を変えれば、どんなレイアウトにも即座に対応できる、柔軟なシステム」の設計図です。
1. ロジック(VBA):どうやって作るか(手順)
2. データ(JSON):何を作るか(内容・見た目)
この2つを切り離すことができた時、君の書くコードは「使い捨てのツール」から「資産としてのソフトウェア」へと進化します。
最初は難しく感じるかもしれません。でも、大丈夫。一つ一つのオブジェクトの動きを理解していけば、必ず制御できるようになります。
さあ、次は実際のJSONファイルを読み込むライブラリの導入に挑戦してみましょう。君の挑戦を、心から応援していますよ!
