【実務・中級編】Application.Windowsコレクションの走査とWindowTypeに応じたUI動的切り替え手法 – Visio VBA解析バイブル

スポンサーリンク

Visioのウィンドウを制する者は、自動化の深淵を制す

Visio VBAにおける`Application.Windows`コレクションの制御。多くの開発者は、これを単なる「現在開いている窓のリスト」程度にしか捉えていない。だが、大規模な自動化システムを構築する際、この「ウィンドウのライフサイクル」を制御できない者は、必ずと言っていいほど「意図しない画面遷移」や「バックグラウンドでのメモリリーク」という地獄を見る。

今日は、VisioのUIをプログラムから掌握し、堅牢な自動化環境を構築するための「ウィンドウ制御の極意」を伝授する。

1. なぜ「全ウィンドウ走査」の設計が重要なのか

Visioのウィンドウは、単なるGUIではない。`DrawingWindow`(作図)、`StencilWindow`(ステンシル)、`ShapeSheetWindow`(シェイプシート)といった異なるTypeが混在し、それぞれが独立したイベントバインドを持つ。

愚かなコードは、特定のドキュメントを決め打ちで操作し、ユーザーがステンシルを閉じた瞬間にランタイムエラーを吐く。真のアーキテクトは、「現在の状態を走査し、必要なWindowを特定した上で、操作を確定させる」というプロシージャを組む。

ウィンドウタイプを判別する際の鉄則

`Window.Type`プロパティを盲信してはいけない。`visDrawing`や`visStencil`といった定数で判別する際、必ず「ウィンドウが有効(Visibleかつアクティブ可能)か」を検証するプロセスを挟む必要がある。

2. 実践:プロダクションレベルのウィンドウ制御コード

以下は、現在開いている全ウィンドウを走査し、特定の条件に基づいて「ステンシルを隠す」「描画ウィンドウを最大化する」といった制御を一括で行うためのテンプレートだ。

Option Explicit

”’

”’ 全ウィンドウを走査し、UIを最適化するメインプロシージャ
”’

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の深淵はまだ先にある。

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