【入門編】【初心者向け】ページサイズを自動判別し、図面枠を中央に自動配置するリサイズ・スクリプト – Visio VBA解析バイブル

スポンサーリンク
スポンサーリンク

マクロ記録の先へ。Visio VBAで「ページサイズ変更と図面枠の自動中央配置」をマスターする

こんにちは。今日は、Visio VBAの世界へ足を踏み入れたばかりのあなたへ、少しだけ「プロの視点」をお裾分けしようと思います。

Visioで図面を作成しているとき、こんな経験はありませんか?
「ページサイズをA4からA3に変更したら、せっかく配置した図面枠が左上に寄ってしまった……」

マクロの記録機能を使えば、確かに「ページサイズを変える操作」は記録できます。しかし、マクロの記録は「あなたが今行った操作のスタンプ」を記録するだけで、「ページが変わったから、これに合わせて図面枠を動かそう」という論理的な判断はしてくれません。

ここをクリアすれば、Visio VBAの基本はバッチリですよ。今日は、ページサイズを自動判別し、図面枠を完璧に中央へ再配置するロジックを、その仕組みから丁寧に紐解いていきましょう。

1. なぜ図面枠は「左上」に寄ってしまうのか?

問題を解決する前に、まずは「なぜそうなるのか」というメカニズムを理解しましょう。ここが、単なる作業者とエンジニアを分ける境界線です。

Visioのページは、数学のグラフと同じ「座標系」で管理されています。
多くの設定では、ページの左上が原点 $(0, 0)$ となっています。

1. ページサイズを変える $\rightarrow$ 座標の「右」と「下」の範囲が広がる。
2. 図面枠の座標 $\rightarrow$ 図面枠が「左上から $10\text{mm}$」の位置にあると指定されていた場合、ページが大きくなってもその図面枠は「左上から $10\text{mm}$」の位置に居続けます。

結果として、ページが広大になればなるほど、図面枠は相対的に「左上にポツンと残された」状態に見えてしまうのです。

私たちがすべきことは、「新しいページの幅と高さの半分」の座標を計算し、そこに図面枠を移動させること。たったこれだけのことなのですが、VBAで書くには少しコツがいります。

2. 実装の鍵を握る「3つの重要概念」

コードを書く前に、これから使う3つの武器を紹介します。これらはVisio VBAの心臓部です。

① PageSheet(ページシート)

Visioのページは、単なるキャンバスではなく、実は「Sheet(シート)」という概念を持っています。ページ自体の幅(Width)や高さ(Height)といった属性は、この「PageSheet」という特別な場所に格納されています。

② PinX / PinY(ピンの位置)

ここが一番の重要ポイントです!
図形(Shape)の位置を指定するとき、図形の「左端」を指定するのか、「中心」を指定するのか。これを決めているのが Pin(ピン) です。
プロの設計では、図形の中心にピンを置きます。そうすれば、「PinX = ページの幅の半分」 と指定するだけで、図形が完璧に中央に配置されるからです。

③ CellsU(ユニバーサル・セル)

VBAでプロパティを操作する際、`Cells` ではなく `CellsU` を使う癖をつけましょう。`U` は Universal の略です。これは、言語設定(日本語版か英語版か)に左右されず、確実にプロパティを特定するための、エンジニアとしての「作法」です。

3. 実践:中央配置リサイズ・スクリプト

それでは、実際に動くコードを見てみましょう。
このコードは、「現在のページサイズを読み取り、’Drawing Frame’ という名前の図形を探して、その中心をページの真ん中に持っていく」 という動きをします。

Option Explicit

''' <summary>
''' ページサイズを自動判別し、指定した図形を中央に再配置する
''' </summary>
Sub ResizePageAndCenterFrame()
    Dim vsoPage As Visio.Page
    Dim vsoShape As Visio.Shape
    Dim pageWidth As Double
    Dim pageHeight As Double
    Dim targetShapeName As String
    
    ' --- 設定エリア ---
    ' 中央に配置したい図形の名前を指定してください
    targetShapeName = "Drawing Frame"
    ' ------------------

    On Error GoTo ErrorHandler

    ' 1. 現在のページを取得
    Set vsoPage = ActivePage

    ' 2. ページサイズを取得 (PageSheetからWidthとHeightを読み取る)
    ' CellsUを使用することで、言語環境に依存しない安定した取得が可能になります
    pageWidth = vsoPage.PageSheet.CellsU("PageWidth").ResultIU
    pageHeight = vsoPage.PageSheet.CellsU("PageHeight").ResultIU
    
    ' ※ ResultIUは内部単位(Inches)での取得を意味しますが、
    ' Visioの計算上、そのまま数値として扱えます。

    ' 3. 図面枠(ターゲットとなる図形)を探す
    ' ページ内のすべての図形をループして名前をチェックします
    Set vsoShape = Nothing
    Dim vsoTempShape As Visio.Shape
    For Each vsoTempShape In vsoPage.Shapes
        If vsoTempShape.Name = targetShapeName Then
            Set vsoShape = vsoTempShape
            Exit For
        End If
    Next vsoTempShape

    ' 図形が見つからなかった場合の処理
    If vsoShape Is Nothing Then
        MsgBox "エラー: '" & targetShapeName & "' という名前の図形が見つかりません。" & vbCrLf & _
               "図形の名前を確認してください。", vbExclamation
        Exit Sub
    End If

    ' 4. 図形を中央へ移動させる
    ' 図形の「PinX(中心のX座標)」を「ページ幅の半分」に設定
    ' 図形の「PinY(中心のY座標)」を「ページ高さの半分」に設定
    ' ※Visioの座標系では、Y座標は下から上に向かって増える点に注意!
    
    ' 描画の更新を高速化するため、一時的に画面更新を止めるようなイメージです
    vsoShape.CellsU("PinX").FormulaU = pageWidth / 2 & " in"
    vsoShape.CellsU("PinY").FormulaU = pageHeight / 2 & " in"

    MsgBox "ページサイズに合わせ、図面枠を中央に配置しました!", vbInformation

    Exit Sub

ErrorHandler:
    MsgBox "予期せぬエラーが発生しました:" & vbCrLf & Err.Description, vbCritical
End Sub

4. コードの解説:ここがプロの仕事

このコード、ただ動くだけではありません。いくつか「現場で役立つ工夫」を盛り込んでいます。

なぜ `FormulaU = … & ” in”` と書いているのか?

Visioのセルに値を書き込むとき、単に数字を入れるのではなく、`”10 in”`(10インチ)のように単位を明示するのが最も安全な方法です。これにより、計算誤差や単位の取り違えを防ぐことができます。

エラーハンドリングの重要性

`On Error GoTo ErrorHandler` を入れています。もし「図形が見つからなかった」ときや「ページがロックされていた」ときに、プログラムがいきなり強制終了してユーザーを驚かせるのは、良いエンジニアの仕事ではありません。「何が起きたか」を優しく教えてあげるのがマナーです。

ループによる図形の探索

`ActivePage.Shapes(“Drawing Frame”)` と直接指定することもできますが、もし名前が少し違っていたらエラーになります。今回のように `For Each` でループさせて探す方法は、より柔軟で、エラーに強い実装と言えます。

5. まとめ:次に進むあなたへ

今回のステップを振り返りましょう。

1. 座標の仕組みを知る(ページは広がり、図形は元の位置を守ろうとする)
2. Pin(ピン)の概念を理解する(中心を動かせば、配置は簡単になる)
3. PageSheetから情報を引き出す(ページそのものの性質を読み取る)

これをマスターしたあなたは、もう「マクロの記録」という魔法の杖を振るだけの初心者ではありません。「オブジェクトのプロパティを制御し、論理的に配置を組み立てる」という、真の自動化エンジニアへの第一歩を踏み出したのです。

「図面枠の名前を変えてみたらどうなるだろう?」
「複数のページを一括で処理するにはどうすればいいだろう?」

そんな疑問が湧いてきたら、それが成長のサインです。ぜひ、コードを書き換えて実験してみてください。

応援していますよ。次はもっと高度な、レイヤー操作や複雑なデータ連携の世界でお会いしましょう!

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