【実務・中級編】Page.PrintPropertiesのVBA制御:用紙サイズ・向き・印刷倍率の一括自動構成ツール – Visio VBA解析バイブル

スポンサーリンク

Visio VBAを掌握する極限の知見:`Page.PrintProperties` を完全制御し、全図面の印刷設定を一撃で統制する

エンタープライズ規模のシステム設計図、あるいは数百ページに及ぶプラント配管図をVisioで管理していると、必ず直面する悪夢がある。
それが「複数ページにわたる印刷設定の不整合」だ。

あるページはA3横、別のページはA4縦、さらにあるページは「1ページに収める」設定が抜けていてPDF出力時に右側がプッツリ切れている――。これを人間の手で1枚ずつプロパティを開いて修正するなど、エンジニアの工数の無駄遣いであり、百害あって一利なしだ。

今回は、Visioのオブジェクトモデルの深層に切り込み、`Page.PrintProperties` を駆使して全ページの用紙サイズ・向き・印刷倍率(自動収まり)をプログラムから一括で強制統制する、プロダクション品質のVBAマクロを授与する。

1. なぜVisioの印刷設定制御はハマりやすいのか?

素人が書いたVisioマクロは、決まって次のようなコードで爆発する。

‘ 【アンチパターン】絶対にやってはいけない実装
Dim shp As Visio.Shape
For Each pg In ActiveDocument.Pages
pg.PageSheet.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPageSize).FormulaU = “7” ‘ A4のつもり
Next

なぜこれがダメなのか?理由は3つある。
1. マジックナンバーの恐怖: `7` が何を表すのか、半年後のあなたには読めない。Visioの用紙サイズ定数(`VisPaperSize`)を正しくマッピングしなければ、プリンタードライバーと喧嘩を始める。
2. 「自動ページ収まり(Fit to)」の排他制御: 「用紙幅・高さに合わせる」プロパティは、単にサイズを入れただけでは有効化されない。`PrintFitOnPages` や `PagesX`, `PagesY` のフラグを連動させて初めて機能する。
3. ドキュメントの重み(パフォーマンス): 画面描画(ScreenUpdating)を制御せずにページを走査すると、図面が点滅し、完了までに無駄な時間を奪われる。

プロのエンジニアであれば、トランザクション的な一括処理、定数の明示化、そして例外を許さない堅牢なエラーハンドリングを実装すべきだ。

2. 堅牢な設計:PrintProperties オブジェクトの構造

Visioの各ページ(`Page`)は、その裏側に必ずシェイプシート(`PageSheet`)を持っている。印刷プロパティ実体は、この `PageSheet` 内の `visSectionObject` > `visRowPrintProperties` セクションに格納されている。

これをVBAから安全に操作するため、以下の仕様を満たすプロシージャを設計する。

  • 用紙サイズ: A4 (`visPaperA4`) または A3 (`visPaperA3`) を動的に指定可能。
  • 向き: 縦 (`visPrnDevOrientationPortrait`) / 横 (`visPrnDevOrientationLandscape`)。
  • 自動収まり: 「横○ページ、縦○ページに収める」の完全制御(例:1ページに収めるなら `PagesX = 1`, `PagesY = 1`)。

3. 【プロダクションコード】全ページ一括印刷設定統制ツール

以下のコードをVisioの標準モジュールに貼り付けてほしい。実務でそのまま使えるよう、画面描画の抑制やエラー対策、実行ログのイミディエイトウィンドウ出力まで完備している。

Option Explicit

‘ ==============================================================================
アクティブドキュメントの全ページの印刷プロパティ(サイズ・向き・収まり)を一括設定する
‘ ==============================================================================
Public Sub ApplyPrintPropertiesToAllPages()

‘ — 設定パラメータ(要件に合わせて変更してください) —
Const TARGET_PAPER_SIZE As Integer = visPaperA4 ; ‘ A4: visPaperA4, A3: visPaperA3
Const TARGET_ORIENTATION As Integer = visPrnDevOrientationLandscape ‘ 縦: visPrnDevOrientationPortrait, 横: visPrnDevOrientationLandscape
Const FIT_TO_PAGE_X As Integer = 1 ; ‘ 横方向に何ページ分に収めるか (0なら無効)
Const FIT_TO_PAGE_Y As Integer = 1 ; ‘ 縦方向に何ページ分に収めるか (0なら無効)
‘ ——————————————————–

Dim targetDoc As Visio.Document
Set targetDoc = ActiveDocument

‘ ドキュメントが開かれているか確認
If targetDoc Is Nothing Then
MsgBox “処理対象のドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If

‘ パフォーマンス劇的改善のための定石
Dim originalScreenUpdating As Boolean
originalScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False

Dim originalWaitCursor As Boolean
originalWaitCursor = Application.WaitCursor
Application.WaitCursor = True

On Error GoTo ErrorHandler

Dim pg As Visio.Page
Dim pageSheet As Visio.Shape
Dim processedCount As Long
processedCount = 0

Debug.Print “=== 印刷設定一括適用プロセス開始 ===”

For Each pg In targetDoc.Pages
‘ バックグラウンドページやマスターページを除外したい場合はここでガードを入れる
If Not pg.Background Then
Set pageSheet = pg.PageSheet

With pageSheet
‘ 1. 用紙サイズの指定
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPageSize).FormulaU = TARGET_PAPER_SIZE

‘ 2. 印刷の向き(縦/横)の指定
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPaperOrientation).FormulaU = TARGET_ORIENTATION

‘ 3. 自動ページ収まり(Fit to)の制御
If FIT_TO_PAGE_X > 0 Or FIT_TO_PAGE_Y > 0 Then
‘ ページに合わせるフラグを有効化 (True = 1)
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesFitFlags).FormulaU = 1
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesScaleMode).FormulaU = 2 ‘ 2: 拡大/縮小して合わせる
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPagesX).FormulaU = FIT_TO_PAGE_X
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPagesY).FormulaU = FIT_TO_PAGE_Y
Else
‘ 収まり設定を無効化する場合
.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesFitFlags).FormulaU = 0
End If
End With

processedCount = processedCount + 1
Debug.Print “適用完了: ページ名 = ” & pg.Name
End If
Next pg

‘ 処理終了後のクリーンアップ
Application.ScreenUpdating = originalScreenUpdating
Application.WaitCursor = originalWaitCursor

Debug.Print “=== プロセス正常終了 (処理ページ数: ” & processedCount & “) ===”
MsgBox “全 ” & processedCount & ” ページの印刷設定を一括更新しました。”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ 異常終了時も必ず画面描画フラグを復元する(これがないとVisioがフリーズしたような挙動になる)
Application.ScreenUpdating = originalScreenUpdating
Application.WaitCursor = originalWaitCursor

MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Description, vbCritical, “致命的エラー”
Debug.Print “【エラー発生】 ” & Err.Description
End Sub

4. コードの急所:エンジニアが押さえるべき実装のポイント

① `Application.ScreenUpdating = False` の絶対死守

Visioは、ページオブジェクトのシェイプシート(`PageSheet`)を書き換えるたびに、UI上のプレビューやレイアウト再計算を走らせようとする。ページ数が50ページを超えたあたりから、この描画処理がボトルネックになり、マクロが異様なほど遅くなる。
コード例のように、処理の最初で画面描画を切り、最後に必ず復元する(エラー時も含む)のがプロの作法だ。

② `CellsSRC` とマジックナンバーのスマートな扱い

Visio VBAでは、セルへのアクセスに `CellsSRC`(Section, Row, Cell)を用いる。
印刷プロパティの行(`visRowPrintProperties`)には、用紙サイズ、向き、倍率、フィッティングフラグが密集している。
今回のコードでは、`VisPaperSize` などのVisio標準列挙体(Enums)を直接FormulaUに流し込んでいるため、プリンター依存のバグを未然に防ぐことができる。

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

Visioには「背景ページ(ヘッダーやフッター、方眼紙テンプレート等)」が存在する。これらに対しても無理やり印刷設定を適用すると、レイアウトの破損や不要なトラブルの元になる。`If Not pg.Background Then` というガード句によって、実体のある作図ページのみを安全にフィルタリングしている点に注目してほしい。

5. データベースや外部ファイル連携への発展性

このマクロをさらに実務で昇華させる場合、ハードコーディングされた `TARGET_PAPER_SIZE` を、Excel管理台帳や外部CSV、あるいはDBから動的に取得するアーキテクチャへと拡張することになる。

例えば、「図面管理DB」から図面IDごとのメタデータ(A3なのかA4なのか)を取得し、ループ内で `Select Case` を回して `TARGET_PAPER_SIZE` を切り替えるだけで、「社内ニッチな図面フォーマット自動コンバーター」の完成だ。

総括

Visio VBAにおけるオブジェクト操作は、背後にあるシェイプシートの構造とライフサイクルを理解していれば、恐るるに足りない。
今回提供した `Page.PrintProperties` 制御ロジックをあなたの開発環境に組み込み、煩雑な手作業地獄からチームを解放してほしい。エンジニアの本懐は、こうした機械的な苦作業をコードで駆逐することにあるのだから。

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