【設計品質を極める】Visio VBA監査ツール:縮尺の不整合を自動検知せよ
「マクロの記録」ボタンを押し、適当に生成されたコードをコピペして動かす。
もしあなたが今、そのフェーズにいるのなら、まずは自分を褒めてあげてください。それはエンジニアとしての第一歩です。
しかし、プロフェッショナルな設計現場において、その手法は「時限爆弾」を抱え込むことと同義です。
特にVisioのような図面作成ツールでは、「ページ設定の縮尺(Scale)」と「シェイプの実際の寸法」が、ユーザーの不注意によって乖離してしまうことが多々あります。1/10の縮尺で作っているはずの図面の中に、なぜか実寸(1/1)で描かれたシェイプが混入している……。これは製造現場や建設現場では致命的なミスに繋がります。
今日は、そんな「図面の嘘」を暴き、設計品質を劇的に向上させる「縮尺監査ツール」の作り方を伝授します。これをマスターすれば、あなたは単なる「マクロ使い」から、プロフェッショナルな「自動化エンジニア」へと昇華するでしょう。
1. 核心:Visioにおける「寸法」の二重構造を理解する
コードを書く前に、Visioの内部構造という「物理法則」を理解しましょう。ここを間違えると、どんなに優れたアルゴリズムも無意味になります。
Visioには、以下の2つの「寸法」が存在します。
1. 描画寸法 (Drawing Dimension):
画面上で、あるいは紙の上で「何インチ(またはmm)の大きさか」という物理的なサイズ。
2. 実寸 (Real-World Dimension):
縮尺を考慮した、設計対象物としての本来のサイズ。
黄金の数式
この関係性は、以下の数式で定義されます。
$$\text{実寸} = \frac{\text{描画寸法}}{\text{ページの縮尺(Scale)}}$$
例えば、ページの縮尺が `1:10`(`Scale = 0.1`)の場合、画面上で `10mm` のシェイプは、実寸では `100mm` となります。
監査ツールの目的は、この計算が「設計意図(例えば、すべての部品はキリの良い数字であるべき)」と矛盾していないかをチェックすることにあります。
2. 実装:縮尺不整合を検知する監査スクリプト
それでは、実際のコードを見ていきましょう。このスクリプトは、ページ内の全シェイプを走査し、実寸が「不自然な端数」を持っている場合に、警告メッセージとともにそのシェイプをハイライトします。
Option Explicit
''' <summary>
''' ページの縮尺設定に基づき、シェイプの実寸が設計意図(キリの良い数字)から
''' 乖離していないかを監査するツール
''' </summary>
Sub AuditScaleConsistency()
Dim vPage As Visio.Page
Dim vShape As Visio.Shape
Dim dScale As Double
Dim dRealWidth As Double
Dim dRealHeight As Double
Dim dTolerance As Double
Dim errorCount As Integer
' --- 設定エリア ---
' 許容誤差(単位:インチ。0.001インチ程度の微小な誤差を許容)
dTolerance = 0.001
' ------------------
Set vPage = ActivePage
dScale = vPage.Scale
errorCount = 0
' 縮尺が0(設定ミス)の場合は終了
If dScale <= 0 Then
MsgBox "ページの縮尺が正しく設定されていません。", vbCritical
Exit Sub
End If
' 画面更新を停止してパフォーマンスを向上(大量のシェイプがある場合)
Application.ScreenUpdating = False
' ページ内の全シェイプをループ
For Each vShape In vPage.Shapes
' グループ内のシェイプや、非表示のシェイプをスキップしたい場合は条件を追加
If Not vShape.SkipDrawing Then
' 1. 描画寸法を取得(ResultIUは内部単位。精度が最も高い)
' 2. 縮尺で割って「実寸」を算出
dRealWidth = vShape.Cells("Width").ResultIU / dScale
dRealHeight = vShape.Cells("Height").ResultIU / dScale
' 変換:内部単位(IU)から、計算しやすい「インチ」に変換
' (Visioの内部単位は 1/72 インチ)
dRealWidth = (vShape.Cells("Width").ResultIU * 0.0138888888888889) / dScale
dRealHeight = (vShape.Cells("Height").ResultIU * 0.0138888888888889) / dScale
' --- 監査ロジック ---
' ここでは例として「実寸が整数(または0.5単位)でない場合は異常」とみなす
' 設計ルールに合わせてここをカスタマイズするのがプロの仕事です
If Not IsRoundNumber(dRealWidth, dTolerance) Or _
Not IsRoundNumber(dRealHeight, dTolerance) Then
' 不整合が見つかった場合、シェイプの色を赤に変えて目立たせる
vShape.Cells("FillForegnd").Formula = "RGB(255, 0, 0)"
errorCount = errorCount + 1
End If
End If
Next vShape
Application.ScreenUpdating = True
' 結果報告
If errorCount > 0 Then
MsgBox "監査完了: " & errorCount & " 個のシェイプに縮尺の不整合(端数)が見つかりました。" & vbCrLf & _
"該当シェイプを赤色にハイライトしています。", vbExclamation
Else
MsgBox "監査完了: 不整合は見つかりませんでした。設計品質は良好です。", vbInformation
End If
End Sub
''' <summary>
''' 数値が設計意図に基づいた「キリの良い数字」かどうかを判定するヘルパー関数
''' </summary>
Private Function IsRoundNumber(ByVal val As Double, ByVal tolerance As Double) As Boolean
' ここでは「0.5単位(0.5, 1.0, 1.5...)」でキリが良いと定義
Dim roundedVal As Double
roundedVal = Round(val * 2) / 2
' 元の値と、丸めた値の差が許容誤差以内ならTrue
If Abs(val - roundedVal) <= tolerance Then
IsRoundNumber = True
Else
IsRoundNumber = False
End If
End Function
3. プロの視点:なぜこのコードは「強い」のか?
このコードには、初学者が陥りがちな罠を回避するための「設計思想」が3つ組み込まれています。
① `ResultIU` の活用
多くの人は `vShape.Width` をそのまま使おうとします。しかし、これは「現在の表示単位(mmやインチ)」に依存してしまい、計算誤差を生みます。
プロは `ResultIU` (Internal Units) を使います。Visioの内部で管理されている最も純粋な数値(1/72インチ単位)を直接操作することで、浮動小数点による計算誤差を最小限に抑え、極めて高い精度を担保します。
② 「誤差(Tolerance)」の概念
コンピュータの世界では、`0.1 + 0.2` が厳密に `0.3` にならないことがあります。
`If val = 1.0 Then` のような比較は、エンジニアリングにおいては「禁忌」です。必ず `Abs(a – b) <= tolerance` という形で、「ある程度の誤差は許容する」という書き方をしてください。これが、現場で動く堅牢なコードの条件です。
③ 計算の分離(Separation of Concerns)
「キリの良い数字か?」という判定ロジックを `IsRoundNumber` という別関数に切り出しています。
これにより、「実寸が10mm単位であるべき」というルールに変更したい場合、メインのループ処理を汚すことなく、判定関数の中身だけを書き換えれば済むようになっています。これは保守性という、自動化エンジニアにとって最も重要な資質です。
4. 次のステップへ:ここをクリアすれば、基本はバッチリ!
このスクリプトを動かしてみて、もし「赤く染まったシェイプ」が出現したら、それはあなたの設計プロセスが進化するためのギフトです。
「なぜこのシェイプは端数になったのか?」「縮尺の設定を間違えたのか? それともシェイプをマウスで適当に引き伸ばしてしまったのか?」
その原因を突き止めることこそが、エンジニアリングの本質です。
今日学んだことのまとめ:
- 縮尺の数式を理解し、描画寸法と実寸を区別する。
- 精度を追求するために `ResultIU` を使いこなす。
- 比較には必ず `Tolerance`(許容誤差) を導入する。
これらを意識するだけで、あなたの書くVBAは「ただ動くもの」から「信頼されるツール」へと変わります。さあ、次はもっと複雑な、レイヤー操作やデータリンクの自動化に挑戦してみましょう。道は続いていますよ!
