Visio VBAを掌握する極限の知見:マスターシェイプのShapeSheetを一括置換し、図形属性を支配する
「マクロの記録」を使って、一つひとつの図形の色を変える。そんな作業に時間を溶かしていませんか?
もしあなたが、「図面全体のスタイルがバラバラで、修正に半日かかる」という状況に直面しているなら、それはあなたが「オブジェクトの表面」ではなく「設計図(ShapeSheet)の深層」にアクセスすべき時が来たという合図です。
こんにちは。今日は、Visio VBAにおける中級への登竜門、「ステンシル内のマスターシェイプに対し、ShapeSheetを介して属性を一括置換する技術」についてお話ししましょう。
ここをクリアすれば、あなたは単なる「マクロ利用者」から、Visioというシステムの「設計者」へと進化できるはずですよ。
1. 概念の整理:なぜ「図形」ではなく「マスター」を叩くのか
まず、私たちが何を操作しようとしているのか、その構造(アーキテクチャ)を整理しましょう。
Visioの構造は、以下の階層になっています。
1. Document (ドキュメント): 開いているファイルそのもの。
2. Stencil (ステンシル): 図形(マスター)のカタログ。
3. Master (マスターシェイプ): ステンシルに格納されている「型」。
4. ShapeSheet (シェイプシート): 図形のすべての性質(色、大きさ、挙動)が記述された、Excelのようなセル形式のデータベース。
通常、画面上にある図形を操作するのは「ドキュメント上のShape」です。しかし、今回私たちが目指すのは「カタログ(ステンシル)そのものの定義を書き換える」ことです。
マスターシェイプのShapeSheetを書き換えれば、その後にドキュメントへドラッグ&ドロップされるすべての図形が、最初から新しい属性を持った状態で登場します。これこそが、一括管理の極意です。
2. 実践:マスターシェイプの属性を一括置換するコード
では、具体的なコードを見ていきましょう。
今回は例として、「特定のステンシル内にあるすべてのマスターシェイプの、塗りつぶし色(FillForeColor)を特定の色に統一する」という処理を実装します。
Option Explicit
''' <summary>
''' 指定したステンシル内の全マスターシェイプの塗りつぶし色を一括変更する
''' </summary>
Sub BatchUpdateMasterShapeColors()
Dim stencil As Visio.Stencil
Dim master As Visio.Master
Dim targetStencilName As String
Dim newColor As Long
' --- 設定エリア ---
targetStencilName = "Basic Shapes.vssx" ' 操作したいステンシルの名前
newColor = RGB(255, 255, 0) ' 変更後の色(例:黄色)
' ------------------
On Error GoTo ErrorHandler
' 1. ステンシルを取得
' すでに開いているステンシルを探し、なければ開くプロセスが必要ですが、
' ここではシンプルに「開いているもの」を対象にします。
Set stencil = Application.Documents(targetStencilName)
If stencil Is Nothing Then
MsgBox "指定されたステンシルが見つかりません: " & targetStencilName, vbCritical
Exit Sub
End If
' 2. トランザクションの開始 (重要!)
' これを行うことで、一連の処理を「一つの操作」として記録できます。
' 万が一失敗しても「元に戻す(Undo)」が一度で済み、パフォーマンスも向上します。
Application.StartTransaction
Debug.Print "--- 置換処理開始 ---"
' 3. マスターのループ処理
For Each master In stencil.Masters
Debug.Print "Processing Master: " & master.Name
' マスターのメインシェイプに対してShapeSheetを操作する
' マスター自体がShapeSheetを持つのではなく、マスターの中の「最初のシェイプ」が
' 主な属性を保持していることが一般的です。
Dim shp As Visio.Shape
Set shp = master.Shapes(1)
' 4. エラー制御付きのセル書き換え
' すべてのマスターに「FillForeColor」セルが存在するとは限りません。
' 存在しないセルにアクセスするとエラーで止まるため、慎重に扱います。
On Error Resume Next
shp.Cells("FillForeColor").Formula = "RGB(" & _
newColor Mod 256 & "," & _
(newColor \ 256) Mod 256 & "," & _
(newColor \ 65536) Mod 256 & ")"
' エラーが発生した(セルが存在しなかった)場合の判定
If Err.Number <> 0 Then
Debug.Print " [Skip] Cell 'FillForeColor' not found in " & master.Name
Err.Clear
Else
Debug.Print " [Success] Color updated."
End If
On Error GoTo ErrorHandler ' エラーハンドリングを元に戻す
Next master
' 5. トランザクションの終了
Application.StopTransaction
MsgBox "マスターシェイプの一括更新が完了しました!", vbInformation
Exit Sub
ErrorHandler:
' エラーが発生した場合は、中途半端な状態を防ぐためにトランザクションを破棄
Application.StopTransaction
MsgBox "予期せぬエラーが発生しました: " & Err.Description, vbCritical
End Sub
3. プロの視点:ここをクリアすれば、あなたはもう初心者ではない
このコードには、単なる「マクロの記録」には決して現れない、プロフェッショナルなテクニックが3つ組み込まれています。
① Transaction(トランザクション)の制御
`Application.StartTransaction` と `StopTransaction` を使っていますか?
これは、データベース操作における「コミット/ロールバック」と同じ概念です。
大量のマスターを書き換える際、これを使わないとVisioは一回一回の変更に対して画面更新や履歴の保存を行おうとするため、動作が極端に重くなります。また、途中でエラーが起きた際、「半分だけ変わって、半分は古いまま」という最悪の状態を防げるのです。
② 「セルの存在」を疑う(防御的プログラミング)
ここが一番の落とし穴です。
すべての図形が「塗りつぶし色」を持っているわけではありません。線だけの図形や、特殊なカスタムシェイプには、`FillForeColor` というセル自体が存在しないことがあります。
存在しないセルに `.Formula` を代入しようとした瞬間、プログラムは悲鳴を上げて止まります。
`On Error Resume Next` を局所的に使い、「なければスキップする」という柔軟性を持たせることが、堅牢なコードへの第一歩です。
③ Formula(数式)への書き込み
ShapeSheetの値を書き換えるとき、`.Result` ではなく `.Formula` を使いましょう。
`.Result` は「現在の計算結果」を読み取るためのもので、値を書き込むためのプロパティではありません。設計図を書き換えるなら、常に「数式(Formula)」をターゲットにする。これがShapeSheetを掌握する鉄則です。
最後に:一歩先へ進むあなたへ
マスターシェイプの操作をマスターすれば、あなたの作るツールは「単なる便利ツール」から「組織の標準を規定するプラットフォーム」へと昇華します。
「一つずつ直す」という作業は、エンジニアの仕事ではありません。「仕組みを作る」ことこそが、私たちの本分です。
もし、今回のコードでエラーが出たり、思い通りに動かなかったりしたら、いつでも相談してください。ShapeSheetの奥深さは、学べば学ぶほど面白いですよ。
さあ、次はどんな自動化に挑戦しますか?応援しています。
