Visio VBAの真髄:`DropMany`で実現する「神速」の図形一括複製術
Visioでマクロを書き始めると、誰もが一度は「コピー&ペースト」の壁にぶつかります。`Selection.Copy`して`Paste`……。これ、実は非常に危険で、かつ遅いやり方なんです。
なぜなら、`Paste`メソッドは「クリップボード」という不安定で低速なOS共有領域を経由するからです。大規模な図面でこれを行うと、Visioがフリーズしたり、思わぬ場所に図形が張り付いたりして、あなたの貴重な時間を浪費してしまいます。
今回は、業務自動化のプロが必ず使う「DropManyメソッド」による、安全かつ高速なシェイプ複製術を伝授します。これを知れば、あなたのVisio自動化のレベルは一気に「脱・初心者」です。
—
1. なぜ「Paste」ではなく「DropMany」なのか?
`Paste`は「人間がマウスとキーボードで行う操作」をVBAで代行しているに過ぎません。これに対して、`DropMany`はVisioのエンジンに対して「直接、設計図を渡して配置させる」命令です。
- 高速性: クリップボードを介さないため、数千個の図形でも一瞬で処理が完了します。
- 堅牢性: ページ遷移やフォーカスに依存せず、メモリ上で直接シェイプを生成するため、実行中のエラーが激減します。
- 安全性: 「どこにペーストされるか」という不確定要素がなく、座標を完全に制御できます。
—
2. DropManyの心臓部:引数のルール
`DropMany`は強力ですが、少しばかりの「儀式」が必要です。以下の4つの引数を渡す必要があります。
1. ObjectsToDrop(): どのマスターシェイプ(図形の元)を使うか。
2. XYArray(): どこに置くか(X1, Y1, X2, Y2…という配列)。
3. ResultList(): 成功したシェイプの参照先を受け取る変数。
少し難しく感じるかもしれませんが、実戦的なコードで見てみましょう。
—
3. 実践:ページ間一括コピーの神コード
以下のコードは、アクティブページの全図形を、新規ページにそのままの座標で複製するサンプルです。
Sub FastCopyShapes()
Dim vsoPageSrc As Visio.Page
Dim vsoPageDst As Visio.Page
Dim vsoShapesSrc As Visio.Shapes
Dim i As Long
‘ 1. オブジェクトの準備
Set vsoPageSrc = ActivePage
Set vsoPageDst = ActiveDocument.Pages.Add
Set vsoShapesSrc = vsoPageSrc.Shapes
‘ 2. DropManyに必要な配列の宣言
Dim count As Long: count = vsoShapesSrc.count
Dim masters() As Object
Dim xyCoords() As Double
ReDim masters(0 To count – 1)
ReDim xyCoords(0 To (count 2) – 1)
‘ 3. 情報を配列に詰め込む(これが高速化の秘訣!)
For i = 0 To count – 1
‘ 元となるマスターシェイプを取得
Set masters(i) = vsoShapesSrc(i + 1).Master
‘ 座標を配列に格納 (X, Yの順でセット)
xyCoords(i 2) = vsoShapesSrc(i + 1).Cells(“PinX”).ResultIU
xyCoords(i 2 + 1) = vsoShapesSrc(i + 1).Cells(“PinY”).ResultIU
Next i
‘ 4. DropManyで一括生成!
‘ 第一引数:マスター配列、第二引数:座標配列、第三引数:結果格納用
vsoPageDst.DropMany masters, xyCoords, Nothing
MsgBox “高速コピー完了!”
End Sub
—
4. 開発現場で陥りやすい罠と解決策
初学者が`DropMany`で挫折するポイントは、実は「マスターシェイプ」の存在です。
罠:マスターシェイプがない図形はどうする?
`DropMany`は基本的に「マスターシェイプ(ステンシル内の図形)」を元にして複製します。もし、画面上の図形がマスターを持たない(あるいはグループ化されている)場合は、`Copy`&`Paste`ではなく、`Shape.Duplicate`メソッドを検討してください。これもクリップボードを使わない優秀なメソッドです。
成功のポイント:
- 座標系に注意: `ResultIU`を使うことで、単位系(インチやミリ)の影響を受けずに座標を取得できます。
- イベントの抑制: 大量に生成する際は `Application.ScreenUpdating = False` を冒頭に入れ、最後に `True` に戻すと、描画コストが抑えられ、さらに高速化します。
—
最後に:先輩からのアドバイス
「マクロの記録」で生成されるコードは、あくまで「初心者の手引き」です。そこから一歩踏み出し、このようにオブジェクトモデルを直接操作する手法を覚えると、Visioは単なる作図ツールから、「自動設計エンジン」へと姿を変えます。
まずはこのコードをコピーして、手元の図面で動かしてみてください。一瞬で図形が湧き上がるあの感覚を味わえば、もう元には戻れないはずですよ。
ここをクリアすれば、Visio VBAの基本はバッチリです。次は「シェイプの接続関係(Connects)」をプログラムから制御する方法に挑戦してみましょう。道は開けています!
