Visio VBAの「速度」を極める:数百のシェイプを一瞬で書き換える『一括処理』の極意
こんにちは。現場でVisioと格闘している皆さん、お疲れ様です。
マクロの記録から一歩踏み出し、「もっと複雑な図面を自動化したい」と考え始めたとき、必ず直面する壁があります。それが「処理速度」です。
「数百個のシェイプのプロパティを書き換えたら、完了までコーヒーを淹れに行けるほど時間がかかる……」
もしそんな経験があるなら、あなたは「1セルずつ操作する」という罠にハマっています。今日は、伝説的なエンジニアが現場で必ず使う`GetFormulasU`と`SetFormulasU`という魔法のメソッドを伝授しましょう。これを知れば、あなたのコードは別次元の速さに進化します。
—
なぜ「1つずつ」操作すると遅いのか?
Visioのセル操作は、本来非常に重い処理です。
`Shape.Cells(“Width”).Formula = “10mm”` というコードをループで100回回すと、Visioは100回、「再計算」「画面描画の更新」「依存関係のチェック」を繰り返します。
これでは、図面が大きくなればなるほど、Visioは悲鳴を上げます。
解決策は「まとめて渡す」こと。
Visioには、配列を使って一括で読み書きする強力なメソッドが備わっています。これが`GetFormulasU`と`SetFormulasU`です。
—
魔法のメソッド:GetFormulasU と SetFormulasU
このメソッドの最大の利点は、「Visioの内部処理を最小限に抑え、メモリ上で一気に計算させる」ことにあります。
実践コード:高速な一括書き換え
以下のコードは、ページ内の全シェイプの「幅(Width)」を配列で取得し、一括で書き換える実用例です。
Sub FastBatchUpdate()
Dim shps As Visio.Shapes
Dim shp As Visio.Shape
Dim i As Long
Dim count As Long
‘ 書き換えたいセルの名前(ユニバーサル名)
Dim cellNameArray(0 To 0) As String
cellNameArray(0) = “Width”
‘ シェイプの参照を取得
Set shps = ActivePage.Shapes
count = shps.Count
‘ 1. 数式を保持する配列を定義
Dim formulas() As Variant
ReDim formulas(1 To count, 1 To 1)
‘ 2. 一括で数式を取得 (GetFormulasUを使用)
‘ ※引数にはセル名配列と、結果を格納する配列を渡す
shps.GetFormulasU cellNameArray, formulas
‘ 3. 配列内のデータをメモリ上で加工
For i = 1 To count
‘ 例えば、幅をすべて20mmに強制設定するなら
formulas(i, 1) = “20mm”
Next i
‘ 4. 一括で数式を書き込み (SetFormulasUを使用)
‘ これにより、再計算は「一度だけ」実行される
shps.SetFormulasU cellNameArray, formulas
MsgBox “全シェイプの幅を瞬時に更新しました!”
End Sub
コードの解説
1. 配列の定義: `formulas(1 To count, 1 To 1)` という2次元配列を用意します。行はシェイプの数、列は操作するセルの数です。
2. GetFormulasU: 指定したセル名(ここでは “Width”)の数式を、一気に配列へ吸い上げます。
3. メモリ内加工: ここで配列の中身を書き換えます。まだVisioの図面自体には何も影響していません。
4. SetFormulasU: 配列の値を一気にVisioへ流し込みます。ここで初めて「再計算」が走るため、圧倒的に速いのです。
—
陥りやすい罠:ここだけは注意!
初学者がこのテクニックを使う際、必ずつまずくポイントが2つあります。
1. 「U」の意味を忘れない(Universal)
メソッド名に「U」がついているのは Universal(ユニバーサル) の意味です。Visioの数式は、OSの言語設定によって「10mm」が「10 mm」になったり、小数点記号が変わったりします。
`GetFormulas` ではなく必ず `GetFormulasU` を使ってください。これを使えば、世界中のどの環境でも動く堅牢なコードになります。
2. セル名が存在しない場合のエラー
対象のシェイプの中に、指定したセル(例: “Width”)を持っていないものが含まれているとエラーになります。
実務では、`On Error Resume Next` で囲むか、シェイプの種類を判定してから配列に含めるなどの防衛的なコーディングが重要です。
—
まとめ:自動化のエンジニアとして
今回紹介した「一括処理」は、単なるテクニックではありません。「Visioの負荷を考慮する」という、アーキテクトとしての視点そのものです。
- 1つずつ操作するのは「手作業」の延長。
- 配列で操作するのは「システム」の構築。
ここをクリアしたあなたは、もう初心者ではありません。次回の業務自動化では、ぜひこの手法を使って、同僚を驚かせるような爆速マクロを組んでみてください。
「Visioは遅い」というのは、使い手の工夫が足りないだけです。あなたのコードで、Visioの真の力を引き出してあげてくださいね。応援しています!
