【入門編】【中級者向け】Word表のデータをXML形式でエクスポートし、システム連携の準備をする – Word VBA解析バイブル

スポンサーリンク
スポンサーリンク

脱・マクロ記録!Word表データを「構造化データ(XML)」へ昇華させる極限の設計術

こんにちは。現場の設計から実装、そしてシステムのアーキテクチャまでを統括しているエンジニアです。

「マクロの記録」を使って、表の文字をコピーしたり、セルに値を書き込んだりする。そこまでは、誰もが通る素晴らしい第一歩です。しかし、あなたがもし「このWordのデータを、Excelや社内システム、あるいはWebアプリにスマートに渡したい」と考えたなら、今のやり方では限界が来ます。

なぜなら、Wordの表は「人間が見るためのレイアウト」であり、「コンピュータが処理するためのデータ」ではないからです。

今回は、Word VBAを単なる「操作の自動化」から、「データの橋渡し(データ・インテグレーション)」へと昇華させるためのステップ、すなわち「Word表のXMLエクスポート」について解説します。ここをマスターすれば、あなたの作るツールは一気に「システムの一部」として価値を高めます。

1. なぜ「XML」なのか? ―― レイアウトとデータの分離

多くの初中級者が陥る罠は、「Wordの見た目」をそのままデータとして扱おうとすることです。

例えば、セルの中に改行があったり、セルが結合されていたりすると、単純なコピー&ペーストではデータの構造が崩れてしまいます。そこで登場するのがXML(Extensible Markup Language)です。

XMLを使う最大のメリットは、「データに意味(タグ)を持たせられること」です。

  • Wordの表: 「2行目の3列目のセル」という位置でデータを特定する。
  • XML: `1500` という意味でデータを特定する。

この「意味」を持たせることで、受け側のシステムは「何行目にあるか」を気にせず、確実に目的のデータを抽出できるようになります。

2. 実装の設計図:オブジェクトのライフサイクルを意識する

コードを書く前に、脳内で「データの流れ」を設計しましょう。プロのエンジニアは、いきなりコードを書き始めません。

1. 探索 (Traverse): Word文書内の `Table` オブジェクトを特定する。
2. 抽出 (Extract): 各行 (`Row`)、各セル (`Cell`) をループで巡回し、テキストを取得する。
3. 浄化 (Sanitize): ここが最重要です。 XMLで使えない特殊文字(`<`, `>`, `&` など)をエスケープ処理する。
4. 構築 (Build): 文字列としてXMLの構造を組み立てる。
5. 出力 (Output): ファイルシステムに書き出す。

特に「3. 浄化」を怠ると、生成されたXMLは壊れ、システム連携時にエラーを吐き出します。これは「動けばいい」レベルのコードと、プロのコードを分ける決定的な境界線です。

3. 実践:表データをXMLへ変換する究極のVBAコード

それでは、実際に動くコードを見ていきましょう。単なるコピーではなく、エラーに強く、再利用性を高めた設計にしています。

Option Explicit

''' <summary>
''' Wordの文書内にある最初の表をXML形式でエクスポートするメインルーチン
''' </summary>
Public Sub ExportFirstTableToXML()
    Dim targetTable As Table
    Dim xmlContent As String
    Dim filePath As String
    
    ' 1. 対象となるテーブルの取得(文書内の最初のテーブル)
    If ActiveDocument.Tables.Count = 0 Then
        MsgBox "文書内にテーブルが見つかりません。", vbExclamation
        Exit Sub
    End If
    Set targetTable = ActiveDocument.Tables(1)
    
    ' 2. XML構造の構築開始
    ' XML宣言からスタート
    xmlContent = "<?xml version=""1.0"" encoding=""UTF-8""?>" & vbCrLf
    xmlContent = xmlContent & "<DocumentData>" & vbCrLf
    xmlContent = xmlContent & "  <Table>" & vbCrLf
    
    ' 3. テーブルの各行をループ処理
    Dim r As Long, c As Long
    Dim cellText As String
    
    On Error Resume Next ' セル結合によるエラー回避のための保険
    For r = 1 To targetTable.Rows.Count
        xmlContent = xmlContent & "    <Row index=""" & r & """>" & vbCrLf
        
        For c = 1 To targetTable.Columns.Count
            ' セルのテキストを取得し、末尾の制御文字(セル区切り文字)を除去
            cellText = targetTable.Cell(r, c).Range.Text
            cellText = Left(cellText, Len(cellText) - 2)
            
            ' 【重要】XML特殊文字のエスケープ処理を適用
            cellText = SanitizeForXML(cellText)
            
            ' セルデータをXMLタグで囲む
            xmlContent = xmlContent & "      <Cell column=""" & c & """>" & cellText & "</Cell>" & vbCrLf
        Next c
        
        xmlContent = xmlContent & "    </Row>" & vbCrLf
    Next r
    On Error GoTo 0
    
    ' 4. XML構造の閉じタグ
    xmlContent = xmlContent & "  </Table>" & vbCrLf
    xmlContent = xmlContent & "</DocumentData>"
    
    ' 5. ファイルへの書き出し
    filePath = ActiveDocument.Path & "\TableData_" & Format(Now, "yyyymmdd_hhnnss") & ".xml"
    
    ' ファイル出力(FileSystemObjectを使用するのが確実)
    Call SaveTextToFile(xmlContent, filePath)
    
    MsgBox "エクスポートが完了しました!" & vbCrLf & "保存先: " & filePath, vbInformation
End Sub

''' <summary>
''' XMLで禁止されている特殊文字をエスケープする関数
''' </summary>
Private Function SanitizeForXML(ByVal text As String) As String
    Dim sanitized As String
    sanitized = text
    ' 順番が重要:& を最初に置換しないと、他の置換後の文字まで壊してしまう
    sanitized = Replace(sanitized, "&", "&amp;")
    sanitized = Replace(sanitized, "<", "&lt;")
    sanitized = Replace(sanitized, ">", "&gt;")
    sanitized = Replace(sanitized, """", "&quot;")
    sanitized = Replace(sanitized, "'", "&apos;")
    SanitizeForXML = sanitized
End Function

''' <summary>
''' 文字列をテキストファイルとして保存する補助関数
''' </summary>
Private Sub SaveTextToFile(ByVal content As String, ByVal filePath As String)
    Dim fso As Object
    Dim ts As Object
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    ' ForWriting: 上書きモード, True: 上書き許可
    Set ts = fso.CreateTextFile(filePath, True, True) ' TrueはUnicode(UTF-16)指定
    ts.Write content
    ts.Close
    
    Set ts = Nothing
    Set fso = Nothing
End Sub

4. 現場で直面する「壁」と、その乗り越え方

このコードを動かした際、あるいは自分でカスタマイズする際に、必ず遭遇する「壁」が2つあります。

① セル結合の恐怖

Wordの表で「セルを結合」している場合、`targetTable.Columns.Count` や `targetTable.Cell(r, c)` は、「その行に存在しないインデックス」を参照した瞬間に実行時エラーで停止します。

  • 対策: 上記コードでは `On Error Resume Next` を用いて、結合セルによってスキップされる箇所を許容していますが、業務レベルでは「結合セルがある場合は、あらかじめ結合を解除する」か、「結合セルの構造をロジカルに解析する(非常に高度な処理)」が必要です。まずは「データ抽出用の表は、結合を使わない」という運用ルールを作るのが、エンジニアとしての賢明な判断です。

② 特殊文字の罠

「マクロの記録」で書いたコードでは、`cellText = targetTable.Cell(r, c).Range.Text` だけを使いがちです。しかし、Wordのセル内には、目に見えない「改行コード」や「セル区切り文字」が含まれています。
これをそのままXMLに書き込むと、XMLパーサー(読み取り側)が「不正な文字がある」とエラーを吐いて止まります。

  • 対策: `Left(cellText, Len(cellText) – 2)` を使い、Word特有の制御文字を削ぎ落とす処理を必ず入れてください。

5. まとめ:ここをクリアすれば、Word VBAの基本はバッチリですよ

今回のポイントを整理しましょう。

1. データとレイアウトを分ける: XMLを使うことで、Wordを「単なる書類」から「データソース」へ変える。
2. エスケープ処理を忘れない: `&` や `<` は、XMLの世界では「特別な意味」を持つ。そのまま流し込むのは禁物。 3. オブジェクトの特性を知る: セル結合や制御文字など、Word特有の挙動を理解してコードに組み込む。

「ただ動くコード」を書く人と、「システムとして信頼されるコード」を書く人の差は、こうした「例外的なケースへの配慮」にあります。

このXMLエクスポートができるようになれば、あなたの作ったWordツールは、他のあらゆるシステムとつながる「最強のインターフェース」になります。一歩ずつ、着実にマスターしていきましょう。応援していますよ!

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