こんにちは! Visioでの自動化やシェイプ開発、日々の作業お疲れ様です。
マクロの記録はマスターしたものの、「いざ複雑な図形を作ろうとすると、コードだけでは挙動が追えない」「ShapeSheet(シェイプシート)のどこにバグがあるのか、目視で探すのに目がチカチカする……」そんな壁にぶつかっていませんか?
今回は、Visio VBAの心臓部であるオブジェクトモデルを縦横無尽に操り、「VBAから一瞬で目的のシェイプのShapeSheetを開き、さらに特定のセルにフォーカスを当てる(ハイライトする)」という、現場で即戦力になる極限の時短テクニックを伝授します。
ここをクリアすれば、Visio VBAの「ウィンドウとビューの概念」はバッチリです。一緒にステップアップしていきましょう!
—
なぜ、ShapeSheetのデバッグは這麼に泥臭いのか?
Visioで高度なステンシルやスマートシェイプを作るとき、避けて通れないのがShapeSheetです。
数式(`Width = Guard(TheTextWidth()+10)` など)をゴリゴリ書いていると、意図通りに動かない瞬間が必ず訪れます。
通常の開発フロー:
1. 図面上のシェイプを右クリックする。
2. 「シェイプシートの表示」をクリックする。
3. 膨大なセクション(Shape Transform, Guard, User-defined Cellsなど)から、目的のセルを目視でスクロールして探す。
……ハッキリ言って、これ、エンジニアの時間をドブに捨てる作業です。
「エラーが発生したシェイプの、特定のセルをVBA側からピンポイントで開けたらどれほど楽か?」
それを実現するのが、今回の主役である `Application.ActiveWindow` と `Windows` コレクションです。
—
Visioウィンドウの構造を理解する(超重要)
コードを書く前に、VisioのUIがVBAからどう見えているのか、その「世界観」を掴みましょう。
Visioのオブジェクトモデルにおいて、画面は次のような階層構造になっています。
Application (Visioアプリ全体)
┗ ActiveWindow (現在アクティブなメインウィンドウ)
┗ Windows (その中に開いているサブウィンドウのコレクション)
┣ 図面描画ウィンドウ (Drawing Window)
┗ シェイプシートウィンドウ (ShapeSheet Window)
Visioでは、1つの図面(Document)に対して、描画画面だけでなく、個別のシェイプのShapeSheetも「独立したウィンドウ」として同じ空間(`Windows` コレクション)にポンポン生成されます。
つまり、「VBAから特定のシェイプを選び、ShapeSheetウィンドウを新しく開き、アクティブにする」という命令をコードで書けばいいのです。
—
実装コード:一瞬でShapeSheetを開き、セルを狙い撃つマクロ
それでは、実際のコードを見てみましょう。
以下のコードをVisioのVBAエディタ(`Alt + F11`)の標準モジュールに貼り付けてください。
このコードは、現在選択している(クリックして選んでいる)シェイプのShapeSheetを開き、さらに幅(Width)セルにフォーカスを当てるサンプルです。
Sub OpenShapeSheetAndFocusCell()
Dim vsoShape As Visio.Shape
Dim vsoWindow As Visio.Window
‘ 1. 選択チェック:何も選択されていない場合は処理を中断
If ActiveWindow.Selection.Count = 0 Then
MsgBox “対象となるシェイプを画面上で選択してください。”, vbExclamation, “デバッグ補助”
Exit Sub
End If
‘ 2. 選択された最初のシェイプを取得
Set vsoShape = ActiveWindow.Selection(1)
On Error GoTo ErrorHandler
‘ 3. シェイプのShapeSheetウィンドウを開く
‘ 秘密兵器:vsoShape.OpenSheet() を使うと、そのシェイプのShapeSheetウィンドウが新規に開きます
Set vsoWindow = vsoShape.OpenSheet()
‘ 4. 特定のセルにフォーカス(ハイライト)を当てる
‘ 引数:(セクションID, 行ID, セルID)
‘ 例として「Shape Transform」セクションの「Width」セルを指定
‘ セクション: visSectionObject (1)
‘ 行: visRowXFormOut (1: WidthやHeightがある行)
‘ セル: visXFormWidth (2: Widthセル)
vsoWindow.ActivateCell visSectionObject, visRowXFormOut, visXFormWidth
‘ 成功メッセージ(不要なら消してください)
‘ Debug.Print vsoShape.Name & ” の ShapeSheet をオープンしました。”
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
End Sub
コードのここがポイント!
- `vsoShape.OpenSheet()`: これが今回の最大のキモです。わざわざ右クリックしなくても、コードから一撃でそのシェイプのShapeSheetウィンドウオブジェクトを生成・取得できます。
- `vsoWindow.ActivateCell(…)`: 開いたShapeSheetウィンドウに対して、「このセクションの、この行の、このセルを光らせろ(選択しろ)」と命令しています。定数(`visSectionObject` など)を使うことで、可読性も抜群になります。
—
テスターや初学者が陥りやすい、VBA開発の現場でありがちなミスをあらかじめ潰しておきましょう。
罠1: 「オブジェクトが必要です」という実行時エラー424
- 原因: シェイプを何も選択していない状態で `ActiveWindow.Selection(1)` を実行すると、空っぽのコレクションから無理やり要素を取ろうとするためエラーになります。
- 対策: 上記コードのように `ActiveWindow.Selection.Count = 0` のガード節を必ず挟みましょう。プロのコードには必ず「優しさ(エラーハンドリング)」があります。
罠2: 別のページのシェイプを指定してしまった
- 原因: `ActiveWindow` は、あくまで「今ユーザーが見ているアクティブなウィンドウ」です。違うページのシェイプIDを直接指定して操作しようとすると、ウィンドウのコンテキストが噛み合わず失敗することがあります。
- 対策: 基本は「画面上で選択しているシェイプ」を起点にするか、`Application.ActivePage.Shapes.ItemByID(…)` などで正確にオブジェクトを特定してから `OpenSheet()` を呼び出してください。
—
現場のスピードを加速させる「自分専用ツール」へ昇華させよう
今回のテクニックを応用すれば、例えば以下のような「最強のデバッグツール」が作れます。
1. エラーチェッカーとの連携:
VBAで図面全体をスキャンし、「名前が不正なシェイプ」や「数式が循環参照しているシェイプ」を自動検出。発見した瞬間に、そのシェイプのShapeSheetをVBAからパッと自動で開いてあげる。
2. カスタムリボンへの配置:
このマクロをVisioのリボンメニューやクイックアクセスツールバーに登録しておけば、ボタン一発で「選択中シェイプのShapeSheetを狙い撃ちオープン」が可能です。
Visio VBAは、オブジェクトのライフサイクルとウィンドウの仕組みさえ掴んでしまえば、あなたの右腕となって設計作業を何倍も高速化してくれます。
「ここをクリアすれば、Visio VBAの基本はバッチリですよ!」
ぜひ今日の開発から、このテクニックを取り入れて、快適なシェイプシートライフを満喫してください。それでは、次の極限の知見でお会いしましょう!
