こんにちは! Visio VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたはいいけれど、中身がスパゲッティコードになってしまった……」と頭を抱えていませんか?
今回は、既存のステンシル(アイコン素材)に一切頼らず、VBAコードの計算だけでピクセル単位(正確にはインチ単位)の図形を精密に組み合わせ、独自のステータスインジケーターを爆誕させる「動的アイコン生成エンジン」の作り方を伝授します。
ここをクリアすれば、単なる「操作の自動化」を超えて、「プログラムでビジュアルを錬金する」というVisio VBAの本当の快感を味わえます。基礎から本質まで、しっかりと言葉を尽くして解説していきますね。
—
1. なぜ「コードによる動的描画」なのか?
実務でVisioを使う場面、例えばネットワーク図やプラント図、システム構成図において、次のような課題に直面したことはありませんか?
- 「サーバーの負荷状態(正常・警告・異常)に応じて、アイコンの色や形を動的に変えたい」
- 「ステンシルを配る手間を省き、配布したマクロだけで誰でも同じクオリティの図形を描画させたい」
市販のステンシルや手動配置では、図形の数が何百個にもなった瞬間に破綻します。しかし、`Shape.DrawRectangle` や `Shape.DrawOval` といったプリミティブ(基本図形)をコードで完璧に座標計算して組み合わせれば、「状態を持つ生きたアイコン」を無限に、一瞬で生成できるようになります。
—
2. Visioオブジェクトモデルの基礎:キャンバスの階層構造
コードを書く前に、Visioの空間がどうなっているかを押さえましょう。ここを間違えると「図形を描いたはずなのに画面に出ない」という初心者マッドゾーンにハマります。
Application (Visio アプリケーション)
┗ Documents (図面ファイル群)
┗ Document (アクティブな図面)
┗ Pages (ページ群)
┗ Page (いま作業しているキャンバス)
┗ Shapes (ページ上の図形コレクション)
私たちが図形を描くとき、ターゲットにするのは「今開いているページの Shapes コレクション」です。具体的には `ActivePage.DrawRectangle(…)` のように記述します。
—
3. 実装:動的インジケーター生成エンジン
それでは、今回の主役である「ステータスインジケーター生成エンジン」のコードを公開します。
このコードは、指定した座標に「外枠の矩形(ベース)」と「状態を示す中央の丸(LEDライト)」を同時に描き、一つのグループ図形としてまとめ上げる高度な処理を行います。
VBAの標準モジュールにコピペして、そのまま実行してみてください。
Option Explicit
‘ ==============================================================================
‘ 処理名: CreateStatusIndicator
‘ 概要 : 指定された座標とステータスに応じて、動的にアイコンを合成・生成するエンジン
‘ 引数 : pinX (中心X), pinY (中心Y), status (1:正常, 2:警告, 3:異常)
‘ ==============================================================================
Public Sub GenerateDynamicIcon()
Dim vsoPage As Visio.Page
Set vsoPage = ActivePage
‘ 画面描画を一時停止し、爆速で処理を実行する(プロの常道テクニック)
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
‘ テストとして、3つの異なるステータスのインジケーターを生成
Call CreateSingleIndicator(vsoPage, 2.0, 5.0, 1, “Webサーバー (正常)”)
Call CreateSingleIndicator(vsoPage, 4.0, 5.0, 2, “DBサーバー (警告)”)
Call CreateSingleIndicator(vsoPage, 6.0, 5.0, 3, “APIゲートウェイ (異常)”)
Application.ScreenUpdating = True
MsgBox “ステータスインジケーターの生成が完了しました!”, vbInformation, “完了”
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “予期せぬエラー”
End Sub
‘ ——————————————————————————
‘ 実務で使えるプライベート関数:単体インジケーターの構築
‘ ——————————————————————————
Private Sub CreateSingleIndicator(vsoPage As Visio.Page, ByVal x As Double, ByVal y As Double, ByVal status As Integer, ByVal labelText As String)
Dim shpRect As Visio.Shape
Dim shpOval As Visio.Shape
Dim shpGroup As Visio.Shape
Dim shapesArray(1) As Visio.Shape
‘ 1. 外枠の矩形を描画 (DrawRectangleの引数: x1, y1, x2, y2 [インチ])
‘ 中心座標 (x, y) から幅 1.5インチ、高さ 0.8インチの矩形を計算
Set shpRect = vsoPage.DrawRectangle(x – 0.75, y + 0.4, x + 0.75, y – 0.4)
shpRect.Text = labelText
‘ 矩形の見栄えを調整(背景を白、枠線をグレーに)
shpRect.Cells(“FillForegnd”).FormulaU = “RGB(245,245,245)”
shpRect.Cells(“LineColor”).FormulaU = “RGB(100,100,100)”
‘ 2. 状態を示すLED(円: DrawOval)を描画
‘ 矩形の左側に配置する計算
Dim ovalX As Double
ovalX = x – 0.45
Set shpOval = vsoPage.DrawOval(ovalX – 0.15, y + 0.15, ovalX + 0.15, y – 0.15)
‘ ステータスに応じてLEDの色を動的に変化させる
Select Case status
Case 1: ‘ 正常 (緑)
shpOval.Cells(“FillForegnd”).FormulaU = “RGB(40,167,69)”
Case 2: ‘ 警告 (黄)
shpOval.Cells(“FillForegnd”).FormulaU = “RGB(255,193,7)”
Case 3: ‘ 異常 (赤)
shpOval.Cells(“FillForegnd”).FormulaU = “RGB(220,53,69)”
Case Else
shpOval.Cells(“FillForegnd”).FormulaU = “RGB(108,117,125)” ‘ 不明 (グレー)
End Select
shpOval.Cells(“LineColor”).FormulaU = “RGB(50,50,50)”
‘ 3. 矩形と円を一つの「グループ」に統合する
Set shapesArray(0) = shpRect
Set shapesArray(1) = shpOval
Set shpGroup = vsoPage.Group(shapesArray)
‘ グループ化によりシェイプ名がリセットされるため、分かりやすく命名
shpGroup.Name = “StatusNode_” & labelText
End Sub
—
4. コードの深掘りと「ここが落とし穴」
このコードには、Visio VBAをマスターする上で絶対に知っておくべき「3つの極意」が隠されています。
① 座標系は「左下基準(インチ)」
Excel VBAやWindowsフォームの感覚でいると、「あれ、Y座標のプラスマイナスが逆だぞ?」と混乱します。
Visioの基本座標系は、ページ全体の「左下」を原点 (0,0) とし、単位はすべて「インチ (Inches)」で計算されます。(コード内で `0.75` や `0.4` としているのはそのためです)。ミリメートルで計算したい場合は `Visio.VisUnitCodes.visMillimeters` を使うか、自前で `25.4` で割るなどの変換を入れてください。
② シェイプのプロパティ操作には `.Cells(…)` を使う
図形の色や線の太さを変えるとき、初心者やりがちなのが `.ForeColor = RGB(…)` のような直接代入です。しかし、Visio VBAではシート(ShapeSheet)の概念があるため、セルの数式(Formula)を書き換える形で指定するのが作法です。
> `shpRect.Cells(“FillForegnd”).FormulaU = “RGB(245,245,245)”`
この `FormulaU`(UはUniversalの意、言語に依存しない英語の数式表現)を使うことで、環境に依存せず確実にプロパティを書き換えることができます。
③ 画面描画のロック (`ScreenUpdating = False`)
図形を1つ描画するたびにVisioの画面がパカパカ再描画されると、処理が遅くなるだけでなく、画面がチラついて見ていられません。
プロのエンジニアは、処理の最初に `Application.ScreenUpdating = False` を挟み、最後に `True` に戻します。これだけで体感速度が何倍も跳ね上がります。
—
5. まとめ:ここをクリアすれば、基本はバッチリ!
お疲れ様でした! 今回は `DrawRectangle` と `DrawOval` を組み合わせ、条件分岐で色をコントロールしながら `Group` 化するという、実務直結の動的描画エンジンを解説しました。
- キャンバスの構造(Page -> Shapes)を理解した
- Visio特有の座標系(左下原点・インチ)をクリアした
- `Cells(“…”).FormulaU` を使ったプロパティ制御の作法を知った
ここをクリアできれば、もうマクロの記録に頼る必要はありません。あなたの思い描いた図形ロジックを、そのままVisio上のキャンバスに具現化できるようになっています。
次は、外部のExcelデータやデータベースから情報を読み込んで、このエンジンに流し込む「完全自動ネットワーク図生成ツール」へとステップアップしていきましょう。それではまた、次の極限の知見でお会いしましょう!
