【Visio VBAの深淵】「印刷されない!」を防ぐ。図面サイズと用紙サイズの不一致を暴く監査ツールの作り方
「マクロの記録」から一歩踏み出し、もっと高度な自動化に挑戦したい。そう思っているあなたへ。
Visioで業務自動化を進めていると、避けては通れない、そして最も恐ろしい問題に直面することがあります。それは「画面では完璧なのに、印刷すると端が切れている、あるいは余白が異常に広い」という、現場からの悲鳴です。
なぜ、このようなことが起きるのか? それは、Visioの中に「図面のサイズ(キャンバス)」と「プリンタの用紙サイズ(出力)」という、二つの異なる概念が共存しているからです。
今日は、この「二つの世界」の不一致を自動で見つけ出し、報告する「監査ツール」の作成を通じて、Visio VBAの真髄である「PageSheet(ページシート)」の操り方を伝授しましょう。ここをマスターすれば、あなたは単なる「記録係」から、プロの「自動化エンジニア」へと進化できます。
1. なぜ「不一致」が起きるのか? 二つの世界の正体
まず、概念を整理しましょう。ここを理解せずにコードを書いても、砂上の楼閣です。
1. 図面サイズ (Page Size):
Visioの編集画面で見えている、デジタル上のキャンバスの大きさです。`Page.PageWidth` や `Page.PageHeight` で取得できる値です。
2. プリンタ用紙サイズ (Print Paper Size):
実際にプリンタに「この紙で印刷してくれ」と命令する設定です。これは、ページオブジェクトそのものの属性ではなく、`PageSheet` という、ページの設定情報が詰まった「隠れたスプレッドシート」の中に格納されています。
多くのユーザーは、図面サイズを A3 に変えたつもりでも、印刷設定(PageSheet)が A4 のままになっていることに気づきません。これが「印刷トラブル」の正体です。
2. 鍵を握る「PageSheet」という概念
マクロの記録を使うと、プロパティを直接書き換えるコードが生成されます。しかし、プロのエンジニアは「PageSheet」にアクセスします。
Visioの各ページは、内部的にExcelのようなセル形式のデータを持っています。これを `PageSheet` と呼びます。
例えば、印刷用紙サイズの設定は、`PageSheet.Cells(“PrintPaperSize”)` というセルに格納されています。
「プロパティを直接いじる」のではなく、「シートのセルを読み書きする」。この視点を持つことが、Visio VBAを掌握する第一歩です。
3. 実装:ページ設定監査ツール
それでは、全ページを巡回し、図面サイズと印刷設定が矛盾していないかをチェックするコードを書いていきましょう。
Option Explicit
''' <summary>
''' 全ページの図面サイズと印刷用紙サイズを比較し、不一致をログ出力する監査ツール
''' </summary>
Sub AuditPagePrintSettings()
Dim doc As Visio.Document
Dim pg As Visio.Page
Dim pgSheet As Visio.PageSheet
Dim report As String
Dim mismatchCount As Integer
' 現在開いているドキュメントを取得
Set doc = ActiveDocument
report = "--- Visio ページ設定監査レポート ---" & vbCrLf
mismatchCount = 0
' ドキュメント内の全ページをループ
For Each pg In doc.Pages
Set pgSheet = pg.PageSheet
' --- 核心部分:PageSheetから印刷設定を取得 ---
' PrintPaperSize は、特定の定数(インデックス)で管理されています。
' ここでは、図面の幅/高さと、印刷設定が「自動調整」になっていないかをチェックします。
Dim printSizeIndex As Long
printSizeIndex = pgSheet.CellsU("PrintPaperSize").ResultIU
' 印刷設定が「Auto(自動)」でない場合、図面サイズとの乖離を疑う
' ※ 0 は通常 'Auto' を指しますが、環境により異なる場合があるため注意。
' ここでは、高度なロジックとして「図面サイズ」と「印刷設定の整合性」をチェックします。
' 簡易的な監査ロジック:
' 印刷設定が「用紙に合わせて縮小(Fit to Page)」になっていないページを抽出
' (PrintPaperSize が特定の用紙サイズに固定されている場合)
' 0: Auto, 1: Letter, 2: Legal... と続きます。
' 0以外(特定のサイズ指定)の場合、図面サイズと一致しているか検証が必要。
If printSizeIndex <> 0 Then
' 印刷設定が固定されている場合、図面サイズとの乖離を警告
' 本来は printSizeIndex から実際の寸法を引く処理が必要ですが、
' ここでは「設定が固定されていること自体」を監査対象とします。
report = report & "[警告] ページ: " & pg.Name & " | 印刷設定が固定されています (Index: " & printSizeIndex & ")" & vbCrLf
mismatchCount = mismatchCount + 1
End If
Next pg
' 結果の出力
report = report & "------------------------------------" & vbCrLf
report = report & "監査完了。不一致/固定設定のページ数: " & mismatchCount & " 件"
' メッセージボックスで表示
MsgBox report, vbInformation, "監査結果"
' 必要に応じてテキストファイルに書き出す処理をここに追加できます
End Sub
コードの解説:ここがプロの視点
1. `CellsU(“PrintPaperSize”)`:
`Cells` ではなく `CellsU` を使っています。`U` は Universal の略。これは、言語設定(日本語/英語)に依存しない「ユニバーサル名」でセルを指定する書き方です。これを使わないと、海外のユーザーがあなたのマクロを動かした時にエラーで止まります。
2. `ResultIU`:
`ResultIU` は “Integer Unit” の略です。セルの値を整数として取得します。`PrintPaperSize` は「A4」という文字列ではなく、「2」といった数値(インデックス)で管理されているため、このメソッドが最適です。
3. `For Each pg In doc.Pages`:
オブジェクトのライフサイクルを意識し、ドキュメント内の全ページを効率的にスキャンしています。
4. 陥りやすいエラーと回避策
このツールを拡張する際に、初心者が必ずハマる落とし穴が2つあります。
① 単位(Unit)の罠
Visio内部では、長さは「インチ」や「ミリメートル」ではなく、「ポイント (Points)」という単位で管理されています。
`pg.PageWidth` を取得して `297` (mm) と比較しようとしても、実際には `841.89…` (points) が返ってきてしまい、「一致しない!」と誤判定されます。
解決策:
`Visio.Application.Convert` 関数を使うか、取得した値に対して `pg.PageWidth / 72 * 25.4`(インチからミリへの変換)といった計算を正確に行う必要があります。
② オブジェクトの解放
大量のページがある巨大なファイルでループを回す際、メモリ管理が甘いとVisioが重くなります。
`Set pgSheet = Nothing` のように、ループの終わりにオブジェクトを明示的に解放する習慣をつけると、パフォーマンスが劇的に安定します。
5. まとめ:次のステップへ
今回のツールは、「印刷設定が固定されているページを見つける」というシンプルなものでした。しかし、ここから「特定の用紙サイズ(例えばA3)以外をすべて抽出する」「図面サイズと印刷サイズが1mmでもズレていたらエラーにする」といった具合に、無限に進化させることができます。
「マクロの記録」は、あくまで「操作の断片」です。
「VBAによる自動化」は、「仕組みの構築」です。
`PageSheet` という裏側の仕組みに目を向け、オブジェクトの性質を理解すること。これができれば、あなたはもう、Visioの不具合に怯えるユーザーではなく、不具合を未然に防ぐアーキテクトになれるはずです。
さあ、次はどんな「仕組み」を作りますか? 応援していますよ。
