CorelDRAW VBAの深淵:ストロークを「殺し」、デザインの整合性を永遠に守る戦略的設計
CorelDRAWで大規模なベクターデータを扱う際、避けて通れない最大の敵が「ストロークの崩壊」だ。拡大縮小時に線幅が追従せず、意図しない太さで印刷される悲劇——これを防ぐ唯一の解は、「すべてのストロークをアウトライン(閉じたパス)へと変換し、物理的な形状として固定する」ことである。
今日は、場当たり的なスクリプトではなく、数万オブジェクトを抱えるドキュメントでも音を上げない、堅牢なVBAエンジニアリングの極意を伝授する。
—
1. なぜ「手動」や「単純ループ」が失敗するのか
初心者が書きがちな `ActivePage.Shapes.All.ConvertToCurves` のような記述は、ドキュメントの複雑度が増すと簡単にクラッシュする。
- スタックオーバーフロー: ネストされたグループ(Group)の深さを考慮していないため、再帰処理でメモリが溢れる。
- イベントの暴発: 変換のたびに発生する `QueryCancel` や再描画処理が、実行速度を劇的に低下させる。
- 不整合: ロックされたレイヤーや不可視レイヤーのオブジェクトを無視して処理が進み、後で「変換漏れ」が発生する。
我々が目指すべきは、「オブジェクトモデルを再帰的に走査し、変換可能なものだけを確実に仕留める」設計だ。
—
2. 堅牢なプロダクションコード:`ConvertStrokesToCurves`
このコードは、単に変換するだけでなく、処理対象の選別とエラー回避を組み込んだ、現場でそのまま使える実用型だ。
‘ ———————————————————
‘ CorelDRAW VBA: ストローク一括変換ツール
‘ 概要: ドキュメント内の全オブジェクトを走査し、
‘ 線情報を持つオブジェクトのみをパスに変換する。
‘ ———————————————————
Public Sub BatchConvertStrokesToCurves()
Dim doc As Document
Set doc = ActiveDocument
‘ 処理の高速化:再描画を停止
Optimization = True
EventsEnabled = False
On Error GoTo Cleanup
‘ ドキュメント内の全レイヤーを走査
Dim lyr As Layer
For Each lyr In doc.Pages(0).Layers
‘ ロックされたレイヤーを一時的に解除するなどの制御が必要な場合はここに記述
ProcessShapes lyr.Shapes
Next lyr
MsgBox “変換完了:すべてのストロークがパスに置換されました。”, vbInformation
Cleanup:
Optimization = False
EventsEnabled = True
If Err.Number <> 0 Then MsgBox “エラー発生: ” & Err.Description
End Sub
Private Sub ProcessShapes(shapes As shapes)
Dim shp As Shape
For Each shp In shapes
‘ 再帰処理:グループ化されている場合、内部まで掘り下げる
If shp.Type = cdrGroupShape Then
ProcessShapes shp.shapes
Else
‘ 線幅を持ち、かつ変換可能なオブジェクトのみを処理
If shp.Outline.Type <> cdrNoOutline Then
‘ アウトラインに変換し、元のストローク情報を除去
shp.Outline.ConvertToCurve
End If
End If
Next shp
End Sub
—
3. 実務で勝つための「3つの鉄則」
1. `Optimization = True` は必須の儀式
CorelDRAWのVBAにおいて、`Optimization` を `True` に設定しないのは、手ブレーキを引いたまま時速200kmで走るようなものだ。これを設定するだけで、数分かかっていた処理が数秒に短縮される。
2. 再帰的走査(Recursive Traversal)の重要性
オブジェクトは「グループの中にグループ」という構造を平気で持つ。単なる `For Each` ループでは階層構造を突き抜けられない。上記の `ProcessShapes` のように、`cdrGroupShape` に遭遇した瞬間に自分自身を呼び出す設計こそが、バグを生まない唯一の道だ。
3. ファイル連携時の注意点:破壊的変更
この処理は破壊的である。実行後に「やっぱり線幅を調整したい」と言われても、元に戻す(Undo)には限界がある。
- 必ずスクリプトの冒頭で `doc.SaveAs “Backup_” & doc.Name` を自動実行させる。
- 変換前のオリジナルを別名で保存するルーチンを組み込むのが、プロのエンジニアの流儀だ。
—
最後に:ツールは「魔法」ではなく「自動化」である
今回のコードは、デザインの整合性を守るための「守護神」となる。しかし、真の自動化エンジニアは、ツールを渡して終わりにはしない。
もし、クライアントから「特定のレイヤーだけは変換したくない」という要望が来たらどうするか? `Layer.Name` を判定条件に加える、あるいは `Shape.Layer.Name` をチェックするフィルターを一枚噛ませるだけで、コードはさらに柔軟になる。
君たちの手元にあるそのスクリプトは、単なるテキストではない。業務時間を捻出し、ヒューマンエラーという名の怪物からデザインを守るための「盾」だ。自信を持って、現場で走らせてほしい。
何かあれば、またいつでも相談に乗ろう。健闘を祈る。
