【入門編】【上級プロ向け】クラッシュした破損CDRファイルのバイナリ構造解析と、VBAによるXMLメタデータの強制サルベージ – CorelDRAW VBA解析バイブル

スポンサーリンク

こんにちは!CorelDRAW VBAの世界へようこそ。
日々の業務でCorelDRAWを使い倒していると、いつか必ず遭遇するのが「朝出社して開こうとしたら、突然『このファイルは破損しています』とエラーが出て開かない悪夢」です。締切直前、何時間もかけたデザインデータがパーになった時の絶望感と言ったら……想像するだけでも冷や汗が出ますよね。

一般的なユーザーならここで終わりですが、私たち「自動化エンジニア」にはVBAという強力な武器があります。実は、近年のCorelDRAWファイル(.cdr)は、内部がZIP圧縮されたコンテナ構造になっており、その中にはSVGやXMLといったテキストベースのメタデータやプレビュー画像が格納されています。

今回は、完全にぶっ壊れてCorelDRAWのGUIからは二度と開けなくなったCDRファイルから、VBAのバイナリ・ファイルI/Oを駆使して内部のXMLやメタデータを強制的にサルベージ(救出)する、超実用的な自己修復エンジンの作り方を伝授します。

ここをクリアすれば、単なるマクロの記録者から「CorelDRAWの内部構造を掌握するエンジニア」へ一気にステップアップできますよ。さあ、知的な冒険に出発しましょう!

1. そもそも「破損したCDRファイル」の正体とは?

「ファイルが壊れた」と言うと、中のデータがすべてゴミクズになったように思えますよね。でも、安心してください。大半のケースにおいて、ファイルの一部(特にヘッダ情報やフッタのインデックス)が破損しているだけで、内部のストリームやXMLチャンクは無傷で残っていることがほとんどです。

近年のCorelDRAWファイル(ZIPベースの構造)を図解すると、こうなっています:

[ 破損した CDR ファイル ]
┣━━ META-INF/
┣━━ content.xml ← ★ここにはオブジェクトの階層構造やテキストが生きて眠っている!
┣━━ preview/ ← ★PNGのサムネイルも救出可能!
└── 略

CorelDRAWのアプリケーションはこの構造を厳密にチェックするため、インデックスが少しでも狂うと「開きません」と冷たく突き放します。ならば、アプリケーションをバイパスして、VBAで直接中身を引っこ抜けばいいのです。

2. 開発の全体像とアプローチ

今回のサルベージエンジンは、以下のステップで動作します。

1. 拡張子の偽装(ZIP展開): VBAの `FileSystemObject` を使い、`.cdr` を `.zip` にリネームしてテンポラリフォルダに解凍する。
2. XMLの直接解析: 解凍された `content.xml` をVBAの `ADODB.Stream` で読み込み、文字化けを防ぎながらテキストとして抽出する。
3. 重要データのサルベージ: テキストの中から、テキストフレームの文字列や座標データなどのテキスト片を正規表現や文字列検索で救い出し、新規ドキュメントへ再構築する。

それでは、実際のコードを見ていきましょう。

3. 実装コード:破損CDRサルベージエンジン

以下のコードは、開発現場でそのままコピペして使える完全版のVBAモジュールです。標準モジュールに貼り付けて実行してください。

Option Explicit

‘ ==============================================================================
‘ 【上級者向け】破損CDRファイル強制サルベージエンジン
‘ 概要: 壊れたCDRをZIPとして解凍し、内部のcontent.xmlからテキストを救出する
‘ ==============================================================================
Public Sub SalvageCorruptedCDR()
Dim fso As Object
Dim sourcePath As String
Dim zipPath As String
Dim extractFolder As String
Dim shellApp As Object
Dim xmlContent As String

‘ 1. 対象ファイルの指定(ダイアログ等で置き換えてもOK)
sourcePath = “C:\Data\BrokenDrawing.cdr”

Set fso = CreateObject(“Scripting.FileSystemObject”)

If Not fso.FileExists(sourcePath) Then
MsgBox “指定されたファイルが存在しません。”, vbCritical, “サルベージ中断”
Exit Sub
End If

‘ 2. 安全のためファイルを一時フォルダにコピーし、拡張子を .zip に偽装
extractFolder = fso.GetSpecialFolder(2) & “\CDR_Salvage_Temp\”
If fso.FolderExists(extractFolder) Then fso.DeleteFolder extractFolder, True
fso.CreateFolder extractFolder

zipPath = extractFolder & “rescue.zip”
fso.CopyFile sourcePath, zipPath, True
fso.MoveFile zipPath, extractFolder & “rescue.zip” ‘ 確実なリネームのため
zipPath = extractFolder & “rescue.zip”

‘ 3. Windows標準のShellを使ってZIPを解凍(サードパーティ製ツール不要)
Set shellApp = CreateObject(“Shell.Application”)

On Error GoTo ErrorHandler
Dim filesInZip As Object
Set filesInZip = shellApp.Namespace(zipPath).Items
shellApp.Namespace(extractFolder).CopyHere filesInZip
On Error GoTo 0

‘ 4. 内部の content.xml を特定してテキストを読み込む
Dim xmlPath As String
xmlPath = extractFolder & “content.xml” ‘ ※バージョンによりパスが異なる場合は要調整

If fso.FileExists(xmlPath) Then
xmlContent = ReadTextFileUTF8(xmlPath)

‘ 5. 救出したXMLからテキストデータを解析・新規ドキュメントへ出力
Call ExtractTextAndRebuild(xmlContent)

MsgBox “サルベージが完了しました!テキストデータを新規ドキュメントに復旧しました。”, vbInformation, “成功”
Else
MsgBox “致命的な破損: 内部の content.xml が見つかりませんでした。”, vbCritical, “サルベージ失敗”
End If

‘ 6. クリーンアップ
If fso.FolderExists(extractFolder) Then fso.DeleteFolder extractFolder, True

Exit Sub

ErrorHandler:
MsgBox “解凍プロセス中にエラーが発生しました。ファイルが完全に破壊されている可能性があります。” & vbCrLf & _
“エラー番号: ” & Err.Number & ” / ” & Err.Description, vbCritical, “致命的エラー”
If fso.FolderExists(extractFolder) Then fso.DeleteFolder extractFolder, True
End Sub

‘ ——————————————————————————
‘ UTF-8形式のXMLファイルを正確に読み込むためのヘルパー関数
‘ ——————————————————————————
Private Function ReadTextFileUTF8(ByVal filePath As String) As String
Dim stream As Object
Set stream = CreateObject(“ADODB.Stream”)

With stream
.Type = 2 ‘ adTypeText
.Charset = “utf-8”
.Open
.LoadFromFile filePath
ReadTextFileUTF8 = .ReadText
.Close
End With

Set stream = Nothing
End Function

‘ ——————————————————————————
‘ XMLからテキスト要素を簡易抽出し、新規CorelDRAWドキュメントに再配置するロジック
‘ ——————————————————————————
Private Sub ExtractTextAndRebuild(ByVal xmlData As String)
Dim doc As Document
Set doc = CreateDocument() ‘ 新規ドキュメント作成

‘ ここでは簡易的に正規表現を使ってXMLタグ内のテキスト片をキャプチャする例を示します
‘ ※実際のCorelDRAWのスキーマに合わせてタグ名を調整してください
Dim regex As Object
Set regex = CreateObject(“VBScript.RegExp”)

With regex
.Pattern = “>([^<]+)” ‘ 例としてのパターン(環境依存あり)
.IgnoreCase = True
.Global = True
End With

Dim matches As Object
Set matches = regex.Execute(xmlData)

Dim match As Object
Dim yPos As Double
yPos = doc.Pages(1).SizeHeight – 10 ‘ 上部から配置

‘ 救出したテキストを順番に新しいキャンバスに書き出す
Dim count As Long
count = 0

For Each match in matches
Dim recoveredText As String
recoveredText = Trim(match.SubMatches(0))

If Len(recoveredText) > 0 Then
doc.Pages(1).ActiveLayer.CreateArtisticText 10, yPos, recoveredText
yPos = yPos – 15 ‘ 次の行へ
count = count + 1

‘ 画面がフリーズしないよう適度にウェードを入れるか、大量すぎる場合は制限する
If count > 500 Then Exit For
End If
Next match

doc.ClearUndoLevel
End Sub

4. 陥りやすい罠とエンジニアの知見

このレベルの自動化を実装する際、多くのプログラマが以下の「罠」にハマります。知見として頭に叩き込んでおいてください。

① 文字コードの罠(Shift_JIS vs UTF-8)

CorelDRAWの内部XMLは原則として UTF-8 でエンコードされています。これを標準の `Open … For Input As #1` などで読み込むと、日本語環境では文字化けを起こしてゴミデータになってしまいます。必ず上記のコードで使用しているような `ADODB.Stream` を使い、明示的に `Charset = “utf-8″` を指定してバイナリからテキストへ変換してください。

② シェルオブジェクトのセキュリティブロック

VBAからWindowsのShellオブジェクトを使ってZIPを解凍する際、環境によってはセキュリティソフトやWindowsの保護機能が働き、一時フォルダへの書き込みがブロックされることがあります。
対策として、VBA側で一時フォルダ (`Environ(“TEMP”)` など) を確実にクリーンアップし、競合を防ぐ設計にすることがプロの条件です。

③ メモリリークとオブジェクトの解放

VBAはガベージコレクションがそこまで賢くありません。特に `FileSystemObject` や `ADODB.Stream`、正規表現オブジェクトなどをループ内で生成・破棄し続けると、メモリリークを起こしてCorelDRAWごとクラッシュします。必ず処理の最後には `Set object = Nothing` で明示的に解放する癖をつけましょう。

まとめ

今回は、一見すると絶望的な「破損したCDRファイル」から、VBAのファイルI/OとXML解析技術を組み合わせてデータをサルベージする手法を解説しました。

  • CDRファイルの実体はZIPコンテナである
  • GUIで開けなくても、VBAならバイナリレベルで内部にアクセスできる
  • `ADODB.Stream` を使えば、UTF-8のXMLデータも完璧に読み込める

ここまで理解できれば、あなたはもう単なるマクロ利用者ではありません。CorelDRAWの内部構造まで見通せる、真の業務自動化エンジニアです。万が一のトラブルが起きた時、「私に任せてください、VBAで救出しますから」と言えるカッコいいエンジニアを目指して、ぜひこのコードをご自身の環境でも試してみてくださいね!

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