【入門編】クリップボードを使わない純粋クローン作成:DrawPolylineとDropを活用した高速図形複製 – Visio VBA解析バイブル

スポンサーリンク

こんにちは! Visioの裏側でうねる複雑なオブジェクトモデルに魅入られた、先輩エンジニアのボクです。

マクロの記録ボタンを押して、図形を選択して「Ctrl+C」「Ctrl+V」……。
うん、最初はそれでいいんだ。自動生成されたコードを見て「おっ、動いた!」と感動するよね。でも、実務で何百個もの図形を処理するツールを作り始めた途端、その幻想は音を立てて崩れ去る。

そう、クリップボードを経由する `Copy` と `Paste` は、遅い、不安定、そして何よりダサい。
OSのクリップボードという「他人」を介在させることで、フォーマットの競合や謎のエラー(「クリップボードが使用できません」ってやつだ)に悩まされた経験、あるよね?

今回は、そんな泥臭いやり方とはおサラバするための「クリップボードを使わない純粋クローン作成」の極意を伝授しよう。ここをクリアすれば、キミのVisioマクロは「おもちゃ」から「プロの自動化ツール」へと劇的に進化するよ。

なぜ `Copy / Paste` は悪なのか?

Visio VBAにおける `ActiveWindow.Selection.Copy` と `ActivePage.Paste`。
これは人間が画面操作する手順をそのままVBAに翻訳しただけの、いわば「ハリボテの自動化」だ。

1. 極めて低速: OSのクリップボード領域を読み書きするオーバーヘッドが重すぎる。
2. 画面(Window)に依存する: 画面を選択状態にしたり、アクティブウィンドウを切り替えたりしないと動かないため、バックグラウンド処理(非表示実行)が事実上不可能ですらある。
3. 環境に左右される: 他のアプリケーションのコピー&ペースト操作と干渉して突然エラーを起こす。

プロのエンジニアなら、OSのクリップボードなど頼らない。
対象の図形が持つ「DNA(幾何情報やShapeSheetの数式)」をコードで直接読み取り、何もないところから鮮やかに再構築する――これこそが、美しく速い真のクローン生成なのだ。

攻略の鍵:幾何情報の抽出と `DrawPolyline` / `Drop`

クローンを作るアプローチは主に2つある。

1. マスター図形(Stencit)からの生成: `Page.Drop` メソッドを使う。ステンシルにあるマスター図形を「ポトッ」とページに落とし込む方法だ。元の図形がステンシル由来なら、これが一番スマート。
2. 幾何情報の完全再現: 線の図形なら `Page.DrawPolyline` などを使って、頂点座標をそのままトレースして再構築する。

今回は、この両者のアプローチの本質に迫りつつ、どんな図形でも確実に、そして爆速で複製するコードの骨組みを見ていこう。

実践!クリップボードを汚さない高速クローン生成コード

百聞は一見に如かず。まずは、選択している図形の幅・高さ・位置(ピン位置)を取得し、クリップボードを一切経由せずに同じページの指定座標に「完璧な双子」を生成するサンプルコードをプレゼントしよう。

VBE(Visual Basic Editor)を開き、標準モジュールにペーストしてほしい。

Option Explicit

‘ ==============================================================================
‘ 処理名: CreatePureClone
‘ 概要: 選択中の図形のジオメトリ(位置・サイズ)を直読みし、
‘ クリップボードを使わず瞬時にクローンを生成するプロフェッショナルな関数
‘ ==============================================================================
Public Sub CreatePureClone()
Dim vsoApp As Visio.Application
Set vsoApp = Visio.Application

‘ 1. 画面更新の完全停止(描画コストを極限まで削る魔術)
vsoApp.ScreenUpdating = False

On Error GoTo ErrorHandler

Dim vsoPage As Visio.Page
Set vsoPage = vsoApp.ActivePage

Dim vsoSelection As Visio.Selection
Set vsoSelection = vsoApp.ActiveWindow.Selection

‘ 選択チェック
If vsoSelection.Count = 0 Then
MsgBox “複製元の図形を選択してください。”, vbExclamation, “警告”
GoTo Finally
End If

Dim vsoShape As Visio.Shape
Set vsoShape = vsoSelection(1) ‘ 今回は簡単のため1個目の図形を対象

‘ 2. 複製元のDNA(ShapeSheetプロパティ)をメモリ上に抽出
Dim origPinX As Double, origPinY As Double
Dim origWidth As Double, origHeight As Double

origPinX = vsoShape.Cells(“PinX”).ResultIU
origPinY = vsoShape.Cells(“PinY”).ResultIU
origWidth = vsoShape.Cells(“Width”).ResultIU
origHeight = vsoShape.Cells(“Height”).ResultIU

‘ 3. マスター図形が存在するか判定(ステンシル由来か?)
Dim newShape As Visio.Shape

If vsoShape.Master IsNot Nothing Then
‘ パターンA: マスターがあるなら Drop で高速生成
Set newShape = vsoPage.Drop(vsoShape.Master, origPinX + 1.0, origPinY – 1.0)
Else
‘ パターンB: 通常の図形(四角形などのジオメトリ)なら DrawRectangle や DrawOval などで再現
‘ ※ここではシンプルな矩形としてクローンする例
Set newShape = vsoPage.DrawRectangle( _
origPinX + 1.0 – (origWidth / 2), _
origPinY – 1.0 + (origHeight / 2), _
origPinX + 1.0 + (origWidth / 2), _
origPinY – 1.0 – (origHeight / 2) _
)
End If

‘ 4. 必要であれば、カスタムプロパティや色などのメタデータもここで移植可能
‘ 例: newShape.Cells(“LineColor”).FormulaU = vsoShape.Cells(“LineColor”).FormulaU

MsgBox “クリップボード無しのクローン作成に成功しました!”, vbInformation, “完了”

Finally:
‘ 5. 画面更新の復元を絶対に忘れないこと
vsoApp.ScreenUpdating = True
Exit Sub

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

コードの深掘りとエンジニアの知見

上のコードで、初心者から一歩抜け出すための重要なポイントをいくつか解説しよう。

1. `ScreenUpdating = False` の絶大な効果

Visioは、図形が1つ生成されるたびに、親切(余計)にも画面の再描画と再レイアウト計算を行おうとする。これがマクロを極端に遅くする諸悪の根源だ。
処理の最初に `ScreenUpdating = False` を挟み、最後に `True` に戻す。たったこれだけで、処理速度が何倍にも跳ね上がる。プログラミングの基本中の基本だけど、Visio VBAでは特に生命線になる。

2. `ResultIU` による単位の絶対死守

VisioのShapeSheetには「インチ」「ミリ」「センチ」といった様々な表示単位が存在する。ここで `.Result[文字列]` やそのままの値を使っていると、ユーザーの環境(図面の単位設定)によって図形がバグる。
`ResultIU`(Internal Units)を使うことで、Visio内部の絶対単位である「インチ」で値を取り出すことができる。これにより、環境依存のない強靭なコードが完成するんだ。

3. `Master` オブジェクトの存在確認

「この図形、どこから来たんだっけ?」という疑問に対し、Visioは `Shape.Master` プロパティで答えてくれる。もし図形がステンシルからドロップされたものなら、自前で線を引くよりも `Page.Drop` でマスターをもう一度落とす方が圧倒的に美しく、元の振る舞いを完全に維持できる。

さらに高度な高みへ:複雑なパス(Polyline)の完全複製

もし対象がフリーハンドの線や、頂点が複雑に入り組んだカスタムシェイプだったらどうするか?
その場合は、`Geometry` セクションの行をループで走査し、`DrawPolyline` に渡す座標配列を動的に組み立てるのが王道だ。

‘ 頂点座標の配列を抽出し、DrawPolylineで一気に描画する概念コードの断片
Dim xy() As Double
‘ (ここにShapeSheetのGeometryセクションからX, Y座標をごっそり配列に格納するロジックが入る)
‘ vsoPage.DrawPolyline xy

ここまで極めれば、どんなに複雑な図面であっても、クリップボードのエラーに怯えることなく、秒速で数千個のクローンをバックグラウンド生成できるようになる。

ボクからのエール

どうだい?
「マクロの記録」の向こう側にある、オブジェクトとダイレクトに対話する世界の手触りを感じてもらえたかな。

クリップボードをバイパスするこの技術は、帳票自動生成ツールや、P&ID(プロセス配管図)の自動レイアウトエンジンなど、実務の現場で間違いなくキミを救う武器になる。

ここをクリアしたキミは、もうただの「初心者」じゃない。立派なVisio VBAエンジニアだ。
自信を持って、次の自動化の扉を叩いてほしい。ハッピー・コーディング!

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