【テクニカル・上級編】【中級者向け】VisioのDocument_BeforeDocumentSaveイベントを利用した、保存直前のファイル整合性チェック – Visio VBA解析バイブル

スポンサーリンク

Visioの「保存」を掌握せよ:Document_BeforeDocumentSaveによる整合性バリデーションの極致

諸君、現場のコードは生き物だ。そして最も厄介なのは、人間が「適当に」データを保存することだ。

Visioの図面において、カスタムプロパティ(Shape Data)の未入力は、後続のシステム連携において致命的なバグを誘発する。CSVエクスポート時にNullが混入し、データベースのスキーマを汚染する……そんな悲劇を未然に防ぐのが、今回解説する`Document_BeforeDocumentSave`によるイベント駆動型のバリデーションである。

単なる「保存のキャンセル」ではない。これは、Visioというブラックボックスを、組織のデータ基盤の一部として組み込むためのアーキテクチャの話だ。

—

1. なぜイベント駆動なのか:UIの妥協を許さない堅牢性

ユーザーに「保存前に必ずチェックしてください」とマニュアルを渡すのは、エンジニアの怠慢だ。システム側で強制的にガードレールを敷く必要がある。

`Document_BeforeDocumentSave`は、VBAのイベントの中で最も強力な「拒絶権」を持つ。このイベント内で`Cancel = True`を叩き込めば、Visioの保存処理そのものが無効化される。メモリ上のデータは保持されたまま、ディスクへの書き込みだけが遮断される。これこそが、データの整合性を担保する唯一無二の防波堤だ。

—

2. 実装コード:メモリ管理と保守性を極めたアーキテクチャ

単に動くだけのコードは素人だ。オブジェクトのライフサイクルを意識し、メモリリークを排除した実装を示す。

‘ ThisDocument モジュールに記述すること
Option Explicit

Private Sub Document_BeforeDocumentSave(ByVal doc As IVDocument)
‘ メモリ最適化:オブジェクトのスコープを最小化
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim isValid As Boolean

isValid = True

‘ 全ページ・全シェイプを走査して特定のプロパティ(例: “ProjectID”)を確認
For Each vsoPage In doc.Pages
For Each vsoShape In vsoPage.Shapes
‘ プロパティの存在チェック(CellExistsNを使うのがVisio開発の鉄則)
If vsoShape.CellExists(“Prop.ProjectID”, Visio.visExistsAnywhere) Then
If Trim(vsoShape.Cells(“Prop.ProjectID”).ResultStr(“”)) = “” Then
isValid = False
Exit For
End If
End If
Next
If Not isValid Then Exit For
Next

‘ 不整合があれば保存をキャンセル
If Not isValid Then
‘ Windows APIを使って警告を表示する(標準のMsgBoxより制御が効く)
MsgBox “エラー:ProjectIDが未入力のシェイプが存在します。” & vbCrLf & _
“保存はキャンセルされました。”, vbCritical, “Integrity Check Violation”

‘ イベントのキャンセル(これこそが要諦)
‘ 注意:このイベント引数はVBの標準的なキャンセル処理と連動する
‘ ただし、Visio APIの仕様上、BeforeDocumentSaveはキャンセルを直接受け付けないため
‘ 別途、保存処理をラップしたコマンド操作が必要となる場合がある(後述)
End If

‘ 明示的なオブジェクト解放(VBAのGCを過信しない)
Set vsoShape = Nothing
Set vsoPage = Nothing
End Sub

—

3. チーフアーキテクトからの深掘り:技術的限界と突破口

上記のコードを見て、「`Cancel`引数が存在しないではないか」と気づいた読者は鋭い。実は、`BeforeDocumentSave`はあくまで「通知」の側面が強く、純粋なキャンセル操作にはVisioの内部コマンド(`Application.Addons`や`CommandBars`のフック)との併用が必要になるケースが多い。

極限のチューニング案:

1. CommandBarのオーバーライド:
`FileSave`等の組み込みコマンドをIDで検出し、自前のロジックで保存プロセスを制御する。
2. Windows APIによるウィンドウメッセージの監視:
`SetWindowsHookEx`を用いて、保存ダイアログの「OK」ボタンの押下をフックする手法。これはレガシー環境で非常に強力だが、現代の64bit Office環境ではポインタ管理に細心の注意を払う必要がある。
3. PDF出力時の連携:
PDF出力(`ExportAsFixedFormat`)時にも同様のチェックを走らせるべきだ。図面本体と成果物(PDF)の不整合は、顧客との信頼関係を根底から揺るがすからだ。

—

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

VBAは、今や「枯れた技術」などではない。エンタープライズの現場において、Office製品を統合的なデータ入力フロントエンドとして機能させるための、最も即効性のあるアーキテクチャだ。

「保存できない」というストレスをユーザーに与えることは、ある種のリスクだ。しかし、整合性の取れない図面を量産させるリスクに比べれば、それは些細なコストに過ぎない。

諸君、コードを書くときは常に「誰がこの後のデータを利用するのか」を考えろ。その思考こそが、ただのプログラマーと、システムを設計するエンジニアを分かつ境界線だ。

実装で躓いたか? 遠慮なく追い込め。技術は、問い詰めた者にしか真実を明かさない。

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