CorelDRAW VBAを掌握する極限の知見:画面描画のちらつきを完全になくす!OptimizationとEventsEnabledを使ったマクロ高速化の極意
CorelDRAW VBAの開発において、数千、数万のオブジェクトを動的生成・変形するバッチ処理を組んだとき、画面が激しく点滅し、タスクマネージャーのCPU使用率が張り付いたまま処理が完了するのを絶望的な気持ちで見守った経験はないだろうか。
アマチュアの開発者は、画面の更新をそのままにループを回し、その遅さをマシンの性能のせいにする。しかし、プロフェッショナルなエンジニアは知っている。CorelDRAWのDOM(Document Object Model)は、デフォルトの状態では「1つのオブジェクトが生成・変更されるたびに、UIの再描画とイベントキューの処理を行っている」という致命的なオーバーヘッドを抱えていることを。
今回は、CorelDRAW VBAのパフォーマンスを極限まで引き上げ、描画のちらつき(フリッカー)を完全に消し去るための決定版イディオム、`Optimization` プロパティと `EventsEnabled` の真の制御手法を解説する。
—
1. なぜCorelDRAW VBAは遅くなるのか?(根本原因の解剖)
CorelDRAWは、DTP業界の厳密な描画要件を満たすため、ドキュメント内のわずかな変更であっても、直ちに画面の再描画(Invalidate & Redraw)と、各種ツール・ドッカーへのイベント通知を行っている。
VBAから以下のようなコードを実行したとする。
Dim i As Long
For i = 1 to 10000
ActiveLayer.CreateRectangle 0, 0, i, i
Next i
このコードが実行されるたび、CorelDRAWの内部エンジンは以下の処理を10,000回強制的に行っている。
1. ベクターデータのメモリ上へのアロケーション
2. ビューポート(画面)の再描画計算とピクセル単位のレンダリング
3. UIイベントのディスパッチ(選択状態の監視、ドッカーの更新など)
これでは、VBA自体のインタプリタとしての遅さに加え、GUIの描画スレッドがボトルネックとなり、処理時間は幾何級数的に悪化する。この無駄なペナルティを排除するための鍵が Optimization である。
—
2. Optimization と EventsEnabled の二大巨頭
CorelDRAWの `Application` オブジェクトには、この描画とイベントの嵐を鎮めるための強力なスイッチが用意されている。
`Optimization = True`
画面の自動更新を完全にフリーズさせる。このモードに入っている間、CorelDRAWは図形の計算(メモリ上の構築)のみを行い、画面へのピクセル出力を行わない。これにより、描画コストが完全にゼロになる。
`EventsEnabled = False`
ドキュメント内で発生する変更イベント(形状変更、選択変更など)のリスナーを一時的に無効化する。不要なイベントハンドラの暴走を防ぐだけでなく、内部メッセージキューの肥大化を防止する。
—
3. 【実践】極限まで最適化された堅牢な実装パターン
実務においてこれらのプロパティを扱う際、最も恐れなければならないのは「エラー発生時の状態異常(ハンギング・操作不能状態)」である。処理の途中でエラー落ちした場合、`Optimization = True` や `EventsEnabled = False` が解除されないままになり、CorelDRAWのUIが完全にフリーズする。
これを防ぐためには、VBAにおける `On Error Goto` を使った確実なクリーンアップパターン(RAIIイディオムのVBA的模倣)が必須となる。
以下のプロダクションコードをテンプレートとして活用してほしい。
‘ ==============================================================================
‘ 模範的な高速バッチ処理実装パターン
‘ ==============================================================================
Sub HighSpeedBatchProcessExample()
Dim startTime As Double
startTime = Timer
‘ 1. エラーハンドリングの準備
On Error GoTo ErrorHandler
‘ 2. 最適化の開始(描画停止 & イベント無効化)
With Application
.Optimization = True
.EventsEnabled = False
.StatusBar = “大量オブジェクトを生成中…”
End With
‘ 3. ドキュメントの参照を最適化(毎回 ActiveDocument を叩かない)
Dim doc As Document
Set doc = CreateDocument() ‘ 新規ドキュメント
Dim layer As Layer
Set layer = doc.ActiveLayer
‘ — ここから高負荷なループ処理 —
Dim i As Long
Dim sh As Shape
For i = 1 to 5000
‘ 座標計算や形状生成を高速実行
Set sh = layer.CreateRectangle(i 0.1, i 0.1, (i 0.1) + 10, (i 0.1) + 10)
sh.Fill.UniformColor.CmykAssign 0, 100, 100, 0
sh.Outline.SetNoOutline
Next i
‘ — ここまで —
ErrorHandler:
‘ 4. エラーの有無に関わらず、必ず環境を復元する(極めて重要)
With Application
.Optimization = False
.EventsEnabled = True
.StatusBar = “”
.Refresh ‘ 最後に一度だけ画面を強制再描画
End With
‘ エラー処理の伝播
If Err.Number <> 0 Then
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
Else
MsgBox “処理が完了しました。実行時間: ” & Format(Timer – startTime, “0.00秒”), vbInformation, “完了”
End If
End Sub
—
4. チーフアーキテクトが教える「さらなる極限チューニング」
上記のイディオムだけでも数倍から数十倍の速度向上が得られるが、さらにシニアレベルの最適化を行うための知見を共有する。
A. オブジェクト変数のスコープと明示的解放(メモリ管理)
VBAのガベージコレクションは非常に気まぐれである。特に大量の `Shape` や `Matrix` オブジェクトをループ内で生成・破棄する場合、メモリリークやメモリ断片化(フラグメンテーション)を引き起こしやすい。
ループ内で一時的に使用するオブジェクト変数には `Set var = Nothing` を明示的に呼び出し、参照カウントを即座にゼロに落とすこと。
B. `ActiveDocument` / `ActiveLayer` の乱用禁止
VBAで `ActiveDocument` や `ActiveLayer` などのグローバルプロパティを呼び出すたびに、CorelDRAWの内部でアクティブコンテキストのルックアップ(検索・解決)が発生する。
数千回のループ内でこれらを呼び出すと、それだけで膨大なオーバーヘッドになる。必ずローカル変数にキャッシュ(参照を保持)してからループを回すこと。
C. Undo(取り消し)グループの制御
CorelDRAWは、デフォルトでVBAの操作をUndoスタックに積もうとする。大量処理においてこれが有効だと、メモリを急速に食いつぶす原因になる。
ドキュメント全体の変更を1つのUndo単位にまとめたい場合は、以下のように `BeginCommandGroup` と `EndCommandGroup` で挟む。
doc.BeginCommandGroup “一括生成処理”
‘ — 処理 —
doc.EndCommandGroup
これにより、Undoスタックの肥大化を防ぎつつ、処理速度を保つことができる。
—
総括
画面描画のちらつきをなくし、マクロを爆速化することは、単に「見た目がスマートになる」ということ以上の意味を持つ。それは、ユーザーの作業ストレスをゼロにし、CorelDRAWという重厚なDTPエンジンをVBAから完全に手なずけているというエンジニアリングの証明に他ならない。
今回紹介した `Optimization = True` と `EventsEnabled = False`、そして確実なクリーンアップ構造をあなたのコードベースに組み込み、真のパフォーマンスを手に入れてほしい。
