【実務・中級編】【上級プロ向け】ドキュメント破棄時のイベントハンドリング:QueryCloseとDocumentCloseExによる変更破棄の厳格な制御 – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAを掌握せよ:ドキュメントライフサイクルを制する「厳格な終了制御」の実践

CorelDRAWの自動化において、最も軽視されがちだが、大規模開発において最も致命的となるのが「終了時のイベントハンドリング」だ。

「ドキュメントを閉じる」という何気ない操作の裏側で、メモリリークや不正なファイル整合性の崩壊が起きていることに、多くのエンジニアは気づいていない。今回は、`QueryClose`と`DocumentCloseEx`を使いこなし、ドキュメントのライフサイクルを完全に掌握するための極限の設計論を授ける。

1. なぜ、標準の「保存確認」では不十分なのか

CorelDRAW標準の保存ダイアログは、あくまで「ユーザーの意思」を確認するだけだ。しかし、業務自動化ツールを設計する我々にとって必要なのは、「保存の成否をプログラム側で完全に握ること」である。

  • 自動バックアップの強制: ユーザーが「保存しない」を選択しても、指定のサーバーパスへバックアップを飛ばす。
  • 整合性チェック: ドキュメント内のメタデータがデータベースと同期されているか検証し、不整合があればログを残す。
  • リソース解放: 巨大なオブジェクトを生成した際、ガベージコレクション的な処理を強制的に走らせる。

これらを実現するには、標準の保存ダイアログを迂回し、イベントの割り込みを実装する必要がある。

2. 実装の鉄則:イベントハンドラは「クラスモジュール」に宿る

標準モジュールにイベントを書いていないか? それはメンテナンス性を捨てる行為だ。CorelDRAWのオブジェクトモデルは、`WithEvents`を介したクラスモジュールでの制御が、唯一にして正解の設計である。

プロダクションコード:`clsAppEvents`(クラスモジュール)

以下のコードは、ドキュメントが閉じられる瞬間にフックをかけ、独自のバックアップ処理を実行するテンプレートだ。

‘ クラスモジュール名: clsAppEvents
Option Explicit

‘ CorelDRAWのApplicationイベントを監視
Public WithEvents App As Application

‘ ドキュメントが閉じられる直前の処理(QueryClose)
Private Sub App_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
On Error GoTo ErrHandler

‘ ここで整合性チェックやログ出力を行う
‘ 厳格な制御が必要な場合、ここで Cancel = True を設定することで閉じる動作を中断可能

If Not ValidateDocumentIntegrity(Doc) Then
MsgBox “整合性エラーが検出されました。強制終了をキャンセルします。”, vbCritical
Cancel = True
Exit Sub
End If

‘ 閉じる直前の自動バックアップ(パスは環境に合わせて変更)
Call PerformAutoBackup(Doc, “C:\Backups\” & Doc.Name & “_” & Format(Now, “yyyymmdd_hhnnss”) & “.cdr”)

Exit Sub

ErrHandler:
Debug.Print “Error in DocumentBeforeClose: ” & Err.Description
End Sub

‘ 独自整合性チェック関数の例
Private Function ValidateDocumentIntegrity(doc As Document) As Boolean
‘ ここにデータベースとの照合処理などを記述
ValidateDocumentIntegrity = True
End Function

‘ バックアップ処理の例
Private Sub PerformAutoBackup(doc As Document, path As String)
‘ 最適化のため、保存時はバックアップ用として別名保存を推奨
doc.SaveAs path, cdrCDR
End Sub

3. 実行環境の構築:インスタンスの永続化

クラスモジュールを作っただけでは動作しない。VBAプロジェクトの初期化時に、このクラスをインスタンス化し、スコープを維持し続ける必要がある。

標準モジュール:`modMain`

Option Explicit

Public gAppEvents As clsAppEvents

Public Sub InitializeApp()
‘ アプリケーションイベントのフック
Set gAppEvents = New clsAppEvents
Set gAppEvents.App = Application
End Sub

この`InitializeApp`を、プロジェクトの初期化時に一度だけ実行する。`gAppEvents`をグローバル変数(あるいはシングルトンのプロパティ)として保持することで、CorelDRAWが終了するまで監視網が維持される。

4. 現場で「死なない」ための3つの知見

① エラーハンドリングの徹底

イベントハンドラ内で例外が発生すると、CorelDRAW自体がクラッシュするか、イベントがデタッチされる。`On Error GoTo`は全メソッドに必須だ。

② ファイルロックへの配慮

`DocumentCloseEx`や`BeforeClose`でファイル操作を行う際、CorelDRAWが保持しているファイルハンドルと競合する場合がある。`DoEvents`を挟む、あるいは保存操作を別プロセス(シェル実行)へ逃がす工夫が必要な場合もある。

③ ユーザー体験との調和

バックアップが長すぎて、ユーザーが「フリーズした」と誤解してタスクマネージャーから殺すケースを想定せよ。処理時間がかかる場合は、ステータスバーへの進捗表示を怠るな。

最後に:エンジニアとしての矜持

VBAはレガシーと言われるが、CorelDRAWの内部モデルを直接叩けるこの言語は、設計次第で極めて強力な武器になる。

今回提示した「終了時の割り込み制御」は、ただのテクニックではない。「ユーザーが何をしたとしても、システムの整合性は絶対に損なわせない」という、エンジニアとしての防衛線を構築する作業だ。

このコードをそのままコピペするだけでなく、君の抱えるシステムの要件に合わせて、どのように「整合性を保証するか」を深く設計してほしい。それができる者だけが、真の自動化エンジニアとして生き残れる。

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