CorelDRAW VBAの「亡霊」を葬れ:Documentオブジェクトのライフサイクルとメモリ解放の深淵
CorelDRAWの自動化を極める過程で、多くの開発者が直面する「見えない壁」がある。マクロを実行するたびにメモリ使用量が増大し、やがてCorelDRAWがフリーズする、あるいはタスクマネージャーに `CorelDRW.exe` がゾンビのように残り続ける現象だ。
これは単なるバグではない。CorelDRAWのオブジェクトモデルにおける「参照カウントの未解決」と「Document終了処理の甘さ」が招く必然である。本稿では、レガシーなVBA環境下において、いかにしてシステムのリソースを完全に制御し、枯れたアーキテクチャを堅牢な自動化エンジンへと昇華させるかを説く。
—
1. ゾンビプロセスの正体:参照の切断とガベージコレクションの限界
VBAは、COM(Component Object Model)のラッパーに過ぎない。あなたが `Set doc = Application.OpenDocument(…)` と書いた瞬間、メモリ上ではインターフェースへのポインタが確保される。
問題は、`doc.Close` を呼んだだけでは「COMオブジェクトの参照」までが即座に破棄されるとは限らない点にある。特にループ処理で複数のドキュメントを扱う場合、参照を明示的にクリアしない限り、CorelDRAWの内部エンジンは「まだどこかでこのドキュメントが使われているかもしれない」と判断し、メモリを解放しない。
—
2. 破壊的後処理のベストプラクティス
ドキュメントを閉じる際の `SaveChanges` パラメータは、単なる保存の有無ではない。OSリソースとの同期を強制するトリガーである。
以下に、現場レベルで確実に動作する「完全終了パターン」を示す。
Public Sub SafeDocumentProcessing(ByVal filePath As String)
Dim doc As Document
‘ エラーハンドリングを組み込み、異常終了時にも確実に解放させる
On Error GoTo Cleanup
Set doc = Application.OpenDocument(filePath)
‘ — ここにメインの業務ロジックを記述 —
‘ 例: doc.ActiveLayer.CreateArtisticText …
‘ ————————————
‘ 変更を保存せずに閉じる場合
‘ cdrDoNotSaveChanges: 保存せずに閉じる
doc.Close cdrDoNotSaveChanges
Cleanup:
‘ 1. オブジェクトの明示的解放(必須)
‘ これを忘れると、VBA上の変数が無効なポインタを保持し続ける
Set doc = Nothing
‘ 2. エラー発生時の処理
If Err.Number <> 0 Then
Debug.Print “Error: ” & Err.Description
End If
End Sub
重要なポイント
- `Set doc = Nothing` の不可欠性: これを省略すると、スコープを抜けるまで参照カウントが減らず、メモリリークの温床となる。
- `cdrDoNotSaveChanges` の活用: 自動化処理において、中間ファイルを意図せず保存させることはリスクである。明確な意図がある場合を除き、読み込み専用で開き、破棄する運用を徹底せよ。
—
3. Windows APIによる強制クリーンアップ(極限の知見)
VBA標準の機能だけでは、CorelDRAWの内部キャッシュが解放されないケースがある。特に大量のファイルを連続処理する場合、`DoEvents` だけでは不十分だ。
もしメモリ不足が顕著な場合は、プロセスを監視し、明示的に `GC.Collect` に相当する処理を模倣するか、Windows APIを用いてUIスレッドを休ませる必要がある。
‘ API宣言(モジュール先頭に配置)
If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If
‘ 連続処理の合間に挟むインターバル
‘ CorelDRAWの内部的な再描画とメモリ管理の同期を待つ
Public Sub ForceMemoryRelease()
DoEvents
Sleep 200 ‘ 200msの休止でCOMの解放を待機させる
End Sub
—
4. チーフアーキテクトからの提言:保守性の高い設計へ
VBAによる自動化で最も避けるべきは、「単一のプロシージャ内に全てのロジックを詰め込むこと」である。
1. 分離: ドキュメントの開閉(ライフサイクル管理)と、描画ロジック(ビジネスロジック)を必ず関数として分割せよ。
2. 監視: 可能な限り、処理対象のドキュメント数は定数または設定ファイルで制御し、無限ループを発生させない設計を行うこと。
3. 検証: 本番環境投入前に、タスクマネージャーで「マクロ実行前」と「マクロ実行後(かつ終了後)」の `CorelDRW.exe` のメモリ消費量を比較せよ。ここが減っていなければ、あなたのコードは未完成だ。
CorelDRAW VBAは古い技術かもしれない。しかし、オブジェクトモデルの挙動を深く理解し、COMの特性を制御下に置くことができれば、それは現代のどの言語よりも強力な「直感的」なツールへと変貌する。
メモリを制する者が、自動化を制する。諸君の健闘を祈る。
