【入門編】【中級】マスターシェイプのカスタムプロパティ(ShapeData)を一括更新する – Visio VBA解析バイブル

スポンサーリンク
スポンサーリンク

ステンシルを支配せよ:マスターシェイプのカスタムプロパティを一括更新する極限の自動化術

こんにちは。現場のコードを、そして設計の魂を自動化で支えるチーフアーキテクトです。

「マクロの記録」ボタンを押し、生成されたコードを眺めては「……で、これをどう応用すればいいんだ?」と立ち止まってしまう。そんな経験はありませんか? もしそうなら、おめでとうございます。あなたは今、「記録者」から「エンジニア」へと進化する境界線に立っています。

今日扱うテーマは、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の世界は、あなたがコードで記述したルールに従って、静かな、しかし完璧な秩序を持って動き出します。その快感を、ぜひ味わってください。

「コードは、あなたの思考を拡張するための翼である。」

また次の技術解説でお会いしましょう。応援していますよ。

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