こんにちは!Visio VBAの自動化の世界へようこそ。
マクロの記録ボタンを押すだけのステージはもう卒業です。今日からあなたを、数千個のシェイプが入り乱れる巨大な図面をも手玉にとる「真のVisioオートメーション・エンジニア」へと導きましょう。
実務でVisioを使っていると、こんな絶望的な状況に出くわしませんか?
- 「どの担当者が作った図面も、レイヤー設定がバラバラで整合性が取れていない……」
- 「電気配線や構造物が、間違ったレイヤーに配置されていて図面として使い物にならない」
- 「目視で全ページ・全シェイプをチェックするなんて、目がいくつあっても足りない!」
ご安心ください。Visioの裏側(VBA)を正しく叩けば、こんな人間業とは思えないチェック作業も、一瞬で、しかも1ミリの狂いもなく完了させることができます。
今回は、図面管理のルール違反を自動検出し、どのページのどのシェイプが未定義のレイヤーに迷い込んでいるかを暴き出す「レイヤー整合性チェッカー」をあなたに授けます。ここをクリアすれば、Visio VBAのオブジェクト構造の基本はバッチリですよ!
—
1. なぜVisioのレイヤー管理は崩壊するのか?(本質的なアプローチ)
まず、Visioの「レイヤー」という概念の裏側を少しだけ覗いてみましょう。
Excelのシートとは異なり、Visioのページには「定義されたレイヤー(Layer)」のリストが存在し、個々のシェイプはそれらのレイヤーの名前(文字列)をプロパティとして保持しています。
しかし、手動で図面を描いていると、以下のような「ヒューマンエラー」が必ず発生します。
1. 存在しないレイヤー名をうっかり入力してしまう。
2. デフォルトのレイヤー(無所属)のままシェイプを放置してしまう。
3. 別の図面からコピペした際、おかしなレイヤー情報が持ち込まれる。
これを防ぐためには、「現在ページに存在する『正しいレイヤー名のリスト』をあらかじめ取得し、各シェイプが持つレイヤー名がそのリストに本当に含まれているか」をプログラムで総当たりチェックすればよいのです。
—
2. 開発の準備:VBAエディタを開こう
まずはVisioでVBAを書くための準備です。
1. Visioを開き、`[Alt] + [F11]` キーを押してVBAエディタ(VBE)を起動します。
2. メニューの `[挿入]` > `[標準モジュール]` をクリックします。
3. 真っ白なエディタ画面が開いたら準備完了です。
—
3. 実装コード:レイヤー整合性チェッカー
現場でそのままコピペして動かせる、実用的なコードを書き下ろしました。
コード内のコメントをしっかりと読みながら、Visio VBAの作法を体に染み込ませてください。
Option Explicit
‘ =====================================================================
‘ 処理名: レイヤー整合性チェッカー
‘ 概要: 全ページの全シェイプを走査し、未定義のレイヤーに属するものを検出する
‘ =====================================================================
Public Sub CheckLayerIntegrity()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim vsoLayer As Visio.Layer
Dim colValidLayers As Collection
Dim layerName As Variant
Dim shapeLayers As Variant
Dim i As Long, j As Long
Dim errorCount As Long
Dim reportLog As String
errorCount = 0
reportLog = “=== レイヤー整合性チェック レポート ===” & vbCrLf
‘ 1. ドキュメント内の全ページをループする
For Each vsoPage In ActiveDocument.Pages
‘ ————————————————————-
‘ ステップA: そのページに「定義されている正しいレイヤー名」のリストを作る
‘ ————————————————————-
Set colValidLayers = New Collection
On Error Resume Next ‘ 重複追加時のエラー回避
For Each vsoLayer In vsoPage.Layers
colValidLayers.Add vsoLayer.Name, vsoLayer.Name
Next vsoLayer
On Error GoTo 0 ‘ エラートラップを通常に戻す
‘ ————————————————————-
‘ ステップB: ページ内の全シェイプ(グループ化された子含む)を走査する
‘ ————————————————————-
For i = 1 vsoPage.Shapes.Count
Set vsoShape = vsoPage.Shapes(i)
‘ シェイプが所属するレイヤー名の配列を取得する
shapeLayers = vsoShape.CellsU(“LayerMember”).ResultStr(“”)
‘ レイヤーが割り当てられている場合のみチェック
If shapeLayers <> “” Then
‘ 複数のレイヤーに所属している場合を考慮して分割(セミコロン区切り)
Dim layerNamesArray() As String
layerNamesArray = Split(shapeLayers, “;”)
For j = LBound(layerNamesArray) To UBound(layerNamesArray)
layerName = Trim(layerNamesArray(j))
If layerName <> “” Then
‘ ステップC: 定義済みリストに含まれているか?
If Not IsInCollection(colValidLayers, CStr(layerName)) Then
errorCount = errorCount + 1
reportLog = reportLog & _
“【警告】 ページ: ” & vsoPage.Name & _
” / シェイプID: ” & vsoShape.ID & _
” / シェイプ名: ” & vsoShape.Name & _
” -> 未定義レイヤー ‘” & layerName & “‘ が指定されています。” & vbCrLf
End If
End If
Next j
End If
‘ ※本格的な再帰処理は割愛していますが、必要に応じてグループ内(Shapes.Count)の
‘ ネスト構造も再帰的に舐めると完璧になります。今回は基本の走査に絞ります。
Next i
Next vsoPage
‘ ————————————————————-
‘ ステップD: 診断結果の出力
‘ ————————————————————-
If errorCount > 0 Then
reportLog = reportLog & vbCrLf & “合計 ” & errorCount & ” 件のルール違反が検出されました。”
MsgBox reportLog, vbExclamation, “レイヤー整合性チェック完了”
Else
MsgBox “素晴らしい!すべてのシェイプが正しいレイヤーに属しています。”, vbInformation, “レイヤー整合性チェック完了”
End
End Sub
‘ =====================================================================
‘ 補助関数: Collectionの中に指定したキーが存在するか判定する
‘ =====================================================================
Private Function IsInCollection(col As Collection, keyStr As String) As Boolean
Dim var As Variant
On Error Resume Next
var = col(keyStr)
If Err.Number = 0 Then
IsInCollection = True
Else
IsInCollection = False
End If
On Error GoTo 0
End Function
—
4. コードの深掘りポイント(ここが分かれば初心者卒業!)
今回のコードで、Visio VBAの本質が詰まっている重要ポイントを3つ解説します。
① `vsoShape.CellsU(“LayerMember”)` の魔力
Visioのシェイプは、位置や色だけでなく、あらゆる情報を「セル(Cell)」という単位で持っています。レイヤー所属情報もその一つです。
`CellsU(“LayerMember”)` を叩くことで、そのシェイプがどのレイヤーに所属しているかを文字列として引き出すことができます。(※末尾の `U` はU(Universal)の意。言語依存しないプロパティ名指定の鉄則です)
② コレクションを使った高速な存在チェック
「未定義かどうか」を調べるために、毎回すべてのレイヤーをループして探すのはプログラムとして美しくありません(計算量が膨らみます)。
ここでは VBAの `Collection` オブジェクトのキー重複エラーの性質 を利用し、あらかじめページ内のレイヤー名を辞書登録して `IsInCollection` 関数で一瞬で判定しています。このスマートなアルゴリズムこそがプロの技です。
③ エラーハンドリングの作法 (`On Error Resume Next`)
VBAでは、存在しないキーにアクセスすると容赦なく実行時エラーで止まります。意図的にエラーをコントロールしたい場面(コレクションの重複チェックなど)では、一時的に `On Error Resume Next` でエラーをいなし、判定が終わったらすぐに `On Error GoTo 0` で元に戻す。この緊張感のコントロールがコードの品質を決めます。
—
5. 陥りやすいエラーと対策
- エラー「オブジェクトが必要です」が出る
- 原因: 変数の宣言漏れ (`Dim` 忘れ) や、`Set` キーワードの付け忘れによって、オブジェクトがメモリ上に正しく生成されていない場合に発生します。`Option Explicit` を必ずモジュールの先頭に書き、コンパイルして確認する癖をつけましょう。
- シェイプが検出されない
- 原因: グループ化された図形の中にある子シェイプは、親の `vsoPage.Shapes` ループだけでは網羅しきれない場合があります。まずは単体のシェイプで動作確認を行い、慣れてきたら再帰関数(自分自身を呼び出す関数)を使ってグループの深部まで潜れるように拡張してみましょう。
—
まとめ
いかがでしたでしょうか?
「ページやシェイプを巡回し、プロパティを検査してレポートする」という一連の流れが掴めれば、Visioを使った図面管理の自動化において、もう怖いものはありません。
手作業によるチェックから解放され、あなた自身の時間はもっとクリエイティブな設計や開発に使えるようになります。
ぜひこの「レイヤー整合性チェッカー」をご自身の環境に導入し、図面の品質管理を自動化してみてください。ここをクリアしたあなたなら、どんな巨大なVisio自動化案件も必ずやし遂げられるはずです!
