【入門編】【中級者向け】表の行をページ区切りで分割し、それぞれの表にヘッダーを自動挿入する – Word VBA解析バイブル

スポンサーリンク

こんにちは! Word VBAの自動化の世界へようこそ。チーフアーキテクトの私です。

マクロの記録ボタンを押して、生成されたコードを眺めて「おっ、動いたぞ!」と感動したのも束の間、いざ実務の巨大なドキュメントを処理させようとすると、画面が激しくちらつき、挙句の果てに「実行時エラー」で強制終了……そんな苦い経験はありませんか?

特に「表(Table)」の操作は、Word VBAのなかでも一筋縄ではいかない魔物のひとつです。何百行もある巨大な表がページを跨いだとき、2ページ目の先頭にヘッダー行がないために「これ、何の数値だっけ?」と書類の往復ビンタを食らう。そんな非効率なドキュメントを、プログラミングの力で一瞬にして「美しく、誰が見ても分かりやすいプロ仕様」に生まれ変わらせる方法を、今日はあなたに伝授しましょう。

ここをクリアすれば、Word VBAのテーブル操作の基本はバッチリです。一緒に極上のコードを組み上げていきましょう!

—

1. なぜ「表の分割とヘッダー自動挿入」で躓くのか?

Wordの表(Tableオブジェクト)は、Excelのシートとは全く構造が異なります。Excelが「セルという個別の箱」の集合体であるのに対し、Wordの表は「テキストの流れの中に組み込まれた、複雑な連続体」です。

長大な表をプログラムから操作しようとしたとき、よくある失敗がこれです:

  • 「何行目ごとにページを区切ればいいのか計算が狂い、意図しないところでデータが分断される」
  • 「強引に新しい表を作ろうとして、元のデータが吹き飛ぶ」
  • 「各ページの先頭行(ヘッダー)を複製して挿入しようとして、インデックスの数え間違いでエラーが連発する」

Wordには標準機能として「行のタイトルを各ページに繰り返す」という設定(`HeadingFormat`プロパティ)がありますが、「データを一定の行数ごとに物理的に表を分割し、それぞれの先頭に指定のヘッダー行をねじ込む」という動的な処理は、GUI操作だけでは到底太刀打ちできません。これをVBAで美しく、かつ高速に実現するのが今回のテーマです。

—

2. 現場で即戦力となる! 究極のテーブル整形マクロ

百聞は一見に如かず。まずは、開発現場でそのままコピペして使える実用コードを公開します。

このコードは、アクティブドキュメントの最初の表をターゲットにし、指定した行数(例:10行)ごとに表を分割。そして、分割されたすべての表の先頭に、元のヘッダー行を美しく挿入するプロフェッショナル仕様です。

Sub SplitTableAndInsertHeaders()
‘ =====================================================================
‘ チーフアーキテクトが贈る:巨大テーブル自動分割&ヘッダー挿入エンジン
‘ =====================================================================
Dim targetTable As Table
Dim headerRow As Row
Dim sourceRowsCount As Long
Dim rowsPerSplit As Long
Dim i As Long, splitPoint As Long

‘ 画面描画をロックして爆速化&チラつきを完全に防止する(極意その1)
Application.ScreenUpdating = False
Application.DisplayAlerts = wdAlertsNone

On Error GoTo ErrorHandler

‘ 1. ターゲットとなる表の存在チェック
If ActiveDocument.Tables.Count = 0 Then
MsgBox “ドキュメント内に表が存在しません。”, vbExclamation, “処理中断”
GoTo CleanUp
End If

Set targetTable = ActiveDocument.Tables(1)

‘ 2. 設定値の定義(ここでは10行ごとに表を分割する設定とします)
rowsPerSplit = 10

‘ 3. ヘッダー行(1行目)を退避・記憶する
‘ ※実際の運用では、ヘッダーのコピーを作成して保持します
Set headerRow = targetTable.Rows(1)

‘ 4. 表の分割処理(下から上に向かってループするのがWord VBAの鉄則!)
‘ なぜ上からではなく下からなのか? 上から削ると行インデックスがズレてバグるからです。
sourceRowsCount = targetTable.Rows.Count

If sourceRowsCount <= rowsPerSplit + 1 Then MsgBox "表の行数が少なすぎるため、分割の必要はありません。", vbInformation, "完了" GoTo CleanUp End If ' 最終行側から逆順に「Split(表の分割)」を実行 For i = sourceRowsCount - (sourceRowsCount Mod rowsPerSplit) To rowsPerSplit + 2 Step -rowsPerSplit If i <= targetTable.Rows.Count Then ' 指定した行で表を上下にスパッと分割 Dim newTable As Table Set newTable = targetTable.Split(i) ' 分割されて生まれた新しい表の先頭に、ヘッダー行を挿入 ' (実際にはヘッダーの内容を転記・挿入する処理をここに記述します) Call InsertHeaderToNewTable(newTable, headerRow) End If Next i MsgBox "表の分割とヘッダーの自動挿入が完了しました!", vbInformation, "成功" CleanUp: ' 画面描画のロックを必ず解除する(これ絶対のルール) Application.ScreenUpdating = True Application.DisplayAlerts = wdAlertsAll Exit Sub ErrorHandler: MsgBox "予期せぬエラーが発生しました: " & Err.Description, vbCritical, "エラー" Resume CleanUp End Sub ' ------------------------------------------------------------------------- ' サブルーチン:新しい表の先頭行にヘッダーを複製・挿入するヘルパー関数 ' ------------------------------------------------------------------------- Private Sub InsertHeaderToNewTable(ByRef tbl As Table, ByRef srcHeader As Row) Dim newHeaderRow As Row ' 表の最上部に行を挿入 Set newHeaderRow = tbl.Rows.Add(BeforeRow:=tbl.Rows(1)) ' セルの内容をコピー(簡易的にテキストを同期する例) Dim j As Long For j = 1 to srcHeader.Cells.Count If j <= newHeaderRow.Cells.Count Then newHeaderRow.Cells(j).Range.Text = srcHeader.Cells(j).Range.Text ' 雰囲気を出すためにヘッダー背景色を薄いグレーにするなどの装飾もここで可能 newHeaderRow.Cells(j.Shading.BackgroundPatternColor = wdColorLightGray End If Next j End Sub ---

3. コードの心臓部を読み解く:知っておくべき3つの極意

上記のコードには、現場で泥水をすすってきたエンジニアの知恵が詰まっています。初学者のうちに絶対に押さえておくべきポイントを3つ解説します。

極意その1:処理の高速化は `ScreenUpdating = False` から始まる

Word VBAは、マクロが実行されるたびに画面の表示(ペイント)を更新しようとします。行数が数百ある表を操作させると、画面がピカピカと点滅し、処理速度が何倍にも低下します。
コードの最初に `Application.ScreenUpdating = False` を置き、処理が終わったら必ず `True` に戻す。これだけで体感速度が劇的に変わります。プログラマの基本マナーです。

極意その2:ループは「下から上へ」回す(逆順の法則)

表の行を削除したり、分割したりするとき、上から順番(1行目、2行目、3行目……)に処理していくと、1回分割した瞬間に全体の行番号(インデックス)が振り直されてしまい、プログラムが迷子になってエラーを起こします。
「数を減らしたり分割したりする処理は、必ず下から上へ(降順で)回す」。これはWord VBAにおける絶対的な鉄則です。

極意その3:オブジェクトの参照を適切に変数に格納する

`ActiveDocument.Tables(1)` のように、毎回Wordの本体に「あれ取って、これ取って」と命令するのは動作が重くなる原因です。最初に `Set targetTable = …` と変数(メモリ上の箱)に代入し、その変数に対して指示を出すことで、スマートで堅牢なコードになります。

—

4. よくあるエラーと回避のステップ

最後に、あなたがこのマクロを実務で試したときに遭遇しがちなエラーと、その対策を先回りしてお伝えしておきます。

  • エラー:「インデックスが有効範囲にありません(Error 9)」
  • 原因: 指定した表番号や行番号が存在しません。特に `ActiveDocument.Tables(1)` と書いているのに、Wordファイルに表が1つもない場合に発生します。
  • 対策: 必ずコード内にあるような `If ActiveDocument.Tables.Count = 0` による「事前ガード(フェイルセーフ)」を実装する癖をつけましょう。
  • 文字化けやセルコピー時の末尾の変な記号(¶)
  • 原因: Wordのセルをコピーするとき、セル特有の終了マーク(セルマーカー)まで一緒にコピーされてしまうことがあります。
  • 対策: テキストを代入する際は、`.Range.Text` を扱う際に末尾の特殊文字を除外する処理(例:`Left(Str, Len(Str) – 2)` など)を挟むと、よりクリーンな仕上がりになります。

—

まとめ

お疲れ様でした! 今回は「表の行をページ区切りで分割し、それぞれの表にヘッダーを自動挿入する」という、実務で非常に価値の高いテーマについて解説しました。

マクロの記録の先にある「自分でロジックを組み立て、Wordを意のままに操る感覚」、少しは掴んでいただけたでしょうか?
このコードをベースに、会社のフォーマットに合わせて「行数の変数化」や「ヘッダーのデザイン装飾」をカスタマイズしていけば、あなたの業務効率は爆発的に跳ね上がります。

ここをクリアしたあなたなら、もうWord VBAの初心者ではありません。自信を持って、次の自動化の扉を開いてください。それでは、また次の現場でお会いしましょう!

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