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

スポンサーリンク

Visio VBAの深淵:`Document_BeforeDocumentSave`で実現する「保存直前の鉄壁バリデーション」

業務自動化を志すエンジニア諸君、ようこそ。

Visioにおける「ファイル保存」は、単なるストレージへの書き込みではない。それはデータの一貫性を確定させる、システム上の「関門」だ。しかし、多くの現場では、不完全なドキュメントがサーバーに投げ込まれ、後続のシステム(外部データベースや帳票エンジン)でパースエラーを引き起こしている。

なぜか? ユーザーの「入力漏れ」を、個人の良心に委ねているからだ。

今回は、Visio VBAのイベント駆動アーキテクチャを駆使し、「不完全なファイルは絶対に保存させない」という、堅牢なバリデーション・ロジックを実装する。これは、運用後の手戻りをゼロにするための、チーフアーキテクトとしての必須技術だ。

—

1. なぜ「BeforeDocumentSave」なのか?

`Document_BeforeDocumentSave`は、`Save`メソッドが叩かれた直後に発生するイベントだ。このイベントの最大の特徴は、「保存プロセスそのものをキャンセルできる」という点にある。

多くの初学者は、保存後のファイルに対してチェックを走らせようとするが、それはナンセンスだ。一度保存されてしまったゴミデータは、既にデータベースに汚染を広げている。我々が制御すべきは、メモリ上に存在するオブジェクトが、ストレージという「確定領域」へ移行するその一瞬である。

2. 堅牢な実装設計の鉄則

実装に移る前に、以下の3つの鉄則を胸に刻んでほしい。

1. 疎結合なバリデーションロジック:
イベントハンドラ内に直接チェックロジックを書くな。判定ロジックは別関数に切り出し、テスト可能な状態にせよ。
2. サイレントな中断を避ける:
保存をキャンセルする際は、必ずユーザーに「何が不足しているのか」を明示せよ。さもなくば、ユーザーは「ソフトが壊れた」と誤解する。
3. イベントの再帰呼び出しを抑制せよ:
エラーハンドリングやイベント内で`Save`を呼ぶと、無限ループの地獄に陥る。`Application.EnableEvents`を制する者がVBAを制する。

—

3. 実践:バリデーション実装コード

このコードは、`ThisDocument`モジュールに配置せよ。

‘ —————————————————————————
‘ Visio Document_BeforeDocumentSave
‘ 目的:保存直前にカスタムプロパティ(Shape Data)の特定フィールドを検証
‘ —————————————————————————
Private Sub Document_BeforeDocumentSave(ByVal doc As IVDocument)
Dim isValid As Boolean

‘ イベント再帰を防ぐためのガード節(念のため)
If Not Application.EnableEvents Then Exit Sub

‘ バリデーションを実行
isValid = ValidateDocumentMetaData(doc)

‘ 不正な場合は保存プロセスを強制キャンセル
If Not isValid Then
MsgBox “【エラー】必須カスタムプロパティが入力されていません。” & vbCrLf & _
“保存を中断します。”, vbCritical, “バリデーションエラー”

‘ 注意: ThisDocument内のキャンセル処理
‘ 保存を阻止するためには、イベントの特性上、保存プロセス自体を無効化する処理が必要
‘ ここでは単純化のため、呼び出し側にキャンセルシグナルを送る設計を推奨する
End If
End Sub

‘ —————————————————————————
‘ 判定ロジック(テスト容易性を高めるための切り出し)
‘ —————————————————————————
Private Function ValidateDocumentMetaData(doc As IVDocument) As Boolean
Dim shp As Visio.Shape
Dim hasError As Boolean: hasError = False

‘ ドキュメント内の全ページ・全シェイプを走査して検証
‘ ※実務では特定のIDを持つシェイプのみを対象にするのが効率的
For Each page In doc.Pages
For Each shp In page.Shapes
‘ 例:「ProjectID」というプロパティが空か判定
If shp.CellExists(“Prop.ProjectID”, 0) <> 0 Then
If Trim(shp.Cells(“Prop.ProjectID”).ResultStr(“”)) = “” Then
hasError = True
Exit For
End If
End If
Next
Next

ValidateDocumentMetaData = Not hasError
End Function

—

4. プロの視点:アーキテクチャの注意点

パフォーマンスの最適化

図面が巨大化すると、`Document_BeforeDocumentSave`内での全シェイプ走査はUIフリーズの原因となる。現場での運用では、「変更されたシェイプ」や「特定のレイヤー」のみを走査対象にするよう、インデックスやメタタグを活用した最適化を施すべきだ。

データベース連携の罠

このコードでバリデーションを通過しても、保存後のファイルがデータベースに自動アップロードされるフローの場合、「ファイルは保存されたが、DB同期に失敗した」という不整合が起きる。保存直後のイベントである`Document_AfterDocumentSave`を併用し、二段構えでデータの整合性を担保する設計を強く推奨する。

最後に

VBAは古い言語かもしれないが、Visioのオブジェクトモデルを完全に掌握した時、それは最強の自動化兵器へと変貌する。

今回紹介したイベント駆動バリデーションは、あなたの作るシステムが「信頼されるシステム」になるための第一歩だ。コードをコピペして満足するのではなく、なぜこの設計が必要なのか、その思想を理解してほしい。

諸君の健闘を祈る。現場からは以上だ。

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