Visioで図面を修正し続けると、ファイルサイズが肥大化して動きが重くなる。誰もが一度は経験するこの「Visioの呪い」に、今日で終止符を打ちましょう。
マクロの記録から一歩踏み出し、Visioの心臓部である「オブジェクトモデル」を直接操作する——。今回は、大規模VSDXファイルを劇的に軽量化するための、玄人向けの最適化ツールを設計します。
—
なぜVisioファイルは肥大化するのか?
Visioのファイルは、実は「XMLベースのデータベース」です。図面の中に使わなくなった「マスターシェイプ(図形の雛形)」や「スタイル」が、ゾンビのように居座り続けることでサイズを食いつぶします。
特に、他の図面からコピペを繰り返すと、不要なマスターシェイプが裏側で増殖し続けます。これを手動で消すのは非効率極まりない。VBAの力で、「使用されていない定義を強制的に摘出する」のが、真のエンジニアの流儀です。
—
極限の最適化:不要なマスターとスタイルの削除
まずは、このコードが何をしているのか、設計思想を理解してください。
1. Mastersの走査: 図面内の全てのマスターシェイプを確認。
2. 使用状況の判定: ページ上の各シェイプを走査し、そのマスターが現在使われているかを論理チェック。
3. Stylesのクリーンアップ: 組み込みスタイル以外で、参照されていない定義をパージ。
軽量化エンジンの実装コード
Option Explicit
‘ メイン処理:現在のドキュメントを最適化する
Public Sub OptimizeVisioDocument()
Dim doc As Visio.Document
Set doc = ActiveDocument
‘ 削除対象をカウント
Dim delCount As Integer
delCount = 0
‘ 1. 不要なマスターシェイプの削除
delCount = delCount + PurgeUnusedMasters(doc)
‘ 2. 不要なスタイルの削除(※慎重に扱うこと)
‘ PurgeUnusedStyles doc
MsgBox “最適化完了: ” & delCount & ” 個の不要なマスターを削除しました。” & vbCrLf & _
“※必ず別名で保存し、ファイルサイズを確認してください。”, vbInformation
End Sub
‘ 使用されていないマスターを削除する関数
Private Function PurgeUnusedMasters(doc As Visio.Document) As Integer
Dim mst As Visio.Master
Dim i As Integer
Dim isUsed As Boolean
Dim count As Integer
‘ 後ろからループを回す(削除によるインデックスのズレを防ぐ鉄則)
For i = doc.Masters.Count To 1 Step -1
Set mst = doc.Masters(i)
‘ 現在のマスターがドキュメント内のどこかで使われているかチェック
If Not IsMasterInUse(mst, doc) Then
mst.Delete
count = count + 1
End If
Next i
PurgeUnusedMasters = count
End Function
‘ マスターが使用中か判定するロジック
Private Function IsMasterInUse(mst As Visio.Master, doc As Visio.Document) As Boolean
Dim pg As Visio.Page
Dim shp As Visio.Shape
‘ 全ページ、全シェイプをなめる(重いが確実な判定)
For Each pg In doc.Pages
For Each shp In pg.Shapes
‘ シェイプの元がこのマスターであれば「使用中」
On Error Resume Next ‘ 稀にマスター情報が取れないシェイプがあるため
If Not shp.Master Is Nothing Then
If shp.Master.Name = mst.Name Then
IsMasterInUse = True
Exit Function
End If
End If
On Error GoTo 0
Next shp
Next pg
IsMasterInUse = False
End Function
—
開発現場で陥りやすい「落とし穴」
このコードを実装する際、必ず遭遇する「壁」があります。
1. インデックスのズレ(逆ループの鉄則)
`For i = 1 To Masters.Count` と書くと、1つ削除した瞬間に2番目が1番目に繰り上がり、チェックがスキップされます。「コレクションを削除するときは、必ず後ろから(Step -1)回せ」。これはVBAエンジニアの鉄の掟です。
2. 「組み込み」を消そうとしないこと
Visioには最初から存在する「Normal」や「None」といったシステムスタイルがあります。これらを削除しようとすると、Visioはエラーを吐いて停止します。`mst.BuiltIn` プロパティをチェックし、`True` の場合は無視するように設計するのが、安全なコードの書き方です。
3. パフォーマンスの重さ
大規模ファイルでは、`IsMasterInUse` 関数がページ数に比例して重くなります。もし「さらに高速化したい」なら、一度マスター名の一覧をDictionaryオブジェクトに格納し、ページ走査の過程でヒットしたものからキーを削除していく、といったアルゴリズムの最適化が必要になります。
—
次のステップへ
今回のコードは、Visioの「構造」を理解するための第一歩です。
慣れてきたら、次は「不要なレイヤーの削除」や「カスタムプロパティ(Shape Data)のクリーンアップ」にも挑戦してみてください。
Visioを自動化するということは、単にマウス操作を代替することではありません。「図面データそのものを意のままに操るアーキテクトになる」ということ。
ここをクリアしたあなたは、もう初心者ではありません。自信を持って、さらに深いVisioの世界へ足を踏み入れてください。応援していますよ。
