ステンシルを支配せよ:マスターシェイプのカスタムプロパティを一括更新する極限の自動化術
こんにちは。現場のコードを、そして設計の魂を自動化で支えるチーフアーキテクトです。
「マクロの記録」ボタンを押し、生成されたコードを眺めては「……で、これをどう応用すればいいんだ?」と立ち止まってしまう。そんな経験はありませんか? もしそうなら、おめでとうございます。あなたは今、「記録者」から「エンジニア」へと進化する境界線に立っています。
今日扱うテーマは、Visio VBAにおける中級への登竜門、「ステンシル内の全マスターに対するカスタムプロパティ(ShapeData)の一括追加・更新」です。
図面標準化の現場では、「すべての部品に『製造元』や『部品番号』の項目を追加してほしい」といった要求が頻繁に舞い込みます。これを手作業で一つずつマスターシェイプを開いて設定していく……そんな作業は、エンジニアの仕事ではありません。
さあ、オブジェクトの階層構造という「真実」を紐解きながら、エレガントな自動化の世界へ踏み出しましょう。
1. 概念の整理:Visioの「階層構造」を理解する
コードを書く前に、まず頭の中に「地図」を作ってください。ここを間違えると、どれほど優れたコードを書いても、目的の場所に辿り着けません。
Visioのオブジェクトモデルは、以下のような厳格な親子関係で成り立っています。
1. Application(Visioそのもの)
2. Document (Stencil)(ステンシルファイル:`.vssx`)
3. Master(マスターシェイプ:ステンシル内のテンプレート)
4. Shape(図面上に配置された個々の形)
5. ShapeData Section(カスタムプロパティが格納されている「領域」)
6. Row/Cell(プロパティの「行」と「値」)
今回のミッションは、「Stencil」の中にある全ての「Master」を探し出し、その中にある「ShapeData」という領域に、新しい「Row(行)」を書き込むことです。
図面上のシェイプをいじるのではなく、「マスター(型紙)そのもの」を書き換える。これが、図面全体を標準化するための鍵となります。
2. 実践:マスタープロパティ一括更新スクリプト
それでは、実際に動くコードを見てみましょう。このコードは、現在開いているステンシル内の全マスターに対し、指定した名前のカスタムプロパティを追加、あるいは既存のものを更新します。
Option Explicit
''' <summary>
''' ステンシル内の全マスターに対し、カスタムプロパティを一括で追加・更新する
''' </summary>
Sub BatchUpdateMasterShapeData()
Dim stn As Visio.Stencil
Dim mst As Visio.Master
Dim masterShape As Visio.Shape
Dim sec As Visio.Section
Dim rowIdx As Visio.Integer
' --- 設定エリア:ここを書き換えてください ---
Const PROP_LABEL As String = "管理番号" ' 追加・更新したいプロパティの表示名
Const PROP_NAME As String = "ID" ' ShapeSheet内部での変数名
Const PROP_VALUE As String = "未設定" ' 初期値
' ------------------------------------------
' 1. 現在アクティブなステンシルを取得
' ※ステンシルが開かれていないとエラーになります
On Error Resume Next
Set stn = ActiveDocument.Stencil
On Error GoTo 0
If stn Is Nothing Then
MsgBox "ステンシルが開かれていないか、ドキュメントがステンシルではありません。", vbCritical
Exit Sub
End If
Debug.Print "--- 更新処理開始 ---"
' 2. ステンシル内の全マスターをループで回す
For Each mst In stn.Masters
' マスター自体は「図形」ではないため、その中にある最初のシェイプのShapeSheetにアクセスする
' 通常、マスターの定義は最初のシェイプに紐付いています
Set masterShape = mst.Shapes(1)
' 3. ShapeDataセクション(カスタムプロパティ領域)を取得
Set sec = masterShape.Section(visSectionShapeData)
' 4. すでに同じ名前のプロパティが存在するかチェック
Dim rowExists As Boolean
rowExists = False
' セクション内の行を走査
For rowIdx = 0 To sec.Count - 1
' 行のラベル(表示名)を比較
If sec.RowLabel(rowIdx, visExists) = PROP_LABEL Then
rowExists = True
Exit For
End If
Next rowIdx
' 5. プロパティの追加または更新
If rowExists Then
' 既に存在する場合は、値を更新する
' RowIdxを特定して、そのセルの値を書き換える
sec.CellsC(rowIdx, PROP_NAME).FormulaU = """" & PROP_VALUE & """"
Debug.Print "Updated: " & mst.Name
Else
' 存在しない場合は、新しい行を追加する
' AddRow(行インデックス, セクション, 挿入位置, 既存行の扱い)
' ここでは末尾に追加
sec.AddRow visSectionRows, PROP_NAME, visAlways
' 追加した行のラベルを設定
sec.CellsC(sec.Count - 1, PROP_NAME).ResultStr = PROP_LABEL
' 値を設定
sec.CellsC(sec.Count - 1, PROP_NAME).FormulaU = """" & PROP_VALUE & """"
Debug.Print "Added: " & mst.Name
End If
Next mst
Debug.Print "--- 更新処理完了 ---"
MsgBox "全てのマスターの更新が完了しました。", vbInformation
End Sub
3. アーキテクトの視点:コードの深層解説
このコードをただコピペするだけでは、本当の力にはなりません。プロのエンジニアとして、以下の3つのポイントを理解してください。
① `mst.Shapes(1)` の意味
マスターオブジェクトそのものは「Shape(図形)」ではありません。しかし、マスターの中身を操作するためには、そのマスターを構成する図形(Shape)の「ShapeSheet(設計図)」にアクセスする必要があります。そのため、`mst.Shapes(1)` を通じて、マスターの心臓部へと潜り込んでいるのです。
② `visSectionShapeData` という領域
Visioの図形には多くの「セクション」が存在します。位置情報、サイズ情報、接続情報……。カスタムプロパティは `visSectionShapeData` という専用のセクションに格納されています。ここを正確に指定することが、迷宮に入り込まないための鉄則です。
③ `FormulaU` と `ResultStr` の使い分け
ここが最も陥りやすいエラーのポイントです。
- `FormulaU`: ShapeSheetに書き込む「式」を指定します。文字列を書き込む場合は、`”””文字列”””` のようにダブルクォーテーションで囲む必要があることに注意してください。
- `ResultStr`: ユーザーに見える「表示名(ラベル)」を扱う際に使います。
4. 陥りやすい罠:エラーを回避する知恵
実戦投入する前に、以下の「落とし穴」を覚えておいてください。
- ステンシルの保護:
読み取り専用のステンシル(`.vssx` ファイルが書き込み禁止など)に対して実行すると、エラーになります。必ず「保存可能な状態」であることを確認しましょう。
- 重複エラー:
`AddRow` を実行する際、すでに存在する行名を追加しようとすると、Visioは悲鳴を上げて停止します。私のコードのように、必ず「存在チェック(`rowExists`)」を行ってから処理を分岐させるのが、堅牢なコードを書くための作法です。
- 変更の反映:
マスターを書き換えた後、すでに図面上に配置されているシェイプには、即座には反映されません。マスターはあくまで「型」です。新しいシェイプを配置したときに、新しいプロパティが現れることを覚えておいてください。
最後に:一歩先へ
このスクリプトをマスターすれば、あなたは「一つ一つの図形を直す人」から、「図面全体のルールを定義する人」へと昇格しました。
次は、このプロパティに「入力規則(特定の文字しか入れられないようにする)」を加えたり、プロパティの値が変わったら「図形の色が変わる」ような動的な仕組み(ShapeSheetのFormula)を組み込んでみてください。
Visio VBAの世界は、あなたがコードで記述したルールに従って、静かな、しかし完璧な秩序を持って動き出します。その快感を、ぜひ味わってください。
「コードは、あなたの思考を拡張するための翼である。」
また次の技術解説でお会いしましょう。応援していますよ。
