Visio VBAの「グローバル変数依存」から脱却せよ:DocumentSheetによる永続的状態管理の極意
多くのエンジニアがVisio VBAでツールを開発する際、陥る罠がある。それは「状態の保持」を標準モジュールのグローバル変数(`Public`変数)に頼り切ることだ。
プロジェクトを閉じればメモリ上の変数は霧散する。ファイルを開き直すたびに設定がリセットされ、かといって外部のINIファイルやレジストリに頼れば、配布のたびに環境依存のトラブルに頭を抱えることになる。
真に堅牢なVisioツールは、「状態をファイルの中に抱え込む」。今回は、Visioの隠れた最強オブジェクト『DocumentSheet』を活用し、ドキュメントそのものに設定やログを刻み込む、プロフェッショナルな状態管理術を伝授する。
—
なぜ「DocumentSheet」なのか?
Visioには、図面全体の設定やメタデータを保持するための特別な「隠しシェイプ」が存在する。それが `Document.DocumentSheet` だ。
ここにある `User` セクションは、本来はVisioの内部動作のために予約されている領域だが、ここに独自のセルを動的に生成・保持させることで、以下のメリットを享受できる。
1. 自己完結性: ファイルを別PCに送っても設定がついていく。
2. 永続性: 保存すれば状態が残る。`Save`操作と連動する。
3. クリーンな構造: セル名と値のペアで管理するため、テキスト解析が不要。
—
実装:DocumentSheet操作のプロダクションコード
まずは、状態を読み書きするためのラッパーモジュールを用意する。この実装では、`User`セクションの存在確認と、なければ自動生成する堅牢性を持たせている。
‘ @description DocumentSheetのUserセクションを活用した設定管理
Option Explicit
”’
”’
Public Sub SetGlobalState(ByVal key As String, ByVal value As String)
Dim docSheet As Visio.Shape
Set docSheet = ThisDocument.DocumentSheet
‘ Userセクションにセルが存在するか確認し、なければ追加
If Not docSheet.CellExists(“User.” & key, visExistsAnywhere) Then
docSheet.AddNamedRow visSectionUser, key, 0
End If
‘ セルに値をセット(文字列として格納)
docSheet.Cells(“User.” & key).Formula = “””” & value & “”””
End Sub
”’
”’
Public Function GetGlobalState(ByVal key As String, Optional ByVal defaultValue As String = “”) As String
Dim docSheet As Visio.Shape
Set docSheet = ThisDocument.DocumentSheet
If docSheet.CellExists(“User.” & key, visExistsAnywhere) Then
‘ FormulaValueは評価済みの値を返すため、そのまま取得可能
GetGlobalState = docSheet.Cells(“User.” & key).ResultStr(“”)
Else
GetGlobalState = defaultValue
End If
End Function
—
運用上のクリティカルな注意点
この手法は強力だが、無秩序に使うとVisioのパフォーマンスを劣化させる。以下のアーキテクチャ設計を忘れてはならない。
1. 「ログ」と「設定」を混同しない
`DocumentSheet`は頻繁な書き込みには向かない。数秒おきのログ記録をここで行うと、Visioの保存操作(Undoスタック)を圧迫する可能性がある。
- 設定(Settings): ツール起動時や変更時に書き込むもの。
- ログ(Logs): 大量の場合は外部テキストファイルへ。直近の実行結果IDなど、軽量な情報のみを保持せよ。
2. 名前空間(プレフィックス)の活用
`DocumentSheet`は他のアドオンやVisio本体の機能と競合するリスクがある。キー名には必ず `MyApp_` のようなプロジェクト独自のプレフィックスを付けること。
3. 型のキャストを意識せよ
`Cell.Formula`には文字列しか入らない。数値を保存する場合も、一度文字列に変換し、読み出し時に `Val()` や `CLng()` で変換する手順を必ず踏むこと。
—
現場のリーダーからの提言
多くの開発者は、「今の業務を自動化する」ことだけに腐心し、「数ヶ月後にこのツールをメンテナンスする自分」を想像していない。
グローバル変数に頼るコードは、デバッグ時に「誰がいつ値を書き換えたのか」を追跡するのが極めて困難だ。一方で、`DocumentSheet`に情報を集約すれば、Visioの「シェイプシート」を開くだけで、現在のツール状態を視覚的にデバッグできる。
「コードの複雑さは、データの可視化で解決せよ」
これが、大規模なVisioツール開発における鉄則である。この仕組みをベースに、あなたの開発するツールを「使い捨てのスクリプト」から「資産となる業務アプリケーション」へと昇華させてほしい。
