【テクニカル・上級編】【初心者向け】図形の選択漏れを防ぐ!レイヤー内の全オブジェクトの数を自動カウントしてレポートするスクリプト – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAを掌握する:レイヤー内オブジェクト集計の深淵と「メモリの作法」

CorelDRAWのオートメーションにおいて、最も初歩的かつ重要な「集計」というタスクでさえ、素人と熟練者ではコードの寿命と信頼性が決定的に異なる。

今回は、レイヤー内の全オブジェクトをカウントし、レポート化するスクリプトを例に、単なる「動くコード」から「保守可能な資産」へと昇華させるための極限の知見を授ける。

なぜ「ただのループ」ではいけないのか

CorelDRAWのオブジェクトモデルは階層構造(Layer -> Shape)を持つが、単に `For Each` を回せば良いというものではない。大規模なドキュメントにおいて、不用意な参照の保持はメモリリークを招き、最悪の場合、CorelDRAWのプロセス全体を不安定にさせる。

シニアエンジニアが重視すべきは以下の3点だ。

1. オブジェクトの明示的解放: `Set obj = Nothing` の徹底。
2. 型指定の最適化: バリアント型ではなく `Shape` 型で定義し、オーバーヘッドを最小化する。
3. 再帰的な走査: グループ化されたオブジェクト(`Shape.Type = cdrGroupShape`)をどう処理するか。ここが腕の見せ所となる。

レイヤーオブジェクト集計の実装コード

このコードは、現在のドキュメントの全ページを走査し、クラスごとにカウントするプロフェッショナル仕様のベースラインだ。

Option Explicit

‘ 伝説のアーキテクトが推奨する、型安全かつメモリ効率を考慮した集計ルーチン
Public Sub ExportLayerReport()
Dim doc As Document
Dim p As Page
Dim layer As layer
Dim shp As Shape

‘ 集計用カウンタ
Dim countVector As Long, countBitmap As Long, countText As Long

Set doc = ActiveDocument

‘ レイヤー走査のパフォーマンスを上げるため、画面描画を停止
Optimization = True

For Each p In doc.Pages
For Each layer In p.Layers
‘ レイヤー内を再帰的に走査するためのヘルパー関数を呼び出す
Call CountShapesRecursive(layer.Shapes, countVector, countBitmap, countText)
Next layer
Next p

Optimization = False

‘ レポート出力
MsgBox “オブジェクト集計完了:” & vbCrLf & _
“ベクター: ” & countVector & vbCrLf & _
“ビットマップ: ” & countBitmap & vbCrLf & _
“テキスト: ” & countText, vbInformation, “System Report”

‘ 明示的なメモリ解放(VBAのガーベジコレクションを信じないのが鉄則)
Set doc = Nothing
End Sub

Private Sub CountShapesRecursive(shapes As shapes, ByRef v As Long, ByRef b As Long, ByRef t As Long)
Dim s As Shape
For Each s In shapes
Select Case s.Type
Case cdrCurveShape, cdrRectangleShape, cdrEllipseShape
v = v + 1
Case cdrBitmapShape
b = b + 1
Case cdrTextShape
t = t + 1
Case cdrGroupShape
‘ グループ内は再帰的に潜る。これが正確性を担保する要諦
Call CountShapesRecursive(s.Shapes, v, b, t)
End Select
Next s
‘ 参照の解放
Set s = Nothing
End Sub

シニアエンジニアが知るべき「現場の極意」

1. Optimization = True の重み

CorelDRAW VBAにおいて `Optimization = True` は単なる描画停止ではない。内部的な「更新通知」を抑制し、DOMへのアクセス頻度を劇的に減らす。数万オブジェクトが存在するファイルでは、これがないだけで処理時間に10倍以上の差が出る。

2. 再帰処理の限界管理

このスクリプトはグループ化にも対応しているが、極端に深い入れ子構造(ネスト)を持つファイルではスタックオーバーフローのリスクがある。業務システムで扱う場合は、スタックサイズを意識するか、ループベースのスタック管理を行うのが「伝説級」の解法となる。

3. Windows APIとの連携(今後の展望)

もしこのカウント結果を外部データベースへ送信したり、ログファイルとして出力したい場合、`Win32 API` の `Kernel32.dll` を呼び出し、メモリマップドファイルを利用してプロセス間通信を行うのが、より高度なシステム連携の定石だ。

結びに:コードは「生き物」である

今回提供したコードはあくまで「始まり」に過ぎない。君たちが現場で直面するであろう「謎のクラッシュ」や「極端な低速化」は、CorelDRAWの仕様の隙間に潜んでいる。

常に `Set obj = Nothing` を忘れず、オブジェクトのライフサイクルを制御下に置くこと。それが、この過酷なVBA開発の荒野を生き抜くための唯一の武器となる。

次は、この集計結果をCSVに書き出し、外部のPythonデータ分析基盤へとシームレスに連携させるアーキテクチャについて語ろうか。準備ができたら、またここへ戻ってくるといい。

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