【Visio VBA 掌握への第一歩】「マクロの記録」を卒業する。マスターシェイプの検索とDropメソッドの真実
こんにちは。現場の設計思想をコードに落とし込む、アーキテクトの視点へようこそ。
Visioでの業務自動化を進めていると、必ずと言っていいほど一つの壁にぶつかります。それは「マクロの記録機能で作ったコードが、自分では全く修正・応用できない」という問題です。
マクロの記録は、いわば「足跡」をなぞるだけの作業です。「何をしたか」はわかりますが、「なぜそのオブジェクトを操作したのか」というオブジェクトの構造(Object Model)が欠落しているからです。
今日は、その壁を突破するための極めて重要なステップ、「ステンシルからマスターシェイプを見つけ出し、ページ上に実体化(Drop)させる」というプロセスについて解説します。ここをマスターすれば、あなたは「記録されたコードの書き換え」から、「自らロジックを構築するエンジニア」へと進化できるはずです。
1. 概念の整理:設計図(Master)と製品(Shape)の違い
まず、プログラミングを始める前に、Visioの頭の中にある「階層構造」を正しく理解しましょう。ここを間違えると、コードを書く際に必ず迷子になります。
Visioの世界は、以下のピラミッド構造で成り立っています。
1. Application: Visioそのもの(宇宙)
2. Document: 開いている図面ファイル(世界)
3. Stencil: 図形が入っているカタログ(道具箱)
4. Master: カタログに載っている「設計図」(型)
5. Shape: ページに配置された「実体」(製品)
ここが最大のポイントです。「マスターシェイプ(Master)」は、まだページには存在していません。 あくまで「こういう形の図形を置いてください」という指示書に過ぎないのです。
私たちがVBAで行うべきことは、「カタログ(Stencil)から指示書(Master)を探し出し、それをページ(Page)というキャンバスに『ドロップ(Drop)』して、実体(Shape)として生成する」という一連の流れなのです。
2. 実装の勘所:マスターをどうやって「見つける」か
初心者が陥りやすいエラーの筆頭は、「存在しないマスターを呼び出そうとして、プログラムが止まってしまう」ことです。
例えば、`Application.FindStencil(“Basic Shapes”)` でステンシルを探し、その中の `”Rectangle”` という名前のマスターを探そうとしたとき、もしスペルミスがあったり、そのステンシルが開いていなかったりすると、VBAは即座にエラーを吐いて停止します。
プロのエンジニアは、常に「もし見つからなかったらどうするか?」という生存確認(存在チェック)をコードに組み込みます。
3. 実践コード:マスター検索からドロップまで
それでは、実際に「Basic Shapes」ステンシルの中から「Rectangle(四角形)」を探して、ページの中央に配置する堅牢なコードを見てみましょう。
Option Explicit
''' <summary>
''' 指定したステンシル内のマスターシェイプを検索し、ページ上に配置する
''' </summary>
Sub DropMasterExample()
Dim vsoPage As Visio.Page
Dim vsoStencil As Visio.Stencil
Dim vsoMaster As Visio.Master
Dim vsoShape As Visio.Shape
Dim stencilName As String
Dim masterName As String
Dim foundMaster As Boolean
' --- 設定エリア ---
stencilName = "Basic Shapes" ' ステンシルの名前(拡張子なしでも可)
masterName = "Rectangle" ' 配置したいマスターの名前
' ------------------
' 1. 操作対象のページを取得
Set vsoPage = ActivePage
foundMaster = False
' 2. ステンシルを取得する
' 注意:既に開いているステンシルを探し、なければエラーになる可能性があるため
' ここでは「開いているものから探す」という作法をとります
On Error Resume Next
Set vsoStencil = Application.FindStencil(stencilName)
On Error GoTo 0
If vsoStencil Is Nothing Then
MsgBox "エラー: ステンシル '" & stencilName & "' が見つかりません。先に開いておいてください。", vbCritical
Exit Sub
End If
' 3. ステンシルの中からマスターシェイプを検索
' マスターのコレクションをループして探すのが最も確実な方法です
Dim m As Visio.Master
For Each m In vsoStencil.Masters
If m.Name = masterName Then
Set vsoMaster = m
foundMaster = True
Exit For
End If
Next m
' 4. マスターが見つかったら、ページにDrop(配置)する
If foundMaster Then
' Dropメソッドの引数: (配置するマスター, X座標, Y座標)
' 座標はインチ単位(デフォルト設定の場合)です
' ここではページの中央付近 (4, 4) に配置します
Set vsoShape = vsoPage.Drop(vsoMaster, 4, 4)
' 配置に成功したら、そのシェイプの名前を変更したり色を変えたりも可能
vsoShape.Text = "配置成功!"
MsgBox "マスター '" & masterName & "' を配置しました。", vbInformation
Else
MsgBox "エラー: ステンシル内に '" & masterName & "' が見つかりませんでした。", vbExclamation
End If
' 5. オブジェクトの解放(メモリ管理の作法)
Set vsoShape = Nothing
Set vsoMaster = Nothing
Set vsoStencil = Nothing
Set vsoPage = Nothing
End Sub
4. 陥りやすいエラーと回避策(アーキテクトの助言)
このコードを動かす上で、あなたが直面するかもしれない壁とその乗り越え方を伝授します。
① 「マスターの名前」の罠
Visioのマスター名は、表示上の名前と内部的な名前が異なる場合があります。
- 対策: `Debug.Print m.Name` をループ内で実行し、イミディエイトウィンドウに表示される「真の名前」を確認してください。
② 「座標」の罠
`vsoPage.Drop(vsoMaster, 4, 4)` の `4, 4` は、目に見える「グリッド」ではなく、Visioの内部的な単位(多くはインチ)に基づいています。
- 対策: ページサイズが極端に小さい場合、指定した座標がページ外になり、シェイプが見えないことがあります。`vsoPage.PageSheet.CellsU(“PageWidth”)` などを使って、ページサイズを動的に取得する癖をつけると、より汎用的なコードになります。
③ 「オブジェクトのライフサイクル」
コードの最後で `Set vsoShape = Nothing` と書いているのが目に入りましたか?
小規模なマクロでは省略しても動きますが、大量の図形を自動生成するようなプロフェッショナルなツールを作る場合、使い終わったオブジェクトを明示的に解放しないと、メモリを食いつぶし、Visioが重くなる原因になります。
まとめ:ここをクリアすれば、基本はバッチリです
今日の学びを整理しましょう。
1. 階層を意識せよ: ステンシルは「カタログ」、マスターは「設計図」、シェイプは「実体」である。
2. Dropは「生成」である: `Drop` メソッドを使うことで、初めて設計図がページ上のオブジェクトに変換される。
3. 存在確認を怠るな: `FindStencil` やループ処理による名前チェックは、エラーを防ぐための「防御的プログラミング」の基本である。
「マクロの記録」はあくまでヒントです。今回のように、オブジェクトの構造を理解して、自らの手で「設計図から製品を作る」ロジックを組み立てられるようになれば、あなたのVisio自動化スキルは劇的に向上します。
一歩ずつ、確実に。次回のレッスンでお会いしましょう。
