【入門編】Application.CustomMenusの動的構築:社内標準Visioツール用の独自操作メニュー追加手法 – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visio VBAの自動化の世界へようこそ。
マクロの記録ボタンを押して図形を動かすだけのステージから、一歩先へ進みたいあなたへ。

今回は、現場で愛される「社内標準ツール」を作るための必須スキル、`Application.CustomMenus` を使った独自操作メニューの動的構築について徹底解説します。

「ExcelやWordにはリボンカスタマイズの機能があるけれど、Visioで自作のマクロをスマートにメニューバーから実行してもらうにはどうすればいいの?」
そんな疑問を、今日ここで完全にクリアにしましょう。ここをマスターすれば、あなたの作ったVisioマクロは、ただの「個人的なお助けスクリプト」から「組織全体で使える公式ツール」へと生まれ変わります。

優しい先輩エンジニアとして、基本のキから実務で使える極意まで、しっかりと導いていきますね。

1. なぜ「独自メニュー」の動的構築が必要なのか?

通常、VisioでVBAマクロを実行するには、[開発]タブを開いて、[マクロ]ボタンを押して……という手順を踏む必要がありますよね。これでは、普段VBAを使わない一般の社員(エンドユーザー)にとってはハードルが高すぎます。

「Visioを起動した瞬間、あるいは図面を開いた瞬間に、見慣れた場所に『社内標準ツール』というメニューがポッと現れ、そこをクリックするだけで自動処理が走る」
これが理想のUI(ユーザーインターフェース)です。

Visioの古いバージョンから受け継がれる `CustomMenus` オブジェクト(※Visio 2010以降のリボンUI環境でもアドイン等との互換性や特定用途で強力に機能します)をVBAから操作することで、「VBAの起動と同時にメニューを生成し、終了時にきれいにお片付けする」という動的なUIコントロールが可能になります。

2. 押さえておきたいVisioオブジェクトの基本

今回のコードを書く前に、Visioのオブジェクトモデルにおける「立ち位置」を整理しておきましょう。

Application (Visioアプリ全体)
┗ Document (現在開いているファイル)
┗ UI (ユーザーインターフェース関連)
┗ CustomMenus (独自メニューのコレクション)

私たちは一番上の親である `Application` オブジェクトから `CustomMenus` を呼び出し、そこに新しいメニューアイテムを「動的に追加」していきます。

3. 実践!独自メニューを追加・削除するVBAコード

それでは、実際に動くコードを見ていきましょう。
今回は、「Visio起動時(またはマクロ実行時)にメニューを登録し、不要になったら消す」というライフサイクルを管理するサンプルコードを用意しました。

このコードは、Visioの標準モジュールにそのままコピペして実行できます。

Option Explicit

‘ ==============================================================================
‘ テーマ: Application.CustomMenusによる独自操作メニューの動的構築
‘ 概要: 実行するとVisioのメニューバーに社内標準ツールを追加し、
‘ クリック時に特定のマクロを呼び出すように設定します。
‘ ==============================================================================

‘ メニューに追加するコマンドの名前(識別用)
Private Const MENU_CAPTION As String = “社内標準ツール(&S)”
Private Const ITEM_CAPTION As String = “図形の自動整列を実行(&A)”
Private Const MACRO_NAME As String = “RunAutoLayout” ‘ 呼び出すマクロ名

Public Sub SetupCustomMenu()
Dim vsoUIObject As Visio.UIObject
Dim vsoMenuSets As Visio.MenuSets
Dim vsoMenuSet As Visio.MenuSet
Dim vsoMenus As Visio.Menus
Dim vsoMenu As Visio.Menu
Dim vsoMenuItems As Visio.MenuItems
Dim vsoMenuItem As Visio.MenuItem

On Error GoTo ErrorHandler

‘ 1. 現在のVisioのUIオブジェクトを取得する
Set vsoUIObject = Application.UIObject

‘ 2. 図面ウィンドウ用のメニューセットを取得 (visUIObjSetDrawing = 0)
Set vsoMenuSets = vsoUIObject.MenuSets
Set vsoMenuSet = vsoMenuSets.Item(Visio.VisUIObjSets.visUIObjSetDrawing)

‘ 3. メニューコレクションを取得
Set vsoMenus = vsoMenuSet.Menus

‘ 【重要】重複作成を防ぐため、すでに同名のメニューがあれば一度削除する
Call RemoveCustomMenu_Silent

‘ 4. 新しいトップレベルメニューを挿入する(「ヘルプ」の左隣あたりに追加)
‘ 引数: 挿入位置のインデックス (-1を指定すると末尾や適切な位置に追加)
Set vsoMenu = vsoMenus.AddAt(-1)
vsoMenu.Caption = MENU_CAPTION

‘ 5. 追加したメニューの中に、実行アイテム(サブメニュー)を追加する
Set vsoMenuItems = vsoMenu.MenuItems
Set vsoMenuItem = vsoMenuItems.AddAt(-1)

‘ 6. メニューアイテムのプロパティを設定
vsoMenuItem.Caption = ITEM_CAPTION
‘ ユーザーがクリックしたときに実行するVBAマクロ名を指定
vsoMenuItem.ActionText = MACRO_NAME

‘ 7. Visioに新しいUIオブジェクトを適用する
Application.SetCustomUI vsoUIObject

MsgBox “社内標準メニューの組み込みが完了しました!”, vbInformation, “成功”
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub

‘ 独自メニューを安全に削除するプロシージャ
Public Sub RemoveCustomMenu()
Call RemoveCustomMenu_Silent
MsgBox “社内標準メニューを削除しました。”, vbInformation, “完了”
End Sub

‘ 内部用:エラーを出さずにメニューをクリーンアップする関数
Private Sub RemoveCustomMenu_Silent()
Dim vsoUIObject As Visio.UIObject
Dim vsoMenuSet As Visio.MenuSet
Dim vsoMenu As Visio.Menu
Dim i As Long

Set vsoUIObject = Application.UIObject
Set vsoMenuSet = vsoUIObject.MenuSets.Item(Visio.VisUIObjSets.visUIObjSetDrawing)

‘ 既存のカスタムメニューを探して削除
For i = vsoMenuSet.Menus.Count & To 1 Step -1
Set vsoMenu = vsoMenuSet.Menus.Item(i)
If vsoMenu.Caption = MENU_CAPTION Then
vsoMenu.Delete
End If
Next i

‘ UIを再適用して変更を反映
Application.SetCustomUI vsoUIObject
End Sub

‘ ——————————————————————————
‘ メニューから呼び出されるサンプルマクロ
‘ ——————————————————————————
Public Sub RunAutoLayout()
MsgBox “社内標準マクロ『図形の自動整列』が呼び出されました!”, vbInformation, “実行確認”
‘ ここに実際の自動化ロジック(図形の整列やデータ連携など)を記述します
End Sub

4. コードの深掘りポイント(エンジニアの知見)

ここで、初学者がハマりやすいポイントや、プロとして知っておくべき「Visio UIのライフサイクル」の闇をいくつか解説しておきます。

① `AddAt(-1)` の魔法

コード内で出てくる `AddAt(-1)` ですが、これは「適切な位置(通常は既存メニューの末尾、ヘルプの前など)に自動で配置しなさい」というVisioのお作法です。無理に特定の番号を指定すると、他のアドインと衝突してエラーになることがあるため、`-1`(末尾追加)を使うのが安全でスマートです。

② メニューの「二重生成」を防ぐ(お掃除の重要性)

VBAでUIを構築する際、最も多いミスが「コードを実行するたびに、同じ名前のメニューが何個も増殖していく」という現象です。
これを防ぐために、今回のコードでは `RemoveCustomMenu_Silent` というプライベート関数を用意し、「新しく作る前に、同名のメニューがあれば必ず消す」という安全装置(イデンプテントな設計)を組み込んでいます。これがプロの仕事です。

③ 適用するタイミング:`Application.SetCustomUI`

せっかくメニューの構造をメモリ上で組み立てても、最後の `Application.SetCustomUI vsoUIObject` を実行しないとVisioの画面には反映されません。忘れずにセットであげましょう。

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

  • エラー:「指定された名前のマクロが見つかりません」
  • 原因: `vsoMenuItem.ActionText` に指定したマクロ名(例: `RunAutoLayout`)が、標準モジュールに存在しないか、スペルミスしています。また、`Private` ではなく `Public` サブルーチンとして定義されているか確認してください。
  • メニューが消えなくなった場合
  • Visioを一度完全に終了し、再度立ち上げればデフォルトのUIに戻ります(コードで明示的に `ThisDocument.DocumentSaved` や `Application_Quit` などのイベントで `RemoveCustomMenu_Silent` を呼ぶようにしておくと、より親切です)。

まとめ:ここをクリアすれば、Visio VBAの基本はバッチリですよ!

お疲れ様でした!今回は `Application.CustomMenus` を使った、社内標準VisioツールのUIカスタム手法について解説しました。

マクロの記録を卒業し、「自分が書いたコードを、誰もが使いやすいUIとして形にする」というステップに踏み出したあなたは、もう立派なVisio自動化エンジニアの仲間入りです。

ぜひ、このコードをベースにご自身の職場で必要な自動化マクロを組み込み、「おっ、このVisio使いやすいぞ!」と周囲を驚かせてみてくださいね。
あなたのVBAライフが、より一層エキサイティングなものになりますように!

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