こんにちは!Visioのオートメーションの世界へようこそ。
マクロの記録ボタンを押して、生成されたコードをただ眺める日々から、一歩先へ進みたい時期ですね。
今回は、Visio VBAをマスターする上で絶対に知っておくべき「隠された司令塔」、`Document.DocumentSheet`(ドキュメントシェイプ)についてお話しします。
「ページごとに設定値がバラバラになって管理しきれない…」
「マクロを実行するたびに、ユーザーに設定値を聞き返すのは面倒だ…」
そんな現場の悩みを一発で解決する、プロの定石とも言えるグローバル変数保持テクニックを伝授しましょう。ここをクリアすれば、あなたのVisio VBAのスキルは確実にワンランク上のステージへ到達しますよ。
—
1. なぜ「普通の変数」ではダメなのか?Visioのライフサイクルを知る
VBAを書くとき、私たちはつい `Public ivalue As Integer` のようなグローバル変数をモジュール内に定義しがちです。しかし、Visioの図面(`.vsd` / `.vsdx`)において、これは悪手であることが多いです。
なぜなら、ユーザーが図面を保存して一旦閉じ、翌日再び開き直したとき、メモリ上に展開されていたVBAのグローバル変数はすべて綺麗さっぱり消え去っているからです。
「図面と一緒に設定値も保存したい」
「図面をメールで別の人に送っても、設定や管理番号を引き継がせたい」
こうした要件を満たすために、Visioには図面ファイル自体にデータを縫い付ける仕組みがあらかじめ用意されています。それが、すべてのドキュメントにひっそりと存在する「ドキュメントシェイプ(DocumentSheet)」です。
—
2. Document.DocumentSheet とは何か?(図解的アプローチ)
Visioのオブジェクト階層を思い浮かべてみてください。
[Application] (Visioアプリ全体)
└ [Document] (開いている図面ファイル)
├ [DocumentSheet] ★今回の主役!図面の裏側に潜む「見えない司令塔」
└ [Pages] (ページたち)
└ [Page] (個別のページ)
└ [Shapes] (図形たち)
通常のシェイプ(四角形や丸など)はページ上に描画されますが、`DocumentSheet` はキャンバスのどこにも見えません。
しかし、こいつの正体は、「図面ファイルに1つだけ必ず存在する、最強のShapeSheet(データ保持庫)」なのです。
ここにカスタムセル(ユーザー定義セルのようなもの)を追加しておけば、図面ファイルと運命を共にする「永続的なグローバル変数」として機能させることができます。
—
3. 実践!DocumentSheet を操作するVBAコード
それでは、実際にドキュメントシェイプに値を書き込み、それを読み出すコードを見てみましょう。
今回は、図面の管理番号(`ProjectID`)と、承認ステータス(`Status`)をドキュメントシェイプに保存するシナリオを想定します。
以下のコードを、VBAエディタ(Alt + F11)の標準モジュールに貼り付けて実行してみてください。
Option Explicit
‘ ==============================================================================
‘ テーマ: Document.DocumentSheet を使ったグローバル変数の読み書き
‘ ==============================================================================
Public Sub ManageGlobalVariables()
Dim doc As Visio.Document
Dim docShp As Visio.Shape
Dim valCell As Visio.Cell
‘ 1. 現在アクティブなドキュメントを取得
Set doc = ActiveDocument
‘ 2. ドキュメントの裏側にある「司令塔(DocumentSheet)」をキャッチする
Set docShp = doc.DocumentSheet
On Error GoTo ErrorHandler
‘ ==========================================================================
‘ 【書き込みのフェーズ】
‘ ==========================================================================
‘ ユーザ定義セルが存在しない場合は新規追加、存在する場合は値の上書きを行う
‘ Visioでは CellExistsU を使って存在確認をするのが安全です。
If docShp.CellExistsU(“User.ProjectID”, False) = False Then
‘ 存在しないので、カスタムセル「User.ProjectID」を追加
Set valCell = docShp.CellsU(“User.ProjectID”)
valCell.FormulaU = “””PRJ-2023-001″”” ‘ 文字列はダブルクォーテーションで囲む
Else
‘ 既に存在するので値を更新
docShp.CellsU(“User.ProjectID”).FormulaU = “””PRJ-2023-999″””
End If
‘ もう一つ別の変数(ステータス)を書き込んでみる
If docShp.CellExistsU(“User.ApprovalStatus”, False) = False Then
Set valCell = docShp.CellsU(“User.ApprovalStatus”)
valCell.FormulaU = “””Draft”””
End If
MsgBox “ドキュメントシェイプへの書き込みが完了しました!”, vbInformation, “保存成功”
‘ ==========================================================================
‘ 【読み出しのフェーズ】
‘ ==========================================================================
Dim loadedProjectID As String
Dim loadedStatus As String
‘ ResultStr(visNone) を使うことで、ShapeSheet内の数式から「生の値(文字列)」を取り出せます
loadedProjectID = docShp.CellsU(“User.ProjectID”).ResultStr(visNone)
loadedStatus = docShp.CellsU(“User.ApprovalStatus”).ResultStr(visNone)
‘ 結果をイミディエイトウィンドウに出力
Debug.Print “— ドキュメント変数リスト —”
Debug.Print “プロジェクトID: ” & loadedProjectID
Debug.Print “承認ステータス: ” & loadedStatus
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
コードの重要ポイント解説
1. `doc.DocumentSheet` の取得
`ActiveDocument.DocumentSheet` と記述するだけで、迷うことなくドキュメント専用のシェイプオブジェクトを取得できます。これだけで準備は完了です。
2. `CellExistsU` による安全確認
いきなり存在しないセルにアクセスするとVBAはエラーを吐いて停止します。`CellExistsU(cellName, False)` を使うことで、そのカスタムセルがすでに作られているかを事前にチェックできます。
3. 文字列を代入するときの罠 (`”””…”””`)
ShapeSheetに文字列の数式を代入するときは、VBA側から見ると二重三重にクォーテーションのエスケープが必要になります。コード内の `”””PRJ-2023-001″””` は、ShapeSheet側に `”PRJ-2023-001″` という文字列(ダブルクォーテーション付きの数式)として書き込むためのVisioお決まりの書き方です。
4. `ResultStr(visNone)` による値の取得
ShapeSheetから値を取り出すときは、単に `.Value` とするよりも `.ResultStr(visNone)` を使う方が、文字列として確実に安全に取り出せるためおすすめです。
—
4. 陥りやすいエラーと「現場の知見」
このテクニックを使う上で、初心者が必ずと言っていいほどハマる罠があります。先輩エンジニアからのアドバイスとして心に留めておいてください。
罠①:「あれ? 保存して開き直したら値が消えた!?」
原因の多くは、図面を上書き保存していないことです。
`DocumentSheet` に書き込んだデータは、あくまで「メモリ上のドキュメント」に保持されています。この状態からファイルを保存(`.Save` や手動での保存)しなければ、ファイル自体には書き込まれません。
マクロで設定値を自動書き込みした後は、必ず `doc.Save` を呼ぶか、ユーザーに保存を促す導線を作ってください。
罠②: ShapeSheetの「名前(Name)」と「ローカライズ」の罠
Visioには、日本語版と英語版の数式・セルの名前問題があります。
コードを書くときは、必ず末尾に `U` がついたメソッド(`CellsU`, `CellExistsU` など)を使用してください。
- ❌ `Cells(“User.ProjectID”)` (言語環境によってエラーになるリスクあり)
- ⭕ `CellsU(“User.ProjectID”)` (言語に依存しないユニバーサル名で安全)
—
まとめ
今回は、Visioの裏側で図面全体のグローバル変数を安全に保持・管理する `Document.DocumentSheet` の活用法を解説しました。
- 通常のVBA変数はファイル閉じたら消えるが、DocumentSheetならファイルと一緒に永続保存される。
- `ActiveDocument.DocumentSheet` で取得し、`User-defined Cells` (ユーザー定義セル)の要領で自由に読み書きできる。
- `CellsU` や `CellExistsU` を使って、言語依存のないスマートなコードを書く。
ここをクリアすれば、単なる「図形を描くだけのマクロ」から、「高度なドキュメント管理システムとしてのVisioアプリ開発」へステップアップできます。
ぜひ、あなたの次の自動化ツールにこの知見を取り入れてみてください。「おっ、分かってるね!」と言われるコードが書けるはずです。それでは、また次回の極限の知見でお会いしましょう!
