こんにちは! Visio VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたはいいけれど、中身が全然読めない……」と頭を抱えていませんか? 大丈夫、その壁を突破する日はもうすぐです。
今回は、複数開いたVisioのウィンドウ(ドキュメント)を行き来し、「マスター図面から最新の図形やデータをかき集めて、拠点ごとの図面に同期・集約する」という、実務でめちゃくちゃ役立つテクニックを伝授します。
ここをクリアすれば、あなたも単なる「操作の自動化」を超えた、真のVisioオブジェクトモデルの使い手になれます。さあ、一緒に扉を開けましょう!
—
1. Visioオブジェクトモデルの「階層構造」を掴もう
Visio VBAをマスターするための第一歩は、ドキュメントや図形がどのような「家族構成」になっているかを知ることです。ここを間違えると、コードは途端に迷子になります。
Visioの世界は、次のようなピラミッド構造をしています。
Application(Visioアプリ全体)
┗ Documents(開いているドキュメントの集合)
┗ Document(個別のファイル:Master.vsdx や BranchA.vsdx など)
┗ Pages(ページたちの集合)
┗ Page(特定のページ)
┗ Shapes(図形たちの集合)
┗ Shape(個別の図形)
複数のファイルを操作するということは、この「Document」という部屋のあちこちに同時にアクセスするということ。複数のウィンドウを行き来するには、それぞれのドキュメントを「変数」という名の目印にしっかり捕まえておく必要があります。
—
2. 陥りやすい罠:なぜ「コピペ」でエラーが出るのか?
マクロの記録を使うと、こんなコードが出力されます。
‘ 録画されたコードによくある書き方
ActiveWindow.Selection.Copy
Windows(“BranchA.vsdx”).Activate
ActiveWindow.Paste
一見動くように見えますが、これは実務の現場では「絶対に行ってはいけないタブー」です。
なぜなら、`ActiveWindow` や `Selection` は、ユーザーがうっかりマウスをクリックして別の画面を選択した瞬間に、ターゲットがすり替わって大暴走を起こすからです。
プロのエンジニアは、画面の選択(アクティブ化)に頼らず、メモリ上でオブジェクトを直接指名してやり取りします。これが「ウィンドウに依存しない堅牢なコード」の秘訣です。
—
3. 実践!複数ドキュメント間でShapeを安全にコピー&リンクする
それでは、マスター図面(例:`Master.vsdx`)にある特定の図形を、各拠点用の図面(例:`Branch_A.vsdx`)の特定ページへ、美しく安全にコピーする実践コードを見てみましょう。
このコードは、あらかじめ両方のファイルがVisioで開かれている状態を前提としています。
Sub SyncMasterShapes()
‘ — 1. 変数の宣言(オブジェクトを安全に捕まえるための網) —
Dim srcDoc As Visio.Document ‘ マスター図面
Dim dstDoc As Visio.Document ‘ 拠点用図面
Dim srcShape As Visio.Shape ‘ コピー元の図形
Dim targetPage As Visio.Page ‘ 貼り付け先のページ
Dim copiedShape As Visio.Shape ‘ コピーされた図形
On Error GoTo ErrorHandler
‘ — 2. ドキュメントの特定と取得 —
‘ ファイル名で確実にターゲットを捕まえます
Set srcDoc = Documents(“Master.vsdx”)
Set dstDoc = Documents(“Branch_A.vsdx”)
‘ — 3. コピー元と貼り付け先の定義 —
‘ マスター図面の「Page-1」にある「Server_Node」という名前の図形を狙う
Set srcShape = srcDoc.Pages.ItemU(“Page-1”).Shapes.ItemU(“Server_Node”)
‘ 拠点用図面の「Page-1」を貼り付け先に指定
Set targetPage = dstDoc.Pages.ItemU(“Page-1”)
‘ — 4. 図形のコピー実行 —
‘ シェイプのCopyメソッドでクリップボードへ
srcShape.Copy
‘ 貼り付け先ページのPasteSpecial、またはPasteで図形を配置
targetPage.Paste
‘ 貼り付け直後の図形を変数にキャッチし、位置を整える
Set copiedShape = ActiveWindow.Selection.Item(1)
copiedShape.CellsU(“PinX”).Result(“mm”) = 100 ‘ X座標を100mmに
copiedShape.CellsU(“PinY”).Result(“mm5”) = 150 ‘ Y座標を150mmに
MsgBox “マスターからの図形同期が正常に完了しました!”, vbInformation
Exit Sub
ErrorHandler:
‘ 思わぬエラー(ファイルが開いていない等)の優しく確実なキャッチ
MsgBox “エラーが発生しました。ファイルが開かれているか確認してください。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
End Sub
コードのここがポイント!
- `Documents(“ファイル名”)`: 画面のアクティブ状態に関係なく、裏側でファイル名を指定して確実にオブジェクトを取得しています。
- `ItemU`: Visio VBAでは、言語の違い(日本語環境・英語環境)によるバグを防ぐため、ユニバーサル名(`ItemU`)を使うのがプロの常識です。
- `CellsU(“PinX”)`: 図形の座標やプロパティをコードから直接ミリ単位で制御しています。マウスでドラッグ&ドロップするより圧倒的に正確です。
—
4. さらに先へ:Shapeの「データ(シェイプデータ)」も一緒に同期する
図形の形だけでなく、図形に埋め込まれたカスタムプロパティ(IPアドレスや担当者名などの「シェイプデータ」)も一緒に同期したい場合は、コピーした後に次のようなプロパティ書き換え処理を追加します。
‘ コピーした図形のシェイプデータ(カスタムプロパティ)を書き換える例
On Error Resume Next ‘ データ項目がない場合のエラー回避
copiedShape.CellsU(“Prop.IPAddress”).FormulaU = “””192.168.1.10″”
On Error GoTo 0
このように、オブジェクトモデルを正しく理解していれば、図形の見た目だけでなく、「中身のデータ構造」ごと複数ドキュメント間で自由自在に操ることができるようになります。
—
まとめ:ここをクリアすれば、Visio VBAの基本はバッチリです!
お疲れ様でした! 今回学んだポイントを整理しておきましょう。
1. Visioの構造はピラミッド型。どのDocument、どのPage、どのShapeを指しているか常に意識する。
2. `ActiveWindow` や `Selection` に頼らない。ファイル名やオブジェクト変数で確実にターゲットを捕まえる。
3. `ItemU` や `CellsU` を使いこなすことで、環境に左右されない堅牢で美しいコードが書ける。
複数ドキュメントをまたぐ処理ができるようになると、日々の図面管理やメンテナンス作業の自動化レベルが一気に跳ね上がります。ぜひご自身の環境でも試してみてくださいね。
それでは、次回の高度なVBA解説でお会いしましょう!
