CorelDRAW VBAを掌握する極限の知見:大量CDRファイル一括変換のアーキテクチャ
業務の現場において、前世紀から連綿と受け継がれてきた数千・数万のCDR(CorelDRAW)ファイル群。これらを新しいバージョンへの一斉移行や、特定のフォーマットへコンバートしなければならない瞬間は突如として訪れる。
「手動でファイルを開き、名前を付けて保存を繰り返す」——このような非人間的な作業をVBAで自動化するのは基本の「キ」だが、プロの現場で通用するコードと、単に動くだけの玩具のコードには、生死を分けるほどの決定的な差がある。
本稿では、File System Object (FSO) を用いたディレクトリ走査をベースに、CorelDRAWの強烈なオブジェクトライフサイクルをねじ伏せ、メモリリークやハングアップを完全に回避しながら大量のファイルを一括処理する、実戦投入可能な実用スクリプトを解説する。
—
1. 現場のエンジニアが陥る「CorelDRAW VBAの罠」
初心者向けの解説書には「`Application.Open` を使ってファイルを開き、`SaveAs` すればよい」と平然と書かれている。しかし、この設計のまま100ファイル以上のバッチ処理を走らせれば、間違いなく中盤でメモリ不足(Out of Memory)またはCorelDRAWプロセスのフリーズに直面する。
CorelDRAWのCOMコンポーネントは、バックグラウンドでのメモリ解放が極めてルーズだ。特に古いバージョン(X7, 2018など)では、ドキュメントを閉じたつもりでも、内部のグラフィックキャッシュやフォントハンドラがメモリ上に残留し、イテレーションを重ねるごとにシステムを窒息させる。
この悪夢を回避するため、シニアエンジニアは以下の鉄則を遵守しなければならない。
1. 画面描画とイベントの完全抑制 (`Optimization = True`)
2. ドキュメントの確実なアンロードとオブジェクト変数の即時破棄 (`Nothing` 代入)
3. エラーハンドリングの局所化(1つの破損ファイルでバッチ全体を止めない)
—
2. 実装:堅牢性を極めた一括別名保存スクリプト
以下に、実務の現場でそのまま耐えうる堅牢性を持たせたVBAコードを提示する。VBE(Visual Basic Editor)の標準モジュールに貼り付けて使用してほしい。
Option Explicit
‘ ==============================================================================
‘ 致命的なメモリリークを防ぐ、CDRファイル一括バージョン変換エンジン
‘ Architecture: Chief Architect Special Edition
‘ ==============================================================================
Sub BatchConvertCDRFiles()
‘ 処理設定(環境に合わせて書き換えてください)
Const TARGET_FOLDER As String = “C:\Data\CDR_Source\”
Const OUTPUT_FOLDER As String = “C:\Data\CDR_Converted\”
Dim fso As Object
Dim srcFolder As Object
Dim fileItem As Object
Dim doc As Document
Dim targetPath As String
Dim fileCount As Long
Dim successCount As Long
‘ FSOのインスタンス生成
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 出力先フォルダの存在確認・自動生成
If Not fso.FolderExists(OUTPUT_FOLDER) Then
fso.CreateFolder OUTPUT_FOLDER
End If
If Not fso.FolderExists(TARGET_FOLDER) Then
MsgBox “指定された入力フォルダが存在しません: ” & TARGET_FOLDER, vbCritical, “致命的なエラー”
Exit Sub
End If
Set srcFolder = fso.GetFolder(TARGET_FOLDER)
If srcFolder.Files.Count = 0 Then
MsgBox “処理対象のファイルが見つかりません。”, vbExclamation, “情報”
GoTo Cleanup_FSO
End If
‘ 【極重要】CorelDRAWの描画更新とUIイベントを完全停止し、処理速度を限界まで引き上げる
EventsEnabled = False
Application.Optimization = True
‘ 予期せぬエラーによるUIロックを防ぐためのトランザクション保護
On Error GoTo ErrorHandler
fileCount = 0
successCount = 0
‘ ディレクトリ走査
For Each fileItem In srcFolder.Files
‘ 拡張子が .cdr であるもののみを対象とする(大文字小文字を区別しない)
If LCase(fso.GetExtensionName(fileItem.Name)) = “cdr” Then
fileCount = fileCount + 1
‘ ドキュメントを開く(非表示モードのパラメータがあれば理想だが、CorelDRAWの仕様上不可視化は限定的)
Set doc = Application.OpenDocument(fileItem.Path)
If Not doc Is Nothing Then
‘ 出力パスの構築(必要に応じてバージョンを指定。ここでは例として最新形式または指定形式)
‘ cdr的版本定数: cdrCorelDRAW2019, cdrVersion15 (X5) など環境に依存
targetPath = OUTPUT_FOLDER & fso.GetBaseName(fileItem.Name) & “_rev.cdr”
‘ 別名保存(ここではCorelDRAW 2019形式での保存を例示)
‘ ※環境のCorelDRAWのタイプライブラリに合わせたバージョン定数を使用してください
doc.SaveAs targetPath, cdrCurrentVersion ‘ または具体的なバージョン定数
‘ ドキュメントを強制的に閉じる(変更を保存済みフラグを立ててからクローズ)
doc.Close
‘ 【最重要】メモリ解放の儀式。参照を切る。
Set doc = Nothing
successCount = successCount + 1
End If
End If
Next fileItem
GoTo Cleanup_Routine
ErrorHandler:
‘ 個別ファイルの破損などでエラーが出ても、バッチ全体を止めずにログに残して次へ進む耐障害設計
Debug.Print “Error processing file. Number: ” & Err.Number & ” Description: ” & Err.Description
If Not doc Is Nothing Then
On Error Resume Next
doc.Close
Set doc = Nothing
On Error GoTo 0
End If
Resume Next
Cleanup_Routine:
‘ 【極重要】最適化フラグとイベントを必ず元の状態に戻す
Application.Optimization = False
EventsEnabled = True
‘ 完了通知
MsgBox “一括変換処理が完了しました。” & vbCrLf & _
“総処理ファイル数: ” & fileCount & ” 件” & vbCrLf & _
“成功件数: ” & successCount & ” 件”, vbInformation, “処理完了”
Cleanup_FSO:
Set fileItem = Nothing
Set srcFolder = Nothing
Set fso = Nothing
End Sub
—
3. チーフアーキテクトが解説するコードの急所
A. `Application.Optimization = True` の魔力
CorelDRAWはドキュメントを開くたび、プレビュー画像の生成、フォントのキャッシュ、UIの再描画などを律儀に行う。これがバッチ処理において最大のボトルネックとなる。
`Optimization = True` を宣言することで、これらすべてのバックグラウンド描画処理がバイパスされ、処理速度が最大で10倍以上に跳ね上がる。ただし、このモード中はエラーが発生しても画面が固まったままになるため、必ず `On Error` と組み合わせたクリーンアップ構文が必須となる。
B. COMオブジェクトのライフサイクル管理 (`Set doc = Nothing`)
VBAのガベージコレクションは非常に曖昧だ。ローカル変数であっても、プロシージャを抜けるまでメモリ上にCOMインスタンスが残存することが多い。
大量のCDRファイルを扱う場合、ループの直近で `doc.Close` した後に `Set doc = Nothing` を明示的に実行する ことで、VBAエンジンに対して「このメモリ領域はもう不要である」と強く調停をかける。これを怠ると、50ファイルを超えたあたりでCorelDRAW自体がメモリ例外でクラッシュする。
C. レガシー環境とバージョン定数の罠
`doc.SaveAs targetPath, cdrCurrentVersion` の部分だが、もし社内に複数バージョンのCorelDRAW混在環境がある場合、`cdrCurrentVersion` の解釈が異なり、意図しない古い形式で保存されるリスクがある。
厳密なシステム間連携を行う場合は、マジックナンバーや列挙型に頼らず、CorelDRAWのタイプライブラリが提供する具体的なバージョン列挙体(例: `cdrVersion17` など)を明示的に指定することを強く推奨する。
—
総括
VBAは、しばしば「おもちゃのプログラミング言語」と揶揄される。しかし、それは書く人間のアーキテクチャ理解が浅い場合の話に過ぎない。
メモリの寿命を意識し、OSとアプリケーションのリソース管理の境界線を見極めて構築されたVBAスクリプトは、企業内のレガシーワークフローを根底から覆すほどの圧倒的な自動化兵器となり得る。
日々の手作業に絶望しているシステム管理者やエンジニア諸賢よ。今こそ、この極限の知見をあなたの開発環境にインストールし、真の自動化を成し遂げてほしい。
