Visioのウィンドウを制する者は、自動化の深淵を制す
Visio VBAにおける`Application.Windows`コレクションの制御。多くの開発者は、これを単なる「現在開いている窓のリスト」程度にしか捉えていない。だが、大規模な自動化システムを構築する際、この「ウィンドウのライフサイクル」を制御できない者は、必ずと言っていいほど「意図しない画面遷移」や「バックグラウンドでのメモリリーク」という地獄を見る。
今日は、VisioのUIをプログラムから掌握し、堅牢な自動化環境を構築するための「ウィンドウ制御の極意」を伝授する。
—
1. なぜ「全ウィンドウ走査」の設計が重要なのか
Visioのウィンドウは、単なるGUIではない。`DrawingWindow`(作図)、`StencilWindow`(ステンシル)、`ShapeSheetWindow`(シェイプシート)といった異なるTypeが混在し、それぞれが独立したイベントバインドを持つ。
愚かなコードは、特定のドキュメントを決め打ちで操作し、ユーザーがステンシルを閉じた瞬間にランタイムエラーを吐く。真のアーキテクトは、「現在の状態を走査し、必要なWindowを特定した上で、操作を確定させる」というプロシージャを組む。
ウィンドウタイプを判別する際の鉄則
`Window.Type`プロパティを盲信してはいけない。`visDrawing`や`visStencil`といった定数で判別する際、必ず「ウィンドウが有効(Visibleかつアクティブ可能)か」を検証するプロセスを挟む必要がある。
—
2. 実践:プロダクションレベルのウィンドウ制御コード
以下は、現在開いている全ウィンドウを走査し、特定の条件に基づいて「ステンシルを隠す」「描画ウィンドウを最大化する」といった制御を一括で行うためのテンプレートだ。
Option Explicit
”’
”’
Public Sub OptimizeVisioLayout()
Dim win As Visio.Window
Dim app As Visio.Application
Set app = Application
‘ 画面更新を一時停止し、パフォーマンスを向上させる
app.ScreenUpdating = False
On Error GoTo ErrorHandler
For Each win In app.Windows
‘ ウィンドウの状態に応じた分岐処理
Select Case win.Type
Case Visio.VisWindowTypes.visDrawing
‘ 描画ウィンドウ:最大化してフォーカスを当てる
win.WindowState = Visio.VisWindowState.visWSMaximized
Case Visio.VisWindowTypes.visStencil
‘ ステンシルウィンドウ:特定の運用ルールで非表示/ドッキング制御
‘ 例:作業効率化のため、一時的にステンシルを隠す
win.Visible = False
Case Visio.VisWindowTypes.visSheet
‘ シェイプシート:開発中以外は閉じる等の制御が可能
Debug.Print “ShapeSheet detected: ” & win.Caption
Case Else
‘ その他ウィンドウの処理
End Select
Next win
Cleanup:
app.ScreenUpdating = True
Exit Sub
ErrorHandler:
Debug.Print “Error ” & Err.Number & “: ” & Err.Description
Resume Cleanup
End Sub
—
3. 実務で「死なない」ための3つのアーキテクチャ設計
コードをコピペして動かすことは簡単だ。しかし、それを「保守可能な資産」にするには以下の視点が不可欠である。
① オブジェクトの生存期間(ライフサイクル)を意識する
`Application.Windows`は動的に変化するコレクションだ。ループ内でウィンドウを閉じたり開いたりする場合、インデックス番号の変化に注意せよ。 削除を行う場合は、必ず逆順ループ(`For i = app.Windows.Count To 1 Step -1`)を採用するのが定石だ。
② ファイル・DB連携時の排他制御
外部データ(ExcelやSQL Server)と連携してシェイプを配置する際、ウィンドウの「アクティブ状態」が変わると、`ActiveWindow.Selection`の参照先が意図せずズレることがある。
「処理を開始する前に、操作対象のWindowオブジェクトを変数に固定する」こと。`ActiveWindow`という動的なプロパティに頼り切るコードは、バグの温床だ。
③ エラーハンドリングの「深さ」
`Window.Visible = False` を実行する際、そのウィンドウが既に閉じられている場合や、排他ロックがかかっている場合はエラーになる。`On Error Resume Next` で誤魔化すのではなく、`If Not win Is Nothing Then` といった明示的なNullチェックを組み込むことで、堅牢性は飛躍的に向上する。
—
最後に:エンジニアとしての矜持
VisioのUI制御は、単なる「見た目の調整」ではない。ユーザーが迷わないための「動的なワークスペース提供」である。
君たちが書くコード一つひとつが、現場のオペレーターの工数を左右する。今回提示したロジックをベースに、自社の業務フローに合わせた「最適化エンジン」を構築してほしい。
もし、さらに深い「イベント駆動型のウィンドウ監視(`WindowActivated`イベント等)」が必要になったら、また声をかけてくれ。Visioの深淵はまだ先にある。
