こんにちは!CorelDRAW VBAの世界へようこそ。
マクロの記録ボタンを押して自動生成されたコードを眺めて、「お、動いた!」と感動したのも束の間、いざ複雑なデザインデータを相手にマクロを走らせたら……「あれ、終わらない? 固まった?」と冷や汗をかいた経験はありませんか?
特に、何千ものオブジェクトが眠る巨大なドキュメントを総なめにする時、何も考えずにすべてのレイヤーを巡回していると、VBAは無駄な計算でパンクしてしまいます。
今回は、現場のプロが実践している「非表示レイヤーやロックレイヤーをスマートにスルーし、爆速でオブジェクトを処理するフィルタリングループの設計手法」を伝授します。ここをクリアすれば、あなたのマクロのパフォーマンスは見違えるほど洗練されますよ。さあ、一緒に本物の自動化エンジニアへの階段を登りましょう!
—
なぜ「全部のオブジェクトを触る」と遅くなるのか?
CorelDRAWのドキュメント構造を思い浮かべてみてください。
ドキュメントは「ページ」を持ち、ページは「レイヤー」を持ち、レイヤーの中に「シェイプ(オブジェクト)」が並んでいます。
[Document]
┗ [Page]
┣ [Layer 1 (表示・編集可)] ── [Shape A], [Shape B]
┣ [Layer 2 (非表示)] ── [Shape C], [Shape D] ← ここも触っちゃダメ!
┗ [Layer 3 (ロック中)] ── [Shape E], [Shape F] ← ここも触っちゃダメ!
もしあなたが「すべての文字を赤色にする」という処理を書きたいとします。
この時、「見えていないレイヤー(非表示)」や「触ってはいけないレイヤー(ロック)」の中にあるオブジェクトまで律儀に処理しに行っていませんか?
- 非表示のオブジェクトの色を変えても、ユーザーには見えません。
- ロックされたオブジェクトを無理やり操作しようとすると、エラーの原因になったり無駄なCPU時間を消費します。
つまり、「処理しなくていいものを、いかに秒速で除外するか」が高速化の極意なのです。
—
陥りがちな罠:全探索ループのアンチパターン
まずは、初心者がやりがちな「重いコード」を見てみましょう。
‘ 【やってはいけないアンチパターン】
Dim s As Shape
For Each s in ActivePage.Shapes
‘ 色を赤に変えるだけの処理なのに、非表示やロックも全無視で突撃!
s.Fill.UniformColor.CmykAssign 0, 100, 100, 0
Next s
このコードの何がいけないか分かりますか?
`ActivePage.Shapes` を使うと、レイヤーの壁を無視してページ上のすべてのシェイプを平面的に拾い集めてしまいます。これでは「どのレイヤーに属していて、表示されているか」の判定コストが高くなり、大規模なデータではフリーズの原因になります。
—
解決策:レイヤー単位で「門番」を置く高速フィルタリング
CorelDRAW VBAで高速かつ安全に処理を行うための鉄則、それは「レイヤーのプロパティ(Visible / Locked)を最初にチェックし、条件に合わないレイヤーは丸ごとスキップする」ことです。
レイヤー自体が非表示、またはロックされている場合、その中にある数千個のオブジェクトを個別に調べる必要すらありません。レイヤー単位で門前払い(スキップ)する方が、圧倒的に処理が速いのです。
実用コード:爆速フィルタリング・テンプレート
以下のコードは、現在のページにある全レイヤーを走査し、「表示されていて、かつ、ロックされていないレイヤー」に属するオブジェクトだけを安全に処理する、現場即戦力のテンプレートです。
Sub FastProcessVisibleLayers()
Dim lr As Layer
Dim sh As Shape
‘ 処理開始のパフォーマンス最適化(画面描画を停止して爆速化)
ActiveDocument.BeginCommandGroup
EventsEnabled = False
On Error GoTo ErrorHandler
‘ 1. ページ内の全レイヤーをループ
For Each lr In ActivePage.Layers
‘ — 【極意】ここで不要なレイヤーを秒速で弾く! —
‘ レイヤーが非表示(Visible = False)またはロック(Locked = True)なら次へスキップ
If lr.Visible = False Or lr.Locked = True Then
GoTo ContinueLoop
End If
‘ 2. 許可された安全なレイヤー内のオブジェクトだけをループ
For Each sh In lr.Shapes
‘ — 【二重の安全確認】シェイプ自体の非表示・ガイド等も除外 —
If Not sh.Displayable Then GoTo NextShape
‘ ==========================================
‘ ここに実際の処理を記述します
‘ 例:テキストシェイプだった場合の色変更など
‘ ==========================================
If sh.Type = cdrTextShape Then
‘ 例として塗りつぶしをシアンに変更
sh.Fill.UniformColor.CmykAssign 100, 0, 0, 0
End If
NextShape:
Next sh
ContinueLoop:
Next lr
‘ 処理終了のクリーンアップ
EventsEnabled = True
ActiveDocument.EndCommandGroup
MsgBox “処理が完了しました!”, vbInformation
Exit Sub
ErrorHandler:
‘ エラー発生時も必ず描画フラグを戻す(これ超重要です!)
EventsEnabled = True
ActiveDocument.EndCommandGroup
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
—
コードのポイント・エンジニアの知見
1. `GoTo` によるスマートなスキップ
VBAでは `Continue For` のような構文が使えないため、`GoTo ContinueLoop` を使って条件に合致しないレイヤーを華麗にスルーします。これが最もシンプルでパフォーマンスが良い方法です。
2. `EventsEnabled = False` による爆速化
VBAがオブジェクトを1つ操作するたびに、CorelDRAWは画面の再描画やイベントの処理を行おうとします。これを一時的にオフ(`False`)にすることで、処理スピードが何倍にも跳ね上がります。
3. エラーハンドリングの徹底
パフォーマンス化のために描画やイベントを止めた時、途中でエラーが起きるとCorelDRAWが固まったままになってしまいます。必ず `On Error GoTo` を用意し、異常終了時でも環境を元に戻す(`EventsEnabled = True`)のがプロの作法です。
—
ここをクリアすれば、CorelDRAW VBAの基本はバッチリ!
今回解説した「オブジェクトモデルの階層を理解し、不要なプロパティを持つコンテナ(レイヤー)を早期にフィルタリングする」という考え方は、CorelDRAW VBAに限らず、すべてのハイエンドなデスクトップアプリの自動化に通じる普遍的なスキルです。
「ただ動くコード」から「大規模データでも軽快に動くプロ仕様のコード」へ。
このテクニックを手に入れたあなたなら、どんなに膨大なページ数のデザイン案件が来ても、マクロ一撃でスマートに片付けられるはずです。
明日からのデザイン自動化ライフを、ぜひ楽しんでくださいね!
