【上級】VBAからAutoCADのメニューバーとツールバーを動的にカスタマイズ!AcadMenuGroupとAcadToolbarの操作
開発プロジェクトのリーダーとして、ハッキリと言わせてもらう。
「業務効率化のために自作のマクロを作った。あとは各担当者が手動でツールバーにボタンを登録してくれ」――この運用は、今日で終わりだ。
プロが作るべきは、ツール本体だけではない。「AutoCADを起動した瞬間、必要なUIが自動構築され、誰がどの端末で開いても同じ環境で動く」という、デプロイメントの自動化までを含めてが真の業務自動化システムである。
今回は、AutoCAD VBAの真骨頂である `AcadMenuGroup` と `AcadToolbar` を駆使し、メニューバーとツールバーをプログラムから動的に制御・構築する極限の知見を授けよう。
—
1. なぜ手動カスタマイズは破綻するのか?(設計の死角)
AutoCADのUIカスタマイズ(CUIxファイルの操作)をGUIで行うのは、ローカル環境依存のスタンドアロンな作業でしかない。複数人への配布、バージョンアップ、環境移行が発生した瞬間、このアプローチは確実に破綻する。
脆弱な手動運用の末路
- CUIxの競合と破損: 複数人が勝手にカスタマイズファイルを上書きし、最悪の場合AutoCADが起動しなくなる。
- マクロパスのロスト: 共有サーバー上の `.dvb` ファイルのパスが変わった途端、すべてのボタンが無効化される。
- バージョン差異の罠: AutoCADのバージョンが変わるたびに、ワークスペースの再設定やボタンの再登録地獄が始まる。
プロが目指すべき「自己修復型UIアーキテクチャ」
VBAの初期化ルーチン(例: `AcadDocument_Activate` や `AcApp_Init`)の中で、「起動時に自分のメニューとツールバーが存在するか確認し、なければコードから動的に生成・修復する」。これが、保守性ゼロのシステムを構築するための唯一の正解だ。
—
2. オブジェクトモデルの理解:CUIx迷宮の歩き方
AutoCADのUIをVBAから制御する場合、以下の階層構造を正確に把握している必要がある。
AcadApplication
└─ MenuGroups (AcadMenuGroups)
└─ AcadMenuGroup (インデックスまたは名前で特定。通常メインは “ACAD”)
├─ Menus (AcadPopupMenus) -> メニューバー
└─ Toolbars (AcadToolbars) -> ツールバー
└─ AcadToolbarItem -> ツールバーボタン
ここで最大の罠がある。それは「編集中のCUIxとAcadMenuGroupの結びつき」だ。
独自のメニューやボタンを追加する場合、メインの `ACAD` グループを汚染するのではなく、独立した部分CUI(またはメインへの動的追加)を安全にハンドリングする必要がある。
—
3. 【プロダクションコード】メニューとツールバーを完全自動構築するVBAモジュール
以下のコードは、実務の現場でそのまま使える、エラーハンドリングを網羅した堅牢なモジュールである。指定した名前のツールバーとカスタムボタンがなければ自動生成し、クリック時に特定のマクロ(例: `_.VBARUN “C:\Macros\Toolbox.dvb!Module1.MainProcess”`)を叩く仕組みを構築する。
Option Explicit
‘ ==============================================================================
‘ モジュール名: CUI_Builder
‘ 概要: AutoCADのメニューバー及びツールバーを動的に構築・修復する
‘ ==============================================================================
Public Sub InitializeCustomUI()
On Error GoTo ErrorHandler
Dim currMenuGroup As AcadMenuGroup
Dim targetToolbarName As String
Dim targetMenuName As String
targetToolbarName = “AutoCAD自動化ツイン”
targetMenuName = “業務支援(&B)”
‘ メインメニューグループ(通常は “ACAD” またはカスタムCUI名)を取得
‘ ※環境に合わせて変更してください
Set currMenuGroup = ThisDrawing.Application.MenuGroups(“ACAD”)
‘ 1. ツールバーの動的生成とボタン配置
Call SetupToolbar(currMenuGroup, targetToolbarName)
‘ 2. メニューバーの動的生成と項目配置
Call SetupPopupMenu(currMenuGroup, targetMenuName)
MsgBox “UIの動的構築が正常に完了しました。”, vbInformation, “初期化成功”
Exit Sub
ErrorHandler:
MsgBox “UI構築中に致命的なエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub
Private Sub SetupToolbar(mg As AcadMenuGroup, tbName As String)
Dim tbs As AcadToolbars
Dim targetTb As AcadToolbar
Dim tbItem As AcadToolbarItem
Dim macroString As String
Dim isExists As Boolean
Dim i As Long
Set tbs = mg.Toolbars
isExists = False
‘ 既存の同名ツールバーを探索
For i = 0 To tbs.Count – 1
If tbs(i).Name = tbName Then
Set targetTb = tbs(i)
isExists = True
Exit For
End If
Next i
‘ 存在しない場合は新規作成
If Not isExists Then
Set targetTb = tbs.Add(tbName)
End If
‘ ツールバーを表示状態にする
targetTb.Visible = True
‘ ボタンの重複作成を防ぐため、一度クリアするか存在チェックを行う
‘ ここではシンプルに既存ボタンがない場合のみ追加する実装例
If targetTb.Count = 0 Then
‘ 実行するマクロのコマンド文字列(VBAのランチャー構文)
‘ 例: 共有フォルダにあるDVB内のプロシージャを呼び出す
macroString = “_.VBARUN “”C:\CAD_Tools\MasterMacro.dvb!RunAutomation”” ”
‘ ボタンの追加 (インデックス, ボタン名, ヘルプ文字列, マクロ文字列, 小アイコン使用有無)
Set tbItem = targetTb.AddToolbarButton(0, “一括処理実行”, “図面の一括クリーンアップを実行します”, macroString, True)
‘ アイコンを設定する場合はここでビットマップを指定可能
‘ tbItem.SetBitmaps “small_icon.bmp”, “large_icon.bmp”
End If
End Sub
Private Sub SetupPopupMenu(mg As AcadMenuGroup, menuName As String)
Dim menus As AcadPopupMenus
Dim targetMenu As AcadPopupMenu
Dim menuItem As AcadPopupMenuItem
Dim macroString As String
Dim isExists As Boolean
Dim i As Long
Set menus = mg.Menus
isExists = False
‘ 既存のポップアップメニュー(プルダウンメニュー)を探索
For i = 0 To menus.Count – 1
If menus(i).Name = menuName Then
Set targetMenu = menus(i)
isExists = True
Exit For
End If
Next i
‘ 存在しない場合は新規作成
If Not isExists Then
‘ メニューバーの末尾に追加
Set targetMenu = menus.Add(menuName)
End If
‘ メニュー項目が空の場合のみ追加
If targetMenu.Count = 0 Then
macroString = “_.VBARUN “”C:\CAD_Tools\MasterMacro.dvb!RunAutomation”” ”
‘ メニューアイテムの追加 (インデックス, キャプション, マクロ文字列)
Set menuItem = targetMenu.AddMenuItem(targetMenu.Count, “一括処理を実行(&E)”, macroString)
‘ 区切り線を挟む場合
‘ targetMenu.AddSeparator targetMenu.Count
End If
‘ メニューバーに表示させる(AutoCADのメインメニューバーにインサート)
‘ ※既にメニューバーに存在するかどうかの厳密なチェックは省略していますが、実務では重複インサートに注意
On Error Resume Next
targetMenu.InsertInMenuBar ThisDrawing.Application.MenuBar.Count + 1
On Error GoTo 0
End Sub
—
4. 実務で絶対に押さえておくべき「3つの鉄則」
現場のチーフとして、このコードをデプロイする際に必ず守るべきルールを授ける。
① パスのハードコーディングを排除せよ
サンプルコードでは分かりやすく `C:\CAD_Tools\MasterMacro.dvb` と書いたが、本番環境では絶対に避けるべきだ。社内ネットワークのパスや、アドインのインストールパスをレジストリ、または環境変数、あるいは図面と同階層(`ThisDrawing.Path`)から動的に解決する仕組みを必ず組み込むこと。
② メニューの重複インサート(Duplication)を防げ
`targetMenu.InsertInMenuBar` を無条件で実行し続けると、AutoCADを起動するたびに同じメニューがメニューバーの右側に増殖していくという悲劇が起きる。メニューバーのコレクション(`ThisDrawing.Application.MenuBar`)をループし、既に名前が登録されているかチェックするガード節を必ず設けること。
③ COMのライフサイクルとエラーハンドリング
AutoCADのUIコレクション操作は、内部のCOMオブジェクトとのやり取りが発生するため非常にデリケートである。特にAutoCADの終了間際や、ドキュメントが完全にロードされていない状態(`DocumentOpen`直後など)で実行するとエラー落ちしやすい。
`AcadDocument_Activate` イベントや、リボン・メニューのロード完了タイミングをフックして安全に実行させるのがプロの技だ。
—
5. おわりに:真の自動化エンジニアへ
今回紹介した `AcadMenuGroup` や `AcadToolbar` の動的制御をマスターすれば、もはや「新しいツールを配るために全台のPCをマニュアル設定して回る」という前時代的な業務とはおさらばできる。
システムをデプロイした瞬間、AutoCADが自ら美しく化粧直しを済ませ、ユーザーの前に完璧なUIを用意する――。それこそが、私たちが目指すべき「真の業務自動化」の姿だ。
コードを書き、現場を圧倒せよ。健闘を祈る。
