【入門編】【中級者向け】レイヤー構造の深部にあるネストされたグループを再帰的に走査し、特定オブジェクトの属性を一括置換するスクリプト – CorelDRAW VBA解析バイブル

スポンサーリンク

こんにちは!CorelDRAWの自動化の世界へようこそ。
マクロの記録ボタンを押して図形を描くだけの自動化から、一歩先へ進みたいあなたへ。

今回は、CorelDRAW VBAの真骨頂である「オブジェクト階層の再帰的走査(Recursive Traversal)」をテーマに、実務でそのまま使える骨太なコードをお届けします。

「グループの中にグループがあり、そのまた奥にある特定のシェイプの色や線幅を、一網打尽に書き換えたい……!」
そんな絶望的なネスト構造(入れ子構造)の迷宮に直面したとき、今回のテクニックがあなたの強力な武器になります。

ここをクリアすれば、CorelDRAW VBAの構造理解は一気に中級者から上級者へとジャンプアップします。一緒に本質をマスターしていきましょう!

なぜ、ネストされたグループの処理は難しいのか?

CorelDRAWのドキュメント構造は、階層(ツリー構造)になっています。

  • Page(ページ)
  • Layer(レイヤー)
  • Shape(通常のシェイプ:長方形や文字など)
  • Group(グループシェイプ)
  • Shape(グループ内のシェイプ)
  • Group(さらにその中にあるグループ!)
  • Shape(目的のシェイプ)

マクロの記録でコードを出力すると、`ActivePage.Layers.FindShape(…)` のような表層的なコードしか生成されません。これでは、グループの「さらにその中」にあるオブジェクトには一切手が届かないのです。

かといって、何重もの `For Each` ループを書くのは現実的ではありません。グループの階層が何階層あるかなんて、案件によってバラバラだからです。

ここで登場するのが、自分自身を呼び出す関数「再帰関数(Recursive Function)」というプログラミングの美しきアプローチです。

解決のアルゴリズム:再帰関数の考え方

再帰関数とは、簡単に言えば「自分と同じ仕事を、もっと小さな範囲で自分自身に再度やらせる」という仕組みです。

1. レイヤーやグループの中にあるオブジェクトを一つずつ見ていく。
2. もしそれが「ただのシェイプ」なら、目的の属性(色や線など)を変更する。
3. もしそれが「グループ(子要素を持つもの)」なら、そのグループの中に入り込み、ステップ1をもう一度やり直す(再帰呼び出し)。

これだけです。このアルゴリズムを実装すれば、無限の深さを持つグループ階層であっても、たった数行のロジックで綺麗に網羅できます。

実装コード:ネストされたグループを一網打尽にするVBAマクロ

それでは、実際にCorelDRAWのVBAエディタ(Alt + F11)に貼り付けて動かせる実用コードを公開します。

今回は、「アクティブページの全レイヤーを走査し、グループの深さに関係なく、全ての「長方形(Rectangle)」の塗りつぶし色を赤に一括置換する」というシナリオです。

Sub ReplaceNestedShapesExample()
Dim lr As Layer
Dim sh As Shape

‘ エラーハンドリングの基本:画面描画を停止してパフォーマンスを爆発的に上げる
EventsEnabled = False
ActiveDocument.BeginCommandGroup “ネスト一括置換処理”

On Error GoTo ErrorHandler

‘ 1. アクティブページの全レイヤーをループ
For Each lr In ActivePage.Layers
‘ レイヤーが非表示またはロックされている場合はスキップ
If Not lr.Visible Or lr.Editable = False Then GoTo NextLayer

‘ 2. レイヤー直下のシェイプ群に対して再帰的走査を開始
For Each sh In lr.Shapes
ProcessShapeRecursive sh
Next sh

NextLayer:
Next lr

‘ 処理終了のクリーンアップ
ActiveDocument.EndCommandGroup
EventsEnabled = True
MsgBox “すべてのネスト構造の走査と属性置換が完了しました!”, vbInformation
Exit Sub

ErrorHandler:
ActiveDocument.EndCommandGroup
EventsEnabled = True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub

『再帰関数の心臓部』:自分自身を呼び出して迷宮の奥底へ潜る
Private Sub ProcessShapeRecursive(ByVal sh As Shape)
‘ 【重要】CorelDRAWのグループは「Shapes」コレクションを持っています
If sh.Type = cdrGroupShape Then
Dim subSh As Shape
‘ グループである場合:中にある個々のシェイプを取り出して、再度この関数を呼ぶ(再帰)
For Each subSh In sh.Shapes
ProcessShapeRecursive subSh
For Next subSh

Else
‘ 【ここが処理の本体】グループではない「単体のシェイプ」に到達した場合の処理
‘ 例として、「長方形(Rectangle)」かつ「特定の条件を満たすもの」を対象にする

‘ シェイプが長方形かどうかを判定 (CorelDRAWのオブジェクト種別判定)
If sh.Type = cdrRectShape Then
‘ 属性を一括置換(例:塗りの色を鮮やかな赤に変更する)
sh.Fill.UniformColor.RGBAColor 255, 0, 0

‘ ついでに枠線を消す場合
‘ sh.Outline.Type = cdrNoOutline
End If

End If
End Sub

コードのポイントと知っておくべき「CorelDRAWの罠」

上記のコードには、CorelDRAW VBAを実務で使う上で絶対に知っておかなければならない「プロの知見」が詰まっています。

1. `EventsEnabled = False` による爆速化

大量のオブジェクトを走査する際、CorelDRAWはシェイプが変更されるたびに画面の再描画やUIの更新を走らせようとします。これがマクロを極端に重くする原因です。
処理の最初に `EventsEnabled = False`(画面更新の抑制)を置き、終了時に `True` に戻すことで、実行速度を数十倍〜数百倍に跳ね上げることができます。

2. `BeginCommandGroup` で「Ctrl + Z」を担保する

自動化スクリプトで怖いのは、「実行した後に、一括置換が意図しない結果になって戻せなくなった」という事態です。
`ActiveDocument.BeginCommandGroup` と `EndCommandGroup` で処理を挟むことにより、マクロ内の何千個の変更であっても、ユーザーの「Ctrl + Z(元に戻す)」の1回で綺麗に一発復元できるようになります。これはプロのツール開発では必須のマナーです。

3. オブジェクトのライフサイクルとエラーハンドリング

ネストされたグループの中には、まれに「結合曲線(Curve)」や「ブレンドグループ」「PowerClipのコンテナ」など、特殊なプロパティを持つものが混ざっています。
単純に `sh.Fill` などにアクセスすると、「このオブジェクトにはそのプロパティはありません」という実行時エラー(Runtime Error)でマクロがクラッシュします。
今回は触れていませんが、実務では `On Error Resume Next` を適切に挟むか、`sh.Type` で厳密に安全確認を行うガード節を入れることが、頑健な(壊れない)プログラムを作るコツです。

まとめ:ここをクリアすれば、もう怖くない!

今回は、ネストされたグループ構造を再帰関数で攻略し、奥深くのオブジェクトを一括置換するスクリプトを解説しました。

  • グループの奥底を攻めるには「再帰関数」を使う。
  • `sh.Type = cdrGroupShape` ならば、再び自分自身を呼び出す。
  • `EventsEnabled` や `CommandGroup` を使って、パフォーマンスと安全性を担保する。

このパターンを一度自分のものにしてしまえば、どれほど複雑に入り組んだデザインデータが持ち込まれても、VBAの力で一瞬にしてクレンジングや属性変更が行えるようになります。

「マクロの記録」の向こう側にある、自由でエキサイティングなCorelDRAW自動化の世界を、ぜひ楽しんでください!それでは、また次回の技術コラムでお会いしましょう。

タイトルとURLをコピーしました