こんにちは!現場でWordの帳票や請求書、報告書と日々格闘しているみなさん、業務自動化の進捗はいかがでしょうか?
「見積書や検収書をWordで作っているけれど、金額の合計だけは電卓を叩いて手入力している……」
「Excelなら `=SUM()` で一瞬なのに、Wordの表(Table)になった途端、マクロの記録すら役に立たなくて絶望した……」
そんな経験はありませんか?
Wordは本来「ワープロソフト」ですから、Excelのような強力な表計算グリッドを標準で意識して作られてはいません。ですが、Word VBAの仕組み(オブジェクトモデル)をほんの少し正しく理解してあげるだけで、Wordの表は思いのままに操れる電卓へと進化します。
今回は、プログラミング初学者や「マクロの記録」から卒業したい方に向けて、「Wordの表の特定列の数値を自動集計し、一番下に合計行をサクッと追加するVBA」をステップ・バイ・ステップで解説します。
ここをクリアすれば、Word VBAのデータ処理の基本はバッチリですよ!一緒にマスターしていきましょう。
—
1. なぜWordの表計算マクロは「記録」で作れないのか?
Excel VBAを触ったことがある方ほど、Word VBAの表操作で最初に強烈な違和感を覚えます。
その最大の原因は、Wordのセルの中に隠れている「見えない文字(終端文字)」の存在です。
Wordのセルは「2文字のゴミ」を抱えている
Wordの表の各セルには、人間の目には見えない制御文字(`Chr(13)`:復帰コード + `Chr(7)`:ベルコード)が必ず末尾に2文字付着しています。
【画面上の見え方】
┌──────────┐
│ 1000 │
└──────────┘
【Word内部のデータ】
┌────────────────────────┐
│ “1000” + [Chr(13)][Chr(7)] │ ← この2文字があるせいで、
└────────────────────────┘ 数値として足し算できない!
もし、セルのテキストをそのまま `Total = Total + Cell.Range.Text` と足そうとすると、VBAは「`1000` に変な文字がくっついているから文字型(String)だな」と判断し、「型が一致しません(エラー 13)」を吐いて止まってしまうのです。
この「セル末尾のお掃除」の作法を覚えることこそが、Word VBAを掌握する第一歩です。
—
2. これが完成形!コピペで動く「合計行自動追加マクロ」
まずは、理屈の前に動くコードを見てみましょう。
カーソルが置かれている表(あるいは文書内の1つ目の表)を対象に、「指定した列(例: 3列目)」の数値を合計して、一番下に「合計」行を追加する実践的なコードです。
WordのVBE(Alt + F11)を開き、標準モジュールに以下のコードを貼り付けてみてください。
Sub AddTotalRowToTable()
‘————————————————————————–
‘ 機能: 選択中の表(または文書の第1テーブル)の特定列を集計し、合計行を追加する
‘————————————————————————–
Dim targetTable As Table
Dim targetColIndex As Long
Dim startRowIndex As Long
Dim lastRowIndex As Long
Dim currentRowIndex As Long
Dim rawText As String
Dim cleanText As String
Dim cellValue As Double
Dim totalSum As Double
‘ ▼ 設定エリア(集計したい列と、集計開始行を指定)
targetColIndex = 3 ‘ 例: 3列目(金額列など)を集計
startRowIndex = 2 ‘ 例: 1行目はヘッダーなので2行目から集計開始
‘ 1. 操作対象の表を安全に取得する
If Selection.Information(wdWithInTable) Then
‘ カーソルが表の中にあれば、その表を対象にする
Set targetTable = Selection.Tables(1)
ElseIf ActiveDocument.Tables.Count > 0 Then
‘ カーソルが表の外なら、文書内の「最初の表」を対象にする
Set targetTable = ActiveDocument.Tables(1)
Else
MsgBox “文書内に表が見つかりません。”, vbExclamation, “エラー”
Exit Sub
End If
‘ 2. 画面のチラつきを抑え、処理速度を向上させる
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
‘ 現在の最終行番号を取得
lastRowIndex = targetTable.Rows.Count
‘ 3. 行を1行ずつループして数値を合算する
totalSum = 0
For currentRowIndex = startRowIndex To lastRowIndex
‘ セルの文字列を取得
rawText = targetTable.Cell(currentRowIndex, targetColIndex).Range.Text
‘ —【超重要】セル末尾の制御文字(Chr(13) & Chr(7))を綺麗に除去する —
cleanText = Replace(rawText, Chr(13), “”)
cleanText = Replace(cleanText, Chr(7), “”)
cleanText = Trim(cleanText) ‘ 前後の空白も除去
‘ カンマ(,)や「¥」が含まれていても計算できるように除去
cleanText = Replace(cleanText, “,”, “”)
cleanText = Replace(cleanText, “¥”, “”)
cleanText = Replace(cleanText, “\”, “”)
‘ 数値に変換できる場合のみ足し算する(空行やテキスト行でのエラーを防止)
If IsNumeric(cleanText) Then
totalSum = totalSum + CDbl(cleanText)
End If
Next currentRowIndex
‘ 4. 表の末尾に新しい「合計行」を追加する
Dim newRow As Row
Set newRow = targetTable.Rows.Add
‘ 5. 追加した行に文字と数値を流し込む
‘ (ここでは1列目に「合計」、対象列に計算結果を書き込みます)
newRow.Cells(1).Range.Text = “合計”
newRow.Cells(targetColIndex).Range.Text = Format(totalSum, “#,
0″)
‘ 合計行の文字を太字にする(プロっぽい仕上げ)
newRow.Range.Bold = True
‘ 6. 後片付けと完了通知
Application.ScreenUpdating = True
MsgBox “合計行の追加が完了しました!” & vbCrLf & _
“集計結果: ” & Format(totalSum, “#,
0″), vbInformation, “完了”
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox “処理中にエラーが発生しました: ” & Err.Description, vbCritical, “システムエラー”
End Sub
—
3. プロの目線で紐解く!重要ポイントの深掘り解説
コードを動かしてみて「動いた!」と喜ぶのも束の間、先輩エンジニアとしては「なぜその書き方をしているのか」の本質をぜひ持って帰ってほしいと思います。
ポイント①:セル文字の「毒抜き」テクニック
cleanText = Replace(rawText, Chr(13), “”)
cleanText = Replace(cleanText, Chr(7), “”)
Wordのセルから `.Range.Text` で文字を取り出すと、末尾に必ず `Chr(13) & Chr(7)` が入っています。
古典的なコードでは `Left(rawText, Len(rawText) – 2)` と書かれることも多いですが、現場では`Replace` 関数で明示的に取り除く手法をおすすめします。もしもセル内改行が存在した場合や特殊な書式でも、`Replace` のほうが予期せぬ文字削れバグを起こしにくいからです。
あわせて `Replace(cleanText, “,”, “”)` などで「カンマ」や「通貨記号」も取り除いておくことで、`1,000` や `¥1,000` と表記されていても安全に数値判定させることができます。
ポイント②:`IsNumeric` と `CDbl` による防御
If IsNumeric(cleanText) Then
totalSum = totalSum + CDbl(cleanText)
End If
実務の帳票では、数値列の中に「-(ハイフン)」や「未定」「対象外」といったテキストが混ざることが日常茶飯事です。
`IsNumeric` で「本当に数値化できるか?」をチェックしてから `CDbl`(倍精度浮動小数点数へのキャスト)を行う。この一手間を挟むだけで、実務で絶対に落ちない堅牢なマクロになります。
ポイント③:`Rows.Add` のスマートさ
Dim newRow As Row
Set newRow = targetTable.Rows.Add
Word VBAの `Table.Rows.Add` メソッドは、引数を省略すると「表の最下部」に自動的に新しい行を追加し、その追加された行オブジェクトを戻り値として返してくれます。
わざわざ「今何行目だから、次の行番号は……」と計算する必要はありません。返ってきた `newRow` に対して直接データを書き込めばいいのです。
—
4. 初心者が陥りがちな「3大トラップ」と処方箋
最後に、今後あなたが自分でカスタマイズするときに必ず遭遇する「Wordの罠」をお伝えしておきます。
トラップ1:セルの結合(Merge)があると死ぬ
Wordの表で行や列を複雑に結合している場合、`targetTable.Cell(r, c)` を参照しようとすると「指定されたコレクションのメンバーは存在しません(エラー 5941)」が発生します。
- 処方箋: 集計対象とする表は、原則として「縦横が整ったグリッド」である必要があります。帳票を作る際は、タイトル部分だけ結合し、データ明細部分は結合を避けるのがWord設計の鉄則です。
トラップ2:二重集計の罠
このマクロを同じ表に対して2回実行するとどうなるでしょうか?
前回追加した「合計行」の数値まで巻き込んで、再び合計行が作られてしまいます。
- 処方箋: 実務で運用する場合は、実行前に「最終行の1列目に『合計』という文字が入っていたら処理を中断(または前回の合計行を削除)する」というチェック処理を入れると、よりプロフェッショナルなツールになります。
トラップ3:画面のチラつきで処理が遅くなる
行数が50行、100行と増えてくると、Wordが画面を描画しようとして激しく点滅し、動作が重くなります。
- 処方箋: コード内に入れている `Application.ScreenUpdating = False` は必須です。処理が終わるまでWordの画面再描画を止めることで、体感速度が数倍から数十倍跳ね上がります。
—
まとめ:Wordの構造が分かれば、業務効率化の幅は一気に広がる!
今回のステップをおさらいしましょう。
1. 対象の表とセルを特定する(Selection または Tablesコレクション)
2. `Replace` でセルの見えない文字(Chr(13), Chr(7))をしっかり掃除する
3. `IsNumeric` で数値判定して安全に合算する
4. `Rows.Add` で最終行をスマートに追加して書き込む
この一連の流れさえ押さえておけば、Word VBAの基本構造は完全に理解できたも同然です!
次は「合計だけでなく平均値も出す」「数値のフォーマットを自社の規定に合わせる」「集計が終わったら行の背景色をグレーにする」など、少しずつ自分仕様にコードを拡張してみてくださいね。
あなたのWord業務が、ボタンひとつで快適になる日を応援しています!
