【入門編】【上級者向け】VSDXファイル内の不要なステンシルやスタイルを削除し、ファイルサイズを劇的に軽量化する最適化ツール – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visioの自動化の世界へようこそ。
これまで「マクロの記録」を使って、なんとなく図形を描画するコードは書けるようになったけれど、ふと気づくと……「ただの図なのに、ファイルサイズが数十メガバイトもある!」「なぜか動作が重い……」なんて壁にぶ和されていませんか?

実はVisioのファイル(.vsdx)は、内部で使っていない「ステンシル(マスターシェイプ)」や「スタイル」をこっそり抱え込む性質があります。図形をコピー&ペーストしたり、他の図面からパーツを引っ張ってきたりするたびに、見えないゴミがどんどん溜まっていくんです。

今回は、そんなVisioの深部を綺麗さっぱりお掃除し、ファイルサイズを劇的に軽量化する「クリーンアップ・ツール」の作り方を伝授します。ここをクリアすれば、あなたも脱・初心者!Visio VBAの裏側を完全に掌握する第一歩を踏み出せますよ。

—

なぜVisioのファイルは肥大化するのか?

Visioで図形を配置すると、その「大元(ひな形)」である Master(マスターシェイプ) がドキュメント(`Document`オブジェクト)の中に自動的に取り込まれます。

厄介なことに、その図形を画面上から削除しても、Masterはドキュメント内に残ったままになる仕様になっています。さらに、不要な文字スタイルや線のスタイル(`Style`オブジェクト)も同様です。

これを人間の手で一つひとつ消すのは、終わりのない苦行。だからこそ、VBAの出番です!

—

現場で即戦力になる!最強クリーンアップ・コード

それでは早速、現在開いているVisio図面から「使われていないマスターシェイプ」と「ユーザー定義以外のスタイル」を根こそぎ削除し、ついでに最適化して保存するVBAコードを公開します。

VBE(Visual Basic Editor)を開き、標準モジュールに以下のコードを貼り付けてください。

Option Explicit

‘ ==============================================================================
‘ 処理名: 肥大化したVSDXファイルを極限まで軽量化するクリーンアップツール
‘ 概要 : 未使用のマスターシェイプおよびカスタムスタイルを安全に削除し、保存します。
‘ ==============================================================================
Public Sub OptimizeCurrentVisioDocument()
Dim docTarget As Visio.Document
Set docTarget = ActiveDocument

‘ 念のため、Visioの画面描画を停止して処理を高速化
Application.ScreenUpdating = False

Dim initialSize As Long
Dim finalSize As Long

On Error GoTo ErrorHandler

Debug.Print “=== 軽量化処理を開始します: ” & docTarget.Name & ” ===”

‘ 1. 未使用マスターシェイプの削除
Call PurgeUnusedMasters(docTarget)

‘ 2. 未使用スタイルの削除
Call PurgeUnusedStyles(docTarget)

‘ 3. 文書の最適化保存(Compact)
‘ ※一度名前をつけて保存し直すことで、内部のXML構造を再構築しファイルサイズを削ぎ落とします
If docTarget.Path <> “” Then
Dim originalPath As String
originalPath = docTarget.Path & docTarget.Name

‘ 変更を保存
docTarget.Save
Debug.Print “=== 軽量化処理が完了しました ===”
Else
MsgBox “未保存のドキュメントです。一度保存してから実行してください。”, vbExclamation, “警告”
End If

CleanUp:
Application.ScreenUpdating = True
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “予期せぬエラー”
Resume CleanUp
End Sub

‘ ——————————————————————————
‘ サブ処理: 未使用マスターのパージ(削除)
‘ ——————————————————————————
Private Sub PurgeUnusedMasters(ByVal doc As Visio.Document)
Dim i As Long
Dim mastersCount As Long
mastersCount = doc.Masters.Count

Dim deletedCount As Long
deletedCount = 0

‘ コレクションの削除は、インデックスのズレを防ぐために「後ろから前へ(逆順)」ループさせるのが鉄則!
For i = mastersCount To 1 Step -1
Dim mst As Visio.Master
Set mst = doc.Masters(i)

‘ 判定基準: ページ上にこのマスターから作られた図形(Shapes.Count)が一つもないか?
‘ ※ さらに、他のマスターの内部でも使われていないかチェックするのが完璧ですが、
‘ 今回は実用性を重視し「ドキュメント内のページで使われているか」を判定します。
If IsMasterUnusedInPages(doc, mst) Then
‘ 組み込みの特殊なマスター(ドキュメント固有の不可視マスターなど)を除外するため保護をチェック
On Error Resume Next
mst.Delete
If Err.Number = 0 Then
deletedCount = deletedCount + 1
Debug.Print ” [削除] マスター: ” & mst.Name
End If
On Error GoTo 0
End If
Next i

Debug.Print ” -> 削除された未使用マスター数: ” & deletedCount
End Sub

‘ ——————————————————————————
‘ 判定関数: 指定されたマスターが全ページで一度も使われていないか確認
‘ ——————————————————————————
Private Function IsMasterUnusedInPages(ByVal doc As Visio.Document, ByVal mst As Visio.Master) As Boolean
Dim pg As Visio.Page
Dim shp As Visio.Shape

IsMasterUnusedInPages = True ‘ 初期値は「使われていない」

For Each pg in doc.Pages
For Each shp in pg.Shapes
‘ 図形の Master プロパティを比較
If Not shp.Master Is Nothing Then
If shp.Master.ID = mst.ID Then
IsMasterUnusedInPages = False
Exit Function
End If
End If
Next shp
Next pg
End Function

‘ ——————————————————————————
‘ サブ処理: 未使用スタイルのパージ
‘ ——————————————————————————
Private Sub PurgeUnusedStyles(ByVal doc As Visio.Document)
Dim i As Long
Dim styleCount As Long
styleCount = doc.Styles.Count

Dim deletedCount As Long
deletedCount = 0

For i = styleCount To 1 Step -1
Dim stl As Visio.Style
Set stl = doc.Styles(i)

‘ Visioの標準スタイル(Normalなど)や、組み込みの必須スタイルは削除してはいけない
If Not stl.BuiltIn Then
‘ ここでは簡易的に「BuiltIn(組み込み)ではないカスタムスタイル」を対象に安全に削除トライ
On Error Resume Next
stl.Delete
If Err.Number = 0 Then
deletedCount = deletedCount + 1
Debug.Print ” [削除] スタイル: ” & stl.Name
End If
On Error GoTo 0
End If
Next i

Debug.Print ” -> 削除されたカスタムスタイル数: ” & deletedCount
End Sub

—

コードのここがポイント!プロが教える「秘伝のタレ」

上記のコードには、Visio VBAを極めたエンジニアならではの「こだわり(知見)」が詰まっています。初心者から一歩抜け出すために、重要なポイントを解説します。

1. コレクション操作は「後ろから前へ(逆順)」回せ!

`For i = mastersCount To 1 Step -1` という書き方に注目してください。
プログラミング初心者がやりがちなのが、`For i = 1 To mastersCount` と前から順番に消していく方法です。これをやると、要素を消した瞬間に後ろのインデックスがズレてしまい、エラーが起きて一部の要素がすり抜けてしまいます。
コレクションを削除・変更しながらループさせる時は「必ず後ろから前へ数える」。これがVBAの鉄則です。

2. `Application.ScreenUpdating = False` で爆速化

大量のオブジェクトを走査して削除する際、Visioの画面が一生懸命「今ここを消しましたよ」と再描画しようとすると、処理がものすごく遅くなります。
処理の最初に画面更新を止め、最後に復元することで、ストレスフリーな速度で動作させることができます。

3. エラーハンドリングの防壁 (`On Error Resume Next`)

Visioのマスターシェイプの中には、システム側が裏でガッチリ掴んでいて「絶対に消しちゃダメ!」という神聖な領域があります。
これをプログラムが無理やり消そうとすると、容赦なく実行時エラーで止まってしまいます。そのため、`On Error Resume Next` を使って「もし消せないシステム系なら無視して次に進む」という大人の対応をさせています。

—

陥りやすいエラーと注意点

  • 「未保存のドキュメントです」と怒られる
  • このツールは一度ファイルとして保存されている(パスが存在する)VSDXファイルを対象にしています。新しく開いたばかりの「ドキュメント1」の状態では `.Path` が空になるため、一度名前をつけて保存してから実行してください。
  • リンクされたステンシルへの配慮
  • 外部のステンシルファイル(.vssx)からドキュメントに「コピー」されたマスターは削除対象になりますが、もし図面がそのステンシルと常時リンクしている場合などは、組織の運用ルールに合わせて削除範囲を調整してください。

—

まとめ:自動化のロマンをその手に

いかがでしょうか?
普段何気なく使っているVisioも、内部の構造(`Masters` や `Styles`)を理解し、VBAでコントロールできるようになると、まるで自分の手足のように操れるようになります。

「ファイルが重くてメールに添付できない!」そんな社内の悲鳴を、このクリーンアップ・ツールを一発走らせるだけでスマートに解決してあげてください。「お、できる奴だな」と一目置かれること間違いなしです。

それでは、快適なVisio自動化ライフを!次のステージでお会いしましょう。

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