CorelDRAW VBAの深淵:多重ネストを「再帰」で征服し、データ構造を完全フラット化せよ
CorelDRAWで複雑なレイアウトを作成し、いざレーザー加工機やカッタープロッターへデータを飛ばそうとした瞬間、「グループ構造が深すぎてデータが読めない」「パスの属性が引き継がれず加工エラーになる」といった壁にぶつかったことはないだろうか。
多くの初学者は、`Shape.Ungroup` を安直にループさせるが、これは地雷だ。グループの中にグループがあり、その中にまたグループがある……という「ネストの迷宮」に対して、単一ループのアプローチは破綻する。
今日は、業務自動化のプロとして、「再帰関数(Recursive)」を用いて、いかなる深さのグループ構造も一撃でフラット化し、加工機が最も好む「生のパス」に変換する設計術を授ける。
—
なぜ「再帰」こそが正解なのか
非効率なエンジニアは、`ActiveLayer.Shapes` を全探索して `Ungroup` を繰り返す。しかし、グループを解除するとコレクションのインデックスが変化し、予期せぬエラー(実行時エラー 91など)を誘発する。
再帰処理の美学は、以下のルールにある。
1. 自己相似性: 処理対象が「グループ」なら、その中身をさらに探索する。
2. 基底条件: 対象が「パス(曲線や矩形)」なら、それをフラットな親(レイヤー)へ移動させ、処理を完了する。
このアプローチにより、コードの堅牢性は劇的に向上し、メンテナンス性が高まる。
—
実装:完全フラット化エンジン
以下のコードは、選択したオブジェクト配下の全ネストを走査し、全てのパスをカレントレイヤーの直下に吸い上げる設計だ。これをベースにすれば、レーザー加工機のパス最適化も容易になる。
‘ ———————————————————
‘ 機能: 多重ネストを完全解除し、すべてのパスをフラット化する
‘ ———————————————————
Public Sub FlattenNestedGroups()
Dim sr As ShapeRange
Set sr = ActiveSelectionRange
If sr.Count = 0 Then
MsgBox “対象オブジェクトを選択してください。”, vbExclamation
Exit Sub
End If
‘ 再帰処理を開始
ProcessShapes sr
MsgBox “フラット化完了。構造が最適化されました。”, vbInformation
End Sub
Private Sub ProcessShapes(shapes As ShapeRange)
Dim s As Shape
Dim i As Long
‘ 後ろから処理することで、Ungroupによるインデックスのズレを回避する(鉄則)
For i = shapes.Count To 1 Step -1
Set s = shapes(i)
If s.Type = cdrGroupShape Then
‘ グループなら中身を再帰的に掘り下げる
ProcessShapes s.Ungroup()
Else
‘ パスオブジェクトなら、現在のレイヤーに配置し直す(必要に応じて処理)
‘ ※グループの制約から解放するだけで十分な場合が多い
s.OrderToFront
End If
Next i
End Sub
—
開発の現場で死なないための「3つの鉄則」
現場でこのコードを運用する際、以下の3点に注意を払うことが、真のプロフェッショナルだ。
1. インデックスの逆順走査(Reverse Traversal)
コード内の `For i = shapes.Count To 1 Step -1` は、単なる趣味ではない。オブジェクトを削除・分解するとコレクションの要素数が変化する。順方向にループすると、必ずインデックス範囲外エラーに突き当たる。「破壊的処理は常に後ろから」が鉄則だ。
2. レイヤー・データベースとの同期
加工機へデータを渡す際は、フラット化するだけでなく、`s.Layer` を明示的に管理せよ。もしデータベース連携やファイル出力(DXF/AIエクスポート)を行うなら、フラット化した直後に特定のレイヤー名に全移動させることで、後続のプログラムが「何がパスデータなのか」を迷わなくなる。
3. パフォーマンスの重み
数万パスを超えるような巨大なデータでは、`Optimization = True` をヘッダーに記述せよ。再帰処理はメモリを消費する。画面の再描画を止めることで、処理速度は劇的に変わる。
‘ 処理冒頭に追記
Optimization = True
‘ 処理終了後に必ず戻す
Optimization = False
—
次のステップ:君がエンジニアとして成長するために
この「フラット化エンジン」を作れるようになった君なら、次は「パスの単純化(ノード削減)」や「カットラインと刻印ラインの自動レイヤー振り分け」を組み合わせることで、オペレーターの工数をゼロに近づけることができるはずだ。
自動化の本質は、ただ楽をすることではない。「人間が介在するとミスが起きる複雑な構造を、アルゴリズムの力で再現性のある単純な形に変換すること」だ。
このコードを叩き台に、君自身の現場に最適化された最強のスクリプトを構築してほしい。質問があれば、いつでもこの「深淵」を覗きに来るといい。
