【入門編】Documentオブジェクトを制す:複数ページを効率よく巡回しプロパティを一括操作する方法 – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visioの自動化の世界へようこそ。
マクロの記録ボタンを押して、生成されたコードをそのまま眺めるフェーズはもう卒業しましたか?

今回は、Visio VBAの基礎でありながら、実務で最も差がつく「Documentオブジェクトとページ巡回の極意」についてお話しします。

「複数のページを巡回して、一括で設定を変えたい」
「図面の整理整頓を自動化したい」

そんな現場の要望に応えるための、安全で美しいコードの書き方を、先輩エンジニアの視点からたっぷりと伝授しますね。ここをクリアすれば、あなたのVisio VBAのスキルは間違いなく一段階上のステージに到達しますよ!

1. Visioオブジェクトモデルの階層構造をイメージしよう

VisioのVBAを書く上で、まず頭に叩き込んでおかなければならないのがオブジェクトの階層構造(親子関係)です。Visioの世界は、巨大なロシア人形のような入れ子構造になっています。

Application(Visioアプリ全体)
└─ Document(開いている図面ファイル)
├─ Page(個々のページ)
│ └─ Shape(図形たち)
└─ Master(ステンシル図形のマスター)

マクロの記録を使っていると忘れがちですが、私たちは常に「今、どのDocumentの、どのPageの上にいるのか」を意識しなければなりません。

特に今回焦点を当てる`Document`オブジェクトは、その図面ファイル全体を司る司令塔です。複数ページを操作する時は、この司令塔から「ページの一覧(Pagesコレクション)」を引っ張り出して、1つずつ見ていくことになります。

2. 陥りがちな罠:アクティブページに頼らない

初学者が最初にやりがちなのが、次のようなコードです。

‘ 【アンチパターン】絶対にやってはいけない例
Sub BadExample()
Dim i As Long
For i = 1 To ActiveDocument.Pages.Count
ActiveDocument.Pages(i).Name = “ページ_” & i
‘ 画面をアクティブに切り替えてしまっている!
ActiveDocument.Pages(i).Activate
Next i
End Sub

これ、何がダメだかわかりますか?
`ActiveDocument.Pages(i).Activate` を実行するたびに、Visioの画面がチラチラと切り替わります。ページ数が50ページあったら、画面が50回高速点滅し、処理速度も劇的に低下します。さらに、画面描画のイベントが走るため、予期せぬエラーの温床になります。

プロのエンジニアは、画面(UI)を一切触らずに、裏側(メモリ上)だけでオブジェクトを高速に料理するのです。

3. 実践!安全かつ高速に複数ページを巡回するコード

それでは、実務でそのまま使える、洗練されたVBAコードを見てみましょう。
このコードでは、以下の3つを実現しています。

1. 画面描画の停止(ScreenUpdating)による爆速化
2. For Each構文を用いたエレガントなコレクション走査
3. エラーハンドリングによる安全性の確保

Option Explicit

Sub UpdateAllPagesNameAndSettings()
‘ —————————————————-
‘ テーマ:Document内の全ページを巡回し、名前のプレフィックス付与と
‘ ドキュメントレベルの設定を安全かつ高速に行う
‘ —————————————————-

Dim targetDoc As Document
Dim targetPage As Page
Dim pageCounter As Long

‘ 1. 処理対象のドキュメントを明確に変数に格納する(ActiveDocumentに依存しない)
Set targetDoc = ActiveDocument

‘ 【重要】開いているドキュメントがない場合のガード節
If targetDoc Is Nothing Then
MsgBox “処理対象のドキュメントがありません。”, vbCritical, “エラー”
Exit Sub
End If

‘ 2. 画面描画を停止し、処理速度を限界まで引き上げる
Application.ScreenUpdating = False

‘ エラー時でも必ず画面描画を復元するための仕掛け
On Error GoTo ErrorHandler

pageCounter = 1

‘ 3. For Each を使ってコレクションをスマートに巡回
For Each targetPage in targetDoc.Pages

‘ バックグラウンドページ(背景用ページ)は除外したい場合の判定
If targetPage.Background = False Then

‘ ページ名を「Sheet_001」「Sheet_002」のように一括変更
targetPage.Name = “Sheet_” & Format(pageCounter, “000”)

‘ ついでにページごとの設定(例:図面尺度を1:10にするなど)もここで制御可能
‘ targetPage.PageSheet.Cells(“DrawingScale”).FormulaU = “1:10”

pageCounter = pageCounter + 1
End If

Next targetPage

‘ 正常終了時の処理
Application.ScreenUpdating = True
MsgBox “全 ” & (pageCounter – 1) & ” ページの処理が完了しました!”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ 異常終了時も必ず画面描画を戻す(これがないとVisioが固まったように見える)
Application.ScreenUpdating = True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”

End Sub

4. コードの深掘り解説:ここがプロの技

上記のコードで使っている「知る人ぞ知る重要テクニック」をいくつか解説しておきます。

① `Application.ScreenUpdating = False` の魔力

Visioは、VBAから図形やページを変更するたびに、親切心で画面を再描画します。これがマクロを遅くする最大の原因です。
処理の最初に `False` にし、終わったら必ず `True` に戻す。これだけで、大規模な図面であっても実行時間が数分から数秒に短縮されます。

② `On Error GoTo` による保険

もし処理の途中でエラーが発生した場合、`ScreenUpdating = False` のままでプログラムが停止すると、Visioの画面が固まったままになり、ユーザーはパニックになります。
必ず `ErrorHandler:` ラベルを用意し、エラーが起きたときでも画面描画を復元するコード(後始末)を入れるのが、プログラマの優しさであり、鉄則です。

③ バックグラウンドページの除外

Visioには「背景ページ」という特殊なページが存在します。通常の図面ページと一緒に背景ページまで名前を変えたりすると、レイアウトが崩れて大惨事になります。
`targetPage.Background = False` というプロパティを使って、「通常ページだけを対象にする」フィルタリングをかけるのが実務では必須となります。

まとめ:Documentオブジェクトを制する者はVisioを制す

今回は、`Document`オブジェクトを起点にして複数ページを安全かつ高速に巡回する方法を解説しました。

  • 画面(ActiveWindow)に頼らず、裏側のオブジェクト(Document/Pages)を操作する
  • `ScreenUpdating` で爆速化とチラつき防止を図る
  • エラーハンドリングで安全な後始末を忘れない

この基本原則さえ押さえておけば、何百ページもある巨大なフローチャートや組織図、ネットワーク図の自動生成・メンテナンスも、怖くありません。

ここをクリアできれば、もうあなたは「マクロの記録の奴隷」ではありません。自由自在にVisioを操るオートメーション・エンジニアです。
ぜひ、日々の業務の自動化にこの知見を役立ててくださいね!それでは、次のステップでお会いしましょう。

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