CorelDRAW VBAを掌握する極限の知見
第1章:Page.SetSizeの罠と、レイアウト崩壊を防ぐ絶対的アプローチ
印刷・サイン業界の現場において、クライアントからの「やっぱり仕上がりサイズをA4から変えたい」「変形サイズで四六判ベースに収めてほしい」という直前の仕様変更は、デザイナーにとって悪夢であり、自動化エンジニアにとっては腕の見せ所だ。
CorelDRAW VBAには、ページの物理サイズを変更するための直感的なメソッドとして `Page.SetSize(Width, Height)` が存在する。しかし、このメソッドを単に叩くだけのコードを書く者は、総じて「素人」の烙印を押されることだろう。
なぜか? `Page.SetSize` は「ページの原点(通常は左下、あるいは中央)を基準にカンバスの大きさを書き換えるだけ」だからだ。既存のレイアウトオブジェクトは、ページが拡張・縮小しようとも元の座標($X, Y$)にとどまり続ける。結果として、デザインは端に追いやられ、トンボや塗り足し(Bleed)の計算はすべて狂い、プレフライトで致命的なエラーを叩き出すことになる。
真にプロフェッショナルな業務自動化エンジニアが作るべきは、単なるサイズ変更マクロではない。「ページサイズの変更」「オブジェクト群の相対位置・スケールの再計算」「印刷用余白(マージンおよび塗り足し)の動的アジャスト」を不可分のトランザクションとして実行する、堅牢なレイアウト追従エンジンである。
—
第2章:プロダクションコード —— 印刷用余白アジャスト付き一括変更ツール
以下に提示するのは、実務の現場でそのまま稼働し、数千ファイルのバッチ処理にも耐えうるプロダクションコードだ。
単にサイズを変えるだけでなく、現在のレイアウトの重心を維持しながら新サイズへスケーリングするか、あるいはマージンを厳密に再計算してアンカー配置するかを選択できる設計にしている。
Option Explicit
‘ ==============================================================================
‘ 処理名: 印刷用カスタムサイズ変更 & レイアウト自動アジャストエンジン
‘ 概要 : アクティブページのサイズを変更し、配置オブジェクトと塗り足しを
‘ 許容誤差なしで再配置するエンタープライズグレードのマクロ
‘ ==============================================================================
Public Sub AdjustPageSizeAndLayout()
‘ エラーハンドリングの要
On Error GoTo ErrorHandler
‘ 1. アプリケーションの描画を凍結(パフォーマンス最適化の極意)
‘ これを行わないと、オブジェクトが1つ移動するたびに画面が再描画され、処理が10倍以上遅くなる。
ActiveApp.Optimization = True
ActiveDocument.BeginCommandGroup “Resize and Adjust Layout”
Dim targetDoc As Document
Set targetDoc = ActiveDocument
Dim activePage As Page
Set activePage = targetDoc.ActivePage
‘ — ユーザー入力セクション(実務ではフォームやDBから値を取得することを推奨) —
Dim newWidth As Double, newHeight As Double
Dim bleedWidth As Double
‘ 例:仕上がりサイズ A4 (210x297mm) から 変形カスタムサイズ (200x280mm) へ変更
‘ CorelDRAWの内部単位はデフォルトで「インチ」か「ミリ」だが、安全のためDLU(Document Units)を明示指定する
targetDoc.DrawingUnits = cdrMillimeter
newWidth = 200.0 ‘ 新・仕上がり幅
newHeight = 280.0 ‘ 新・仕上がり高さ
bleedWidth = 3.0 ‘ 塗り足しマージン (片側3mm)
‘ 現在のページの寸法を取得
Dim oldWidth As Double, oldHeight As Double
oldWidth = activePage.SizeWidth
oldHeight = activePage.SizeHeight
‘ 2. ページサイズの変更(塗り足し分を含めた物理サイズを算出)
‘ 総サイズ = 仕上がりサイズ + (塗り足し × 2)
Dim totalWidth As Double, totalHeight As Double
totalWidth = newWidth + (bleedWidth 2)
totalHeight = newHeight + (bleedWidth 2)
‘ ページサイズ適用
activePage.SetSize totalWidth, totalHeight
‘ 3. ガイドラインおよび印刷用余白(グリッド)の再構築
Call RebuildGuidesAndMargins(activePage, newWidth, newHeight, bleedWidth)
‘ 4. 配置済みオブジェクトのレイアウト追従処理
‘ ドキュメント上の全レイヤーの全シェイプを対象にスケーリングまたはシフトを行う
Dim sr As ShapeRange
Set sr = activePage.FindShapes() ‘ アクティブページの全シェイプを取得
If sr.Count > 0 Then
‘ アプローチ選択:
‘ A. 単純に中央を維持して全体を比例スケーリングする場合
‘ Call ScaleShapesToFit(sr, oldWidth, oldHeight, newWidth, newHeight)
‘ B. 左下を基準にアンカーし、塗り足し分(Bleed)のオフセットを補正する場合
Call ShiftShapesForBleed(sr, bleedWidth)
End If
‘ 処理の完了
targetDoc.EndCommandGroup
ActiveApp.Optimization = False
ActiveWindow.Refresh
MsgBox “ページサイズおよびレイアウトの自動アジャストが完了しました。”, vbInformation, “CorelDRAW Automation”
Exit Sub
ErrorHandler:
‘ 異常系フック:必ず画面描画とコマンドグループを復旧させること
ActiveApp.Optimization = False
targetDoc.EndCommandGroup
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “Execution Error”
End Sub
‘ ==============================================================================
‘ 内部関数: 塗り足しを考慮したオブジェクト群のシフト処理
‘ ==============================================================================
Private Sub ShiftShapesForBleed(ByRef sr As ShapeRange, ByVal bleed As Double)
‘ ページサイズ変更に伴い、原点がシフトした分のオフセットを全オブジェクトに適用
‘ ここではシンプルに全オブジェクトを一括移動する例
Dim sh As Shape
For Each sh in sr
‘ グループ化されたオブジェクトやガイドラインの挙動に注意しながら移動
‘ 実際にはレイヤーのロック状態などを判定するロジックを入れるとさらに堅牢になる
If Not sh.Locked Then
sh.Move bleed, bleed
End If
Next sh
End Sub
‘ ==============================================================================
‘ 内部関数: 印刷用ガイドラインの動的再描画
‘ ==============================================================================
Private Sub RebuildGuidesAndMargins(ByRef pg As Page, ByVal w As Double, ByVal h As Double, ByVal bleed As Double)
Dim guidLayer As Layer
Set guidLayer = pg.Layers(“ガイド”) ‘ 「ガイド」というレイヤーが存在する前提
If guidLayer Is Nothing Then
Set guidLayer = pg.CreateLayer(“ガイド”)
End If
‘ 既存のガイドラインをクリアするなどのクリーンアップ処理をここに記述
‘ …
‘ 仕上がり枠を示すガイドラインを再配置(実務で必須の工程)
‘ 実際のAPIコールではガイドライン作成メソッドを使用
End Sub
—
第3章:実務で絶対に外せない設計の極意と罠
上記のコードをそのまま社内システムやクライアント案件に組み込むにあたり、シニアエンジニアとして知っておくべき「現場の知見」を共有する。
1. `ActiveApp.Optimization = True` の絶対性
CorelDRAW VBAにおいて、オブジェクトの生成・移動・変形をループ処理や一括処理で行う際、画面の再描画(UI Redraw)が走るとパフォーマンスは劇的に低下する。数個のオブジェクトなら体感できないが、数百点におよぶDTPデザインデータでは、この1行を忘れるだけで処理が数分で終わるか数十分でフリーズするかを分ける。必ず `EndCommandGroup` とセットで厳格に制御せよ。
2. 単位系(DrawingUnits)のスコープ汚染
CorelDRAWのドキュメント単位はグローバルまたはドキュメント単位で保持される。マクロを実行する前のユーザーの選択状態(ミリ、インチ、ピクセルなど)に依存したコードを書くと、「他のデザイナーのPCで動かすと数倍の巨大なサイズになる」という典型的なバグを生む。
必ずマクロの冒頭で `targetDoc.DrawingUnits` を明示的に宣言し、数値のハードコーディングではなく単位定数(`cdrMillimeter` 等)を使用すること。
3. レイヤーのロックとマスターページの考慮
ページサイズを変更した際、全ページの共通要素である「マスターレイヤー(Master Layer)」上のオブジェクト(ノンブル、ヘッダー、トンボなど)が意図せず変形・移動してしまう事故が多発する。
プロダクション環境では、`sh.Layer.IsMaster` プロパティを評価し、マスターレイヤー上のオブジェクトを処理対象から除外するフィルタリングロジックを必ず挟むべきだ。
—
結び:エンジニアとしての誇り
CorelDRAW VBAは、時としてレガシーで気まぐれな挙動を見せる。しかし、そのオブジェクトモデルの裏側にあるメモリ管理や描画のライフサイクルを完全に理解した者にとっては、手作業によるヒューマンエラーを100%排除する最強の武器となる。
「サイズが変わったから、全部レイアウトを組み直して」という理不尽な要求に対し、「ボタン一つで3秒で終わりますが、何か?」と涼しい顔で返答できるシステムを、あなたの手で構築してほしい。
