Visio VBAマスターへの道:複雑な図面を整理する「レイヤー自動整理」ルーチンを創り出す!
皆さん、こんにちは!Visio VBAの世界へようこそ。私は、日頃から業務自動化の最前線で、Visio VBAを駆使して日々のルーチンワークを楽々こなしているチーフアーキテクトです。
「マクロの記録」から一歩踏み出して、もっとスマートにVisioを使いこなしたい!そう思っているあなた。今日は、そんなあなたのために、Visio VBAの奥深い世界への扉を開く、とっておきのテクニックをご紹介します。
今回ご紹介するのは、「ページ内の全シェイプを特定のレイヤーに自動振り分けする『レイヤー自動整理』ルーチン」です。
なぜ「レイヤー自動整理」が重要なのか?
Visioで複雑な図面を作成していると、気がつけばシェイプがごちゃ混ぜになり、目的のシェイプを見つけるのに一苦労…なんて経験はありませんか?
- 「この線はどの設備のものだっけ?」
- 「このテキストボックス、どこに配置したっけ?」
こんな悩み、レイヤーをうまく活用すれば劇的に解決できます!レイヤーとは、図面上の要素を「グループ分け」する機能のこと。例えば、「設備機器」「配管」「電気配線」「注釈」など、目的に応じてレイヤーを分けることで、表示・非表示を切り替えたり、特定のレイヤーだけを編集したりと、図面管理が格段に楽になります。
しかし、手作業で一つ一つシェイプをレイヤーに振り分けるのは、時間も手間もかかりますよね。そこで登場するのが、今回ご紹介する「レイヤー自動整理」ルーチンです!このルーチンを使えば、シェイプの種類や属性を自動で判定し、あらかじめ設定したルールに従って、シェイプを適切なレイヤーに自動で移動させることができます。
まるで、図面のお掃除ロボットのようなものですね!これにより、図面の可読性が向上し、メンテナンス性も格段にアップします。
読者の皆さんへ:ここをクリアすれば、Visio VBAの基本はバッチリ!
この記事では、Visio VBAの基本的な使い方から、コードの意味、そして開発でよく遭遇するエラーとその対処法まで、図解を交えながら丁寧に解説していきます。
- 「VBAって難しそう…」
- 「マクロの記録しか使ったことがない…」
そんな不安を感じている方も大丈夫!優しく、そして知的に、あなたのVisio VBAマスターへの道をサポートします。さあ、一緒にこの「レイヤー自動整理」ルーチンを創り上げていきましょう!
—
第1章:Visio VBAの基礎の基礎 ~オブジェクトとプロパティを理解する~
まず、Visio VBAを理解するために、いくつかの基本的な概念を押さえましょう。
1.1 Visio VBAにおける「オブジェクト」とは?
Visio VBAの世界では、図面を構成するあらゆるものが「オブジェクト」として扱われます。
- Application: Visioアプリケーションそのもの
- Document: 開いているVisioファイル(.vsd, .vsdxなど)
- Page: ドキュメント内の各ページ
- Shape: 図面上の図形(線、四角、テキストボックスなど)
- Layer: シェイプをグループ化するためのレイヤー
これらのオブジェクトは、それぞれが持つ「プロパティ」や「メソッド」を通じて操作できます。
図解:オブジェクトの階層構造
イメージとしては、親から子へ、より具体的なものへと連なるような構造です。
Application
└─ Documents (コレクション)
└─ Document (特定のドキュメント)
└─ Pages (コレクション)
└─ Page (特定のページ)
└─ Shapes (コレクション)
└─ Shape (特定のシェイプ)
この階層構造を理解することが、VBAコードを書く上での地図となります。
1.2 オブジェクトの「プロパティ」と「メソッド」
- プロパティ (Property): オブジェクトの「状態」や「属性」を表します。例:「シェイプの色」「テキストの内容」「シェイプの位置」など。
- `Shape.Text = “これはテキストです”`
- `Shape.Cells(“FillColor”).FormulaU = “RGB(255,0,0)”` (塗りつぶし色を赤に設定)
- メソッド (Method): オブジェクトが実行できる「操作」や「動作」を表します。例:「シェイプを削除する」「シェイプをコピーする」「シェイプのサイズを変更する」など。
- `Shape.Delete`
- `Shape.Copy`
これらのプロパティやメソッドを組み合わせて、私たちはVisioの操作を自動化していくのです。
1.3 「レイヤー」オブジェクトと「シェイプ」オブジェクトの関係
今回のテーマである「レイヤー」と「シェイプ」の関係も、VBAで操作する上で非常に重要です。
- Page オブジェクト: 各ページは、複数の「Layer」オブジェクトの集合体(コレクション)を持っています。
- Layer オブジェクト: 各レイヤーは、そのレイヤーに属する「Shape」オブジェクトの集合体(コレクション)を持つわけではありません。
- Shape オブジェクト: 各シェイプは、自分がどの「Layer」に属しているか、という情報(プロパティ)を持っています。
これが少しトリッキーな点かもしれません。シェイプは、自分が属するレイヤーの情報を「持っている」のですが、レイヤー側が「このシェイプが私に属していますよ」という情報を直接管理しているわけではないのです。
シェイプを特定のレイヤーに移動させるということは、そのシェイプの「Layer」プロパティを、目的のレイヤーの「Name」や「ID」に設定し直す、ということになります。
—
第2章:レイヤー自動整理ルーチンの設計 ~何をするか、どうやるか~
いよいよ本題です!「レイヤー自動整理」ルーチンをどのように設計するか、具体的なステップを見ていきましょう。
2.1 ルーチンの全体像
このルーチンは、以下の流れで動作します。
1. 対象ページの特定: どのページを整理するかを決めます。通常はアクティブなページです。
2. レイヤーの準備: 整理に必要なレイヤーが存在するか確認し、なければ作成します。
3. シェイプの抽出: 対象ページ上の全てのシェイプを取得します。
4. シェイプの判定: 各シェイプが何者か(例:テキストボックス、コネクタ、特定のステンシルから作られたシェイプなど)を判定します。
5. レイヤーへの割り当て: 判定結果に基づいて、シェイプを適切なレイヤーに移動させます。
6. 完了メッセージ: 処理が完了したことをユーザーに伝えます。
2.2 シェイプの判定ロジック:ここが「頭脳」部分!
「シェイプの判定」が、このルーチンの肝となります。どのような基準でシェイプを振り分けるか、いくつかの例を考えてみましょう。
- シェイプのタイプで分ける:
- テキストボックス (`visTypeLabel`): 「注釈」レイヤーへ
- コネクタ (`visTypeConnectoe`): 「コネクタ」レイヤーへ
- グループシェイプ (`visTypeGroup`): 「グループ」レイヤーへ
- シェイプのテキスト内容で分ける:
- テキストに「設備名」が含まれる: 「設備」レイヤーへ
- テキストに「型番」が含まれる: 「部品情報」レイヤーへ
- シェイプのスタイル(ステンシル)で分ける:
- 「ネットワーク図」ステンシルの「ルーター」シェイプ: 「ネットワーク機器」レイヤーへ
- 「基本図形」ステンシルの「円」シェイプ: 「図形」レイヤーへ
今回は、比較的シンプルで汎用性の高い「シェイプのタイプ」と「シェイプのテキスト」で判定するロジックを実装してみましょう。
2.3 必要なレイヤーの準備
整理を始める前に、今回使用するレイヤーが存在するか確認し、なければ作成する必要があります。
- 「注釈」レイヤー
- 「コネクタ」レイヤー
- 「設備」レイヤー
- 「その他」レイヤー (上記いずれにも当てはまらないもの)
これらのレイヤーがない場合、VBAコードで新規作成できるようにしておきます。
—
第3章:実践!レイヤー自動整理ルーチン VBAコード解説
さあ、いよいよ具体的なVBAコードを見ていきましょう。コードブロックには、各行の処理内容を丁寧にコメントで解説します。
3.1 コード全体(Sub プロシージャ)
まず、全体の骨格となるSubプロシージャです。
Option Explicit ‘ 変数宣言を強制するおまじない
Sub AutoOrganizeShapesByLayer()
‘ === 変数宣言 ===
Dim TargetPage As Visio.Page ‘ 対象となるページオブジェクト
Dim CurrentShape As Visio.Shape ‘ 現在処理中のシェイプオブジェクト
Dim TargetLayerName As String ‘ 移動先のレイヤー名
Dim LayerExists As Boolean ‘ 指定したレイヤーが存在するかどうか
Dim LayerObj As Visio.Layer ‘ Layerオブジェクト
Dim ShapeType As Integer ‘ シェイプのタイプ
Dim ShapeText As String ‘ シェイプのテキスト
Dim DefaultLayerName As String ‘ デフォルト(その他)レイヤー名
Dim TargetLayer As Visio.Layer ‘ 移動先のレイヤーオブジェクト
‘ === 初期設定 ===
Const ALLOCATED_LAYER_PREFIX As String = “AutoLayer_” ‘ 自動割り当てレイヤーのプレフィックス
DefaultLayerName = ALLOCATED_LAYER_PREFIX & “Others” ‘ 「その他」レイヤー名
‘ === 1. 対象ページの特定 ===
‘ 現在アクティブなページを取得
On Error Resume Next ‘ エラーが発生しても処理を続行する設定(ページがない場合などに備える)
Set TargetPage = Visio.ActivePage
On Error GoTo 0 ‘ エラーハンドリングを元に戻す
If TargetPage Is Nothing Then
MsgBox “アクティブなページがありません。図面を開いて、ページを選択してください。”, vbExclamation
Exit Sub ‘ 処理を終了
End If
‘ === 2. レイヤーの準備 ===
‘ 必要なレイヤー(「その他」レイヤー)が存在するか確認し、なければ作成
LayerExists = False
For Each LayerObj In TargetPage.Layers
If LayerObj.Name = DefaultLayerName Then
LayerExists = True
Exit For
End If
Next LayerObj
If Not LayerExists Then
‘ レイヤーが存在しない場合、新しく作成する
Set LayerObj = TargetPage.Layers.Add(DefaultLayerName)
‘ 新しく作成したレイヤーをデフォルトレイヤーとして設定
Set TargetLayer = LayerObj
Debug.Print “レイヤー ‘” & DefaultLayerName & “‘ を作成しました。”
Else
‘ 既存のレイヤーオブジェクトを取得
Set TargetLayer = TargetPage.Layers(DefaultLayerName)
End If
‘ === 3. シェイプの抽出 ===
‘ ページ内の全てのシェイプをループ処理
‘ TargetPage.Shapesコレクションには、グループシェイプ内のシェイプは直接含まれないため、
‘ 各シェイプのGeometryCountプロパティなどを確認し、グループシェイプではないものを対象とする
‘ より高度な処理では、再帰処理でグループ内のシェイプも取得するが、今回はシンプルにページ直下のシェイプを対象とする
For Each CurrentShape In TargetPage.Shapes
‘ === 4. シェイプの判定とレイヤーへの割り当て ===
ShapeType = CurrentShape.Type
ShapeText = Trim(CurrentShape.Text) ‘ シェイプのテキストを取得し、前後の空白を削除
‘ 初期状態では「その他」レイヤーを仮定
TargetLayerName = DefaultLayerName
‘ — 判定ロジック —
Select Case ShapeType
Case Visio.visTypeLabel ‘ テキストラベルの場合
‘ テキスト内容で判定
If InStr(1, ShapeText, “注意:”, vbTextCompare) > 0 Or _
InStr(1, ShapeText, “情報:”, vbTextCompare) > 0 Then
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Notes”
ElseIf Len(ShapeText) > 0 Then ‘ テキストが空でない場合
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Labels”
Else
TargetLayerName = DefaultLayerName ‘ テキストが空なら「その他」
End If
Case Visio.visTypeConnector ‘ コネクタの場合
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Connectors”
Case Visio.visTypeGroup ‘ グループシェイプの場合
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Groups”
‘ ここに、さらにシェイプのマスター名やカスタムプロパティで判定するロジックを追加できます
‘ 例: If CurrentShape.Name = “Basic_Rectangle.1616” Then TargetLayerName = “MyShapes”
Case Else ‘ その他のシェイプタイプ
TargetLayerName = DefaultLayerName ‘ 一旦「その他」に割り当て
End Select
‘ — レイヤーの存在確認と作成 —
‘ 判定結果で指定されたレイヤーが存在するか確認
LayerExists = False
For Each LayerObj In TargetPage.Layers
If LayerObj.Name = TargetLayerName Then
LayerExists = True
Exit For
End If
Next LayerObj
‘ 存在しない場合は作成
If Not LayerExists Then
Set LayerObj = TargetPage.Layers.Add(TargetLayerName)
Debug.Print “レイヤー ‘” & TargetLayerName & “‘ を作成しました。”
End If
‘ — シェイプを対象レイヤーに移動 —
‘ 現在のシェイプが、目的のレイヤーとは異なる場合のみ移動処理を実行
If CurrentShape.Layer.Name <> TargetLayerName Then
Set TargetLayer = TargetPage.Layers(TargetLayerName) ‘ 目的のレイヤーオブジェクトを取得
CurrentShape.Layer = TargetLayer ‘ シェイプのLayerプロパティに目的のレイヤーを設定
‘ Debug.Print “シェイプ ‘” & CurrentShape.Name & “‘ をレイヤー ‘” & TargetLayerName & “‘ に移動しました。”
End If
Next CurrentShape
‘ === 5. 完了メッセージ ===
MsgBox “ページ ‘” & TargetPage.Name & “‘ のシェイプ整理が完了しました。”, vbInformation
End Sub
3.2 コードのポイント解説
3.2.1 `Option Explicit`
`Option Explicit` は、VBAコードの冒頭に記述することで、宣言されていない変数の使用を禁止します。これは非常に重要な習慣です。
- メリット:
- タイプミスによるエラーの防止: 変数名を間違えた場合、コンパイルエラーで早期に発見できます。
- コードの可読性向上: どの変数が使用されているかが明確になります。
- メモリの節約: 不要な変数の生成を防ぎます。
3.2.2 変数宣言 (`Dim`)
VBAでは、使用する変数は事前に `Dim` キーワードを使って宣言する必要があります。これにより、変数の型(Integer, String, Objectなど)が明確になり、プログラムの効率と安全性が向上します。
- `Dim TargetPage As Visio.Page`: `Visio.Page` 型の `TargetPage` という名前の変数を宣言しています。
- `Dim CurrentShape As Visio.Shape`: `Visio.Shape` 型の `CurrentShape` という名前の変数を宣言しています。
- `Dim LayerExists As Boolean`: `Boolean` 型(True/False)の `LayerExists` という名前の変数を宣言しています。
3.2.3 定数 (`Const`)
`Const` キーワードは、プログラムの実行中に値が変わらない定数を宣言します。
- `Const ALLOCATED_LAYER_PREFIX As String = “AutoLayer_”`: 自動作成されるレイヤー名の先頭に付けるプレフィックスを定義しています。これにより、後でレイヤー名を変更したい場合でも、この1行を修正するだけで済みます。
3.2.4 `TargetPage = Visio.ActivePage`
Visioアプリケーションの `ActivePage` プロパティは、現在アクティブになっている(一番手前に表示されている)ページオブジェクトを返します。これを `TargetPage` 変数に代入することで、どのページを処理対象とするかを指定しています。
3.2.5 レイヤーの存在確認と作成
LayerExists = False
For Each LayerObj In TargetPage.Layers
If LayerObj.Name = DefaultLayerName Then
LayerExists = True
Exit For
End If
Next LayerObj
If Not LayerExists Then
Set LayerObj = TargetPage.Layers.Add(DefaultLayerName)
Set TargetLayer = LayerObj ‘ 作成したレイヤーをTargetLayerに設定
Debug.Print “レイヤー ‘” & DefaultLayerName & “‘ を作成しました。”
Else
Set TargetLayer = TargetPage.Layers(DefaultLayerName) ‘ 既存のレイヤーを取得
End If
この部分は、目的のレイヤー(今回はデフォルトの「その他」レイヤー)が既に存在するかどうかを確認しています。
`TargetPage.Layers` は、そのページに存在する全てのレイヤーのコレクションです。`For Each` ループで各レイヤーを順番にチェックし、名前が一致するかどうかを確認します。
もし存在しなければ、`TargetPage.Layers.Add(LayerName)` メソッドを使って新しいレイヤーを作成します。
3.2.6 シェイプのループ処理 (`For Each CurrentShape In TargetPage.Shapes`)
`TargetPage.Shapes` コレクションには、そのページに直接配置されている全てのシェイプが含まれています。`For Each` ループを使うことで、コレクション内の各シェイプに対して、順番に処理を行うことができます。
3.2.7 シェイプの判定 (`CurrentShape.Type` と `CurrentShape.Text`)
- `CurrentShape.Type`: シェイプの種類を定数(`Visio.visTypeLabel`, `Visio.visTypeConnector` など)で返します。
- `CurrentShape.Text`: シェイプに含まれるテキストを返します。`Trim()` 関数で前後の不要な空白を取り除いてから判定に使うと、より正確な判定ができます。
3.2.8 `Select Case` ステートメント
`Select Case` は、ある変数の値に応じて、実行する処理を分岐させるのに便利な構文です。今回のコードでは、`ShapeType` の値によって、どのレイヤーに割り当てるかを判断しています。
3.2.9 `InStr` 関数
`InStr(start, string1, string2, [compare])` 関数は、`string2` が `string1` の中で最初に出現する位置を返します。
今回のコードでは、`InStr(1, ShapeText, “注意:”, vbTextCompare) > 0` のように使用しています。
これは、「`ShapeText` という文字列の中に、”注意:” という文字列が(大文字・小文字を区別せずに)含まれているか?」を判定しています。含まれていれば、その開始位置(0より大きい値)が返されるため、条件が真(True)となります。
3.2.10 シェイプのレイヤー移動 (`CurrentShape.Layer = TargetLayer`)
これが、シェイプを目的のレイヤーに移動させる核心部分です。
`CurrentShape.Layer` プロパティに、移動先の `Layer` オブジェクトを代入するだけで、シェイプは自動的にそのレイヤーに移動します。
3.2.11 `Debug.Print`
`Debug.Print` は、VBAエディタの「イミディエイトウィンドウ」にメッセージを出力するコマンドです。プログラムの動作確認やデバッグ(エラーの原因調査)に非常に役立ちます。
3.3 実行前の準備:VBAエディタの起動
1. Visioで図面を開きます。
2. `Alt` + `F11` キーを押して、VBAエディタ(Microsoft Visual Basic for Applications)を起動します。
3. 左側の「プロジェクトエクスプローラー」ウィンドウで、開いているVisioファイルに対応するプロジェクト(例: `ThisDocument` や `Module1` など)を探します。
4. もしモジュールがない場合は、「挿入」メニューから「標準モジュール」を選択して新しいモジュールを作成します。
5. 作成したモジュールに、上記のVBAコードをコピー&ペーストします。
6. VBAエディタのメニューから「実行」->「Sub/ユーザーフォームの実行」を選択するか、`F5` キーを押して `AutoOrganizeShapesByLayer` マクロを実行します。
—
第4章:よくあるエラーとその回避策 ~開発でつまずきやすいポイント~
VBA開発で避けては通れないのが、エラーとの遭遇です。ここでは、このルーチンでよく遭遇しそうなエラーとその対処法を解説します。
4.1 エラー1:オブジェクトが設定されていません (エラー番号: 91)
原因
`Set` ステートメントでオブジェクト変数にオブジェクトが代入されていない状態で、そのオブジェクトのプロパティやメソッドにアクセスしようとした場合に発生します。
具体例
- `TargetPage` が `Nothing` のまま `TargetPage.Shapes` にアクセスしようとした。
- 存在しないレイヤー名を指定して `TargetPage.Layers(“存在しないレイヤー名”)` としてしまい、それを `TargetLayer` に代入しようとした。
回避策
- `On Error Resume Next` と `On Error GoTo 0`: エラーが発生しそうな箇所で一時的にエラーハンドリングを無効にし、処理が続行できるようにします。その後、オブジェクトが `Nothing` でないかチェックします。
Dim MyLayer As Visio.Layer
On Error Resume Next
Set MyLayer = TargetPage.Layers(“存在しないレイヤー”)
On Error GoTo 0
If MyLayer Is Nothing Then
MsgBox “レイヤーが見つかりませんでした。”
‘ ここで処理を中断するか、レイヤーを作成するなどの対応を行う
Else
‘ MyLayer を使った処理
End If
- 事前チェック: オブジェクトが `Nothing` でないかを確認してから、プロパティやメソッドにアクセスします。
If Not TargetPage Is Nothing Then
‘ TargetPage を使った処理
Else
MsgBox “ページが選択されていません。”
End If
4.2 エラー2:インデックスが有効範囲にありません (エラー番号: 9)
原因
コレクション(例: `Shapes`, `Layers`)に対して、存在しないインデックス番号(添え字)を指定してアクセスしようとした場合に発生します。
具体例
- `TargetPage.Layers(10)` のように、10番目のレイヤーが存在しないのにアクセスしようとした。
- `TargetPage.Shapes(1000)` のように、1000個のシェイプが存在しないのにアクセスしようとした。
回避策
- `For Each` ループの使用: コレクションの全要素を順番に処理する場合は、`For Each` ループが安全で推奨されます。インデックス番号を意識する必要がありません。
- インデックスの存在確認: 特定のインデックスにアクセスする前に、コレクションの要素数と比較するなどして、インデックスが有効範囲内にあるかを確認します。
If TargetPage.Layers.Count >= 10 Then
Set MyLayer = TargetPage.Layers(10)
Else
MsgBox “レイヤーが10個ありません。”
End If
4.3 エラー3:指定したレイヤー名が存在しません
原因
`TargetPage.Layers(“レイヤー名”)` のように、実際には存在しないレイヤー名を指定して `Layer` オブジェクトを取得しようとした場合に発生します。これは、上記のエラー2(インデックスが有効範囲にありません)と似た状況ですが、名前でアクセスした場合に発生することがあります。
回避策
- レイヤーの事前作成: コードの冒頭で、必要なレイヤーが存在しない場合は作成するようにします。今回のコードでは、`DefaultLayerName` についてはこの処理を行っています。他のレイヤーについても同様に、判定ロジック内で存在確認と作成を行うように拡張できます。
- ループでの名前検索: `For Each` ループでレイヤー名を検索し、存在するかどうかを確認してからアクセスします。
4.4 その他の注意点
- グループシェイプ内のシェイプ: 今回のコードでは、`TargetPage.Shapes` コレクションを直接ループしていますが、これにはグループシェイプ内のシェイプは含まれません。グループ内のシェイプも処理したい場合は、再帰処理(関数自身を呼び出す処理)を用いて、グループシェイプを分解して中身を処理する必要があります。これは少し高度なテクニックになります。
- シェイプのロック: ロックされているシェイプは、VBAから変更できない場合があります。必要に応じて、コードでシェイプのロックを解除する処理を追加することも検討してください。
- Visioのバージョン: VBAのオブジェクトモデルは、Visioのバージョンによって微妙に異なる場合があります。使用しているVisioのバージョンに合わせて、必要に応じてコードを調整してください。
—
第5章:さらに高度な活用へ ~応用編~
今回ご紹介した「レイヤー自動整理」ルーチンは、基本をマスターするための第一歩です。ここからさらに発展させることで、より強力な自動化ツールへと進化させることができます。
5.1 シェイプのカスタムプロパティを活用する
Visioのシェイプには、標準のプロパティ(色、サイズ、テキストなど)以外に、「カスタムプロパティ」を設定できます。これは、シェイプに独自の情報を付加する機能です。
例えば、ネットワーク図で各機器に「IPアドレス」「役割」といったカスタムプロパティを設定しておき、VBAでそのカスタムプロパティの値を見てレイヤーに振り分ける、といったことが可能です。
‘ 例:カスタムプロパティ “役割” の値でレイヤーを決定
Dim propValue As String
On Error Resume Next ‘ プロパティが存在しない場合のエラー回避
propValue = CurrentShape.Cells(“Prop.役割”).ResultStrU(“”) ‘ “Prop.役割” はカスタムプロパティ名
On Error GoTo 0
If propValue = “サーバー” Then
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Servers”
ElseIf propValue = “ルーター” Then
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Routers”
End If
※カスタムプロパティのセル参照は `Prop.プロパティ名` となります。
5.2 マスターシェイプ名による判定
特定のステンシルから配置されたシェイプには、そのマスターシェイプの名前が付与されています。この名前を利用して、シェイプを振り分けることもできます。
‘ 例:マスターシェイプ名でレイヤーを決定
Dim masterName As String
masterName = CurrentShape.Master.Name
If masterName = “サーバー” Then ‘ マスターシェイプ名が “サーバー” の場合
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Servers”
ElseIf masterName = “ルーター” Then
TargetLayerName = ALLOCATED_LAYER_PREFIX & “Routers”
End If
※`CurrentShape.Master.Name` は、シェイプが配置されたマスターシェイプの名前を返します。
5.3 複数のページに一括適用
現在アクティブなページだけでなく、ドキュメント内の全てのページにこの処理を適用したい場合もあります。その場合は、`Document.Pages` コレクションをループ処理します。
Sub AutoOrganizeAllPages()
Dim TargetPage As Visio.Page
Dim CurrentShape As Visio.Shape
‘ … (上記 AutoOrganizeShapesByLayer のコードをここに記述) …
‘ 全ページをループ処理
For Each TargetPage In Visio.ActiveDocument.Pages
‘ — ここに AutoOrganizeShapesByLayer の本体コードを配置 —
‘ (ただし、TargetPage = Visio.ActivePage の部分は削除またはコメントアウト)
‘ ページごとの処理が完了したら、次のページへ
Next TargetPage
MsgBox “全ページのシェイプ整理が完了しました。”, vbInformation
End Sub
※この場合、`AutoOrganizeShapesByLayer` のコードをそのままコピペするのではなく、`TargetPage = Visio.ActivePage` の行を削除またはコメントアウトし、`For Each TargetPage In Visio.ActiveDocument.Pages` のループの中に、レイヤー準備からシェイプ移動までの処理を記述する必要があります。
5.4 ユーザーフォームによるインタラクティブな操作
さらに高度な使い方として、ユーザーフォームを作成し、ユーザーに整理したいレイヤーのルールや対象ページを選択させる、といったことも可能です。これにより、より柔軟で使いやすい自動化ツールを開発できます。
—
まとめ:Visio VBAで、図面管理のストレスから解放されよう!
いかがでしたでしょうか?
今回は、Visio VBAを使った「レイヤー自動整理」ルーチンについて、基礎から実践、そして応用までを解説しました。
- Visio VBAのオブジェクト指向の考え方
- シェイプとレイヤーの関係
- 具体的なVBAコードとその解説
- 開発で遭遇しがちなエラーとその対策
これらの知識を身につけることで、あなたは「マクロの記録」という限られた世界から一歩踏み出し、Visio VBAを自在に操るための確かな一歩を踏み出せます。
今回ご紹介した「レイヤー自動整理」ルーチンは、複雑な図面管理のコストを劇的に削減し、あなたの業務効率を飛躍的に向上させる可能性を秘めています。ぜひ、ご自身のVisioファイルで試してみてください。
最初は少し難しく感じるかもしれませんが、一つ一つのコードの意味を理解し、実際に手を動かすことで、必ず習得できます。焦らず、楽しみながら、Visio VBAの世界を広げていきましょう。
このブログが、あなたのVisio VBAマスターへの道のりを照らす一助となれば幸いです。
それでは、また次回の技術解説でお会いしましょう!
