こんにちは!CorelDRAW VBAの世界へようこそ。
マクロの記録ボタンを押して「動いた!」と喜んでいた時期を通り越し、いざ「何百個ものファイルを自動処理するぞ!」と意気込んだとき、多くの人が最初に直面する壁――それが「メモリリークと突然の強制終了(フリーズ)」です。
「なぜか処理が進むにつれてPCが重くなり、最後にはCorelDRAWごと落ちてしまう……」
もしあなたがそんな悩みを抱えているなら、原因はコードの書き方ではなく、「ドキュメントの閉じ方」と「オブジェクトの片付け方」にあります。
ここをクリアすれば、あなたの書くマクロは見違えるほど安定し、プロのエンジニアが作るシステムと同等の堅牢性を手に入れられますよ。さあ、一緒にCorelDRAW VBAの本質をマスターしていきましょう!
—
1. なぜ大量処理でCorelDRAWが固まるのか?(メモリリークの正体)
VBAでドキュメントを開き、何か処理をして閉じる。一見、完璧に見えるコードでも、裏側ではOSのメモリ(RAM)を少しずつドカ食いし続ける罠が潜んでいます。
原因は主に以下の2点です。
1. 変更の保存(SaveChanges)の制御ミスにより、意図しないダイアログが出てプログラムが停止する、あるいは不要なゴミデータが残る。
2. オブジェクト変数(`Document`や`Shape`など)を `Nothing` で解放していないため、VBAがメモリ上にドキュメントの残骸をずっと保持し続ける。
CorelDRAWのオブジェクトモデルは非常に強力ですが、それゆえにメモリ管理のルールに少し厳しいところがあります。次の章から、その具体的な解決策を見ていきましょう。
—
2. `Document.Close` の正しい作法と `SaveChanges` の制御
まずは、ドキュメントを閉じるメソッド `Close` の正しい使い方です。
ドキュメントを閉じる際、何も考えずに `doc.Close` と書くと、ファイルに変更が加えられていた場合に「変更を保存しますか?」というお節介なダイアログが表示されます。自動処理中にこれが起まると、ユーザーが「はい」か「いいえ」を押すまでプログラムは永遠にフリーズします。
これを防ぐためには、`SaveChanges` パラメータを明示的に制御する必要があります。
`cdrSave` と `cdrSaveChanges` の違い
- `cdrSaveChanges` (または `True`): 変更をそのまま上書き保存して閉じます。
- `cdrDontSaveChanges` (または `False`): 変更を破棄して(保存せずに)閉じます。
—
3. 確実なドキュメント破棄と変数解放のテンプレートコード
それでは、現場でそのまま使える「安全なファイル処理のテンプレート」をお見せします。
「開く ➔ 処理する ➔ 保存せずに閉じる ➔ 変数を完全に空にする」という一連の流れが美しく組まれています。
Sub ProcessDocumentSafely()
Dim targetPath As String
Dim targetDoc As Document
‘ 処理対象のファイルパス(環境に合わせて変更してください)
targetPath = “C:\MyFolder\sample.cdr”
‘ 【1. ドキュメントを開く】
‘ OpenDocumentは、開いたドキュメントの参照をオブジェクト変数に返します
Set targetDoc = Application.OpenDocument(targetPath)
‘ 万が一、ファイルが開けなかった場合のガード処理
If targetDoc Is Nothing Then
MsgBox “ファイルのオープンに失敗しました。”, vbCritical
Exit Sub
End If
On Error GoTo ErrorHandler ‘ 予期せぬエラーが起きたときも確実に片付けるため
‘ ==========================================
‘ 【2. ここに実際の処理を記述する】
‘ ==========================================
‘ 例:レイヤーを追加してみる
targetDoc.Layers.Add (“AutoProcessed_Layer”)
‘ ==========================================
‘ 【3. ドキュメントを閉じる & 保存制御】
‘ ==========================================
‘ 今回は「変更を保存して閉じる」パターン
‘ ※保存したくない場合は cdrDontSaveChanges を指定します
targetDoc.Close cdrSaveChanges
‘ 【4. オブジェクト変数の完全解放(最重要!)】
‘ メモリ上に残った参照を完全に消去します
Set targetDoc = Nothing
MsgBox “正常に処理が完了しました!”, vbInformation
Exit Sub
ErrorHandler:
‘ エラー発生時の安全装置
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
‘ エラー時でもドキュメントが開いているなら強制的に閉じる(保存しない)
If Not targetDoc Is Nothing Then
targetDoc.Close cdrDontSaveChanges
Set targetDoc = Nothing
End If
End Sub
コードのここがポイント!
- `Set targetDoc = Nothing` の意味
VBAのオブジェクト変数は、役割が終わってもプログラムが終了するまでメモリ内に「居座る」性質があります。これを `Set 変数名 = Nothing` と明示的に書き換えることで、「もうこのメモリ領域は使わないよ」とOSに返却し、メモリリークを完全に防ぎます。
- エラーハンドラー (`On Error GoTo`) の常備
処理の途中でエラー(オブジェクトが見つからない等)が起きた場合でも、必ず `Close` と `Set … = Nothing` を通るように設計するのが、プロのエンジニアの流儀です。
—
4. ループ処理(大量ファイル処理)への応用
先ほどのコードをベースに、フォルダ内のファイルを次々と自動処理するマクロに応用してみましょう。
Sub BatchProcessFolder()
Dim folderPath As String
Dim fileName As String
Dim doc As Document
folderPath = “C:\MyFolder\BatchTarget\”
fileName = Dir(folderPath & “.cdr”)
‘ フォルダ内にCDRファイルが存在する間ループ
Do While fileName <> “”
‘ ドキュメントを開く
Set doc = Application.OpenDocument(folderPath & fileName)
‘ — 処理の本体 —
‘ 例として、すべてのページの背景色を変える処理など
‘ doc.Pages.Item(1).Background… (省略)
‘ ——————
‘ 処理が終わったら「変更を保存して」閉じる
doc.Close cdrSaveChanges
‘ ★超重要:ループの1回ごとに必ず変数を空にする!
Set doc = Nothing
‘ 次のファイルへ
fileName = Dir()
Loop
MsgBox “すべてのファイルのバッチ処理が完了しました!”, vbInformation
End Sub
ループの中で `Set doc = Nothing` を挟むことが、何百、何千というファイルをCorelDRAWに処理させてもメモリを1バイトも漏らさないための絶対的な秘訣です。
—
まとめ:ここをクリアすれば、もう怖くない!
今回は、CorelDRAW VBAにおける `Document.Close` のパラメータ制御と、メモリリークを防ぐための `Nothing` による変数解放の極意を解説しました。
1. `Close` 時は `cdrSaveChanges` や `cdrDontSaveChanges` を使って、ダイアログによる停止を完全になくす。
2. 処理の終了時には必ず `Set doc = Nothing` を実行し、メモリを解放する。
3. エラーが起きても確実に片付けられるよう、エラーハンドリングを意識する。
この基本原則さえ体に染み込ませておけば、どれほど巨大なプロジェクトや膨大な数のファイルが相手でも、CorelDRAWは軽快に安定して動き続けます。
基礎から本質を押さえたあなたなら、もうマクロの強制終了に怯える必要はありません。ぜひ明日の開発現場で試してみてくださいね。応援しています!
