【テクニカル・上級編】Application.ActiveWindowプロパティの一括制御:グリッド・ルーラー・ガイド表示の「プレゼンテーションモード」切り替えマクロ – Visio VBA解析バイブル

スポンサーリンク

Visio VBAを掌握する極限の知見:ActiveWindow一括制御による「プレゼンテーションモード」の構築

VisioのUI制御において、最も見落とされがちなのが `Application.ActiveWindow` が持つプロパティ群の挙動特性と、それに伴う再描画コストの最適化だ。

多くのジュニアプログラマは、図面を閲覧モードへ切り替える際に、無造作にウィンドウの表示フラグを逐次書き換える。しかし、それでは画面のちらつき(フリッカ)が発生するだけでなく、大規模な図面において無駄なレイアウト計算と再描画が連鎖し、パフォーマンスを著しく低下させる。

本稿では、Visioのオブジェクトモデルの深層に踏込み、グリッド・ルーラー・ガイド・接続ポイントを一括制御して「プレゼンテーションモード」をミリ秒単位で実現する、極限まで洗練されたVBAマクロを提示する。

1. Visioウィンドウ制御におけるアーキテクチャ上の罠

Visioの `Window` オブジェクト(`ActiveWindow`)は、単なるビューポートではない。背後にあるドキュメントのビュー状態、選択セット、そしてUIの視覚的オーバーレイを統括する重厚なCOMオブジェクトである。

これらを制御する際の鉄則は以下の2点に集約される。

1. 画面更新の完全な抑止(`ScreenUpdating`): 複数の表示フラグを切り替える際、フラグを変更するたびにVisioはウィンドウの再描画を試みる。これを防ぐには、アプリケーションレベルでの描画停止が不可欠である。
2. オブジェクトのライフサイクル管理: `ActiveWindow` はカレントコンテキストに依存するため、冗長な変数代入を避け、スコープを限定して参照コストを最小化する。

2. 実装コード:プレゼンテーションモード一括制御エンジン

以下のコードは、編集用のフル機能ビューと、レビュー・プレゼン用のクリーンなビューをトグル(トグルスイッチ)で瞬時に切り替えるプロフェッショナル向けの実装である。

Option Explicit

‘ =================================================================================
‘ módulo名: modPresentationMode
‘ 概要: ActiveWindowのプロパティを操作し、編集モードとプレゼンテーションモードを
‘ 高速かつ確実にトグル切り替えするモジュール
‘ =================================================================================

Public Sub TogglePresentationMode()
Dim appVisio As Visio.Application
Set appVisio = Application

‘ アクティブドキュメントが存在しない場合は早期リターン
If appVisio.Documents.Count = 0 Then
MsgBox “制御対象のドキュメントが開かれていません。”, vbExclamation, “Visio Architect”
Exit Sub
End If

Dim targetWindow As Visio.Window
Set targetWindow = appVisio.ActiveWindow

‘ ウィンドウが描画をサポートしていないタイプ(シェイプシート等)の場合は除外
If targetWindow.Type <> visWinTypeDrawing Then
MsgBox “このウィンドウではプレゼンテーションモードを利用できません。”, vbInformation, “Visio Architect”
Exit Sub
End If

‘ 【極限最適化】画面描画とイベントを完全に凍結し、描画コストをゼロにする
appVisio.ScreenUpdating = False
appVisio.EventsEnabled = False

On Error GoTo ErrorHandler

‘ 現在の状態を判定基準として反転させる(トグル動作)
‘ GridShowを基準にモード判定(Trueならプレゼンモードへ、Falseなら編集モードへ)
Dim isCurrentlyEditing As Boolean
isCurrentlyEditing = targetWindow.GridShow

If isCurrentlyEditing Then
‘ ==========================================
‘ プレゼンテーションモード(クリーンビュー)へ移行
‘ ==========================================
targetWindow.GridShow = False ‘ グリッド非表示
targetWindow.RulerShow = False ‘ ルーラー非表示
targetWindow.GuideShow = False ‘ ガイド非表示
targetWindow.PageSplitShow = False ‘ ページ区切り非表示

‘ 接続ポイントはWindow側ではなくDocument/Page側の設定、
‘ あるいはWindowのViewSettingに依存するため、ActiveDocument全体で制御
Call SetConnectionPointsVisibility(appVisio.ActiveDocument, False)

appVisio.StatusBar = “ステータス: プレゼンテーションモード(閲覧用)”
Else
‘ ==========================================
‘ 編集モード(フルスペックビュー)へ復帰
‘ ==========================================
targetWindow.GridShow = True ‘ グリッド表示
targetWindow.RulerShow = True ‘ ルーラー表示
targetWindow.GuideShow = True ‘ ガイド表示
targetWindow.PageSplitShow = True ‘ ページ区切り表示

Call SetConnectionPointsVisibility(appVisio.ActiveDocument, True)

appVisio.StatusBar = “ステータス: 編集モード(標準)”
End If

ErrorHandler:
If Err.Number <> 0 Then
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “Critical Error”
End If

‘ 【重要】必ず描画とイベントを復元する。さもないとVisioがフリーズしたような挙動に陥る
appVisio.EventsEnabled = True
appVisio.ScreenUpdating = True

‘ オブジェクト参照の明示的な解放(VBAガベージコレクションの補助)
Set targetWindow = Nothing
Set appVisio = Nothing
End Sub

‘ =================================================================================
‘ 補助ルーチン: 接続ポイントの表示/非表示をドキュメント全体で制御
3 ‘ 理由: 接続ポイントの表示はWindowプロパティではなく、アプリ/ドキュメントの
‘ 設定に依存するため、API層を掘り下げる必要がある。
‘ =================================================================================
Private Sub SetConnectionPointsVisibility(ByVal targetDoc As Visio.Document, ByVal showState As Boolean)
Dim originalShowCP As Integer

If showState Then
‘ Visioのデフォルトの接続ポイント表示設定に戻す(通常はON)
targetDoc.SpaceHandles = visSpaceHandlesDetailed
Else
‘ 接続ポイントを隠すためにハンドルの表示を抑制
‘ ※Visioのバージョン依存を考慮し、エラーハンドリングを包含
On Error Resume Next
targetDoc.SpaceHandles = 0
On Error GoTo 0
End If
End Sub

3. チーフアーキテクトが解説するコードの急所

A. `ScreenUpdating = False` の不可欠性

数式やプロパティの書き換えがわずか数行であっても、Visioは内部でDirectX/GDI+を介した画面の再構築(レイアウト再計算)を実行する。これを抑制せずにプロパティを連打すると、画面が激しく点滅し、ユーザーエクスペリエンスを著しく損なう。コードの冒頭で停止し、エラー発生時も含めて確実に復元させる構造(Try-FinallyイディオムのVBA的実践)がプロフェッショナルの条件である。

B. ウィンドウタイプの厳密なバリデーション

`ActiveWindow.Type` を検証せずに出力処理を行うと、シェイプシートウィンドウやステンシルウィンドウがアクティブな時に実行された場合、ランタイムエラー(実行時エラー)を引き起こす。`visWinTypeDrawing` を明示的にガード節でチェックすることで、予期せぬクラッシュを未然に防ぐ。

C. 接続ポイント(Connection Points)の深い制御

グリッドやルーラーと異なり、接続ポイントの可視性はウィンドウ単位ではなく、ドキュメントの表示仕様やVisioのグローバル設定に深く結びついている。レガシーバージョン(Visio 2010〜2016)から最新のMicrosoft 365版に至るまで、安定して動作させるためのフォールバックを `On Error Resume Next` で担保している点に注目してほしい。

4. システム間連携・アドイン展開への応用

このVBAマクロは、単なる個人用の便利ツールにとどまらない。
社内ニッチなドキュメント管理システムや、外部のRPA(UiPathやPower Automateなど)からVisioをリモート制御する際、「閲覧時は邪魔な線をすべて消し、キャプチャ画像として高精度にエクスポートする」 という前処理(Pre-processing)としてもそのまま流用できる。

VBAの限界を超えてC# (VSTO) やCOMアドインとして再実装する場合でも、この `ActiveWindow` プロパティ群を操作する順序と、`ScreenUpdating` によるパフォーマンス担保の思想は完全に共通している。

アーキテクトたるもの、コードの「動く・動かない」に一喜一憂するな。
背後にあるオブジェクトのライフサイクルと描画エンジンの挙動を完全に支配し、秒速で完結する洗練されたコードベースを構築してこそ、真の自動化エンジニアである。

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