こんにちは!Word VBAの世界へようこそ。
マクロの記録ボタンを押して「なんだかよく分からないけれど動いたぞ!」と感動したのも束の間、「いざ実務のデータを整えようとすると、途端に手が出なくなる……」そんな壁にぶつかっていませんか?
大丈夫、その壁の向こう側には、業務を劇的に効率化する素晴らしい自動化の世界が広がっています。
今回は、実務のデータ整理で本当によくある「一つのセルに複数のデータが改行入りで入っている状態」を美しく正規化(データ整形)するテクニックを授けましょう。
ここをクリアすれば、Word VBAのオブジェクト操作の基本と、泥臭いテキスト処理の本質がバッチリ見えてきますよ。一緒に優しく、深く、マスターしていきましょう!
—
1. 为什么我们需要「行の分割転記」なのか?(背景と課題)
例えば、以下のようなアンケート結果や顧客リストのWord表を見たことはありませんか?
| 担当者 | 保持している資格(問題のセル) |
| :— | :— |
| 山田 | 応用情報技術者
TOEIC 900点
AWS認定 |
| 佐藤 | 宅地建物取引士 |
「資格」のセルの中に、改行を挟んで複数のデータが押し込められています。このまだとExcelにエクスポートして集計することもできませんし、見た目も美しくありません。
これを次のように、データ一つにつき1行の表に分解(正規化)するのが今回のミッションです。
| 担当者 | 保持している資格(整形後) |
| :— | :— |
| 山田 | 応用情報技術者 |
| 山田 | TOEIC 900点 |
| 山田 | AWS認定 |
| 佐藤 | 宅地建物取引士 |
「なんだ、手動でコピペすればいいじゃないか」と思いました?
データが100件、1000件あったらどうでしょう? 手作業なら半日仕事ですが、Word VBAなら一瞬(0.5秒)です。
—
2. Word表の「改行」を読み解くキホン
Wordの表(`Table`オブジェクト)の中にあるセル(`Cell`オブジェクト)のテキストを扱うとき、初学者が最初にハマる罠があります。それが「改行コードの正体」です。
Excelのセル内改行は `vbLf` や `Chr(10)` ですが、Wordのセル内改行は `vbCr`(または段落記号 `vbCrLf` の `vbCr` 部分)であるケースが多いのです。さらに、セル自体の終わりには必ず「セルの終端文字(`Chr(7)`相当)」という目に見えない特殊文字が潜んでいます。
したがって、セル内の文字列から改行コードを見つけるには、次のようなアプローチをとります。
1. セル内の文字列を取得する (`Cell.Range.Text`)
2. 文字列の末尾にある不要なWord特有の制御文字を削る
3. 改行コード(`vbCr` など)で文字列を分割(`Split`関数)する
4. 分割された個数に合わせて、表の行を動的に増やす、あるいは新しい表を再構築する
—
3. 【実践】セル内改行を分解して再配置するVBAコード
百聞は一見にしかず。実務の現場でそのままコピペして動かせる、洗練されたコードをプレゼントします。
今回は安全かつ確実に処理するため、「元の表を読み取り、整形済みの新しい表をドキュメントの末尾に生成する」というアプローチを取りましょう。これが一番、実行時エラー(インデックスが範囲を超えています、など)を防げる安全な設計です。
Sub SplitCellDataAndRebuildTable()
Dim doc As Document
Set doc = ActiveDocument
‘ エラー対策と画面描画の抑制(パフォーマンス向上)
Application.ScreenUpdating = False
‘ 【前提】アクティブ文書の最初の表を対象とする
If doc.Tables.Count = 0 Then
MsgBox “ドキュメントに表が見つかりません。”, vbExclamation
Exit Sub
End If
Dim srcTable As Table
Set srcTable = doc.Tables(1)
‘ 新しい表を作成するための準備(行数は後から追加、列数は元と同じ2列と仮定)
Dim newTable As Table
Dim targetRange As Range
Set targetRange = doc.Content
targetRange.Collapse wdCollapseEnd
targetRange.InsertParagraphAfter ‘ 改行を入れてから表を作る
‘ ひとまずヘッダー行だけの表を作成
Set newTable = doc.Tables.Add(Range:=doc.Content.Paragraphs(doc.Content.Paragraphs.Count).Range, _
NumRows:=1, NumColumns:=srcTable.Columns.Count)
‘ ヘッダーのコピー(1行目)
Dim c As Long
For c = 1 To srcTable.Columns.Count
‘ WordのCell.Range.Textは末尾に特殊文字(Chr(13) + Chr(7))を含むためトリムする
newTable.Cell(1, c).Range.Text = CleanCellText(srcTable.Cell(1, c).Range.Text)
Next c
‘ 2行目以降(データ行)を走査して分解・転記
Dim r As Long
Dim cellText As String
Dim lines() As String
Dim i As Long
Dim newRow As Row
For r = 2 To srcTable.Rows.Count
‘ 例として「1列目:担当者」「2列目:資格(改行あり)」を想定
Dim col1Text As String
Dim col2Text As String
col1Text = CleanCellText(srcTable.Cell(r, 1).Range.Text)
col2Text = CleanCellText(srcTable.Cell(r, 2).Range.Text)
‘ 2列目のデータを改行コード(vbCr)で分割
‘ ※Wordのセル内改行は一般的に vbCr (Carriage Return) です
lines = Split(col2Text, vbCr)
‘ 分割された行数分だけ、新しい表にデータを流し込む
For i = LBound(lines) > To UBound(lines) ‘ 構文上の安全策
Next i
For i = 0 To UBound(lines)
‘ 空行でなければ処理する
If Trim(lines(i)) <> “” Then
Set newRow = newTable.Rows.Add
newRow.Cells(1).Range.Text = col1Text
newRow.Cells(2).Range.Text = Trim(lines(i))
End If
Next i
Next r
‘ 画面描画を復元
Application.ScreenUpdating = True
MsgBox “データの正規化が完了しました!”, vbInformation
End Sub
‘ ————————————————–
‘ 補助関数:Wordのセル特有のゴミ文字を除去する
‘ ————————————————–
Function CleanCellText(ByVal rawText As String) As String
‘ Wordのセルテキストは末尾に必ず [CR][CELL] (Chr(13) & Chr(7)) が含まれる
If Len(rawText) >= 2 Then
CleanCellText = Left(rawText, Len(rawText) – 2)
Else
CleanCellText = rawText
End If
‘ 前後の空白も念のため削除
CleanCellText = Trim(CleanCellText)
End Function
—
D4. 陥りやすいエラーと、シニアエンジニアからのアドバイス
このコードを動かすとき、あるいは自分でカスタマイズするときに、初心者が必ずと言っていいほどハマる罠があります。あらかじめ知っておきましょう。
1. 「文字化けしてる?」または「分割できない?」現象
- 原因: Wordのセル内改行は環境や入力方法によって、`vbCr`(Chr(13))ではなく、`vbLf`(Chr(10))や、あるいは通常の段落区切り(`vbCrLf`)になっていることがあります。
- 対策: もし `Split(col2Text, vbCr)` でうまく割れない場合は、一度 `Replace(col2Text, vbLf, vbCr)` のように改行コードを `vbCr` に統一してから `Split` かけるという防衛的プログラミングを行うと、極めて頑健(ロバスト)なマクロになります。
2. 実行時エラー 4605 「このメソッドまたはプロパティは、選択されている領域が表の中にないため使用できません。」
- 原因: セルを選択していない(あるいはカーソルが外にある)状態で `.Range` や `.Rows.Add` を叩いたときにおきます。
- 対策: 冒頭のコードのように、`Selection` オブジェクト(今画面でどこを選んでいるか)に頼らず、文書内の `Table` オブジェクトを直接操作するコードを書くのが、バグを生みにくいプロの流儀です。
—
5. おわりに
お疲れ様でした!
「Wordの表」と聞くと、なんだか自由度が低くて難しそうに見えますよね。しかし、今回のように「セルの終端文字の存在」を理解し、「Split関数でバラして新しい行(Row)として積み上げていく」というアルゴリズムを知ってしまえば、どんなに複雑な汚い表であっても、あなたの自由自在に調教できるようになります。
ここをクリアしたあなたなら、もう「マクロの記録」だけの初学者ではありません。立派なWord VBA使いへの第一歩を踏み出しています。
日々の面倒なコピペ作業はプログラムに押し付けて、あなた更有意義でクリエイティブな仕事に時間を使いましょう。それでは、また次の冒険でお会いしましょう!
