【入門編】【上級】SQL Server上のマスターシェイプ・メタデータとVisioの同期 – Visio VBA解析バイブル

スポンサーリンク
スポンサーリンク

データと図面を同期せよ:SQL Serverの資産情報からVisioマスターを動的に召喚する極限の設計術

こんにちは。現場の泥臭い自動化から、大規模エンタープライズのアーキテクチャ設計まで、図面の「裏側」にあるデータの流れを設計し続けてきたチーフアーキテクトです。

「マクロの記録」を使って、なんとかボタン一つで図形が動くようになった……。もしあなたが今、そこに立っているなら、まずは自分を褒めてあげてください。それは素晴らしい第一歩です。

しかし、プロフェッショナルの世界、特に数千台のサーバーやネットワーク機器を管理するエンタープライズの現場では、「手動で図形を配置する」という行為自体が、一種の「リスク」と見なされます。現場が求めているのは、「データベース(SQL Server)にある最新の資産情報に基づき、Visioが自律的に図面を再構築する」という、データ駆動型の自動化なのです。

今日は、単なる「図形を描くVBA」を卒業し、「データベースとVisioを同期させるアーキテクチャ」へとステップアップするための知見を伝授します。

1. なぜ「データベース連携」が必要なのか?

想像してみてください。あなたの会社に1,000台のサーバーがあるとき、誰かが構成変更を行いました。
「マクロで図形を置く」だけなら、その1,000台を毎回手動で、あるいは単純なループで配置することになります。しかし、それだけでは不十分です。

  • 情報の乖離(データの不整合): 図面上のIPアドレスと、実際のDB上のIPアドレスがズレる。
  • 更新コスト: 構成が変わるたびに、図面を修正する作業が発生する。
  • ヒューマンエラー: 違う種類のシェイプ(マスター)を置いてしまう。

これらを解決するのが、「SQL Serverから属性情報を読み取り、その属性に基づいて適切なマスターシェイプをステンシルから選択・配置し、さらにシェイプのプロパティ(ShapeSheet)にデータを流し込む」という一連のプロセスです。

2. アーキテクチャの全体像

このシステムを構築するための「三種の神器」を整理しましょう。

1. SQL Server (Source of Truth): 資産の「真実」が眠る場所。
2. Visio Stencil (The Library): 配置すべき「型(マスター)」が格納されたライブラリ。
3. VBA + ADO (The Bridge): DBからデータを引き抜き、Visioのオブジェクトモデルを操る指揮者。

データの流れ

`SQL Server` $\rightarrow$ `ADO Recordset` $\rightarrow$ `Loop` $\rightarrow$ `Stencil.Masters` $\rightarrow$ `Shape.Drop` $\rightarrow$ `ShapeSheet Update`

3. 実践:極限の同期コード

さあ、理論はここまでです。実際に動くコードを見ていきましょう。
ここでは、「SQL Serverから機器リストを取得し、その『機器種別』に基づいて、適切なステンシルのマスターを配置する」というシナリオを想定します。

※事前に `Microsoft ActiveX Data Objects x.x Library` への参照設定を忘れないでください。

Option Explicit

' ==============================================================================
' プログラム名: SyncAssetsFromSQL
' 概要: SQL Serverの資産情報に基づき、Visio上にマスターシェイプを動的に配置する
' ==============================================================================
Sub SyncAssetsFromSQL()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim connString As String
    Dim stencil As Visio.Document
    Dim master As Visio.Master
    Dim targetShape As Visio.Shape
    Dim sql As String
    Dim i As Integer
    
    ' --- 1. 設定エリア ---
    ' SQL Serverへの接続文字列(環境に合わせて調整してください)
    connString = "Provider=SQLOLEDB;Data Source=YOUR_SERVER;Initial Catalog=YOUR_DB;Integrated Security=SSPI;"
    
    ' 使用するステンシルのパス
    Dim stencilPath As String
    stencilPath = "C:\Templates\NetworkDevices.vssx"
    
    ' 取得するSQL文(機器名、種別、IP、配置座標X,Yを含む想定)
    sql = "SELECT DeviceName, DeviceType, IPAddress, PosX, PosY FROM AssetInventory"

    On Error GoTo ErrorHandler

    ' --- 2. 接続とデータ取得 ---
    Set conn = New ADODB.Connection
    conn.Open connString
    
    Set rs = New ADODB.Recordset
    rs.Open sql, conn, adOpenStatic, adLockReadOnly

    ' --- 3. ステンシルの準備 ---
    ' ステンシルを「ドキュメント」として開く。これがマスターへの入り口になる。
    Set stencil = Application.Documents.OpenEx(stencilPath, visOpenDocked)
    
    ' 既存の図面をクリアする場合(必要に応じて)
    ' Application.ActivePage.Shapes.SelectAll
    ' Application.ActivePage.Application.ActiveWindow.Selection.Delete

    ' --- 4. メインループ:データの同期 ---
    Do While Not rs.EOF
        ' 【ここが肝!】DBのDeviceType(例: "Server", "Switch")と
        ' ステンシル内のマスター名が一致している必要がある
        Dim masterName As String
        masterName = rs.Fields("DeviceType").Value
        
        ' マスターの検索
        Set master = Nothing
        On Error Resume Next
        Set master = stencil.Masters.FindMaster(masterName)
        On Error GoTo ErrorHandler
        
        If Not master Is Nothing Then
            ' マスターをページ上に配置 (Drop)
            ' 引数は (X座標, Y座標)
            Set targetShape = Application.ActivePage.Drop(master, rs.Fields("PosX").Value, rs.Fields("PosY").Value)
            
            ' --- 5. メタデータの同期 (ShapeSheetへの書き込み) ---
            ' 図形に属性情報を埋め込む。これにより、図面自体がDBのコピーになる。
            ' CellsUを使うのがプロの流儀(Unicode対応で堅牢)
            targetShape.CellsU("Prop.DeviceName").FormulaU = """" & rs.Fields("DeviceName").Value & """"
            targetShape.CellsU("Prop.IPAddress").FormulaU = """" & rs.Fields("IPAddress").Value & """"
            
            Debug.Print "Placed: " & rs.Fields("DeviceName").Value
        Else
            Debug.Print "Warning: Master not found for type: " & masterName
        End If
        
        rs.MoveNext
    Loop

    MsgBox "同期が完了しました。", vbInformation

CleanUp:
    ' --- 6. リソースの解放(オブジェクトのライフサイクル管理) ---
    ' これを怠ると、Visioがメモリを食いつぶしたり、DB接続が残り続けたりします
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then rs.Close
    End If
    Set rs = Nothing
    Set conn = Nothing
    ' ステンシルは必要に応じて閉じる
    ' stencil.Close
    Exit Sub

ErrorHandler:
    MsgMsgBox "エラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

4. 伝説のアーキテクトが教える「陥りやすい罠」と回避術

このコードを動かす際、多くのエンジニアが以下の3つの壁にぶつかります。ここをクリアすれば、あなたはもう初心者ではありません。

① 「マスター名」と「パターン名」の混同

`stencil.Masters.FindMaster(“Server”)` と書いたとき、ステンシル内のマスターの名前が正確に `”Server”` である必要があります。
注意点: Visioのマスターは、ドキュメントに配置された瞬間に「Pattern」という概念に変わります。DBに保存する名称は、必ずステンシル上のマスター名(Nameプロパティ)と完全に一致させておく設計にしてください。

② ShapeSheetへの書き込みにおける「クォーテーションの呪い」

コード内のここを見てください。
`targetShape.CellsU(“Prop.IPAddress”).FormulaU = “””” & rs.Fields(“IPAddress”).Value & “”””`
ShapeSheetのセルに文字列を書き込むときは、値をダブルクォーテーションで囲む必要があります。これを行わないと、Visioは「IPアドレスの値そのものが、数式(Formula)である」と勘違いし、エラーを吐いて止まります。

③ パフォーマンスの重み:APIコールのオーバーヘッド

ループの中で `Application.ActivePage` を何度も呼び出したり、頻繁に `Select` を行うのは、パフォーマンスを著しく低下させます。

  • Bad: ループの中で毎回ページを探す。
  • Good: ループの外で `Set myPage = Application.ActivePage` と変数に格納し、ループ内ではその変数を使う。

オブジェクトのライフサイクル(`Set Nothing` による解放)を意識することは、メモリリークを防ぐだけでなく、大規模な自動化における「安定性」に直結します。

最後に:図面を「絵」から「データ」へ

これまでのあなたは、Visioを「綺麗な図を描くためのツール」として使っていたかもしれません。
しかし、この技術を習得したあなたは、Visioを「複雑なシステムの情報を、人間が理解できる形に変換する、高度なデータ・ビジュアライザー」として扱うことができます。

DBと同期された図面は、単なる絵ではありません。それは、システムの「生きた設計図」です。

一歩ずつ、コードの裏側にある論理を理解していってください。道は必ず開けます。
それでは、素晴らしい自動化ライフを!

タイトルとURLをコピーしました