【実務・中級編】Visio標準コマンドをVBAから直接実行する:Application.DoCmdを活用した手動操作の自動化 – Visio VBA解析バイブル

スポンサーリンク

Visioを「操る」極致:Application.DoCmdで標準機能をハックせよ

VisioのVBA開発において、多くのエンジニアが躓く壁がある。それは、「API(メソッドやプロパティ)として提供されていない機能をどう自動化するか」という問題だ。

「グループ化の解除」や「図形の整列」、「レイアウトの自動調整」。これらはAPIが用意されていないケースも多い。多くの初心者はここでSendKeysという「禁じ手(非推奨)」に手を出し、処理の不安定さに夜を徹して頭を抱えることになる。

だが、真のプロフェッショナルは知っている。Visioには、UI上のあらゆる操作を内部的に呼び出すための「裏口」が用意されていることを。それが `Application.DoCmd` だ。

1. なぜ「DoCmd」なのか:SendKeysとの決定的違い

`SendKeys` は、キーボード入力をオペレーティングシステム経由で「横取り」して投げる。これはOSのイベントキューに依存するため、ウィンドウがフォーカスを失ったり、画面描画が遅れたりした瞬間に破綻する。いわば「目隠しをしてキーボードを叩く」ようなものだ。

対して `Application.DoCmd` は、Visioのコマンド識別子(visCmd…)を直接実行する。これはVisioの内部コマンドを関数呼び出しとして直接叩くため、実行の確実性が桁違いだ。

2. 「DoCmd」運用の鉄則:堅牢なコードを書くための作法

実務で「落ちないツール」を作るためには、以下の3原則を厳守せよ。

1. Selection(選択状態)を制御せよ: 多くのDoCmdは「選択されている図形」に対して作用する。コード内で `ActiveWindow.Select` を適切に行い、操作対象を明確にしてから実行すること。
2. イベントの抑制: DoCmd実行中に別のイベントが発火し、無限ループや予期せぬ挙動を招くことがある。`Application.ScreenUpdating = False` と `Application.AlertResponse = 0` (警告を自動で「はい」にする等) の合わせ技で、実行環境を隔離せよ。
3. コマンドIDの正体: コマンドIDは `Visio.VisUICmds` 列挙体で管理されている。これ以外の「隠しコマンド」も存在するが、公式の列挙体以外は将来のバージョンで動かなくなるリスクがあることを理解せよ。

3. 実践コード:プロ品質の「一括自動整列・グループ化」ツール

以下は、選択した図形群を一瞬で整列し、グループ化して名前を付ける、現場で即戦力となるテンプレートだ。

Option Explicit

”’

”’ 選択中の図形を一括整列し、グループ化する堅牢な実装例
”’

Public Sub SmartGroupAndAlign()
Dim vsoApp As Visio.Application
Set vsoApp = Application

‘ 1. エラーハンドリングと環境保護
On Error GoTo Cleanup
vsoApp.ScreenUpdating = False
vsoApp.AlertResponse = 7 ‘ 警告が出た場合、デフォルトで「キャンセル/いいえ」を返す

‘ 2. 選択図形があるか確認
If vsoApp.ActiveWindow.Selection.Count < 2 Then MsgBox "対象となる図形を2つ以上選択してください。", vbExclamation GoTo Cleanup End If ' 3. DoCmdによる標準機能の呼び出し ' visCmdAlignMiddle (1032): 左右中央揃え ' visCmdAlignCenter (1033): 上下中央揃え vsoApp.DoCmd visCmdAlignMiddle vsoApp.DoCmd visCmdAlignCenter ' 4. グループ化の実行 ' APIにGroupメソッドはあるが、DoCmdの方が複雑な配置を維持しやすい場合がある vsoApp.DoCmd visCmdGroup ' 5. 後処理:グループ化した図形に名前を付与 Dim vsoShape As Visio.Shape Set vsoShape = vsoApp.ActiveWindow.Selection(1) vsoShape.Name = "AutoGenerated_Group_" & Format(Now, "hhmmss") Cleanup: ' 環境を元に戻す(重要) vsoApp.ScreenUpdating = True vsoApp.AlertResponse = 0 If Err.Number <> 0 Then
Debug.Print “Error: ” & Err.Description
End If
End Sub

4. アーキテクトからの助言:データベース連携への応用

もし君がVisioからデータベース(SQL Server等)に情報を同期させようとしているなら、DoCmdを「最終手段」として捉えるべきだ。

データリンクが目的なら、DoCmdで操作するのではなく、`vsoShape.DataItems` や `vsoPage.DataRecordsets` を直接操作する方が遥かに高速で安定する。DoCmdはあくまで「APIがどうしても届かないUI操作」を代行させるためのものだ。

ツールを作る際、「APIでできること」と「DoCmdでしかできないこと」を切り分けよ。この境界線を理解した時、君の自動化ツールは「おもちゃ」から「エンジニアリング・プロダクト」へと進化する。

Visioの深い森を探索する諸君の健闘を祈る。何か不明点があれば、またいつでも問いに来るといい。

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