こんにちは!Visio VBAの世界へようこそ。
マクロの記録ボタンを押して「なんだかよく分からないけれど動いたぞ!」と感動したのも束の間、「複数の図面を開いたまま一括で綺麗に保存して閉じたい」「VBAでスマートにメモリを解放したい」と思ったとき、途端に手が止まってしまうことってありますよね。
今回は、Visio VBAの基礎を固めつつ、実務で絶対に役立つ「開いている全ての図面を一括保存して安全に閉じるルーチン」を一緒に紐解いていきましょう。
ここをしっかりとクリアできれば、あなたのVisio自動化スキルは間違いなくワンランク上のステージに到達します。難しい専門用語は噛み砕いて解説しますので、リラックスしてついてきてくださいね!
—
1. なぜ「一括保存とクローズ」がVisio VBAの登竜門なのか?
Visioで複数の図面を開きながら作業していると、退勤間際に「あぁ、保存し忘れたファイルがあるかも…」「メモリが圧迫されて動作が重い…」なんて焦ることはありませんか?
人間が一つずつ「名前をつけて保存」「閉じる」を繰り返すのは、単純作業のようでいて実は大きなストレスです。これをVBAに任せれば、一瞬で、しかも確実に処理が終わります。
しかし、ここでプログラミング初心者がやりがちな「危険な罠」があります。それが、「コレクションの逆順ループ」です。
🚨 初学者がハマる最大の罠:前から順番に閉じるとどうなる?
Visioで開いているすべてのファイルは、`Documents` という「ファイルの束(コレクション)」で管理されています。
もし、この束の上から順に「閉じる(Close)」を指示していくとどうなるでしょうか?
1. 1番目のファイルが閉じる。
2. 2番目のファイルが、繰り上がって「1番目」になる。
3. ループのカウンターが「2」に進むため、元の2番目(いま1番目になったファイル)がスキップされてしまう!
結果として、ファイルが閉じきらなかったり、思わぬエラーを引き起こしたりします。
だからこそ、複数のファイルを扱うときは「後ろから前へ数えていく(逆順ループ)」というプロの知恵が必要なのです。ここ、今日の最重要ポイントですよ!
—
2. 全ドキュメントを安全に一括保存・クローズする実用コード
それでは、実際のコードを見てみましょう。
以下のコードをVisioのVBAエディタ(Alt + F11)の標準モジュールに貼り付けて実行してみてください。
Sub SaveAndCloseAllDocuments()
‘ 変数の宣言
Dim i As Long
Dim docTarget As Visio.Document
Dim activeCount As Long
‘ 現在開いているドキュメントの数を取得
activeCount = Visio.Documents.Count
‘ 開いているドキュメントが0個ならメッセージを出して終了
If activeCount = 0 Then
MsgBox “現在、開いているVisioドキュメントはありません。”, vbInformation, “確認”
Exit Sub
End If
‘ 実行確認のダイアログ
If MsgBox(“開いているすべてのドキュメント (” & activeCount & “件) を保存して閉じますか?”, _
vbYesNo + vbQuestion, “一括処理の確認”) = vbNo Then
Exit Sub
End If
‘ 【重要】「後ろから前へ」ループを回す(インデックスのズレを防ぐため)
For i = activeCount To 1 Step -1
Set docTarget = Visio.Documents(i)
‘ テンプレートやステンシル(静的なツール群)は対象外とする判定
‘ (通常の図面ファイル .vsd, .vsdx のみを対象にする)
If docTarget.Type = visTypeDrawing Then
‘ すでに保存されたファイル名を持っているかチェック
If docTarget.Path <> “” Then
‘ 上書き保存
docTarget.Save
Else
‘ まだ一度も保存されていない(名前なし)図面の場合
‘ ※必要に応じてパスを指定して保存することも可能です
Debug.Print “未保存の新規ドキュメントのためスキップします: ” & docTarget.Name
End If
‘ ドキュメントを閉じる(メモリから解放)
docTarget.Close
End If
Next i
‘ 完了報告
MsgBox “すべての図面の保存とクローズが完了しました。”, vbInformation, “処理完了”
End Sub
—
3. コードの仕組みを優しく解説
先ほどのコード、一つひとつのパーツがどんな役割を持っているのか、丁寧に分解していきましょう。
① `Visio.Documents.Count` でファイルの総数を数える
今、Visioの中で何枚のキャンバス(ドキュメント)が広がっているか、その数を数えるのが `Count` プロパティです。「総数がいくつあるか」が分かれば、あとでループを回すときのゴールが明確になりますよね。
② `For i = activeCount To 1 Step -1` (逆順ループの魔法)
先ほど解説した「ファイルを途中でスキップさせないための工夫」がこの `Step -1` です。
一番最後のファイルからスタートし、カウントをマイナスしながら最初のファイルに向かって処理を進めることで、ファイルが閉じられて番号がズレる現象を華麗に回避しています。ここが書けるようになると、VBAの中級者オーラが一気に出てきますよ!
③ `docTarget.Type = visTypeDrawing` による安全フィルター
Visioを開いているとき、裏側では「ステンシル(図形のパーツ入れ)」や「マスターシェイプ」といった、私たちが普段直接編集しないシステム的なファイルも一緒に開かれています。
これらを誤って保存しようとするとエラーの原因になるため、`visTypeDrawing`(=私たちが普段描く図面ファイル)だけに処理を限定しています。この優しさが、エラーのない堅牢なマクロを作ります。
④ `docTarget.Close` による確実なメモリ解放
ファイルを閉じる `Close` メソッドを実行することで、その図面が占有していたメモリ領域がVBAによって綺麗に解放されます。Visioを立ち上げたまま大量の図面を処理するような現場でも、メモリリーク(メモリが徐々に圧迫される現象)を防ぐことができるため、非常に安全です。
—
4. 開発現場でよくある「うっかりエラー」と対策
最後に、実際にこのコードを運用する中で直面しがちな「つまずきポイント」を先回りしてクリアしておきましょう。
- Q. 「名前をつけて保存」されていない新規ファイルの扱いは?
- A. コード内の `If docTarget.Path <> “” Then` という条件分岐がこれに答えています。まだ一度も保存されておらず、ファイル名(パス)が決まっていない新規図面に対して無理に上書き保存をかけようとすると、Visioが「どこに保存すればいいの?」とダイアログを出してしまい、マクロが途中でフリーズしたように止まってしまいます。そのため、実務では「名前のついていないファイルは一旦ダイアログで保存させる」あるいは「今回はスキップする」といった配慮が必要です。
- Q. 読み取り専用(Read-Only)のファイルが開いていた場合は?
- A. 読み取り専用ファイルに対して `docTarget.Save` を実行するとエラーになります。厳密に作り込む場合は `If Not docTarget.ReadOnly Then` などの条件を挟むと、さらにプロフェッショナルなコードになりますよ。
—
おわりに:ここをクリアすれば、Visio VBAの基本はバッチリ!
お疲れ様でした!今回は「開いている全てのVisioドキュメントをループ処理で一括保存し、メモリを解放する」というテーマを解説しました。
- コレクションの数を数えて、
- 「後ろから前へ(Step -1)」ループを回し、
- 種類を判定して安全に保存・クローズする。
この一連の流れは、VisioだけでなくExcelやWordなどの他のOffice VBAでも共通する、極めて重要で美しいデザインパターンです。
ここをクリアできたあなたなら、もう「マクロの記録の奴隷」ではありません。ぜひご自身の業務環境に合わせてこのコードをアレンジし、日々の作業をスマートに自動化してみてくださいね。
それでは、次回の応用編でお会いしましょう!あなたのVBAライフが素晴らしいものになりますように。
