こんにちは! Visio VBAの奥深い世界へようこそ。
マクロの記録ボタンを押して出てきたコードを眺めるだけの日々は、もうおしまい。ここからは、Visioという巨大な図形エンジンの心臓部を直接コントロールする「真の自動化エンジニア」への階段を登っていきましょう。
今回は、現場のシステム開発で確実に歓声が上がる、「SQL Serverと連携したユーザー別レイヤー動的制御システム」の構築法を伝授します。
「図面を開いた瞬間、ログインしているユーザーの権限(営業・技術・管理など)に合わせて、必要なレイヤーだけが自動でパッと表示される」――そんな高度なパーソナライズをVisio VBAで実現します。
ここをクリアすれば、単なる「お絵描きツール」としてのVisioの殻を破り、立派な「業務システムの一部」として昇華させることができますよ。さあ、一緒に本質に迫っていきましょう!
—
1. なぜ「レイヤー×外部DB連携」が上級者の必須スキルなのか?
Visioのレイヤー機能(`Layer`オブジェクト)は、図面上の複雑な情報を整理する強力な武器です。しかし、これを手動で切り替えているようでは、マルチユーザー環境や大規模なプラント図・ネットワーク図の運用において必ず破綻します。
上級エンジニアである私たちが目指すべきは、「図面の表現力(View)」と「データの管理(Model)」の完全な分離です。
ユーザーの属性情報をSQL Serverなどの外部データベースに持たせ、Visio起動時に非同期でフェッチ(取得)し、瞬時にレイヤーの表示状態(`VisLayerMember` / `Stat`プロパティ)を書き換える。このアーキテクチャをモノにすれば、どんなに複雑な図面管理要件も怖くありません。
—
2. 全体アーキテクチャとデータベース設計
まずは、裏側でどのようなデータやり取りが行われるかをイメージしましょう。
1. Visio起動(`Document_Open`イベント)
2. Windowsログオンユーザー名等の取得
3. SQL ServerへODBC/ADO経由で接続
4. ユーザーが閲覧可能な「レイヤー名のリスト」を取得
5. Visioの全レイヤーを一度非表示にし、取得したリストに合致するものだけを表示に切り替え
データベース側の簡易テーブル構造(例)
SQL Server側に、ユーザーと表示すべきレイヤーを紐付けるテーブルを用意します。
CREATE TABLE VisioLayerPermissions (
UserName NVARCHAR(50),
DocumentName NVARCHAR(100),
LayerName NVARCHAR(50),
IsVisible INT — 1: 表示, 0: 非表示
);
—
3. 【実践】SQL Server連携・レイヤー制御VBAコード
それでは、Visioの「ThisDocument」モジュールに実装する実用コードを公開します。
実務でそのままコピペして使えるよう、エラーハンドリングとオブジェクトの解放処理(メモリリーク対策)を徹底したプロ仕様です。
‘ ==============================================================================
‘ モジュール名: ThisDocument (Visio VBA)
‘ 概要: ドキュメントオープン時にSQL Serverからレイヤー権限を取得し、表示を制御する
‘ ==============================================================================
Private Sub Document_Open()
On Error GoTo ErrorHandler
Dim conn As Object
Dim rs As Object
Dim connString As String
Dim sql As String
Dim currentUser As String
‘ 1. 現在のWindowsログインユーザー名を取得(環境に合わせて変更可能)
currentUser = Environ(“USERNAME”)
‘ 2. ADOによるSQL Server接続文字列の定義(環境に合わせて書き換えてください)
connString = “Provider=MSOLEDBSQL;Server=YOUR_SERVER_NAME;Database=YOUR_DB_NAME;Trusted_Connection=yes;”
Set conn = CreateObject(“ADODB.Connection”)
Set rs = CreateObject(“ADODB.Recordset”)
‘ データベース接続
conn.Open connString
‘ 3. ユーザーごとの表示許可レイヤーを取得するクエリ
sql = “SELECT LayerName FROM VisioLayerPermissions WHERE UserName = ‘” & currentUser & “‘ AND DocumentName = ‘” & ActiveDocument.Name & “‘ AND IsVisible = 1”
rs.Open sql, conn
‘ 4. Visio側のレイヤー表示を動的に制御
Call ApplyLayerPermissions(rs)
‘ 5. クリーンアップ
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
Exit Sub
ErrorHandler:
MsgBox “レイヤー権限の取得中にエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “システム連携エラー”
‘ 異常終了時のオブジェクト解放
If Not rs Is Nothing Then If rs.State = 1 Then rs.Close: Set rs = Nothing
If Not conn Is Nothing Then If conn.State = 1 Then conn.Close: Set conn = Nothing
End Sub
‘ ==============================================================================
‘ サブルーチン: 取得した権限リストを基に、アクティブページのレイヤーを制御
‘ =================================================5=============================
Private Sub ApplyLayerPermissions(ByRef permissionRecordSet As Object)
Dim vsoPage As Visio.Page
Dim vsoLayer As Visio.Layer
Dim layerName As String
Dim isVisibleAllowed As Boolean
‘ アクティブページを取得(複数ページある場合はLoop処理に変更してください)
Set vsoPage = ActivePage
‘ 念のため、画面の再描画を停止してパフォーマンスを向上
Application.ScreenUpdating = False
‘ ステップA: 一旦、すべてのレイヤーを「非表示」にする(安全な初期化)
For Each vsoLayer In vsoPage.Layers
‘ レイヤーの表示状態プロパティ (visLayerVisible = 1, 非表示は他の値やビット操作)
‘ ここでは簡易的にCellプロパティやStatプロパティを操作
vsoLayer.CellsC(visLayerVisible).ResultIU = 0 ‘ 0で非表示
Next vsoLayer
‘ ステップB: DBから取得した許可リストに合致するレイヤーだけを表示にする
Do While Not permissionRecordSet.EOF
layerName = permissionRecordSet.Fields(“LayerName”).Value
On Error Resume Next
Set vsoLayer = vsoPage.Layers.Item(layerName)
On Error GoTo 0
If Not vsoLayer Is Nothing Then
‘ 該当レイヤーを表示状態(1)にする
vsoLayer.CellsC(visLayerVisible).ResultIU = 1
End If
permissionRecordSet.MoveNext
Loop
‘ 画面描画を再開
Application.ScreenUpdating = True
‘ オブジェクト変数の解放
Set vsoLayer = Nothing
Set vsoPage = Nothing
End Sub
—
4. 現場で躓きやすいポイントと「知る人ぞ知る」罠
このコードを実装するにあたり、初学者や中級者が必ずハマる「Visio特有の罠」がいくつかあります。プロの視点から事前に回避方法を授けておきますね。
① `Visio.Layer`のインデックスは1から始まる
VBAのコレクション操作全般に言えることですが、Visioの `Layers` コレクションも 1始まり(1-based index) です。さらに、存在しないレイヤー名を `vsoPage.Layers.Item(“存在しない名前”)` で指定すると、容赦なく実行時エラー(エラー4: オブジェクトが見つかりません)が発生します。
必ず上記のコードのように `On Error Resume Next` でトラップするか、事前に存在確認を行う防御的プログラミングを徹底しましょう。
② 画面描画のロック(`ScreenUpdating`)を忘れないこと
Visioは、レイヤーの表示状態を1つ変更するたびに、画面全体の再描画(再計算)走査を行おうとします。レイヤーが数十個ある図面でこれをやると、画面がチラつき、処理が数秒〜数十秒フリーズします。
処理の冒頭で `Application.ScreenUpdating = False` をかけ、最後に `True` に戻す。この一手間で、プロらしいサクサク動くアプリケーションに生まれ変わります。
③ オブジェクトの完全解放(メモリ管理)
ADO(`ADODB.Connection`)などの外部COMオブジェクトをVBAで扱う際、参照を切る(`Set obj = Nothing`)のをサボると、Visioを終了してもプロセスがメモリ上に残り続ける「ゴーストプロセス問題」を引き起こします。エラー時も含めたクリーンアップ処理(ErrorHandlerでの解放)は、プロのエンジニアとしてのマスト要件です。
—
ここをクリアすれば、Visio VBAの基本はバッチリですよ!
お疲れ様でした!今回は、単なるマクロの記録を遥かに超越した、実務直結の「データベース連携型レイヤー制御システム」を解説しました。
- 外部DB(SQL Server)からの情報取得
- Visioオブジェクト(Page, Layer)のプログラム的制御
- パフォーマンス最適化(画面描画の抑制)
- 堅牢なエラーハンドリングとメモリ管理
これだけの要素を自分の手でコントロールできれば、あなたのVisio VBAスキルは、間違いなく「初学者」から「上級自動化エンジニア」へとシフトしています。
現場のユーザーが図面を開いた瞬間、「うわっ、自分に必要な情報だけが綺麗に整理されて表示された!」と驚く顔を、ぜひ楽しみにしていてください。それでは、次回の高度な自動化の世界でお会いしましょう!
