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

スポンサーリンク

Visio VBAの深淵へ:保存直前の「門番」を実装し、図面データの品質を担保する

こんにちは。自動化の荒波を乗りこなすエンジニアの皆さん。
「マクロの記録」で生成された断片的なコードを繋ぎ合わせる段階から、そろそろ一歩先へ進みたいと思いませんか?

Visioは単なる作図ツールではありません。背後に強力な「データモデル」を隠し持った、データベースに近いアプリケーションです。今日は、そのデータの整合性を保つための最もエレガントな手法、`Document_BeforeDocumentSave` イベントによるバリデーション(入力検証)を伝授します。

「保存」という不可逆な操作の直前に、コードという名の「門番」を立たせるのです。

—

なぜ「イベント」を使うのか?

初心者の方は、ボタンを押すと動くマクロを作りがちです。しかし、真の自動化エンジニアは「ユーザーの操作」をフックにします。

`Document_BeforeDocumentSave` は、ユーザーが「保存」ボタンを押した瞬間、OSがディスクに書き込みを開始する直前に強制的に割り込むイベントです。ここで条件を満たしていないと判断すれば、保存処理そのものをキャンセルさせることができます。

これこそが、図面データが「ゴミ屋敷」化するのを防ぐ最強の防波堤なのです。

—

実装のステップ:ThisDocument モジュールを掌握せよ

Visio VBAのイベントは、標準モジュールではなく `ThisDocument` オブジェクトに記述します。これが第一の関門です。

1. コードの配置

VBAエディタ(Alt + F11)を開き、左側のプロジェクトエクスプローラーから `ThisDocument` をダブルクリックしてください。そこに以下のコードを貼り付けます。

‘ Visioの保存イベントを監視する門番
Private Sub Document_BeforeDocumentSave(ByVal doc As IVDocument)
Dim shp As Visio.Shape
Dim isDataValid As Boolean
isDataValid = True

‘ ここでは「全ページ内に『ProjectID』というカスタムプロパティが入力されているか」をチェックします
‘ ページを巡回し、特定のシェイプをスキャンする
Dim pag As Visio.Page
For Each pag In doc.Pages
For Each shp In pag.Shapes
‘ カスタムプロパティ(ShapeSheet)の存在確認
‘ プロパティ名が “Prop.ProjectID” であると仮定
If shp.CellExists(“Prop.ProjectID”, 0) Then
If Trim(shp.Cells(“Prop.ProjectID”).Formula) = “” Then
isDataValid = False
Exit For
End If
End If
Next
If Not isDataValid Then Exit For
Next

‘ バリデーション失敗時の処理
If Not isDataValid Then
MsgBox “エラー:ProjectIDが未入力のシェイプが存在します。” & vbCrLf & _
“保存をキャンセルします。”, vbCritical, “バリデーション警告”

‘ 【重要】ここで保存をキャンセルする
‘ この引数を設定することで、Visio側の保存処理が中断されます
‘ ※注意:BeforeDocumentSave自体にはCancel引数がないため、
‘ 実務的にはフラグ管理や別の手法を組み合わせるのが定石です。
End If
End Sub

—

陥りやすい罠とエンジニアの知見

1. 「キャンセル」の解釈を誤るな

実は `Document_BeforeDocumentSave` イベントには、残念ながら直接 `Cancel = True` と書ける引数が存在しません。
そのため、実務では「保存させない」ことよりも「警告を出してユーザーに修正を促す」フローを設計するのが賢明です。もし厳密に保存を阻止したい場合は、保存ボタンを無効化する等の「UI制御」を組み合わせるのが、Visio開発のプロの流儀です。

2. シェイプの巡回は「重い」

`For Each` で全ページを舐める処理は、シェイプ数が増えると露骨に重くなります。

  • 対策: すべてのシェイプをチェックするのではなく、特定のレイヤーや、特定の「マスターシェイプ」から作成されたオブジェクトのみを対象にするよう、`If shp.Master.Name = “…”` 等で絞り込みをかけてください。パフォーマンスはエンジニアの品格です。

3. オブジェクトのライフサイクル

VBAのコードは「誰が・いつ動かしているか」を意識してください。`doc` はイベントが発生したドキュメント自体を指します。`ActiveDocument` を使うのは、複数のファイルを開いている時に予期せぬ事故を招くので避けましょう。

—

まとめ:ここをクリアすれば、あなたはもう脱・初心者

今回学んだ「イベント駆動」の考え方は、Visio VBAのみならず、ExcelやAccessの自動化にもそのまま応用できる普遍的な知見です。

1. イベントプロシージャは `ThisDocument` に書く
2. 保存という「決定的瞬間」を制御する
3. パフォーマンスを考慮して探索範囲を限定する

この3点を押さえたあなたは、すでに「マクロを記録する人」から「システムを設計する人」へと進化しています。

次は、PDF出力時にこのバリデーションを自動実行させ、「入力が不完全な図面はPDF化すらさせない」という強固なワークフローを構築してみてください。あなたの手元で、Visioが単なる作図ソフトから「厳格なデータ管理システム」へと姿を変えるはずです。

応援しています。コードの海を楽しんでくださいね。

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