CorelDRAW VBAを掌握せよ:全フォント棚卸しスクリプトで見る「真の自動化」の設計思想
CorelDRAWの自動化において、最も犯しやすい過ちは「とりあえず動くコード」を書くことだ。オブジェクトを闇雲にループさせ、メモリを浪費し、複雑なドキュメントでクラッシュさせる。そんなコードは自動化ではなく、単なる「バグの仕込み」に過ぎない。
今回は、実務で頻出する「ドキュメント内の全フォント一覧化」というタスクを題材に、「保守性」「パフォーマンス」「堅牢性」を兼ね備えたプロフェッショナルな設計思想を伝授する。
—
なぜ「直感的なループ」が地獄を生むのか
初心者は、`ActivePage.Shapes` を再帰的に呼び出すコードを書きがちだ。しかし、CorelDRAWのオブジェクトモデルにおいて、深い階層のグループやコンテナを単純なループで探索するのは非効率極まりない。
真のエンジニアが守るべき設計原則:
1. コレクションの先行評価を避ける: メモリ上に全オブジェクトを展開させない。
2. 辞書オブジェクト(Scripting.Dictionary)の活用: 重複排除は自前でロジックを書かず、ハッシュテーブルに任せる。
3. エラーハンドリングの徹底: 欠損フォントや埋め込みオブジェクトによる例外を制御下に置く。
—
実装:堅牢なフォントスキャナー
以下のコードは、単にフォントを列挙するだけではない。`Scripting.Dictionary`を活用し、O(n)の計算量で高速に重複を除去するプロダクションコードだ。
‘ 参照設定: Microsoft Scripting Runtime が必要
Option Explicit
Public Sub ExportUniqueFonts()
Dim doc As Document
Set doc = ActiveDocument
‘ Dictionaryを使って重複を自動排除(キーにフォント名を入れる)
Dim fontDict As Object
Set fontDict = CreateObject(“Scripting.Dictionary”)
‘ 再帰処理で全シェイプをスキャン
ProcessShapes doc.ActiveLayer.Shapes, fontDict
‘ 結果出力
If fontDict.Count = 0 Then
MsgBox “フォントが見つかりませんでした。”
Exit Sub
End If
‘ 出力用に配列化
Dim result As String
result = Join(fontDict.Keys, vbCrLf)
‘ 簡易的なデバッグウィンドウ表示
Debug.Print “— 使用フォント一覧 —”
Debug.Print result
MsgBox “抽出完了: ” & fontDict.Count & ” 種類のフォントを発見しました。” & vbCrLf & vbCrLf & result
End Sub
Private Sub ProcessShapes(shapes As shapes, dict As Object)
Dim shp As Shape
For Each shp In shapes
‘ グループやコンテナの場合、再帰的に探索
If shp.Type = cdrGroupShape Then
ProcessShapes shp.Shapes, dict
‘ テキストフレームを特定してフォント名を取得
ElseIf shp.Type = cdrTextShape Then
Dim fontName As String
fontName = shp.Text.Story.Font
‘ Dictionaryに登録(存在しなければ追加される)
If Not dict.Exists(fontName) Then
dict.Add fontName, True
End If
End If
Next shp
End Sub
—
プロフェッショナルのための深掘り:保守性の極意
1. 外部連携を見据えた設計
もしこのリストをExcelやCSVに書き出す必要がある場合、上記のコードの `MsgBox` 部分をファイル出力ルーチンに切り離すべきだ。ロジック(データの抽出)とプレゼンテーション(出力先の決定)を分離することで、将来的な仕様変更(JSONエクスポートやDB格納など)に強いコードになる。
2. なぜ `Scripting.Dictionary` なのか
VBA標準の配列で重複チェックを行うと、要素数が増えるごとに計算量が二乗で増える。10,000個のオブジェクトがあるドキュメントでそれを行うのは自殺行為だ。`Dictionary`はハッシュテーブルであるため、件数が増えてもパフォーマンスが劣化しない。これが業務自動化エンジニアの嗜みだ。
3. 実行環境のバリデーション
実務環境では、ドキュメントが閉じている、あるいは選択オブジェクトが存在しないケースなど、予期せぬ状態が多発する。
If ActiveDocument Is Nothing Then
MsgBox “ドキュメントが開かれていません。”
Exit Sub
End If
このような「ガード節」を先頭に置く習慣があるか否かで、ツールの安定性は決定的に変わる。
—
次なるステップへ
このコードは、あなたの「ツールボックス」のほんの一パーツに過ぎない。次はこれに「欠損フォントの自動置換」や「特定のフォントを使用しているオブジェクトの全選択」という機能を加えていくといい。
技術は目的ではない。「いかに早く、ミスなく、人間が退屈な作業から解放されるか」。それこそが、我々エンジニアが追及すべき唯一の到達点だ。コードを書き換え、自分の業務をハックし続けろ。現場の課題は、あなたの書くコードが解決する。
