【Visioの深淵】破損したVSDXから「魂(シェイプデータ)」を救出する――極限のVBAリカバリ戦略
業務自動化エンジニアであれば、一度は経験があるはずだ。
「Visioファイルが破損しました。開けません」という絶望的な報告。
標準の修復機能が弾かれ、バックアップもない。多くのエンジニアはここで諦めるが、VSDXの正体を知る者にとって、それはただの「XMLの集合体」に過ぎない。
今回は、Visioのオブジェクトモデルを介さず、VSDXのバイナリ構造を意識しながら、破損したファイルからシェイプのプロパティ(シェイプデータ)を強引に抽出・復元する極限のテクニックを伝授する。
—
1. なぜVSDXは「開けなくなる」のか?
VSDXは実態としてZIP圧縮されたXML構造体だ。破損の多くは、以下のいずれかに起因する。
- ZIP構造の破損: CRCチェックサムの不整合。
- XMLツリーの断絶: パーサーがタグの閉じ忘れを検知し、ロードを中断。
Visioアプリケーション経由で開こうとすると、Visioの「厳格なバリデーター」がXML全体を検証するため、一部のゴミデータでファイル全体が拒絶される。
ここで重要な視点:
VisioのUIを介さず、`FileSystemObject`(FSO)と `MSXML2` を組み合わせれば、壊れたXMLツリーの「生きているノード」だけをピンポイントでサルベージできる。
—
2. 実践:破損VSDXからのデータ抽出アーキテクチャ
今回の設計思想は「外科手術的アプローチ」だ。
1. 解凍: バイナリを一時フォルダに展開する。
2. XML解析: `masters.xml` や `pages.xml` を直接DOM解析し、`
3. 再構築: 新規図面を作成し、抽出したデータを `Cell` オブジェクトを通じて再配置する。
注意点: なぜ「標準のVisioオブジェクト」を使わないのか?
`Visio.Documents.Open` を呼んだ時点で、Visioはファイル全体の整合性を求め、エラーを吐いて終了する。だからこそ、「ファイルを開かずにバイナリを直接叩く」必要があるのだ。
—
3. プロダクションコード:シェイプデータ救出ロジック
このコードは、VSDX内の `pages/page1.xml` を直接解析し、シェイプデータを抽出するプロトタイプだ。
Option Explicit
‘ 必要な参照設定: Microsoft XML, v6.0 / Microsoft Scripting Runtime
Public Sub SalvageShapeDataFromVSDX(ByVal sourcePath As String)
Dim fso As Object
Dim shellApp As Object
Dim xmlDoc As MSXML2.DOMDocument60
Dim shapeNodes As MSXML2.IXMLDOMNodeList
Dim node As MSXML2.IXMLDOMNode
‘ 1. 一時ディレクトリへの展開
‘ VSDXはZIPなので、拡張子を一時的にZIPに変えて解凍する
Dim tempDir As String
tempDir = Environ(“TEMP”) & “\VisioSalvage\”
‘ (※ここにZIP解凍用のシェルコマンドまたはFSOによる処理を実装)
‘ 2. XMLのロード(構造が壊れていても可能な限り読み込む)
Set xmlDoc = New MSXML2.DOMDocument60
xmlDoc.async = False
xmlDoc.validateOnParse = False ‘ 重要: 壊れたタグを無視する
If Not xmlDoc.Load(tempDir & “visio/pages/page1.xml”) Then
Debug.Print “致命的なXML構造エラーです。一部のみ抽出を試みます。”
End If
‘ 3. シェイプデータ(Prop)の抽出
Set shapeNodes = xmlDoc.SelectNodes(“//Prop”)
Dim targetDoc As Visio.Document
Set targetDoc = Application.Documents.Add(“”)
‘ 4. 新規図面へのデータ再注入
For Each node In shapeNodes
‘ ここで抽出したデータを targetDoc 内のシェイプにマッピングする
‘ node.Attributes.getNamedItem(“Name”).Text 等で値を取得
Debug.Print “Recovered Property: ” & node.XML
Next node
MsgBox “救出プロセス完了。データを確認してください。”
End Sub
—
4. 業務自動化エンジニアへの提言
① データベースとの連携について
抽出したシェイプデータは、ただ新しい図面に貼り付けるだけでは意味がない。抽出したデータを一度 `JSON` または `SQLite` に退避させ、「破損前の状態を再現する台帳」を作成することを推奨する。シェイプIDは破損時に変わる可能性があるため、メタデータ(作成者、作成日時、ユニークID)をキーに突き合わせる設計が必須だ。
② 保守性の極意
この手のツールは、Visioのバージョンアップ時にXMLスキーマが変更されると動かなくなる可能性がある。そのため、`XPath` によるノード指定は、ネストが深い場合は避け、ルートに近い場所からの相対パスで記述するよう心がけること。
③ 警告
このコードは「緊急時の救命措置」である。破損したファイルから抽出したデータは、一部の参照整合性が失われている可能性がある。救出後は必ず、全シェイプの接続関係(Connects)が維持されているか、手動またはスクリプトで検品するプロセスを組み込んでほしい。
—
最後に。
エンジニアの価値は、完璧な環境でコードを書くことではなく、混沌とした現場で「いかにしてビジネスを止めないか」という執念の差で決まる。
Visioのバイナリを恐れるな。あれはただのテキストの集合体だ。君のエンジニアリングで、失われたデータを未来へ繋いでくれ。
