【テクニカル・上級編】【初心者向け】アクティブページ内の全パスオブジェクトの頂点数(ノード数)をカウントしてレポートする監査ツール – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAを掌握する極限の知見:アクティブページ頂点数監査ツールの実装

レガシーシステムの保守、そして膨大なベクターデータを取り扱う現場において、最も恐れられるボトルネックの正体を知っているか。それは「過剰なノード数(頂点数)」を持つパスオブジェクトである。

DTPの現場や大規模なサイングラフィックス製作において、CADから出力された図面や、Web用SVGを無理やりインポートした複雑怪奇なパスは、RIP処理のフリーズ、PDF書き出し時のメモリバースト、そして最悪の場合、CorelDRAWそのものの強制終了を引き起こす。

今回は、CorelDRAW VBAのオブジェクトモデルの深淵に踏り込み、アクティブページ内の全パスオブジェクトを走査し、その頂点数をミリ秒単位のオーバーヘッドで計測・レポートする「パス頂点数監査ツール」の全貌を公開する。

リファレンスをなぞるだけのコードではない。メモリのライフサイクル、COMオブジェクトの解放、そして実務で耐えうる堅牢性を備えたプロダクションコードを提示する。

1. CorelDRAW VBAにおけるパフォーマンスの罠とオブジェクトライフサイクル

初心者が陥る最大の罠は、「ActivePage.Shapes」コレクションを安易にループさせ、その中で暗黙のCOMオブジェクト生成と解放漏れを起こすことだ。

CorelDRAWのVBA環境(VBA 7.1以降であっても)は、背後でCOM(Component Object Model)の参照カウンタが稼働している。特に `Shape` や `SubPath`、`Node` といったオブジェクトを巡回する際、適切な変数管理を行わないと、メモリリークだけでなく、CorelDRAW特有の「Automation Error」や動作不安定を引き起こす。

シニアエンジニアが守るべき鉄則は以下の3点だ。
1. オブジェクト変数の明示的な型指定(`Dim s As Shape` の徹底)。
2. ループ脱出時の参照の即座の破棄(必要に応じた `Set s = Nothing`)。
3. グループ化(Group)やブレンド、コンテナ構造に対する再帰的(Recursive)アプローチ

今回の監査ツールでは、単一のシェイプだけでなく、グループ化されたネストの内部まで潜り込み、正確なノード数を算出しなければならない。

2. 実装コード:パス頂点数監査ツール(Production Ready)

以下のコードをCorelDRAWのVBAエディタ(Alt + F11)の標準モジュールに貼り付けて実行してほしい。イミディエイトウィンドウ(Ctrl + G)に、ページ内の全パスの頂点数が構造化されて出力される。

Option Explicit

‘ =================================================================================
‘ ツール名: PathNodeAuditor for CorelDRAW
概要: アクティブページ内の全パスオブジェクト(グループ内包含む)を再帰的に走査し、
‘ 頂点数(ノード数)を計測してイミディエイトウィンドウにレポートする。
‘ 著者: チーフアーキテクト
‘ =================================================================================
Public Sub AuditActivePageNodes()
‘ 実行時間の計測開始(パフォーマンス監視)
Dim startTime As Single
startTime = Timer

Dim targetPage As Page
Set targetPage = ActivePage

If targetPage Is Nothing Then
MsgBox “アクティブなページが存在しません。”, vbCritical, “監査ツールエラー”
Exit Sub
End If

Debug.Print “========================================================”
Debug.Print ” パス頂点数監査レポート – 対象ページ: ” & targetPage.Index
Debug.Print ” 実行日時: ” & Now
Debug.Print “========================================================”

Dim totalShapes As Long
Dim totalNodes As Long
totalShapes = 0
totalNodes = 0

‘ 再帰処理によるシェイプ走査の実行
ProcessShapes targetPage.Shapes, totalShapes, totalNodes

Debug.Print “——————————————————–”
Debug.Print ” 監査完了”
Debug.Print ” 総スキャンパス数 : ” & totalShapes & ” シェイプ”
Debug.Print ” 総頂点数(ノード): ” & totalNodes & ” ノード”
Debug.Print ” 処理時間 : ” & Format(Timer – startTime, “0.000”) & ” 秒”
Debug.Print “========================================================”

‘ メモリ解放
Set targetPage = Nothing
End Sub

‘ =================================================================================
‘ 内部関数: 再帰的シェイプ走査エンジン
‘ 概要: グループやコンテナの中にネストされたシェイプを漏れなくキャッチする
‘ =================================================================================
Private Sub ProcessShapes(ByVal shapesCol As Shapes, ByRef shapeCount As Long, ByRef nodeCount As Long)
Dim sh As Shape
Dim i As Long

‘ コレクションの逆順ループ(削除等の動的操作を行う場合の安全策だが、参照のみでも安全性を考慮)
For i = shapesCol.Count To 1 Step -1
Set sh = shapesCol(i)

‘ プレースホルダーやガイドラインをスキップ
If Not sh.$.\\Type = cdrGuidelineShape Then

‘ グループ化されている場合は再帰呼び出し
If sh.Type = cdrGroupShape Then
ProcessShapes sh.Shapes, shapeCount, nodeCount

‘ パスを持つオブジェクト(Curve, Rectangle, Ellipse等)の判定
‘ ※CorelDRAWでは多くのベクター形状がCurveに変換可能、またはCurveオブジェクトとして直接保持される
ElseIf sh.Type = cdrCurveShape Or sh.Type = cdrRectangleShape Or sh.Type = cdrEllipseShape Or sh.Type = cdrPolygonShape Then

Dim currentNodeCount As Long
currentNodeCount = GetShapeNodeCount(sh)

If currentNodeCount > 0 Then
shapeCount = shapeCount + 1
nodeCount = nodeCount + currentNodeCount

‘ 1000ノードを超える「爆弾オブジェクト」は警告を出力
Dim warningStr As String
If currentNodeCount > 1000 Then
warningStr = ” [⚠️ 要注意: 高負荷パス]”
Else
warningStr = “”
End If

Debug.Print ” [Path] ID: ” & sh.StaticID & ” | タイプ: ” & GetShapeTypeName(sh.Type) & ” | ノード数: ” & currentNodeCount & warningStr
End If

End If

End If

Set sh = Nothing
Next i
End Sub

‘ =================================================================================
‘ 内部関数: 個別シェイプのノード数算出
‘ =================================================================================
Private Function GetShapeNodeCount(ByVal sh As Shape) As Long
Dim nTotal As Long
nTotal = 0

On Error GoTo ErrorHandler

‘ Curveオブジェクトにアクセスしてサブパスとセグメントを走査
Dim crv As Curve
Set crv = sh.Curve

If Not crv Is Nothing Then
Dim sp As SubPath
For Each sp In crv.SubPaths
‘ 各サブパスのノード(Nodes)数を加算
nTotal = nTotal + sp.Nodes.Count
Next sp
End If

ErrorHandler:
‘ エラー(パスに変換できないシェイプ等)は無視して0を返す
GetShapeNodeCount = nTotal
Set crv = Nothing
End Function

‘ =================================================================================
‘ 補助関数: シェイプタイプの文字列変換
‘ =================================================================================
Private Function GetShapeTypeName(ByVal sType As Long) As String
Select Case sType
Case cdrCurveShape: GetShapeTypeName = “Curve”
Case cdrRectangleShape: GetShapeTypeName = “Rectangle”
Case cdrEllipseShape: GetShapeTypeName = “Ellipse”
Case cdrPolygonShape: GetShapeTypeName = “Polygon”
Case cdrGroupShape: GetShapeTypeName = “Group”
Case Else: GetShapeTypeName = “Other (” & sType & “)”
End Select
End Function

3. コードのアーキテクチャ解説:なぜこの書き方なのか

再帰的走査(Recursive Traversal)の優位性

CorelDRAWのドキュメント構造はツリー構造をなしている。ユーザーがグループ化したオブジェクトの内部は、親シェイプの `Shapes` プロパティの配下に隠されている。平坦な(Flatな) `ActivePage.Shapes` のループだけでは、グループ内のパスを完全に見落とす。上記の `ProcessShapes` プロシージャは、ネストの深さに関係なく全てのベクターを網羅する堅牢な設計だ。

パフォーマンスとメモリ管理

VBAにおけるオブジェクトの開放 (`Set … = Nothing`) を怠ると、CorelDRAWのプロセス内にCOMの参照が残り続け、連続実行時にメモリ消費量が跳ね上がる。このコードでは、ループの各イテレーションの終端で確実に `Set sh = Nothing` を実行し、ガベージコレクションの確実な発火を促している。

1000ノード閾値による「爆弾検知」

実務において、1つのパスに数千〜数万のノードが含まれるデータは、出力工程における最大の癌(がん)である。コード内では `currentNodeCount > 1000` の条件でイミディエイトウィンドウに警告フラグ (`[⚠️ 要注意: 高負荷パス]`) を付与するように設計した。これにより、オペレーターは視覚的にどのオブジェクトがトラブルの元凶であるかを特定できる。

4. チーフアーキテクトからの実務的助言

この監査ツールは、単体でマクロとして走査するだけでなく、プリフライト(事前印刷前チェック)システムの一部として組み込むべきだ。

例えば、社内の自動化サーバーや、CorelDRAWのドキュメント保存イベント (`GlobalMacroStorage_DocumentSave`) にフックさせ、一定数(例:総ノード数50,000以上)を超えた場合にアラートを出したり、自動的にパスの単純化(`Curve.Simplify` メソッドの適用)を試みるバッチ処理へと拡張することが可能である。

レガシーなシステムであっても、VBAの底力を正しく引き出し、メモリとオブジェクトのライフサイクルを支配下に置けば、CorelDRAWは極めて強力な自動化プラットフォームに変貌する。

妥協のないコードで、安定したDTP・製造ラインを構築せよ。

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