WordからExcelへ「呪われたデータ」を解き放つ:境界を超えるメモリ管理と正規化の技術
Wordの表(Table)をクリップボード経由でExcelへ流し込む。一見、手作業の延長のような単純なタスクに見える。しかし、実務の現場でそれを「システム」として実装しようとした瞬間、エンジニアはWordという名の巨大なブラックボックスと、不安定なクリップボードという「魔境」に足を踏み入れることになる。
結合セル、改行コードの混入、段落記号によるデータの断片化。これらをいかにして「綺麗なレコードセット」としてExcelへ再構築するか。今日は、泥臭い回避策ではなく、オブジェクトのライフサイクルを制御した「アーキテクトの作法」を伝授する。
—
1. 泥沼化する「クリップボード経由」の真実
Wordの表を単純に `.Copy` すると、Wordはリッチテキスト形式(RTF)やHTML形式を含んだ、極めて重いデータをクリップボードに詰め込む。これをExcelが受け取ると、結合セルの崩壊や、意図しない型変換が起きる。
これを防ぐには、「クリップボードを介さない」または「文字列として純化させた後に流し込む」という二段構えの戦略が必要だ。
2. 実装の要諦:オブジェクトの明示的解放とメモリの断捨離
Wordのオブジェクト操作で最も忌むべきは、暗黙的な参照の残存によるメモリリークだ。特に表の走査中にWordインスタンスを掴み続けると、巨大なドキュメントでは確実にパフォーマンスが劣化する。
実装コード:Word表の正規化とテキスト抽出
以下のコードは、Word上の表を走査し、結合セルを考慮した純粋な配列として抽出するプロトタイプだ。
‘ Word側で実行:表データを配列として抽出するロジック
Public Function ExtractTableData(targetTable As Table) As Variant
Dim r As Long, c As Long
Dim result() As String
‘ 表の行列数から配列を再構築
ReDim result(1 To targetTable.Rows.Count, 1 To targetTable.Columns.Count)
‘ セル内の改行コードはExcel側で毒となるため、置換してクリーンな文字列にする
For r = 1 To targetTable.Rows.Count
For c = 1 To targetTable.Columns.Count
Dim cellText As String
cellText = targetTable.Cell(r, c).Range.Text
‘ 段落記号(Chr(13))とセル終端記号(Chr(7))を除去
cellText = Replace(cellText, vbCr & Chr(7), “”)
cellText = Replace(cellText, vbCr, ” “)
result(r, c) = Trim(cellText)
Next c
Next r
ExtractTableData = result
‘ オブジェクトの明示的解放は不要だが、巨大なRangeオブジェクトを保持しないよう注意
End Function
—
3. Windows APIによるクリップボードの「外科手術」
Excel側でペーストを行う際、標準の `Paste` メソッドを信じてはならない。特に社内システムでは、クリップボードが他プロセスによってロックされる事態が頻発する。
ここで、Windows APIの `OpenClipboard` を使用し、排他制御を強化する手法が有効だ。
‘ VBAからAPIを叩き、クリップボードを強制的にクリーンアップする
If VBA7 Then
Private Declare PtrSafe Function OpenClipboard Lib “user32” (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function EmptyClipboard Lib “user32” () As Long
Private Declare PtrSafe Function CloseClipboard Lib “user32” () As Long
Else
Private Declare Function OpenClipboard Lib “user32” (ByVal hwnd As Long) As Long
‘ …以下略
End If
Public Sub ClearClipboard()
If OpenClipboard(0) <> 0 Then
Call EmptyClipboard
Call CloseClipboard
End If
End Sub
このAPI呼び出しを、データ転送の直前に挟むことで、ペースト時の「謎の挙動」を劇的に減らすことができる。
—
4. 伝説のエンジニアとしてのアドバイス:結合セルへの回答
読者諸君が最も苦しんでいるのは「Wordの結合セル」だろう。Wordの `Cell.Merge` は、セルを一つに統合するが、データ構造を破壊する。
結論:Word側で結合セルを解析しようとしないこと。
Wordの `Table.Cell(r, c)` は、結合されている場合、先行するセルと重複してアクセスされる。あえて「結合を解除する」か、あるいは「隠しプロパティ(Rangeの開始位置)」を比較して、物理座標をExcelのセル番地にマッピングするアダプター層を設けるのが、シニアエンジニアの流儀だ。
結びに:技術は「回避」するためにある
WordとExcelの連携は、永遠に続くレガシーとの戦いである。しかし、アプリケーションの境界を「データ」という抽象レイヤーで捉え、APIで制御し、メモリのライフサイクルを意識するだけで、そのコードは「動く」から「堅牢である」へと昇華する。
泥臭い自動化に魂を込めよ。その細部への執着こそが、あなたのコードを伝説にする唯一の道だ。
