CorelDRAW VBAを掌握する極限の知見:`UndoLock`による大規模ループ処理の爆速化と堅牢な履歴管理
開発プロジェクトの現場で、こんな悪夢を見たことはないだろうか。
「何千個ものオブジェクトを生成・変形するマクロを実行したら、CorelDRAWが突如として『応答なし』になり、数時間の作業が水の泡になった」
「数万点のエレメントを扱う図面データの整理ツールを作ったが、処理が進むにつれて露骨に動作が重くなり、最終的にメモリ不足で強制終了する」
犯人は明確だ。『Undo(元に戻す)バッファの肥大化』である。
CorelDRAW VBAにおいて、オブジェクトを1つ生成、移動、変形するたびに、エンジンは「ユーザーがCtrl+Zで戻せるようにするため」の履歴スナップショットを内部のUndoスタックへ黙々と積み上げる。数千回、数万回のループのなかでこれをやらせれば、VBAのランタイムではなく、CorelDRAWのUndoマネージャーが悲鳴を上げるのは当然の摂理なのだ。
今回は、このボトルネックを完全に粉砕し、実務レベルの大規模バッチ処理を圧倒的な速度と安定性で完遂させるための奥義――`ActiveDocument.UndoLock`の活用法を伝授する。
—
なぜデフォルトのループ処理は地獄と化すのか?
初心者が書くループ処理の典型例を見てみよう。
‘ 【アンチパターン】絶対にやってはいけないループ
Dim i As Long
For i = 1 to 10000
‘ ループの回数分だけオブジェクトが作られ、その都度Undo履歴が生成される
ActiveLayer.CreateRectangle 0, 0, 10, 10
Next i
このコードが実行される時、CorelDRAWの内部では以下の重労働が10,000回行われている。
1. 図形を描画する。
2. その状態をメモリ上のUndoスタックにシリアライズして記録する。
3. 画面の再描画(あるいはそのイベント検知)を行う。
結果、メモリは圧迫され、CPUはガベージコレクションや履歴管理にリソースを奪われ、処理速度は幾何級数的に低下していく。
救世主 `UndoLock` とトランザクション思想
この惨劇を防ぐために存在するプロパティが `UndoLock` だ。
これを `True` に設定すると、CorelDRAWは「この瞬間から、ユーザー(またはVBA)が何をやろうとも、Undo履歴を一切生成するな」という特権モードに入る。
履歴の記録という重い呪縛から解放されたCorelDRAWは、真のポテンシャルを発揮し、驚異的な速度でメモリ上でオブジェクトを咀嚼していく。
—
堅牢なプロダクションコードの設計思想
実務で使うマクロにおいて、「ただ速ければいい」というのはアマチュアの考えだ。プロのエンジニアが満たすべき要件は以下の3点である。
1. エラーハンドリングの徹底(死活管理)
`UndoLock = True` の状態で予期せぬエラー(ゼロ除算、オブジェクト参照切れ等)が発生し、そのままマクロが中断した場合、Undoロックがかかったままの危険なドキュメント状態が残る。これを防ぐため、必ず `On Error GoTo` によるクリーンアップ処理(`UndoLock = False` への復帰)を担保しなければならない。
2. 画面描画の凍結(`Optimization = True`)
`UndoLock` とセットで使うべきなのが、画面の再描画を止める `Application.Optimization = True` だ。DOMの操作ごとに画面を書き換える無駄を排除する。
3. トランザクションの明示
変更の開始から終了までを1つの不可分な操作(あるいは「元に戻すときは一網打尽に1つの動作とする」)として扱わせる。
—
【実装例】数千オブジェクトの生成を爆速化するプロフェッショナル・テンプレート
以下のコードは、実務の現場でそのまま組み込める、堅牢性とパフォーマンスを極限まで高めたプロダクションコードの模範解答だ。
Sub OptimizeMassCreationSample()
‘ —————————————————————–
定制開発スタンダード:大規模オブジェクト生成・処理テンプレート
‘ —————————————————————–
Dim startTime As Double
startTime = Timer
‘ 1. 環境退避と最適化フラグの有効化
Dim origOptimization As Boolean
origOptimization = Application.Optimization
Application.Optimization = True
‘ 画面の自動更新を完全停止(パフォーマンス劇的向上)
ActiveDocument.BeginCommandGroup “大規模バッチ処理”
‘ 2. UndoLockの適用(ここが今回の核心)
‘ ※このブロック内での操作は「Ctrl+Z」で一括して「実行前」に戻るようになる、
‘ あるいは履歴すら持たせない制御が可能になる。
ActiveDocument.UndoLock = True
‘ エラーハンドリングのフックを準備
On Error GoTo ErrorHandler
‘ —————————————————————–
‘ 【メイン処理】例:10,000個の矩形を高速生成するシミュレーション
‘ —————————————————————–
Dim i As Long
Dim sh As Shape
Dim x As Double, y As Double
For i = 1 to 10000
x = (i Mod 100) 15
y = (i \ 100) 15
‘ オブジェクトの生成
Set sh = ActiveLayer.CreateRectangle(x, y, x + 10, y + 10)
‘ 属性の付与(必要に応じて)
sh.Fill.UniformColor.RGBAColor 255, 0, 0
sh.Outline.SetNoOutline
Next i
‘ —————————————————————–
‘ 正常終了ルート
GoTo CleanUp
ErrorHandler:
‘ 異常発生時のログ出力・ユーザー通知
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “CorelDRAW VBA Error”
CleanUp:
‘ 3. 必ず実行するリソースの解放と状態復元
‘ 順番が極めて重要。UndoLockを解除してからCommandGroupを閉じる、または破棄する。
ActiveDocument.UndoLock = False
ActiveDocument.EndCommandGroup
Application.Optimization = origOptimization
‘ 画面の強制リフレッシュ
ActiveWindow.Refresh
MsgBox “処理が完了しました。実行時間: ” & Format(Timer – startTime, “0.00”) & ” 秒”, vbInformation, “完了”
End Sub
—
コードの急所:ここを間違えるとシステムが崩壊する
上記のコードで、ベテランエンジニアなら気づいたはずだ。「`UndoLock` と `BeginCommandGroup` の関係性」について。
`BeginCommandGroup` との併用における注意点
CorelDRAW VBAにおいて、`BeginCommandGroup` から `EndCommandGroup` は、ユーザーにとっての1つの「元に戻す(Undo)」単位を定義する。
`UndoLock = True` にしている間、このグループ内の操作はUndoバッファに積まれない。
もし、エラーハンドリングの `CleanUp` ラベルで `UndoLock = False` に戻し忘れたり、順序を誤って `EndCommandGroup` を呼び出したりすると、CorelDRAWの内部ステートが不整合を起こし、最悪の場合ファイルを保存して閉じようとした瞬間にクラッシュする。
だからこそ、上記のコードのように `On Error GoTo` を必ず経由する強制クリンナップ構造 が実務では絶対に不可欠なのだ。
—
データベース・外部ファイル連携時のベストプラクティス
この `UndoLock` テクニックが真価を発揮するのは、外部のCSV、Excel、あるいはSQLデータベースから数千件のレコードを読み込み、CorelDRAW上で名刺や図面、パッケージ展開図を自動生成するような「データ駆動型パブリッシング」の現場である。
外部DBとの連携時は、以下の設計を組み合わせることで、堅牢性がさらに一段階跳ね上がる。
1. チャンク(分割)処理の検討
数万件レベル(例: 50,000件以上)になると、いくら `UndoLock` をかけてもメモリの物理限界に達する場合がある。その場合は、10,000件ごとに一度処理を区切り、`UndoLock` を解除・再設定するか、適宜ガベージコレクションを意識したオブジェクト変数の解放(`Set sh = Nothing`)を行うこと。
2. 自動保存(Auto-Backup)の一時無効化
大規模ループの最中にCorelDRAWの標準「自動バックアップ」機能が走ると、ロック中のドキュメント構造と衝突してファイル破損の原因になる。大規模処理の前には `Application.AutoBackup = False` にし、処理後に元に戻す配慮があれば、あなたはもう「シニア・CorelDRAW・アーキテクト」と名乗って差し支えない。
—
総括
CorelDRAW VBAにおけるパフォーマンスチューニングは、小手先のテクニックの積み重ねではない。CorelDRAWという巨大なグラフィックスエンジンの「ライフサイクルとメモリ管理の仕組み」をどれだけ解剖できているかにかかっている。
今回解説した `ActiveDocument.UndoLock` は、大規模バッチ処理におけるマスト・ハブの知見だ。
「動けばいいコード」から「現場で絶対に止まらない、神速のプロダクションコード」へ。あなたのVBAスキルを、この瞬間から一段上のステージへと引き上げてほしい。
