【入門編】【中級】ステンシル内の全マスターシェイプを一覧化してExcelに出力する – Visio VBA解析バイブル

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

【Visio VBA極限講義】ステンシルの深淵を覗く:全マスターシェイプをExcelへ一括抽出する究極の自動化術

こんにちは。現場の設計自動化を司るアーキテクトです。

「マクロの記録」ボタンを押して、記録されたコードを眺めては「……で、ここからどうすればいいんだ?」と立ち止まってしまう。そんな経験はありませんか?

マクロの記録は、いわば「足跡」を辿る作業に過ぎません。しかし、真の自動化エンジニアに必要なのは、足跡を辿ることではなく、「その背後にある構造(オブジェクトモデル)を理解し、自らの意志で操作すること」です。

今日は、Visioの資産管理における最重要課題の一つである「ステンシル内のマスターシェイプをスキャンし、そのメタデータをExcelへ書き出す」という高度なタスクを題材に、プロフェッショナルなコードの書き方を伝授します。

ここをクリアすれば、あなたは「記録マクロ使い」を卒業し、「VBAエンジニア」への第一歩を踏み出すことになるでしょう。

1. 概念の理解:ステンシルとマスターの「階層構造」

コードを書く前に、まずVisioの脳内構造を理解しましょう。ここを飛ばすと、必ずエラーの迷宮に迷い込みます。

Visioにおける形状の管理は、以下の階層で行われています。

1. Application (Visio本体)
2. Document (ステンシルファイル / .vssx)

  • ステンシルは、それ自体が一つの「ドキュメント」として扱われます。

3. Masters (コレクション)

  • ステンシルの中に格納されている「マスターシェイプの集合体」です。

4. Master (個々のマスターオブジェクト)

  • これが、私たちが抽出したい「設計図」の正体です。

私たちが今回行うのは、「特定のドキュメント(ステンシル)を開き、その中のMastersコレクションを一つずつ巡回(Loop)して、中身の情報を抜き出す」というプロセスです。

2. 実践:マスター抽出・Excel出力スクリプト

それでは、魂を込めて書いたコードを見ていきましょう。このコードは、単に動くだけでなく、「配布してもエラーが起きにくい(Late Binding)」かつ「メンテナンス性が高い」設計にしています。

Option Explicit

''' <summary>
''' 指定したステンシル内の全マスター情報を抽出し、Excelへ出力する
''' </summary>
Sub ExportStencilMastersToExcel()
    ' --- 1. オブジェクトの宣言 ---
    Dim visioApp As Visio.Application
    Dim stencilDoc As Visio.Document
    Dim masterObj As Visio.Master
    Dim excelApp As Object ' Late Binding: 参照設定なしで動作させるためObject型
    Dim excelWorkbook As Object
    Dim excelSheet As Object
    Dim rowIdx As Long
    Dim stencilName As String
    
    ' ターゲットとなるステンシルの名前(開いているもの、またはパスを指定)
    ' ここでは例として、現在アクティブなステンシルを対象にします
    On Error Resume Next
    Set stencilDoc = Visio.ActiveDocument
    On Error GoTo 0
    
    If stencilDoc Is Nothing Then
        MsgBox "有効なステンシルドキュメントが開かれていません。", vbCritical
        Exit Sub
    End If
    
    stencilName = stencilDoc.Name
    
    ' --- 2. Excelの起動 (Late Binding) ---
    ' 参照設定(Microsoft Excel Object Library)をしていなくても動作するように設計
    On Error Resume Next
    Set excelApp = CreateObject("Excel.Application")
    If excelApp Is Nothing Then
        MsgBox "Excelを起動できませんでした。", vbCritical
        Exit Sub
    End If
    On Error GoTo 0
    
    ' Excelを可視化(進捗が見えるように)
    excelApp.Visible = True
    Set excelWorkbook = excelApp.Workbooks.Add
    Set excelSheet = excelWorkbook.Sheets(1)
    
    ' --- 3. Excelシートのヘッダー作成 ---
    With excelSheet
        .Cells(1, 1).Value = "Stencil Name"
        .Cells(1, 2).Value = "Master Name (Local)"
        .Cells(1, 3).Value = "Master Name (Unformatted)"
        .Cells(1, 4).Value = "Master ID"
        .Cells(1, 5).Value = "Page ID"
        ' 見栄えを整える
        .Range("A1:E1").Font.Bold = True
        .Range("A1:E1").Interior.Color = RGB(200, 200, 200)
    End With
    
    rowIdx = 2 ' データ書き出し開始行
    
    ' --- 4. マスターのループ処理 (ここが核心) ---
    ' stencilDoc.Masters コレクションを一つずつ走査します
    For Each masterObj In stencilDoc.Masters
        With excelSheet
            .Cells(rowIdx, 1).Value = stencilName
            ' Name は表示名(多言語対応などの影響を受ける)、NameU は一意の内部名
            .Cells(rowIdx, 2).Value = masterObj.Name
            .Cells(rowIdx, 3).Value = masterObj.NameU 
            .Cells(rowIdx, 4).Value = masterObj.ID
            .Cells(rowIdx, 5).Value = masterObj.PageID
        End With
        rowIdx = rowIdx + 1
    Next masterObj
    
    ' 列幅の自動調整
    excelSheet.Columns("A:E").AutoFit
    
    ' --- 5. 後処理 (クリーンアップ) ---
    ' オブジェクトの解放はプロフェッショナルのたしなみ
    Set excelSheet = Nothing
    Set excelWorkbook = Nothing
    Set excelApp = Nothing
    Set masterObj = Nothing
    Set stencilDoc = Nothing
    
    MsgBox "抽出が完了しました!" & vbCrLf & "抽出件数: " & (rowIdx - 2) & " 件", vbInformation
End Sub

3. アーキテクトの視点:なぜこう書いたのか?

単に「動くコード」を提示するだけでは、あなたの成長には繋がりません。なぜ私がこの書き方を選んだのか、その「意図」を解説します。

① 「Late Binding(遅延結合)」の採用

コード内で `Dim excelApp As Object` と宣言している点に注目してください。
通常、Excelを操作するには「参照設定」が必要ですが、これを行うと、作成したツールを他の人のPCで動かした際、Excelのバージョン違いによって「参照不可」エラーで止まるリスクがあります。
`CreateObject(“Excel.Application”)` を使うことで、実行時に初めてExcelを探しに行くため、環境に左右されない強固なツールになります。

② 「Name」と「NameU」の使い分け

ここが初級者と中級者の最大の分かれ道です。

  • `Name`: ユーザーに見える名前。言語設定によって「Circle」が「円」に変わる可能性があります。
  • `NameU` (Unformatted Name): Visio内部で管理されている、改変されない一意の名前です。

プログラムで「特定の形状を探す」といった処理を行う場合は、必ず `NameU` を使用してください。そうしないと、日本語環境で動いたコードが英語環境で壊れるという悲劇を招きます。

③ オブジェクトのライフサイクル管理

コードの最後に `Set … = Nothing` を並べていますね。
VisioやExcelのような巨大なアプリケーションを操作する場合、メモリ上にオブジェクトが残り続けると、プログラム終了後もプロセスが居座り、PCの動作を重くする原因になります。「使い終わったリソースは、責任を持って解放する」。これが、プロのエンジニアの作法です。

4. 陥りやすいエラーと対策

このスクリプトを運用する上で、以下の点に注意してください。

エラー・事象 原因 対策
実行時エラー ‘429’ Excelが正しくインストールされていない、または破損している。 Excelの修復、または環境確認を行う。
マスターが抽出されない ステンシルが「読み取り専用」で、正しく開けていない可能性がある。 `stencilDoc` が正しくセットされているかデバッグ出力で確認。
処理が異常に遅い マスターの数が数千件ある場合、Excelへの書き込み回数が多い。 `Application.ScreenUpdating = False` を活用し、一括で書き込む工夫をする。

最後に:次なるステップへ

お疲れ様でした。これであなたは、Visioの資産(マスター)を自在にリスト化し、管理台帳を作る術を手にしました。

しかし、これはまだ入り口に過ぎません。
次は、「抽出したリストに基づいて、特定の条件に合うマスターを自動で図面に配置する」といった、「情報の読み取り」から「アクション(操作)」への橋渡しに挑戦してみてください。

Visio VBAの世界は、構造を理解すれば理解するほど、あなたの強力な武器になります。
一歩ずつ、確実に。共に極限を目指しましょう。

Happy Coding!

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