こんにちは! Visio VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたはいいけれど、中身が呪文のようで手が出せない……」と悩んでいませんか?
大丈夫。今回は、多くのエンジニアが躓きやすい「図形の面積(Area)と長さ(Length)の正確な取得」をテーマに、Visioのオブジェクトモデルの本質を優しく、かつ深く解説していきます。
ここをクリアすれば、図面から自動でデータを集計し、Excelへ流し込むような実務直結の自動化ツールが自由自在に作れるようになりますよ。さあ、一緒にVisio VBAの扉を開きましょう!
—
1. なぜVisioの数値取得は一筋縄ではいかないのか?
図面上の四角形や部屋の図形から、サクッと面積や周長を取りたい。誰もがそう思いますよね。しかし、ここでVisio VBA特有の「罠」にハマる人が続出します。
- 罠その1:取得できる値の単位が「インチ(内部単位)」であること
Visioのエンジンは、表示単位が何であれ、内部ではすべて「インチ」で計算しています。これをそのままメートルや平米に直そうとすると、計算が狂って大惨事になります。
- 罠その2:すべての図形が `Area` や `Length` を持っているわけではないこと
例えば、ただの「線(Line)」に面積を求めようとするとエラーになりますし、逆に「四角形」にLengthを求めると外周が返ってきます。
この「単位系の壁」と「図形の性質」を正しく理解することが、Visio VBAを掌握する第一歩です。
—
2. Visioオブジェクトモデルの基本ピラミッド
Visioのマクロを書くときは、今自分がどこを操作しているのかという「階層構造(オブジェクトモデル)」を意識することが極めて重要です。
[Application] (Visioアプリ全体)
└─ [Document] (開いている図面ファイル)
└─ [Page] (ページのタブ)
└─ [Shape] (個々の図形・部屋・線)
今回のマクロでは、`Page` に含まれるすべての `Shape` をひとつずつペロリと舐めるように巡回(ループ)し、それぞれの `Area` と `Length` を抽出しに行きます。
—
3. 実践!面積と長さを自動集計してExcelに出力するマクロ
それでは、実務でそのまま使えるコピペ可能なマクロコードを公開します。
このコードは、アクティブなページにあるすべての図形を走査し、面積(平方メートル換算)と周長(メートル換算)をイミディエイトウィンドウに出力(さらにExcelへの拡張も容易な構造)するものです。
Sub ExportShapeMetricsToExcel()
‘ —————————————————-
‘ 目的: アクティブページの全図形の面積と長さを取得し、
‘ 適切な単位系に変換してイミディエイトウィンドウに出力する
‘ —————————————————-
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim dblArea As Double
Dim dblLength As Double
Dim strShapeName As String
‘ 1. 現在アクティブなページを取得
Set vsoPage = ActivePage
‘ 2. ヘッダーをイミディエイトウィンドウに出力
Debug.Print “図形名”, “面積 (m²)”, “周長/長さ (m)”
Debug.Print “————————————————–”
‘ 3. ページ内の全図形をループ処理
For Each vsoShape in vsoPage.Shapes
‘ エラー対策: テキストボックスやグループなど、
‘ 面積を持たない図形でのエラーを防ぎつつ処理を継続
On Error Resume Next
‘ —————————————————-
‘ 【重要】Visioの内部単位(インチ)からメートル法への変換
‘ —————————————————-
‘ Areaプロパティは「平方インチ」で返るため、
‘ 1インチ = 0.0254m を使って平米(m²)に変換します。
‘ (0.0254 0.0254 = 0.00064516)
dblArea = 0
If vsoShape.Area > 0 Then
dblArea = vsoShape.Area 0.00064516
End If
‘ Lengthプロパティは「インチ」で返るため、
‘ メートル(m)に変換します ( 0.0254 )
dblLength = 0
If vsoShape.Length > 0 Then
dblLength = vsoShape.Length 0.0254
End If
‘ 図形名(マスター名またはシェイプ名)を取得
strShapeName = vsoShape.Name
‘ 4. 結果をイミディエイトウィンドウに表示
‘ ※実務ではここでExcelのセルに値を代入していくとスマートです
If dblArea > 0 Or dblLength > 0 Then
Debug.Print strShapeName, Format(dblArea, “0.00”), Format(dblLength, “0.00”)
End If
On Error GoTo 0 ‘ エラー監視をリセット
Next vsoShape
MsgBox “集計が完了しました!イミディエイトウィンドウを確認してください。”, vbInformation, “処理完了”
End Sub
コードのここがポイント!
1. `On Error Resume Next` の正しい使い方
すべての図形が `Area` を持っているわけではありません。例えば、線分(Line)やガイド線に対して `Area` を呼び出すとエラーになります。ここでは「エラーが出たら無視して次の図形へ進む」という安全策をあえて取っています。
2. マジックナンバーの正体 `0.00064516`
Visioの内部単位は常に「インチ」です。1インチは `0.0254` メートル。面積は2次元(縦×横)なので、`0.0254 × 0.0254 = 0.00064516` を掛けることで、正確な平方メートル($m^2$)に変換しています。ここを知っているだけで、他のエンジニアに大きく差をつけられます。
—
4. 現場でよくあるトラブルと解決策(FAQ)
Q1. マクロを実行しても何も出力されません……
A: 図形が「グループ化」されている可能性があります。
Visioのグループ図形は、親グループの中に子図形が隠れているため、単純な `For Each vsoShape In vsoPage.Shapes` だけでは中の図形を拾えないことがあります。階層構造の深い図面を扱う場合は、再帰処理(Recursive)を使って子シェイプまで潜るロジックが必要になります。まずは「グループ化を解除したフラットな図面」でテストしてみてください。
Q2. 取得した数値が実際の図面のサイズと全然違う気がします。
A: 図面自体の「縮尺(スケール)」が設定されている可能性があります。
図面が「1/100」などの縮尺で描かれている場合、Visioの内部計算と人間の見た目にズレが生じます。厳密な縮尺を考慮したい場合は、`Page.PageScale` や `Page.DrawingScale` プロパティを参照して補正係数を掛ける必要があります。
—
おわりに:ここをクリアすれば、Visio VBAはバッチリです!
今回は、Visio VBAにおける最大の難所の一つである「幾何学的要素(面積・長さ)の取得と単位変換」について解説しました。
- Visioの内部単位は「インチ」であること
- 図形の性質に応じたエラーハンドリングの重要性
- オブジェクトをループで総なめにする基本構造
この3つさえ押さえておけば、レイアウト図面からの自動集計ツール作成はもうあなたの手のうちにあります。ぜひご自身の図面で試して、日々の手作業地獄から脱出してくださいね。
それでは、次回の高度なVisio自動化の世界でお会いしましょう!
