こんにちは! Visio VBAの世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺めて、「なんだかよく分からないけれど動くぞ……」と感動したのも束の間、いざ図面のサイズを変えたり、用紙いっぱいに図形を配置しようとした途端に、意図しない場所に図形が吹っ飛んでいったり、ページからはみ出したりして頭を抱えていませんか?
よく分かります。Excel VBAの「セル座標」や、PowerPointの「スライド座標」の感覚でVisioを触ると、必ずこの「座標の壁」にぶつかります。なぜなら、Visioは「プリンタの用紙サイズ」「図面の縮尺」「独自の内部単位(インチ・DPC)」という、3つの異なるレイヤーが複雑に絡み合っているからです。
ここをクリアすれば、Visio VBAの基本はバッチリですよ。
今回は、Visioの心臓部である`Page`オブジェクトの座標系を完全にハックし、コードからダイナミックに用紙サイズや向きを制御する極意を、優しく、そして本質的に解説していきます。
—
1. Visio座標系の「3つの罠」を解き明かす
まずは、Visioがどのようにキャンバスを管理しているか、その裏側の仕組みを覗いてみましょう。
Excelなら `Range(“A1”)`、PowerPointなら `Slides(1).Width` で直感的に位置を指定できますが、Visioの`Page`オブジェクトには以下の3つの重要なプロパティが存在します。
1. Page.PageSheet(ページシート): 用紙の幅(PageWidth)や高さ(PageHeight)を保持する特殊なシェイプ。
2. Page.Type(ページタイプ): 図面ページなのか、バックグラウンド(背景)ページなのかの種別。
3. Internal Units(内部単位): VBAの世界では、表示単位(ミリやセンチ)に関わらず、すべて「インチ(Inches)」で処理されるという絶対の掟。
特に「3つ目の掟」は重要です。画面上で「A4・横・ミリ単位」で作業していても、VBAで数値を扱うときは強制的にインチ換算されます(1インチ = 25.4ミリ)。この仕様を知らないと、「100ミリ移動したつがいに、画面の端っこにチョコンとしか動かない!」という悲劇が起きます。
—
2. 実践:VBAでページサイズと向きを完全に掌握する
それでは、百聞は一見に如かず。アクティブなページの用紙サイズを「A4・横」に動的に変更し、さらに図面の描画領域(PageWidth/Height)を用紙ぴったりに自動アジャストする実用コードを見てみましょう。
開発タブのVisual Basic Editorを開き、標準モジュールに以下のコードを貼り付けてみてください。
Sub OptimizePageForA4Landscape()
Dim vsoPage As Visio.Page
Dim vsoPageSheet As Visio.Shape
‘ 1. 現在アクティブなページを取得
Set vsoPage = ActivePage
‘ 2. ページのサイズと向きを保持する「ページシート」を取得
‘ ※すべてのページ設定は、このPageSheetという隠しシェイプのセルに格納されています
Set vsoPageSheet = vsoPage.PageSheet
‘ 3. 単位を「A4・横 (Landscape)」に設定する
‘ A4の長辺は 297mm ≒ 11.692インチ、短辺は 210mm ≒ 8.268インチ
‘ Visio VBAでは、必ず「インチ」単位の数値を代入するのが鉄則です!
‘ 描画領域の幅(横)をA4長辺に設定
vsoPageSheet.CellsU(“PageWidth”).FormulaU = “297 mm”
‘ 描画領域の高さをA4短辺に設定
vsoPageSheet.CellsU(“PageHeight”).FormulaU = “210 mm”
‘ 4. プリンタの用紙サイズも連動して横向き(Landscape)に設定
‘ 0 = 縦(Portrait), 1 = 横(Landscape)
vsoPageSheet.CellsU(“PrintLandscape”).FormulaU = “1”
‘ 5. 完了メッセージ
MsgBox “現在のページを「A4・横」の最適サイズに再構築しました!”, vbInformation, “Visio VBA 制御完了”
End Sub
コードのここがポイント!
- `CellsU` メソッドの「U」の意味:
Visio VBAには `Cells` と `CellsU` がありますが、マクロを書くときは必ず `CellsU`(UniversalのU) を使ってください。通常の `Cells` だと、Excelと同様にユーザーのExcel言語設定や表示単位(日本語・英語・ミリ・インチ)に依存してしまい、別環境で動かした時にエラー(#NAME?など)を吐きます。`CellsU` は世界共通の英語・インチ基準で値を読み書きするプロフェッショナルの必須作法です。
- 単位付き文字列の代入:
`”297 mm”` のように、数値だけでなく単位文字列をそのまま渡せるのがVisioシェイプシートの強力な特徴です。内部で自動的にインチ(`11.692 in`)に換算して保持してくれます。
—
3. 「図面サイズ」と「用紙サイズ」の動的フィット
Visioでありがちなトラブルが、「図面を描いたら用紙からはみ出てしまった」「逆に用紙が無駄に広すぎて、PDF化したときに余白だらけになった」というケースです。
これをプログラムで自動検知し、「ページ上にあるすべての図形を囲む最小限のサイズに、用紙をぴったり合わせる(オートサイズ)」高度なテクニックを授けましょう。
Sub FitPageToShapesContent()
Dim vsoPage As Visio.Page
Dim vsoPageSheet As Visio.Shape
Dim dblMinX As Double, dblMinY As Double
Dim dblMaxX As Double, dblMaxY As Double
Dim margin As Double
Set vsoPage = ActivePage
Set vsoPageSheet = vsoPage.PageSheet
‘ 余白を設定(例: 10ミリをインチ換算して持たせる -> 10 / 25.4)
margin = 10 / 25.4
On Error GoTo ErrorHandler
‘ ページ上のすべての図形を含む最小・最大座標を一発で取得するメソッド
‘ ※ページに図形が1つもない場合はエラーになるためエラーハンドリングが必須
vsoPage.BoundingBox Visio.VisBoundingBoxType.visBBoxDrawingCode, _
dblMinX, dblMinY, dblMaxX, dblMaxY
‘ 取得した図形の範囲に「マージン(余白)」を持たせて、PageWidth / PageHeight を更新
‘ ピンチ(Pin)やオフセット(PageLeft / PageBottom)も考慮して再計算します
With vsoPageSheet
.CellsU(“PageWidth”).FormulaU = (dblMaxX – dblMinX) + (margin 2)
.CellsU(“PageHeight”).FormulaU = (dblMaxY – dblMinY) + (margin 2)
‘ 図形の左端・下端に合わせてページの原点もシフトさせる
.CellsU(“PageLeft”).FormulaU = dblMinX – margin
.CellsU(“PageBottom”).FormulaU = dblMinY – margin
End With
MsgBox “キャンバスを用形内の図形サイズにピッタリスッキリ合わせました!”, vbInformation
Exit Sub
ErrorHandler:
If Err.Number = 91# Or Err.Number = 3400 Then
MsgBox “このページには図形が配置されていないため、フィット処理をスキップしました。”, vbExclamation, “情報”
Else
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub
このコードが現場で重宝される理由
実務の現場では、「外部システムから吐き出されたデータを元に、Visio図面を自動生成してPDF化し、メールで飛ばす」という一連のバッチ処理を組むことがよくあります。
その際、生成される図面の大きさが毎回バラバラであっても、この `FitPageToShapesContent` を最後に挟み込むだけで、「まるで人間が手作業で整えたかのような、美しく切り抜かれたドキュメント」を全自動で量産できるようになります。
—
まとめ:Visio VBAは「PageSheetの支配」から始まる
今回は、`Page`オブジェクトの裏側にある `PageSheet` を通じて、座標系や用紙サイズを動的にコントロールする本質的なアプローチを解説しました。
- 原則1: VBAで扱う数値・座標は、表示単位に関わらずすべて「インチ(Inches)」。
- 原則2: 用紙の幅や高さ、余白を変えたければ、泥臭く図形を動かすのではなく、`Page.PageSheet.CellsU` の数値を書き換える。
- 原則3: 異国でもエラーを出さないために、プロパティ操作には必ず `CellsU` を採用する。
ここをクリアできれば、あなたはもう「マクロの記録の奴隷」ではありません。自由自在にキャンバスを操るVisioアーキテクトです。ぜひ日々の業務自動化にこの知見を組み込み、圧倒的な生産性を叩き出してください。それでは、次回の極限の知見でお会いしましょう!
