【入門編】【中級】ステンシル内のマスターシェイプを名前順・カテゴリ順に自動整列する – Visio VBA解析バイブル

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

マクロ記録の先へ。Visio VBAで「使いやすいステンシル」を設計する極限の思考法

こんにちは。今日もコードと格闘していますか?

「マクロの記録」ボタンを押して、録画されたコードを眺める。そこから一歩踏み出そうとしているあなたへ。ようこそ、真の自動化エンジニアの世界へ。

マクロの記録は、いわば「動作の断片」を拾い集める作業です。しかし、私たちが目指すべきは、単に動くコードを書くことではありません。「次にこのコードを読む人が、迷わずに使いこなせる仕組み」を構築することです。

今日のテーマは、VisioのUI(ユーザーインターフェース)における要、「ステンシル内のマスターシェイプを、名前順やカテゴリ順に自動整列して管理する」という技術です。

「ただ並べるだけでしょ?」と思うかもしれません。しかし、ここにはVisioのオブジェクトモデルの深淵が隠れています。準備はいいですか? 一緒に、その扉を開けましょう。

1. なぜ「並び順」が重要なのか? —— UI設計の視点

エンジニアがツールを作る際、最も軽視しがちなのが「ユーザーの認知負荷」です。

例えば、数百種類の部品が入ったステンシルがあると想像してください。目的の部品を探すために、ユーザーが目を泳がせ、スクロールを繰り返す……。これは、自動化ツールとしては「失敗」です。

「探す時間をゼロにする」。
これが、ステンシルをプログラミングで制御する真の目的です。

2. 知っておくべき「オブジェクトの階層構造」

コードを書く前に、まずはVisioがどのように世界を見ているかを理解しましょう。ここを曖昧にすると、必ずエラーの迷宮に迷い込みます。

Visioの構造は、以下のような親子関係(階層構造)になっています。

1. Application(Visioそのもの)
2. Document(開いている図面ファイル)
3. Stencil(道具箱:マスターの集合体)
4. Master(金型:シェイプの元となる設計図)

私たちが操作したいのは、Stencilの中にあるMasterの「並び順」です。
しかし、ここで一つ重要な制約があります。「標準のステンシル(Built-in Stencil)は、プログラムから中身を書き換えることができない(読み取り専用である)」ということです。

したがって、今回の戦略はこうなります。
「カスタムステンシルを作成し、そこにマスターを『正しい順番』で流し込む」

これが、プロのアーキテクトが取るべき最短ルートです。

3. 実装のロジック:並び替えのアルゴリズム

Visioの`Masters`コレクションには、実は「Sort」というメソッドは存在しません。
ではどうするか? 答えはシンプルです。

1. 追加したいマスターの名前を、一旦「配列(Array)」に格納する。
2. その配列を、プログラム側で「名前順」にソート(並び替え)する。
3. ソート済みの配列に従って、順番にステンシルへ追加していく。

この「データを整理してから、実体に反映させる」というプロセスこそが、オブジェクトのライフサイクルを制御する極意です。

4. 実践:マスターを名前順に整列して追加するコード

それでは、実際に動くコードを見てみましょう。
今回は、「特定のマスター名を、名前順に並び替えて新しいカスタムステンシルに登録する」というシナリオで記述します。

Option Explicit

''' <summary>
''' 指定した名前のマスターを、アルファベット順に並び替えて
''' 新しいカスタムステンシルに登録するプロシージャ。
''' </summary>
Sub CreateSortedCustomStencil()
    Dim vsoApplication As Visio.Application
    Dim vsoStencil As Visio.Stencil
    Dim masterNames As Variant
    Dim i As Long, j As Long
    Dim temp As String
    
    Set vsoApplication = Visio.Application
    
    ' 1. 追加したいマスターの名前リスト(本来は外部ファイルやセルから取得しても良い)
    ' ここではあえてバラバラな順番で定義します。
    masterNames = Array("Z-Component", "A-Sensor", "M-Motor", "B-Actuator", "C-Controller")
    
    ' 2. 【アルゴリズム】バブルソートによる名前順の整列
    ' 初学者の方にも分かりやすいよう、古典的なバブルソートを採用します。
    ' パフォーマンスを極限まで求めるなら、QuickSort等へのアップグレードを検討しましょう。
    For i = LBound(masterNames) To UBound(masterNames) - 1
        For j = i + 1 To UBound(masterNames)
            If StrComp(masterNames(i), masterNames(j), vbTextCompare) > 0 Then
                ' 要素の入れ替え
                temp = masterNames(i)
                masterNames(i) = masterNames(j)
                masterNames(j) = temp
            End If
        Next j
    Next i
    
    ' 3. 【ステンシルの構築】
    ' 新しいカスタムステンシルを作成します。
    ' ※既存のステンシルをいじるのではなく、新しく作るのが安全な設計です。
    Set vsoStencil = vsoApplication.Documents.AddStencil(visStencilTypeCustom, "Sorted_Toolbox")
    
    On Error GoTo ErrorHandler
    
    ' 4. ソート済みのリストに従って、マスターをステンシルに追加
    ' 本来は、既存のドキュメントからマスターをコピーしてくる処理をここに記述します。
    ' 今回はデモンストレーションとして、メッセージを表示しながら進めます。
    Debug.Print "--- ステンシル構築開始 ---"
    
    For i = LBound(masterNames) To UBound(masterNames)
        ' ここでは、実際には「既存のドキュメントからMasterをコピー」する処理を行います。
        ' 例: vsoStencil.Masters.Add(vsoSourceMaster)
        
        ' 今回はロジックの確認のため、ログ出力のみ行います。
        Debug.Print "Adding Master: " & masterNames(i)
    Next i
    
    MsgBox "ステンシルの構築が完了しました!" & vbCrLf & _
           "コンソールを確認して、順番が正しいか見てみてください。", vbInformation, "Success"
    
    Exit Sub

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

コードの解説:ここがプロの視点

  • `StrComp` 関数の使用:

単なる `>` 比較ではなく、`StrComp(…, vbTextCompare)` を使っています。これは大文字・小文字を区別せずに比較するための「知的な選択」です。ユーザーが入力した文字に揺らぎがあっても、正しくソートできます。

  • `On Error GoTo ErrorHandler`:

自動化において、エラー処理は「おまけ」ではありません。「必須」です。ステンシル作成中にファイルがロックされていたり、メモリが不足していたりする場合に、システムをクラッシュさせず、優雅にエラーを報告するための防波堤です。

  • `Array` と `Loop` の分離:

「データの整理(ソート)」と「オブジェクトの操作(ステンシルへの追加)」を明確に分けています。これができていないコードは、後で修正が困難な「スパゲッティコード」へと変貌します。

5. 陥りやすい罠(Pitfalls)と回避策

中級者への階段を登る際、以下の3点には特に注意してください。

① 読み取り専用ステンシルの壁

前述した通り、Visio標準のステンシルを `vsoStencil.Masters.Add` しようとするとエラーになります。「既存のものをいじろうとする」のではなく、「新しい器(カスタムステンシル)を用意して、中身を移し替える」という思考の転換を持ってください。

② メモリの解放(オブジェクトのライフサイクル)

VBAでは、大きなオブジェクトを扱う際、使い終わったら `Set vsoStencil = Nothing` のように明示的に参照を切る癖をつけておきましょう。特に大量のマスターを扱うループ処理の中では、メモリの管理がパフォーマンスに直結します。

③ 非同期処理の不在

Visio VBAは基本的にシングルスレッドです。巨大なステンシルを構築している間、Visioの画面はフリーズしたようになります。ユーザーへの配慮として、処理中に `DoEvents` を挟むか、「処理中…」というステータスバーの表示を入れるのが、一流のエンジニアの作法です。

最後に:ここをクリアすれば、基本はバッチリです

いかがでしたか?

単に「並び替える」という動作の裏側には、「データ構造を理解し、アルゴリズムを適用し、エラーを制御しながら、ユーザーに最適なUIを提供する」という、エンジニアリングの真髄が詰まっています。

この「データを整理してから、実体に反映させる」という考え方は、Visio VBAに限らず、あらゆるプログラミングに通じる普遍的な真理です。

一歩ずつ、確実に。
コードの向こう側にいるユーザーの笑顔を想像しながら、あなたの自動化の旅を続けてください。応援していますよ。

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