【実務・中級編】CorelDRAWのUndo(元に戻す)バッファをVBAからコントロールし、カスタム処理を1つの履歴としてまとめる – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAを掌握する極限の知見:Undoバッファを支配し、マクロの挙動を「製品レベル」へ昇華させる技術

CorelDRAWでの業務自動化を進める中で、避けて通れない壁がある。それは「マクロが実行した大量の図形操作が、すべて個別のUndo(元に戻す)履歴として積み上がってしまう問題」だ。

例えば、1,000個のオブジェクトを整列し、色を変更し、特定のタグを付与するスクリプトを書いたとする。処理が終わったあと、ユーザーが操作ミスに気づいて「Ctrl+Z」を押した。するとどうなるか。ユーザーは元の状態に戻すために、1,000回も「Ctrl+Z」を連打しなければならない。

……これでは、業務効率化ツールのつもりが、かえって現場のストレスを生む「不良品」と言わざるを得ない。

プロのエンジニアが作るべき自動化ツールとは、単に処理を速く終わらせるだけではない。ホストアプリケーションの作法を深く理解し、ネイティブ機能とシームレスに融和していることが絶対条件だ。

今回は、CorelDRAWのUndoバッファをVBAから完全にコントロールし、マクロ内の膨大な処理を「1つの不可分な履歴(トランザクション)」として束ねる極意を授けよう。

1. なぜ「そのまま」のVBAコードは地獄を生むのか?

CorelDRAWのオブジェクトモデルは非常に強力だが、その裏で動作するUndoマネージャーは、VBAからの命令を「1つの操作」としてデフォルトでは認識してくれない。

VBAから以下のようなコードを実行したとしよう。

Dim s As Shape
Dim i As Long
For i = 1 to 1000
Set s = ActiveLayer.CreateRectangle(i, i, i + 10, i + 10)
s.Fill.UniformColor.CmykAssign 0, 100, 100, 0
Next i

このループが回るたび、CorelDRAWのUndoスタックには「矩形の作成」「塗りの変更」というイベントが何千件もプッシュされる。これがパフォーマンスの劣化を招くだけでなく、ユーザーの操作体験を致命的に破壊する原因となる。

我々が目指すべきは、データベースのトランザクション制御(ACID特性)に近い思想だ。
「処理の開始を宣言し、その中のすべての変更を不可分の塊(グループ)として閉じ込め、処理の終了を宣言する」

これを行うためのAPIが、CorelDRAWが提供する `BeginCommandGroup` と `EndCommandGroup` である。

2. Undoバッファを制御する王道:`BeginCommandGroup` の正しい作法

CorelDRAW Applicationオブジェクトには、Undoのグループ化を制御するためのメソッドが用意されている。

  • `Application.BeginCommandGroup [Name]` : コマンドグループの開始。引数にUndo履歴に表示する名前を指定できる。
  • `Application.EndCommandGroup` : コマンドグループの終了。

これらを適切に配置するだけで、マクロ内のあらゆる破壊的変更は「Ctrl+Z」一発で綺麗に消し去ることが可能になる。

しかし、実務でこれを実装する際、「絶対に避けて通れない鉄則」がある。

⚠️ プロジェクトリーダーが警告する「エラーハンドリングの罠」

もし、`BeginCommandGroup` を呼び出した後、コードの途中で実行時エラー(Runtime Error)が発生してプログラムが中断したらどうなるか?
`EndCommandGroup` が呼ばれないまま処理が途切れるため、CorelDRAWのUndoスタックとアプリケーションの状態が不整合を起こし、最悪の場合、アプリケーション全体の不安定化やメモリリークを招く。

したがって、Undoグループ化を行うコードには、必ず `On Error` によるトランザクション保証(例外処理)を実装しなければならない。

3. 【プロダクションコード】堅牢性を極めた一括Undo制御マクロ

以下のコードは、エラーハンドリングを完備し、大量のオブジェクト生成・修飾を1つのUndo履歴にまとめる実務レベルのテンプレートだ。そのまま業務ツールに組み込んで活用してほしい。

‘ ==============================================================================
‘ 模块名: clsUndoController / 標準モジュール
‘ 概要: 大量の図形処理を1つのUndo履歴にまとめ、堅牢に実行するサンプル
‘ ==============================================================================
Sub ExecuteBatchProcessWithSingleUndo()
Dim startTime As Double
startTime = Timer

‘ 1. 画面描画の凍結(パフォーマンス爆速化の基本)
ActiveDocument.BeginOptimization

‘ 2. Undoトランザクションの開始(Ctrl+Zで一発に戻せる名前を指定)
‘ ※注意: Application.BeginCommandGroup ではなく、グローバル空間から呼び出すか、
‘ Applicationオブジェクトを明示します。
Application.BeginCommandGroup “一括レイアウト生成処理”

‘ 3. エラーハンドリングの有効化(Undoの閉じ忘れを絶対に防ぐ)
On Error GoTo ErrorHandler

‘ — 【ここから実際の重い処理を記述】 —
Dim i As Long
Dim sh As Shape

‘ 例として、500個の矩形をランダムに配置し色を塗る処理
For i = 1 To 500
Set sh = ActiveLayer.CreateRectangle( _
Rnd() 200, _
Rnd() 200, _
Rnd() 200 + 10, _
Rnd() 200 + 10 _
)
sh.Fill.UniformColor.RGBAssign 255, 100, 0
sh.Outline.SetNoOutline
Next i
‘ — 【ここまで】 —

‘ 4. 正常終了時のUndoグループクローズ
Application.EndCommandGroup

‘ 5. 画面描画の再開
ActiveDocument.EndOptimization

‘ 正常終了メッセージ
MsgBox “処理が完了しました。実行時間: ” & Format(Timer – startTime, “0.00”) & “秒”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ — 異常終了時のフォールバック処理 —
‘ エラーが発生しても、必ずUndoグループを閉じてアプリケーションの状態を復旧させる
Application.EndCommandGroup
ActiveDocument.EndOptimization

‘ 画面を強制再描画
CorelDRAW.Refresh

MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“内容: ” & Err.Description, vbCritical, “エラー”

End Sub

4. コードの解説とアーキテクチャの急所

上記のコードには、単にUndoをまとめるだけでなく、プロのエンジニアが実務で必ず組み込むべき「2つの武器」が同居している。

① `BeginOptimization` とのシナジー

Undoグループ化(`BeginCommandGroup`)と並行して、`ActiveDocument.BeginOptimization` と `EndOptimization` を必ずセットで使うこと。
CorelDRAWは、図形が1つ生成されるたびにプレビュー画面を再描画しようとする。これを一時停止(オプティマイズ)することで、処理速度が文字通り「数十倍」に跳ね上がる。Undoのグループ化と画面描画の凍結は、高速化の二大巨頭である。

② 例外時の「強制クローズ」

`ErrorHandler` ラベル内に配置された `Application.EndCommandGroup` こが、このコードの最も価値のある部分だ。
もしエラー発生時にここを通らないと、CorelDRAW内部のコマンドグループカウンタがズレてしまい、その後のユーザーの手動操作によるUndoまでが狂い始める。VBAからアプリケーションを操作する際、「開いたものは、例外時であっても確実に閉じる(Try-FinallyパターンのVBA実装)」は鉄則中の鉄則である。

5. チーフアーキテクトからの総括

VBAを書くとき、私たちはついつい「動けばいい」という動的なコードに逃げ込みがちだ。しかし、それを現場のデザイナーやオペレーターに渡した瞬間、「Ctrl+Zを押したらマクロの途中の変な状態に戻ってしまった」「アプリがフリーズした」というクレームに直面する。

今回解説した `BeginCommandGroup` によるUndoバッファの制御は、単なる便利機能ではない。「ユーザーの作業文脈を破壊しないための、エンジニアとしての最低限の責任」である。

この知見をあなたのツールに組み込み、誰もが安心して使える「真にプロフェッショナルな自動化環境」を構築してほしい。

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