【実務・中級編】【中級者向け】表内のテキストを読み取り、特定のキーワードでグループ分けして別表へ転記する – Word VBA解析バイブル

スポンサーリンク

Word VBAを「兵器」に変える:表データの動的グループ化と再構成の極意

Word VBAで「表を操作する」こと。それは単なるレイアウト調整ではありません。メモリ空間上の巨大なオブジェクトツリーを制御する、繊細な外科手術です。

多くの開発者が陥る罠は、`Selection`オブジェクトを多用して画面をチラつかせ、処理を低速化させる「素人コード」です。本稿では、プロフェッショナルが現場で採用する、「非破壊・高速・保守的」な表データ再構築の手法を伝授します。

—

1. なぜ「力技のコピー」が地獄を生むのか

表からデータを抜き出して別表を作る際、`Selection.Copy` や `Selection.Paste` を繰り返していませんか?

  • クリップボード依存の脆さ: クリップボードはOSと共有する共有資源です。他のアプリが割り込めば即座にエラーとなります。
  • オブジェクトのライフサイクル: `Selection`はカーソル位置に依存するため、ドキュメントの構造が複雑になると意図しない位置でペーストが走ります。

我々が目指すべきは、「Rangeオブジェクト」を用いたメモリ上での完全制御です。画面を描画させず、背後で静かにデータを再構成する。これがバグを生まない唯一の正解です。

—

2. 堅牢な設計:データ抽出と再構築のアーキテクチャ

今回のテーマである「キーワードによるグループ分け」を実現するため、以下の3ステップで設計します。

1. データ構造の抽象化: `Dictionary`オブジェクトを使用し、カテゴリをキー、抽出データを値のリストとして保持する。
2. Rangeを用いた解析: `Table.Cell(r, c).Range.Text` を読み取り、Word特有の「セル末尾の特殊文字(Chr(13) & Chr(7))」をクリーニングする。
3. 動的表生成: `Documents.Add` または既存文書の末尾に `Tables.Add` を呼び出し、メモリ上でデータを流し込む。

—

3. プロダクションコード:グループ化転記の実装

このコードは、既存の表(1列目にカテゴリ、2列目に内容がある想定)から、特定のカテゴリを抽出して新しい表を作成する実用的なテンプレートです。

Option Explicit

‘ プロジェクトで推奨される「Early Binding(事前バインディング)」を使用
‘ 参照設定: Microsoft Scripting Runtime を有効にすること
Sub GroupingTableData()
Dim doc As Document
Dim srcTable As Table
Dim targetDoc As Document
Dim dict As New Scripting.Dictionary
Dim r As Long, c As Long
Dim category As String, content As String
Dim key As Variant

Set doc = ActiveDocument
Set srcTable = doc.Tables(1)

‘ 1. データ解析:Dictionaryにグループ化して格納
For r = 1 To srcTable.Rows.Count
‘ Wordのセル末尾文字(Chr(13)+Chr(7))を削除
category = Left(srcTable.Cell(r, 1).Range.Text, Len(srcTable.Cell(r, 1).Range.Text) – 2)
content = Left(srcTable.Cell(r, 2).Range.Text, Len(srcTable.Cell(r, 2).Range.Text) – 2)

If Not dict.Exists(category) Then
dict.Add category, New Collection
End If
dict(category).Add content
Next r

‘ 2. 新規ドキュメントへ再構築
Set targetDoc = Documents.Add

For Each key In dict.Keys
targetDoc.Range.InsertAfter “■カテゴリ: ” & key & vbCrLf

‘ 表の生成
Dim newTable As Table
Set newTable = targetDoc.Tables.Add(targetDoc.Range.Characters.Last, dict(key).Count, 1)
newTable.Borders.Enable = True

‘ データ流し込み
Dim i As Long
For i = 1 To dict(key).Count
newTable.Cell(i, 1).Range.Text = dict(key)(i)
Next i

targetDoc.Range.InsertAfter vbCrLf
Next key

MsgBox “データの振り分けが完了しました。”, vbInformation
End Sub

—

4. 現場で生き残るための「鉄則」

文字列のクリーニングを甘く見るな

Wordのセル内文字列は、必ず最後に `vbCr & Chr(7)` が付与されます。これを削除せずに比較演算を行うと、キーワード一致判定で一生バグり続けます。`Left(…, Len(…) – 2)` は、この世界の常識として刻み込んでください。

大規模データへの対応

もしデータ数が数千行を超える場合、`ScreenUpdating = False` を必ず設定してください。描画処理を止めるだけで、速度は10倍変わります。

エラーハンドリングの重要性

本番環境では、表が存在しない場合や、結合セルが存在する場合の `On Error Goto` によるトラップが必須です。特に結合セルは `Cell(r, c)` のインデックスがずれるため、ループの設計には細心の注意を払ってください。

—

結論:自動化は「設計」で決まる

今回紹介した「`Dictionary`によるグループ化」と「`Range`による動的生成」の組み合わせは、業務自動化において最も応用範囲の広いパターンです。

「コピペで動く」から一歩進んで、「なぜ動くのか」を理解したとき、あなたのコードは現場を救う強力な武器になります。次は、これをExcelからデータを取得するパターンへ発展させてみてください。アーキテクチャの本質は、WordであれExcelであれ変わりません。

さあ、退屈な手作業から自分を解放しましょう。

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