【実務・中級編】【中級者向け】複雑にネストされたグループ構造とシンボルインスタンスを再帰関数(Recursive Function)で完全に分解し、すべてのシェイプをフラットなレイヤー階層へ再構築する処理 – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAの深淵:再帰アルゴリズムで「グループの呪縛」を解き放つ

CorelDRAWで外部データとの連携を試みた際、最も開発者を絶望させるのは「複雑にネストされたグループ構造」です。サードパーティ製のCAMソフトやWeb向けSVGコンバータ、あるいは独自のデータベース連携処理において、階層が深いデータはエラーの温床となります。

「グループを解除してフラットにする」という単純な操作を、なぜ手動ではなくVBAで書くのか。それは、「構造を破壊せず、かつ階層を消滅させる」という矛盾した要件を、機械的な精度で実行するためです。

今日は、業務自動化エンジニアの現場で培った「安全かつ堅牢なフラット化アルゴリズム」を伝授します。

—

1. なぜ「単純なループ」では破綻するのか

初心者が陥りがちなミスは、`Group.Ungroup` を安易に繰り返すことです。しかし、これには致命的な欠陥があります。

  • インデックスの喪失: グループを解除した瞬間、元のオブジェクトのインデックスが変わるため、ループ処理が迷子になります。
  • スタックオーバーフロー: シンボルインスタンスや極端に深いネストは、再帰の終了条件を誤るとメモリを食いつぶします。
  • レイヤーの断絶: グループ内に異なるレイヤーに跨がるオブジェクトが存在する場合、安易なフラット化は階層構造を破壊し、本来のレイヤー情報を消失させます。

我々が目指すべきは、「階層を辿り、フラットなレイヤー構造へ『転送』する」という設計思想です。

—

2. 堅牢な再帰フラット化エンジンの実装

以下のコードは、選択されたすべてのオブジェクトを走査し、グループやシンボルを分解して、指定したターゲットレイヤーへフラットにコピーするプロダクションコードです。

‘ CorelDRAW VBA: Recursive Shape Flattener
‘ 複雑な構造を解析し、単一レイヤーへフラットに再構築する

Public Sub FlattenShapesToLayer()
Dim doc As Document
Dim targetLayer As Layer

Set doc = ActiveDocument
‘ 念のため実行前にUndoグループを作成
doc.BeginCommandGroup “Flatten Hierarchy”

‘ 出力先のレイヤーを指定(存在しなければ作成)
Set targetLayer = doc.ActivePage.CreateLayer(“Flattened_Data”)

‘ 選択オブジェクトを再帰的に処理
Dim s As Shape
For Each s In doc.SelectionRange
ProcessShape s, targetLayer
Next s

doc.EndCommandGroup
End Sub

‘ 再帰関数: シェイプを判定し、グループなら分解、そうでなければコピー
Private Sub ProcessShape(sh As Shape, destLayer As Layer)
‘ シンボルインスタンスの分解(必要に応じて)
If sh.Type = cdrSymbolShape Then
sh.Symbol.Detach
End If

‘ グループかどうかを判定
If sh.Type = cdrGroupShape Then
Dim subSh As Shape
‘ グループ内の全オブジェクトに対して再帰呼び出し
For Each subSh In sh.Shapes
ProcessShape subSh, destLayer
Next subSh
Else
‘ グループ以外(カーブ、テキスト、ビットマップ等)はターゲットへコピー
‘ CloneではなくCopyで独立した実体を作成するのが鉄則
sh.Copy
destLayer.Paste
End If
End Sub

—

3. 実務で生き残るための設計上の注意点

このコードを現場で運用する際、以下の3点に注意してください。

① 座標系の維持(グローバル座標への変換)

上記コードは簡略化のため`Copy & Paste`を使用していますが、厳密な座標保持が必要な場合は `sh.PositionX`, `sh.PositionY` を直接参照し、ルートレベルでの配置を計算する必要があります。グループ内の相対座標は、親の座標を積算することで求められます。

② シンボルインスタンスの「罠」

`cdrSymbolShape` は単なるグループではありません。マスター定義へのリンクです。もし元のシンボル構造を維持したままフラット化したい場合は、`Detach` せずにプロパティだけを抽出するロジックが必要になります。現場の要件に応じて `Detach` するか否かを選択してください。

③ データベース連携時のID管理

この処理でフラット化した後、外部アプリへ渡す際には「どのオブジェクトが元々どのグループに属していたか」というメタデータが消滅します。
もし必要であれば、フラット化する前に `sh.ObjectData` にGUIDを付与し、フラット化した後のオブジェクトにもそのIDを継承させる「メタデータ追跡アルゴリズム」を組み込むのが、真にプロフェッショナルな実装です。

—

まとめ:自動化の先にあるもの

再帰関数を使いこなすことは、CorelDRAWの内部構造(ドキュメントモデル)を支配することと同義です。今回紹介した「分解して転送する」というアプローチは、単なるフラット化に留まらず、データのクレンジングやフォーマット変換の強力な基盤となります。

「動けばいい」コードは誰にでも書けますが、「将来の仕様変更やデータ構造の破綻を予見して書く」のがアーキテクトの仕事です。ぜひ、この再帰ロジックをあなたの武器に加えてください。

次回の記事では、このフラット化されたデータをJSON形式でエクスポートし、外部のPython環境と連携するパイプラインについて解説する予定です。お楽しみに。

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