【実務・中級編】ページ設定セルへの直接アクセス:Page.PageSheetのVBA操作と特殊アスペクト比の適用 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAを掌握する極限の知見:Page.PageSheetが生む「真の自動化」の領域

こんにちは。開発プロジェクトの現場で、数々の巨大なVisio自動化アーキテクチャを構築してきたチーフアーキテクトだ。

VisioのVBA開発において、多くのエンジニアが最初に直面し、そして深い絶望を味わうポイントがある。それが「用紙サイズと図面スケールの動的制御」だ。
標準的な `Page.PageWidth` や `Page.PageScale` プロパティを叩いて安心しているそこのあなた。そのコードは、非標準の特殊アスペクト比や、ミリ単位の厳密なレイアウト制御が求められる現場において、必ず破綻する。

今回は、Visioのオブジェクトモデルの深層に巣食う`PageSheet`を直撃し、UIの制限を完全にバイパスして用紙サイズを支配する極限のテクニックを伝授しよう。

なぜ通常のプロパティ操作では「敗北」するのか?

VisioのVBA初学者は、ページサイズを変更しようとして以下のようなコードを書く。

‘ 【アンチパターン】よくある素朴なコード
ActivePage.PageWidth = 297 ‘ mm換算がおかしくなる温床
ActivePage.PageHeight = 420

このアプローチは実務では使い物にならない。なぜなら、Visioの裏側には強力な「ShapeSheet」という数式エンジンが鎮座しており、UIや単純なプロパティ経由の変更は、ガード節や暗黙の単位変換(インチ基準)によって歪められるからだ。さらに、図面スケール(`PageScale` / `DrawingScale`)との整合性が崩れた瞬間、図形が意図しないサイズへ勝手にスケーリングされるという「Visioあるあるの怪奇現象」を引き起こす。

プロダクトの現場で求められる「真の解決策」

私たちが目指すべきは、UIの背後で息づくPageオブジェクトの形状データ(PageSheet)に直接数式をブッ込むことだ。
`Page.PageSheet` は、図面ページそのものが持つ「見えないマスターシェイプ」である。ここを掌握してこそ、真のVisioオートメーションエンジニアと名乗る資格が生まれる。

堅牢なPageSheet操作の設計思想

`Page.PageSheet` から取得できる `Visio.Shape` オブジェクトに対し、`CellsU`(ユニバーサル名によるセル指定)を用いて数式を流し込む。
ここで重要なのは、「文字列として数式を代入する」という点だ。VBAの数値渡しではなく、文字列として `”=297 mm”` のように単位を明示して書き込むことで、Visioの内部パーサーに正確な意図を伝える。

押さすべき主要なCell名

  • `PageWidth`: ページの幅
  • `PageHeight`: ページの高さ
  • `DrawingScale`: 図面スケール(例: 1 mm = 1 mm なら `1`)
  • `PageScale`: ページスケール

【プロダクションコード】特殊アスペクト比を適用する堅牢なVBAモジュール

以下に、外部データや設定ファイルから読み込んだ任意のアスペクト比・寸法を、エラーなく安全に適用するためのプロダクションコードを提示する。エラーハンドリング、オブジェクトの適切な解放、単位の厳密な制御を組み込んだ、現場でそのまま使える実用モジュールだ。

Option Explicit

Public Sub ApplyCustomPageSize(ByVal targetPage As Visio.Page, ByVal widthMm As Double, ByVal heightMm As Double)
‘ ——————————————————————————–
‘ 概要: 指定されたページのPageSheetに直接アクセスし、特殊アスペクト比の用紙サイズを強制適用する
‘ 引数: targetPage – 対象のVisio.Pageオブジェクト
‘ widthMm – 目的の幅 (ミリメートル)
‘ heightMm – 目的の高さ (ミリメートル)
‘ ——————————————————————————–

Dim vsoPageSheet As Visio.Shape
Dim errNum As Long

On Error GoTo ErrorHandler

‘ 1. ページのPageSheet(ページ自体のプロパティを保持する特殊なShape)を取得
Set vsoPageSheet = targetPage.PageSheet

‘ 2. 単位系の競合を防ぐため、一旦アプリケーショントランザクションを開始(Visioでは実質的なスコープ制御)
‘ ※ Visio VBAではApplication.BeginUndoScope等を使うとより堅牢になる
Dim undoScopeID As Long
undoScopeID = Application.BeginUndoScope(“カスタムページサイズ適用”)

‘ 3. CellsU メソッドを用いて、強制的に数式を書き込む
‘ “mm” 文字列を付与することで、Visioの内部単位(インチ)への自動変換を安全に行わせる
With vsoPageSheet
‘ 図面スケールを 1:1 に固定(意図しないスケーリングの防止)
.CellsU(“DrawingScale”).FormulaU = “1 mm”
.CellsU(“PageScale”).FormulaU = “1 mm”

‘ ページの物理サイズを直接書き換え
.CellsU(“PageWidth”).FormulaU = CStr(widthMm) & ” mm”
.CellsU(“PageHeight”).FormulaU = CStr(heightMm) & ” mm”
End With

‘ トランザクション正常終了
Application.EndUndoScope undoScopeID, True

Exit Sub

ErrorHandler:
‘ 異常終了時のハンドリングとトランザクションのロールバック
errNum = Err.Number
If undoScopeID <> 0 Then
Application.EndUndoScope undoScopeID, False
End If

MsgBox “PageSheetの操作中に致命的なエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & errNum & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “VisioAutomation Error”

End Sub

‘ — 【実行テスト用ラッパープロシージャ】 —
Public Sub RunSample_SetBannersize()
‘ 例: 特殊なバナーサイズ(幅: 800mm, 高さ: 300mm)をアクティブページに適用する
Call ApplyCustomPageSize(ActivePage, 800, 300)
End Sub

現場で役立つ!ファイル・DB連携時の設計指針

このコードを実際の業務システム(Excelマクロからの連携、あるいはC#/.NETからのCOM互換呼び出し)に組み込む際、以下の2点に留意してほしい。

1. データベース(SQL Server / SQLite等)からの動的寸法取得
製造ラインの図面自動生成などでは、DBから取得した「製品ごとのミリ単位の寸法」をそのまま `CStr(widthMm) & ” mm”` の形式に組み込むこと。浮動小数点誤差(例: `297.0000001 mm`)を防ぐために、VBA側で `Round(val, 2)` などの丸め処理を入れておくと、Visioのパーサーエラーを未然に防げる。

2. 多重ループ処理時のパフォーマンス最適化
数百ページの図面を一括生成・設定する場合、画面描画(ScreenUpdating)やイベントの発生がボトルネックになる。
処理の冒頭で `Application.ScreenUpdating = False` をかけ、処理が終わったら `True` に戻すお作法を忘れないこと。これだけで実行速度が数倍〜数十倍に跳ね上がる。

総括

`Page.PageSheet` を操る技術は、Visio VBA開発者にとっての「隠しコマンド」のようなものだ。UIの制約に縛られず、数式エンジンを直接ハックすることで、どんな変則的なフォーマットであっても完全自動化の射程に収めることができる。

既製のプロパティに頼るフェーズはもう終わりだ。オブジェクトの深層を理解し、思い通りのキャンバスをコードで自在に彫り出す——それこそが、プロフェッショナルな業務自動化エンジニアの仕事である。

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