【中級編】Visio VBAで「印刷用レイヤー」を完全制御する —— ドラフト注釈をスマートに消し去るプロの技
こんにちは。現場の自動化を支えるアーキテクトです。
Visioで図面を作成していると、必ずと言っていいほど直面する問題があります。それは、「作業用のメモやドラフト(下書き)の注釈を、PDF出力時だけサッと消したい」という要望です。
「レイヤーを分けて、手動で非表示にしてから印刷している」……もしあなたがそうしているなら、それはまだ「マクロの記録」の延長線上にいます。ここから一歩踏み出し、「ドキュメント全体の状態をコードで支配する」段階へ進みましょう。
今日は、全ページのレイヤープロパティを瞬時に、かつ安全に制御する「極限の制御術」を伝授します。
1. なぜ「マクロの記録」では不十分なのか?
「マクロの記録」は、あなたがマウスで行った操作を忠実にコード化します。しかし、記録されたコードは「特定のページにある、特定のレイヤー」に対してしか命令を出しません。
もし図面が100ページあったら? あるいは、新しいページが追加されたら?
記録されたマクロでは、新しいページには一切対応できません。
プロのエンジニアは、特定の対象(Object)を指名するのではなく、「全ページを巡回し、条件に合致するレイヤーを自動で見つけ出す」というロジックを組みます。これが「制御」の本質です。
2. 知っておくべき「レイヤーの3要素」
レイヤーを制御する際、混乱しやすいのが以下の3つのプロパティです。ここを混同すると、「画面では見えているのに、PDFに出力されてしまった!」という致命的なミスを招きます。
| プロパティ | 意味 | 実務での使い分け |
|---|---|---|
| `Visible` | 画面上の表示 | 作業中に注釈を見たい場合は `True` にしておく。 |
| `Print` | 印刷・PDF出力 | ここが最重要。 PDFに出したくない注釈は `False` にする。 |
| `Lock` | 編集のロック | 作業中に誤って注釈を動かしたくない場合に `True` にする。 |
今回のゴール:
「作業中は `Visible = True` で見えていてほしいが、PDF出力時は `Print = False` で消えていてほしい」という状態を、全ページ一括で実現することです。
3. 【実践】全ページ一括レイヤー制御スクリプト
それでは、実戦で使えるコードを見ていきましょう。このコードは、指定した名前のレイヤー(例:「Draft」や「注釈」)を、全ページから探し出し、印刷設定を一括変更します。
Option Explicit
''' <summary>
''' 指定した名前のレイヤーの印刷設定を一括制御する
''' </summary>
''' <param name="targetLayerName">制御したいレイヤーの名前</param>
''' <param name="shouldPrint">Trueなら印刷対象、Falseなら非表示(印刷不可)</param>
Sub SetLayerPrintStatus(targetLayerName As String, shouldPrint As Boolean)
Dim pg As Visio.Page
Dim lyr As Visio.Layer
Dim foundCount As Integer
' --- パフォーマンス最適化の極意 ---
' 描画更新を停止することで、ループ中の画面のチラつきを抑え、処理速度を劇的に向上させます。
Application.ScreenUpdating = False
foundCount = 0
' 1. ドキュメント内の全ページをループ処理
For Each pg In ActiveDocument.Pages
' 2. 各ページに含まれるレイヤーをループ処理
' ※Page.Layersコレクションは、そのページで使用されているレイヤーを保持しています。
For Each lyr In pg.Layers
' 3. 条件判定:対象のレイヤー名と一致するか?
' StrCompを使用することで、大文字小文字の揺らぎに強い判定が可能です。
If StrComp(lyr.Name, targetLayerName, vbTextCompare) = 0 Then
' 4. プロパティの書き換え
lyr.Print = shouldPrint
' 処理した件数をカウント(デバッグ用)
foundCount = foundCount + 1
End If
Next lyr
Next pg
' 描画更新を再開
Application.ScreenUpdating = True
' 結果の通知
If foundCount > 0 Then
MsgBox targetLayerName & " レイヤーの印刷設定を " & _
IIf(shouldPrint, "【ON】", "【OFF】") & " に変更しました。" & vbCrLf & _
"(対象ページ数: " & foundCount & "箇所)", vbInformation, "完了"
Else
MsgBox "対象のレイヤー「" & targetLayerName & "」は見つかりませんでした。", vbExclamation, "警告"
End If
End Sub
''' <summary>
''' 実行用メインマクロ:ドラフト用注釈をPDF出力用に非表示にする
''' </summary>
Sub PrepareForPDF()
' ここでレイヤー名を指定します。プロジェクトに合わせて書き換えてください。
Call SetLayerPrintStatus("Draft", False)
End Sub
''' <summary>
''' 実行用メインマクロ:作業用に注釈を再表示する
''' </summary>
Sub PrepareForWork()
' 作業時は印刷設定に関わらず、画面に見えるように設定します。
' (Print設定はそのままに、Visibleだけ変えたい場合はロジックの微調整が必要です)
Call SetLayerPrintStatus("Draft", True)
End Sub
4. アーキテクトの視点:陥りやすい罠と回避策
このコードを運用する上で、中級者が必ずと言っていいほどハマるポイントが2つあります。
① レイヤー名の不一致(名前の「揺らぎ」)
「Draft」という名前でコードを書いたのに、実際のレイヤー名が「Draft 」(最後にスペースが入っている)だった場合、プログラムは見つけることができず、何も起きません。
対策: 上記コードでは `StrComp` 関数を使用していますが、実務ではレイヤー名の管理ルール(命名規則)をチーム内で徹底することが、最も強力なエラー対策になります。
② オブジェクトのライフサイクルとパフォーマンス
ページ数が多い図面で、`Application.ScreenUpdating = False` を忘れると、1ページごとにVisioが画面を再描画しようとして、処理が極端に重くなります。
対策: 大規模なループ処理を行うときは、「まず画面を止め、処理が終わってから解き放つ」。これがプロの作法です。
5. まとめ:ここをクリアすれば、Visio VBAの基本はバッチリです
今回のポイントを振り返りましょう。
1. `Visible`(表示)と `Print`(印刷)は別物である。
2. 特定のオブジェクトではなく、`For Each` を使って「集合(コレクション)」を走査する。
3. `ScreenUpdating` を制御して、パフォーマンスを確保する。
マクロの記録から卒業し、このように「構造」を意識したコードが書けるようになると、Visioは単なる作図ツールから、あなたの指示を完璧に遂行する「強力な自動化エンジン」へと進化します。
一歩ずつ、コードの裏側にあるオブジェクトの動きを感じながら進んでいきましょう。応援していますよ!
