【実務・中級編】【中級者向け】Word表の全セルを走査し、空欄のセルに「-」を自動入力するクリーンアップ – Word VBA解析バイブル

スポンサーリンク

【Word VBA】実務で恥をかかない!表の全セルを走査し「空欄」を「-」で埋め尽くすクリーンアップ自動化

開発現場の最終フェーズで、最も見落とされがちなのが「納品ドキュメントの細部」だ。
幾度となくレビューを重ねたはずの仕様書や報告書。いざクライアントに提出して手元に戻ってきたとき、そこにはぽっかりと口を開けた「空欄のセル」が……。

「あとで埋めておきます」と言いつつ忘れたデータ。
「該当なし」と書くべきか、空白のままにするべきか判断に迷って放置されたセル。

こうした未入力セルの放置は、単なる「書き忘れ」にとどまらず、「ドキュメント品質の管理が行き届いていない」という致命的な印象を読み手に与えかねない。

今回は、Word文書内に散らばるすべての表(Table)を高速かつ安全に走査し、空欄セルを自動的に「-(ハイフン)」で埋め尽くす、実務直結のクリーンアップマクロを伝授しよう。

—

1. なぜ「愚直なセル走査」は実務で破綻するのか?

Word VBA初学者や、Excel VBAのノウハウを引きずったエンジニアが陥りがちないちばんの罠。それは、`For Each` を使って無思考にセルを舐め回すコードだ。

‘ 【反面教師:絶対に書いてはいけないアンチパターン】
Dim c As Cell
For Each c In ActiveDocument.Tables(1).Range.Cells
If c.Range.Text = vbCr Then ‘ 空白判定のつもり
c.Range.Text = “-”
End If
Next c

このコードは、実務のドキュメント(特に複雑なレイアウトの仕様書)では確実にバグを引き起こすか、あるいはフリーズする。理由は以下の3点だ。

1. Wordのセル終端文字(End of Cell Mark)の罠
Wordのセル内テキストは、常に特殊な制御文字(`vbCr` と 7バイト目のセルのマーカー)を含んでいる。単に `c.Range.Text = “”` と比較しても、空欄判定が正しく機能しない。
2. 結合セル(Merged Cells)の爆弾
行方向や列方向にセルが結合されている表に対して `Range.Cells` を回すと、結合された親セル・子セルが重複して取得され、予期せぬインデックスエラーや無限ループを引き起こす。
3. 画面描画(ScreenUpdating)のコスト
数千行に及ぶ巨大な仕様書の場合、セルを1つ書き換えるたびにWordが画面を再描画するため、完了までに絶望的な時間がかかる。

我々プロのエンジニアが書くべきコードは、これらすべてのハードルをクリアした「堅牢で、かつ電光石石のスピードを誇る」ものでなければならない。

—

2. 堅牢なクリーンアップエンジンの設計思想

今回のプロダクションコードでは、以下の設計思想を貫く。

  • 完全なる描画停止(Optimization)

`ScreenUpdating` と `DisplayAlerts` を完全にロックし、CPUパワーを文字列処理だけに集中させる。

  • 厳密な空白判定(Trim & Clean)

Word特有の末尾制御文字(`Chr(13)` や `Chr(7)`)を除去した上で、純粋な文字数が `0` であるものだけを「真の空欄」とみなす。

  • 結合セルの安全なバイパス

結合セルの構成単位で発生する重複書き込みやエラーを防ぐロジックを組み込む。

—

3. 【コピペ即実戦投入】全表クリーンアップ・プロダクションコード

以下のコードをWordのVBAエディタ(`Alt + F11` -> ` 標準モジュール`)に貼り付けて実行してほしい。ドキュメント内のすべての表が、一瞬で美しくクリーンアップされる。

Option Explicit

‘ ==============================================================================
‘ 処理名 : CleanUpEmptyCellsInTables
‘ 概要 : アクティブドキュメント内の全テーブルを走査し、完全な空欄セルに
‘ 指定したプレースホルダー(デフォルト: “-“)を自動入力する。
‘ 著者 : Enterprise Automation Architect
‘ ==============================================================================
Public Sub CleanUpEmptyCellsInTables()
Dim targetDoc As Document
Set targetDoc = ActiveDocument

‘ 表が存在しない場合は早期リターン
If targetDoc.Tables.Count = 0 Then
MsgBox “文書内にテーブルが見つかりませんでした。”, vbInformation, “処理終了”
Exit Sub
End If

‘ — 1. 実行前最適化(パフォーマンスの極限追求) —
With Application
.ScreenUpdating = False
.Calculation = wdCalculationManual
.DisplayAlerts = wdAlertsNone
End With

Dim startTime As Double
startTime = Timer

Dim tbl As Table
Dim cel As Cell
Dim rawText As String
dataCleanedCount As Long
dataCleanedCount = 0

On Error GoTo ErrorHandler

‘ — 2. テーブルおよびセルの二重ループ走査 —
For Each tbl In targetDoc.Tables

‘ 自動的にサイズ調整される設定を一時解除(レイアウト崩れ防止)
tbl.AllowAutoFit = False

For Each cel In tbl.Range.Cells

‘ 【重要】結合セルの重複インデックスによるエラーを回避
‘ 結合されている場合、Row/Columnの厳密な判定が必要になるが、
‘ 単純な空白チェックであればRangeの長さを利用して安全に判定する。

‘ Wordのセル内テキストは必ず末尾に (Chr(13) + Chr(7)) が含まれる。
‘ これを取り除いた実質的な長さを取得する。
rawText = cel.Range.Text
rawText = Left(rawText, Len(rawText) – 2) ‘ 末尾の制御文字2文字をカット
rawText = Trim$(rawText) ‘ 前後の空白スペースも除去

‘ 完全な空欄である場合のみ「-」を流し込む
If Len(rawText) = 0 Then
‘ セル全体のRangeに代入するとセル構造自体が破壊されるため、
‘ セル内の段落テキスト、あるいはRangeの末尾2文字手前までを置換する
‘ 最も安全なアプローチ:セル内の文字部分のみを書き換える

‘ セル内の書式を維持するため、テキスト部分のみ指定
Dim rngText As Range
Set rngText = cel.Range
‘ 末尾の制御文字 (Chr(13) + Chr(7)) を除いた範囲を指定
rngText.End = rngText.End – 2

rngText.Text = “-”
dataCleanedCount = dataCleanedCount + 1
End If

Next cel
Next tbl

‘ — 3. 実行後処理・復元 —
GoTo Finally

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”

Finally:
‘ 環境を元に戻す
With Application
.ScreenUpdating = True
.Calculation = wdCalculationAutomatic
.DisplayAlerts = wdAlertsAll
End With

‘ 処理結果のレポート
Dim elapsedTime As Double
elapsedTime = Timer – startTime

MsgBox “クリーンアップが完了しました。” & vbCrLf & _
“処理対象テーブル数: ” & targetDoc.Tables.Count & vbCrLf & _
“空欄を埋めたセル数: ” & dataCleanedCount & ” 箇所” & vbCrLf & _
“処理時間: ” & Format(elapsedTime, “0.00”) & ” 秒”, _
vbInformation, “完了”

End Sub

—

4. コードの急所:なぜこの書き方が「最強」なのか?

① Word特有の「終端文字(Chr(13) + Chr(7))」の完全無力化

Excelのセルと違い、Wordのセルは内部に必ず改行コードとセルマーカーを含んでいる。
`c.Range.Text = “”` という判定が機能しないのはこれが原因だ。本コードでは、`Len(rawText) – 2` によって制御文字を物理的に切り落とし、「純粋なユーザー入力文字がゼロか否か」を厳密に判定している。

② セル構造(レイアウト)を破壊しない代入ロジック

単に `cel.Range.Text = “-“` と書いてしまうと、そのセル自体が崩壊し、最悪の場合は表全体の構造が歪む。
本コードでは `rngText.End = rngText.End – 2` とすることで、「セル自体の枠組み(グリッド)は保持したまま、内部のテキスト領域のみを安全に書き換える」という、Word VBAにおける神髄とも言えるテクニックを用いている。

③ 圧倒的なパフォーマンス

`ScreenUpdating = False` と `Calculation = wdCalculationManual` のコンボにより、数十ページある分厚い社内規定や巨大なデータシートであっても、数秒足らずで処理が完結する。実務において「待たされない自動化」は正義だ。

—

5. 現場でさらに応用するための発展形

このコードをベースに、実務では以下のようなカスタマイズを行うと、さらに自動化の価値が跳ね上がる。

  • 特定条件の列だけを対象にする

`If cel.ColumnIndex = 3 Then` のように条件を挟むことで、「備考欄だけ空欄なら『-』を入れるが、数値列は空白のままにする」といった制御が可能になる。

  • 背景色やフォントの変更を同時に行う

「自動補完したセルが一目でわかるように、文字色を灰色(薄いグレー)にする」といった演出を加えると、ドキュメントの品質レビュー時に「どこが自動で埋められたか」を視覚的に追跡できるようになり、監査性が飛躍的に向上する。

‘ 応用例:自動補完したセルの文字色をグレーにする場合
rngText.Text = “-”
rngText.Font.Color = wdColorGray50

まとめ

業務自動化の本質は、単なる「手作業の肩代わり」ではなく、「ヒューマンエラーの根絶と品質の均一化」にある。
今回紹介したクリーンアップマクロを最終チェックのフローに組み込むだけで、「未入力による差し戻し」や「クライアントからの指摘」という不毛な手戻りをゼロにすることができる。

プロフェッショナルなエンジニアとして、細部にまで魂の宿ったクリーンなドキュメント作成基盤を、あなたの現場にも構築してほしい。

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