【入門編】非表示ステンシルの安全な動的生成:Document.OpenStencilと自動破棄によるクリーンなVBAツール構築 – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visioのオートメーション開発の世界へようこそ。
マクロの記録ボタンを押すだけのステップを卒業し、「自分の手で自由自在に図面を操りたい」と思ったあなたへ。

今回は、プロの現場でもよく使われる「非表示ステンシルの安全な動的生成と確実なメモリ解放」という、ワンランク上のテクニックを伝授します。

「ツール実行時だけこっそり裏でステンシルを開いて、マスターシェイプを取り出したら、痕跡を残さず綺麗に片付ける」
これができるようになると、あなたの作るVBAツールは一気にプロフェッショナルな品質に生まれ変わります。

ここをクリアすれば、Visio VBAのオブジェクト管理の基本はバッチリですよ。さあ、一緒に本質を学んでいきましょう!

1. なぜ「非表示ステンシル」の制御が必要なのか?

Visioで図形(Shape)をプログラムから配置するとき、大元の設計図である「マスターシェイプ」をステンシルから取得する必要があります。

よくある初学者向けのコードでは、画面上にステンシルを表示しっぱなしにしたり、手動で開かせておいたりしがちです。しかし、これでは実務で使い物になりません。

  • 画面がガチャガチャうるさい:ツールが動くたびに余計なウィンドウが開閉するのはユーザーにとってストレスです。
  • メモリのリーク(老朽化):プログラムが終了しても見えないところでドキュメントオブジェクトが残り続け、Visio全体の動作が重くなる原因になります。

だからこそ、「必要なときだけ裏側(バックグラウンド)でこっそり開き、用事が済んだら跡形もなく消去する」というライフサイクル管理が絶対に必要なのです。

2. Visioオブジェクトモデルの基本構造

Visioの世界は、ロシアの人形「マトリョーシカ」のように綺麗に階層構造(オブジェクトモデル)でできています。

Application (Visioアプリ全体)
┗ Documents (開いている図面・ステンシルコレクション)
┗ Document (個別の図面 / ステンシルファイル .vssx)
┗ Masters (マスターシェイプのコレクション)
┗ Master (個別のマスターシェイプ)

今回のミッションは、このツリー構造の中に一時的にステンシル(Document)をロードし、マスターを収穫したら、速やかに`Document.Close`で閉じるという一連の流れをコードで完璧にコントロールすることです。

3. 実装コード:安全な動的生成とクリーンアップの全貌

それでは実際のコードを見てみましょう。
開発現場でそのままコピペして使えるよう、エラーハンドリング(万が一の時の備え)も組み込んだ実用的なプロシージャを用意しました。

Option Explicit

‘ ==============================================================================
‘ 処理名: テンポラリステンシルからマスターを取得し、安全に破棄するサンプル
‘ 概要:
‘ 指定したパスのステンシルを非表示で開き、必要なマスターを自ドキュメントに
‘ ドロップ(インスタンス化)したのち、確実にステンシルをクローズします。
‘ ==============================================================================
Sub CreateShapeFromTemporaryStencil()

Dim targetDoc As Visio.Document
Dim stencilDoc As Visio.Document
Dim mst As Visio.Master
Dim shp As Visio.Shape

‘ 【重要】実際の環境に合わせてステンシルのフルパスに変更してください
Const STENCIL_PATH As String = “C:\MyTools\Shapes\CustomIcons.vssx”
Const MASTER_NAME As String = “サーバー” ‘ ステンシル内のマスター名

Set targetDoc = ActiveDocument ‘ 操作対象のアクティブ図面

On Error GoTo ErrorHandler ‘ 予期せぬエラー時にメモリ解放へジャンプする保険

‘ —————————————————————-01. 非表示でステンシルを開く
‘ visOpenRO (読み取り専用) と visOpenHidden (非表示) を足し合わせます
Debug.Print “ステンシルをバックグラウンドでオープンします…”
Set stencilDoc = Documents.OpenEx(STENCIL_PATH, visOpenRO + visOpenHidden)

‘ —————————————————————-02. マスターの取得
‘ ステンシルの中に目的のマスターが存在するかチェック
On Error Resume Next
Set mst = stencilDoc.Masters(MASTER_NAME)
On Error GoTo ErrorHandler

If mst Is Nothing Then
MsgBox “指定されたマスターが見つかりません: ” & MASTER_NAME, vbCritical, “エラー”
GoTo CleanupAndExit
End If

‘ —————————————————————-03. 図形をページに配置
‘ Dropメソッドを使って、アクティブページの座標(4.0, 5.0)に図形を生成
Set shp = targetDoc.Pages(1).Drop(mst, 4.0, 5.0)
Debug.Print “図形を正常に配置しました: ” & shp.Name

CleanupAndExit:
‘ —————————————————————-04. 【最重要】ステンシルの確実なクローズ
‘ オブジェクトがメモリに残るのを防ぐため、開いたものは必ず閉じます
If Not stencilDoc Is Nothing Then
stencilDoc.Close
Set stencilDoc = Nothing ‘ 参照を完全に解放
Debug.Print “ステンシルを安全にクローズし、メモリを解放しました。”
End If

Exit Sub

ErrorHandler:
‘ エラー発生時のフォールバック(強制終了時も確実に片付ける)
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanupAndExit

End Sub

4. コードの深掘り解説:ここがエンジニアのこだわりポイント

初心者のうちは動けば満足してしまいがちですが、プロのコードには「なぜそう書くのか」の理由があります。

① `Documents.OpenEx` とフラグの魔法

通常の `Documents.Open` だと、ユーザーの画面にステンシルウィンドウがドコンと表示されてしまいます。
ここで `visOpenRO + visOpenHidden` という合成フラグを使うのがポイントです。「読み取り専用かつ非表示で開く」という指定により、ユーザーに存在を一切意識させずに裏でこっそり仕事をさせることができます。

② クリーンアップ(後始末)の徹底

VBAにおいて、オブジェクト変数(`Set stencilDoc = …` で取得したもの)は、処理が終わってもメモリ領域に居座り続ける性質があります。
これを放置すると、マクロを何回も実行しているうちにVisioの動作が重くなったり、最悪の場合はファイルがロックされて開けなくなったりします。

コードの最後にある `CleanupAndExit` ラベルと `Set stencilDoc = Nothing` は、「借りてきたものは綺麗に洗って元の場所に返す」というプログラミングの美徳そのものです。エラーが起きたときでも必ずここを通るように `On Error GoTo` を仕込んでいるのが、アーキテクトとしてのこだわりです。

おわりに

今回は、非表示ステンシルの安全な動的生成と確実なメモリ解放について解説しました。

一見すると地味なテクニックに見えるかもしれませんが、「リソースを美しく管理し、痕跡を残さないこと」こそが、壊れにくく保守しやすいVBAツールを作るための最大の秘訣です。

このパターンをあなたの引き出しに加えることで、Visio VBAの基礎はもう完璧と言って良いでしょう。ぜひ、実際の業務ツール開発に応用してみてくださいね。
それでは、次回の高度な自動化の世界でお会いしましょう!

タイトルとURLをコピーしました