【実務・中級編】【中級・上級】CreateShapeRangeFromExclusionなど高度なブール演算(結合・交差・抜粋)のVBA自動実行 – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAの深淵:ブール演算を制する者が自動化を制す

CorelDRAWの自動化において、多くのエンジニアが「パス操作」の泥沼に足を取られる。特に、複数の図形を複雑に合成するブール演算(溶接、トリム、交差)は、手動で行えば一瞬だが、コードで制御しようとすると途端に不安定になる箇所だ。

「なぜかエラーで止まる」「予期せぬ形状で結合される」——。これらはCorelDRAWのオブジェクトモデルに対する理解不足と、メモリ管理の甘さが原因である。今日は、現場で即戦力となる、堅牢かつ高速なブール演算処理の極意を伝授する。

1. なぜ「単純なメソッド」では不十分なのか

CorelDRAW VBAのブール演算には `Weld`、`Trim`、`Intersect` といったメソッドが存在する。しかし、これらを安易にループ内で呼び出すのは「初心者の罠」だ。

  • ライフサイクルの消失: ブール演算を実行すると、対象となったShapeオブジェクトは消滅し、新しいShapeが生成される。このとき、元の変数(Shapeオブジェクト)は「破棄されたメモリ」を指し続けるため、その直後にアクセスすると即座にランタイムエラーとなる。
  • レンダリングの負荷: 演算のたびに画面を更新させれば、処理速度は劇的に低下する。

これらを解決するためのキーワードは「`ShapeRange`の最適化」「演算対象の厳密な管理」である。

2. 堅牢なブール演算実装コード

以下は、選択した複数のオブジェクトを効率的にトリム(型抜き)し、結果を安全に取得するためのプロダクションコードである。

‘ ——————————————————————
‘ 堅牢なトリム処理関数:ターゲットからソースを切り抜く
‘ @param targetShp: 切り抜かれる側の親オブジェクト
‘ @param sourceShp: 切り抜く側の形状オブジェクト
‘ ——————————————————————
Public Function ExecuteRobustTrim(ByRef targetShp As Shape, ByRef sourceShp As Shape) As Shape
On Error GoTo ErrorHandler

‘ 演算前に整合性をチェック
If targetShp Is Nothing Or sourceShp Is Nothing Then Exit Function

‘ 処理の高速化:一時的に画面更新を停止
Optimization = True

‘ トリム実行:戻り値として新しいShapeを受け取る
‘ ※Trimメソッドは演算後のオブジェクトを返す
Dim resultShp As Shape
Set resultShp = targetShp.Trim(sourceShp, True, True)

‘ 処理終了後のクリーンアップ
Optimization = False
ActiveWindow.Refresh

Set ExecuteRobustTrim = resultShp
Exit Function

ErrorHandler:
Optimization = False
MsgBox “演算エラー: ” & Err.Description, vbCritical
Set ExecuteRobustTrim = Nothing
End Function

3. 開発現場で生き残るための「3つの鉄則」

① `Optimization` フラグの徹底

CorelDRAWのVBAでは、`Optimization = True` を宣言することで、オブジェクト生成ごとの再描画を抑止できる。数千個のオブジェクトを扱う場合、これだけで処理速度が10倍以上変わる。

② `ShapeRange` を活用したバッチ処理

個別に `Weld` を繰り返すのは非効率だ。複数のオブジェクトを一度に処理する場合は、`CreateShapeRangeFromObjects` で範囲を定義し、そのRangeに対して演算を行うのが定石だ。

‘ 複数オブジェクトを一括結合する例
Dim sr As ShapeRange
Set sr = ActivePage.Shapes.All ‘ または特定の範囲
Dim weldedShp As Shape
Set weldedShp = sr.Weld(sr.FirstShape)

③ トランザクションの意識

複雑な処理を行う際は、必ず `ActiveDocument.BeginCommandGroup` と `EndCommandGroup` で囲むこと。これにより、誤った演算結果になった場合でも「Ctrl+Z」の一回で処理全体をロールバックできるようになる。これはユーザーの信頼を得るための最低限のマナーだ。

4. プロフェッショナルへのアドバイス

ブール演算は「パスの複雑さ」に比例して計算コストが指数関数的に増大する。もし `Trim` や `Intersect` で処理が止まるなら、それはパスのノード数が多すぎる可能性がある。その場合は、一度 `Simplify` メソッドでパスを簡略化するか、演算前に `Curve` オブジェクトとしての妥当性をチェックするプロセスを挟むべきだ。

自動化の本質は、「機械に作業をさせる」ことではなく、「失敗する余地をコードから排除する」ことにある。

今回提供したパターンをベースに、自社のワークフローに合わせてカスタマイズしてほしい。君の書くコードが、誰かの残業を確実に減らすことを期待している。


追伸:もし特定の複雑なパス形状で演算が失敗する場合は、`Shape.Curve.Nodes.Count` を監視し、演算前に閾値を超えていないかチェックするロジックを追加せよ。それが伝説的なアーキテクトへの第一歩だ。

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