CorelDRAW VBAを掌握する極限の知見:大量オブジェクト処理のパフォーマンスを極限まで引き上げる描画凍結の鉄則
CorelDRAW VBAによる自動化開発において、数千、数万に及ぶベクターオブジェクトを一括生成・変形する処理を実装した際、開発者が最初に直面する壁が「圧倒的な処理の遅延」と「画面の激しいチラつき(フリッカー)」である。
デフォルトの状態のCorelDRAWは、VBAから発行される1つひとつのメソッド呼び出し(`CreateRectangle`や`Rotate`など)に対し、律儀にドキュメントの再描画を行い、UIの変更イベントを拾い上げ、アンドゥ(Undo)スタックの構築を試みる。このオーバーヘッドこそが、マクロの実行速度を数十分の壱へと劣化させる元凶だ。
今回は、CorelDRAWの内部レンダリングエンジンとイベントループを完全に掌握し、処理速度を限界までブーストするための2大プロパティ、`Optimization` と `EventsEnabled` の正しい実装アプローチを、実戦投入可能な定型コードとともに解説する。
—
1. 描画遅延の元凶:なぜCorelDRAW VBAは遅いのか
CorelDRAWのオブジェクトモデルは強力だが、COM(Component Object Model)経由での操作は、ホストアプリケーションとの間でコンテキストの切り替えが発生する。
特に以下の3つの要素がパフォーマンスを深刻にスポイルする。
1. 画面のリアルタイム再描画(Redraw): 1オブジェクト生成されるごとにビューポートが再計算され、画面が更新される。
2. イベントのディスパッチ(EventsEnabled): 選択状態の変化やドキュメントの変更など、GUI側への通知イベントがその都度処理される。
3. アンドゥ情報の逐次生成: すべての操作がUndoステップとしてメモリに積まれる。
これらを制御下におくことなく数万個のパスを処理させれば、CPU使用率は跳ね上がり、最悪の場合は「応答なし」の状態に陥る。プロフェッショナルな自動化エンジニアであれば、コードの実行前に環境を「沈黙」させ、処理完了後に「復元」するライフサイクル管理を徹底しなければならない。
—
2. 制御の要:`Optimization` と `EventsEnabled` の真実
パフォーマンスチューニングにおいて、以下の2つのスイッチを適切に操作する。
- `Application.Optimization = True`
画面の再描画を完全に停止し、内部メモリ上だけでオブジェクトの構築・編集を行わせる。これにより、GDI/DirectX層の描画コストが完全に消滅する。
- `Application.EventsEnabled = False`
CorelDRAW内部のイベントハンドラを無効化する。ユーザー操作による割り込みや、無駄なイベントの伝播を防ぐことで、CPUリソースを純粋な演算処理に集中させる。
【極上の注意点】例外処理(Error Handling)の義務化
これらの最適化フラグを `True` / `False` に切り替えた状態でコードが実行時エラー(ランタイムエラー)を起こし、そのままルーチンが中断された場合、CorelDRAWの画面が描画停止・イベント無効状態のまま凍結する。最悪の場合、アプリケーションの強制終了を余儀なくされ、未保存のデータが失われる。
したがって、後述する 「確実な原状復帰(Finally相当の処理)」 を実装しないコードは、現場においては「欠陥品」とみなされる。
—
3. 実装パターン:極限まで最適化された堅牢なテンプレートコード
以下に、実務の現場でそのまま使用できる、エラーセーフな一括処理の定型コードを示す。
Option Explicit
Sub BatchProcessOptimizationTemplate()
‘ —————————————————-
‘ 厳格なエラーハンドリングと描画停止による高速化テンプレート
‘ —————————————————-
‘ 最適化前の状態を保持する変数
Dim originalOptimization As Boolean
Dim originalEvents As Boolean
Dim originalScreenUpdating As Boolean
‘ 処理対象の変数定義
Dim doc As Document
Dim layer As Layer
Dim i As Long
‘ エラーハンドラーのラベル
On Error GoTo ErrorHandler
‘ 1. 現在のアプリケーション状態を退避
originalOptimization = Application.Optimization
originalEvents = Application.EventsEnabled
originalScreenUpdating = Application.ScreenUpdating
‘ 2. 【最重要】パフォーマンス最適化の適用
Application.Optimization = True
Application.EventsEnabled = False
Application.ScreenUpdating = False
‘ アクティブドキュメントの取得(存在チェック付き)
If ActiveDocument Is Nothing Then
MsgBox “処理対象のドキュメントが開かれていません。”, vbCritical, “システムエラー”
GoTo Finally
End If
Set doc = ActiveDocument
Set layer = doc.ActiveLayer
‘ ドキュメントの単位を明示的に設定(演算ブレを防ぐため)
doc.Unit = cdrMillimeter
‘ —————————————————-
‘ 3. 高負荷な一括処理ループ(例:5000個の矩形を生成)
‘ —————————————————-
Dim sh As Shape
For i = 1 to 5000
‘ 画面更新が止まっているため、この生成処理は爆速でメモリ上に行われる
Set sh = layer.CreateRectangle(i 0.5, i 0.5, (i 0.5) + 10, (i 0.5) + 10)
‘ 必要に応じたプロパティ変更(これも一括処理の対象)
sh.Outline.Color.CMYKAssign 0, 100, 100, 0
Next i
‘ —————————————————-
‘ 4. 処理完了後の明示的なクリーンアップ
‘ —————————————————-
Finally:
‘ 状態を必ず元の設定に戻す(逆順が望ましい)
Application.Optimization = originalOptimization
Application.EventsEnabled = originalEvents
Application.ScreenUpdating = originalScreenUpdating
‘ 強制的に画面を再描画させ、変更を反映
doc.CorelScript.Redraw
Application.Refresh
MsgBox “一括処理が正常に完了しました。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
‘ 予期せぬエラーが発生した場合でも、必ずUIの凍結を解除する
MsgBox “実行時エラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
Resume Finally
End Sub
—
4. チーフアーキテクトからの実践的アドバイス
上記の基本構造に加え、大規模システムや複雑なデータ連携を行うVBA開発においては、以下の知見を押さえておくべきである。
オブジェクト変数の即時解放(`Set … = Nothing`)
数万回のループ内で図形オブジェクト(`Shape` や `ShapeRange`)を生成・参照し続けると、VBAのガベージコレクションが追いつかず、メモリリークやメモリ不足エラーを引き起こすことがある。
ループ内で変数を使い回す場合は、適切に `Set sh = Nothing` を挟み、COMオブジェクトへの参照カウントを意図的に解放する配慮が求められる。
レガシー環境・外部システム連携時の注意
COMオートメーションを通じて外部(C#製アドインやWindowsスクリプト等)からCorelDRAWを制御する場合、`Optimization = True` の最中に外部プロセスからクエリを投げると、デッドロックやタイムアウトを引き起こすリスクがある。
スタンドアロンのVBAマクロ完結であれば問題ないが、他システムとの連携基盤の一部として組み込む場合は、イベント制御のスコープを最小限に絞る設計思想が必要だ。
総括
`Optimization = True` と `EventsEnabled = False` の組み合わせは、CorelDRAW VBAのパフォーマンスを限界突破させるための強力な武器である。しかし、それは同時に「安全装置を外して疾走する」行為に他ならない。
必ずエラーハンドリング(`On Error GoTo`)と組み合わせ、いかなる例外が起きようとも確実に環境を復元させる防衛的プログラミングを徹底すること。この鉄則を遵守する者だけが、CorelDRAWのポテンシャルを100%引き出した、極限の自動化システムを構築することができる。
