—
【極限の最適化】CorelDRAW VBAで数百のテキストを瞬時に掌握する「次元の違う」走査術
現場の最前線で戦うエンジニア諸君、今日もCorelDRAWのオブジェクトモデルと格闘しているだろうか。
「数百ものテキストオブジェクトをループで回し、フォントやサイズを変更していたら、画面がカクつき、処理完了まで数分待たされた」……もし君がそんなコードを書いているなら、それはプログラミングではなく、ただの「苦行」だ。
CorelDRAW VBAは、一歩間違えればCOM(Component Object Model)のオーバーヘッドという深い沼に沈む。しかし、アーキテクチャの本質を理解すれば、一瞬で全ドキュメントを書き換える「魔法」に変貌する。
今回は、「大量のテキストフレームに対する高速なフォント一括置換とスタイル適用」をテーマに、実務で絶対に外せない設計思想とプロダクションコードを伝授する。
—
1. なぜ君のコードは遅いのか? —— 3つの戦犯
初心者が書きがちな「遅い」コードには、必ずと言っていいほど以下の3つの問題が潜んでいる。
① UI更新の垂れ流し
CorelDRAWは、VBAからプロパティが変更されるたびに画面を再描画しようとする。100個のテキストがあれば、100回再描画が走る。これは致命的だ。
② 無差別な再帰的ループ
`For Each s In ActivePage.Shapes` を使い、全シェイプの中から「それがテキストかどうか」をIf文で判定する。これでは、背後にある数千のベクターパスまで走査対象になり、計算資源が枯渇する。
③ Undoスタックの断片化
一回一回の変更を「元に戻す」の履歴に刻んでいくと、メモリ消費量は跳ね上がる。これを一つの「コマンドグループ」にまとめない手はない。
—
2. アーキテクトの戦略:高速化の三種の神器
パフォーマンスを極限まで高めるには、以下の3つのアプローチを組み込む。
1. Application.Optimization: 画面更新とイベントを凍結する。
2. FindShapes (Filter): オブジェクトのフィルタリングをエンジン側に任せる。
3. CommandGroup: 処理を論理的な1ユニットにカプセル化する。
—
3. 実戦投入用:高速テキスト一括置換コード
このコードは、ドキュメント内の全ページ・全レイヤー(パワークリップ内を含む)からテキストオブジェクトのみを抽出、特定の条件に基づいてスタイルを適用する。
Option Explicit
”’
”’
Public Sub FastBatchTextUpdate()
Dim targetFont As String: targetFont = “Arial”
Dim targetSize As Double: targetSize = 12#
Dim targetColor As Color
‘ カラー設定の初期化(CMYK/RGBはプロジェクトに合わせて選択)
Set targetColor = CreateCMYKColor(0, 100, 100, 0) ‘ Red
‘ 1. アプリケーションの最適化(これが生命線)
On Error GoTo ErrorHandler
Optimization = True
EventsEnabled = False
‘ 2. Undo履歴を1つに統合
ActiveDocument.BeginCommandGroup “Batch Text Style Update”
Dim p As Page
Dim sr As ShapeRange
Dim s As Shape
‘ 全ページを走査
For Each p In ActiveDocument.Pages
‘ FindShapesにより、テキストオブジェクト(cdrTextShape)のみを高速抽出
‘ 期待するオブジェクトのみをメモリ上のShapeRangeに展開する
Set sr = p.Shapes.FindShapes(Type:=cdrTextShape)
‘ 3. ShapeRangeに対して一括処理
For Each s In sr
‘ 個別のプロパティアクセスを最小限にする
With s.Text.Story
‘ 現在のフォントをチェックする等の条件分岐が必要ならここで行う
‘ 例: If .Font = “MS Gothic” Then …
.Font = targetFont
.Size = targetSize
.Fill.ApplyUniformFill targetColor
End With
Next s
Next p
‘ 正常終了時の処理
ActiveDocument.EndCommandGroup
CleanUp:
‘ 4. 最適化設定を必ず解除する(忘れるとCorelDRAWがフリーズしたように見える)
Optimization = False
EventsEnabled = True
Application.Refresh
MsgBox “処理が完了しました。”, vbInformation
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
Resume CleanUp
End Sub
—
4. 堅牢性を高めるプロの知見
外部設定(CSV/JSON)との連携
実務では、フォント名をコードに直書きすることはない。外部のCSVファイルやデータベースから「置換前」「置換後」のリストを読み込むのが定石だ。
VBAであれば `FileSystemObject` を使い、辞書オブジェクト(`Scripting.Dictionary`)にマッピングを格納してから走査を開始せよ。
パワークリップ(PowerClip)の罠
上記の `FindShapes` は、基本的には通常レイヤー上のオブジェクトを探すが、パワークリップの中まで深く潜る必要がある場合は注意が必要だ。
その場合は、`FindShapes` の引数 `Recursive:=True` を活用するか、オブジェクトツリーを再帰的に掘り下げる専用の関数を組む。
データベース連携時の注意点
もしDB(SQL Server等)からテキスト情報を流し込む場合、VBA内で毎回コネクションを張るのは愚策だ。
1. 一括フェッチ: 必要なデータを最初に配列やコレクションにすべて取り込む。
2. 一括適用: CorelDRAW側のオブジェクトID(StaticID)をキーにして、メモリ上で紐付けを行う。
—
5. 結論:保守性の高いコードこそが最強のツール
私が常にチームに伝えているのは、「動くコードを書くのは誰でもできる。止まらない、そして速いコードを書くのがプロだ」ということだ。
今回紹介した `Optimization` と `FindShapes` の組み合わせは、CorelDRAW VBAにおける最適化の基本中の基本でありながら、最も効果が高い。
この構造をテンプレートとして持っておけば、テキスト置換だけでなく、複雑なベクター演算やアウトラインの一括変更など、あらゆる大量処理に応用できるだろう。
君のコードが、現場の時間を奪う「重石」ではなく、ビジネスを加速させる「翼」になることを願っている。
