【入門編】Shape.SetFormulasUを活用した複数幾何図形への動的計算式一括注入とパラメータ連動 – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visioの裏側に広がる無限の自動化ワールドへようこそ。
マクロの記録ボタンを押して生成されたコードを眺め、「なんだか同じような行がダラダラと続いているな…」「もっとスマートに書けないものか」と感じていませんか?

今回は、Visio VBAの真骨頂とも言える「Shape.SetFormulasUを用いた複数幾何図形への数式一括注入とパラメータ連動」について解説します。

ここをクリアすれば、単なる「操作の自動化」から脱却し、「生きた図面(パラメータ駆動型図面)」を構築できるようになります。基礎から本質まで、優しく、そしてディープに紐解いていきましょう!

1. なぜ「Formula」をコードで操る必要があるのか?

Visioの図形(Shape)は、ただの絵ではありません。内部に「ShapeSheet(シェイプシート)」という強力な表計算データベースを持っています。

例えば、「親シェイプの幅が変わったら、子シェイプもそれに追従して縦横比を維持しながら大きくなる」という要件を考えてみましょう。これを手動でやったり、一つずつVBAで`.CellsU(“Width”).FormulaU = …`と代入したりするのは、プログラミングの世界では「アンチパターン(ご法度)」です。

なぜなら、Visioのオブジェクトモデルにおいて、個別のセルにアクセスするたびに画面の再描画やイベントが発生し、パフォーマンスが著しく低下するからです。

そこで登場するのが、今回マスターする `SetFormulasU` です。これを使えば、一撃で複数の数式を配列としてシェイプに流し込むことができます。爆速かつスマート、これぞプロの技です。

2. 基礎知識:Shape.SetFormulasU の正体

まずは、このメソッドの仕様をサラッと頭に入れておきましょう。

object.SetFormulasU(StreamNameArray, FormulaArray, Flags)

  • StreamNameArray: どのセルの数式を変更するか(例: `Width`, `Height`, `PinX`)の配列。
  • FormulaArray: 設定したい数式(文字列)の配列。「`=Width0.5`」のように、Universal名(英語表記・大文字)で指定するのが鉄則です。
  • Flags: 動作フラグ。通常は `visSetFormulasNull`(0)を指定します。

数式を「値」ではなく「数式(Formula)」として流し込むため、一度設定してしまあとは、Visioのエンジンが勝手にパラメータの変更を監視し、自動で計算・再描画してくれます。

3. 実践!親シェイプに子シェイプが連動する動的パラメータ注入コード

百聞は一見にしかず。今回は、「親となるマスターボックスのサイズ変更に追従し、内部の複数のパーツ(子シェイプ)が自動計算でレイアウトされる」という実用的なスクリプトを書いてみましょう。

以下のコードを、VisioのVBAエディタ(`Alt + F11`)の標準モジュールに貼り付けて実行してみてください。

Sub CreateParametricLayout()
Dim vsoPage As Visio.Page
Set vsoPage = ActivePage

‘ 1. 親シェイプ(コンテナとなる長方形)をドロップ
Dim vsoParentShape As Visio.Shape
Set vsoParentShape = vsoPage.Drop(vsoPage.Application.Document(1).Masters.ItemU(“Rectangle”), 4, 5)

‘ 親シェイプの初期サイズと名前を設定
vsoParentShape.Text = “親パラメータ制御Box”
vsoParentShape.CellsU(“Width”).FormulaU = “6in”
vsoParentShape.CellsU(“Height”).FormulaU = “4in”

‘ 2. 子シェイプ(連動するパーツ)を2つドロップ
Dim vsoChild1 As Visio.Shape, vsoChild2 As Visio.Shape
Set vsoChild1 = vsoPage.Drop(vsoPage.Application.Document(1).Masters.ItemU(“Rectangle”), 2, 3)
Set vsoChild2 = vsoPage.Drop(vsoPage.Application.Document(1).Masters.ItemU(“Rectangle”), 6, 3)

vsoChild1.Text = “子パーツ A”
vsoChild2.Text = “子パーツ B”

‘ 3. 【核心】SetFormulasU を使った複数数式の一括注入(子パーツA)
‘ 配列のインデックスは 0 から始まります
Dim srcNames1(2) As String
Dim srcFormulas1(2) As String

srcNames1(0) = “Width”
srcFormulas1(0) = “Sheet.” & vsoParentShape.ID & “!Width0.4” ‘ 親のWidthの40%

srcNames1(1) = “Height”
srcFormulas1(1) = “Sheet.” & vsoParentShape.ID & “!Height0.8” ‘ 親のHeightの80%

srcNames1(2) = “PinX”
srcFormulas1(2) = “Sheet.” & vsoParentShape.ID & “!PinX-1” ‘ 親の中心から左へオフセット

‘ 一括適用!
vsoChild1.SetFormulasU srcNames1, srcFormulas1, visSetFormulasNull

‘ 4. 子パーツBにも同様に数式を一括注入
Dim srcNames2(1) As String
Dim srcFormulas2(1) As String

srcNames2(0) = “Width”
srcFormulas2(0) = “Sheet.” & vsoParentShape.ID & “!Width0.4”

srcNames2(1) = “Height”
srcFormulas2(1) = “Sheet.” & vsoParentShape.ID & “!Height0.8”

vsoChild2.SetFormulasU srcNames2, srcFormulas2, visSetFormulasNull

‘ 完了メッセージ
MsgBox “パラメータ連動図形の構築が完了しました!親シェイプのサイズを変更してみてください。”, vbInformation
End Sub

このコードのヤバい(すごい)ポイント

  • `Sheet.ID` を使った動的リンク: どのシェイプと連動するかをIDベースで指定しているため、シェイプの生成順序が変わっても意図した数式が正確に結ばれます。
  • 一括処理の美しさ: `SetFormulasU` に配列を渡すことで、Visio内部の計算エンジンへの負荷を最小限に抑え、一瞬でパラメータの紐付けが完了します。

4. 陥りやすい罠とエラー回避の知見

現場でこの手法を使う際、初学者が必ずと言っていいほどハマる「落とし穴」がいくつかあります。先輩からのアドバイスとして心に留めておいてください。

罠①: ローカル言語の数式を入れてしまう

`CellsU` や `SetFormulasU` の末尾にある `U` は 「Universal(ユニバーサル)」 の略です。
Excel関数で言うところの英語関数名(`SUM` など)を使うのと同じで、Visioでも `Width` や `Height` といった英語のセルのローカル名を使わなければなりません。「幅」などと日本語で書くと、英語環境のPCや別バージョンのVisioで盛大にエラーを吐きます。数式は必ず英語(Universal名)で書きましょう。

罠②: 配列の次元数とインデックスのミスマッチ

VBAで配列を `Dim arr(2) As String` と宣言すると、`0, 1, 2` の合計 3つの要素 を持つことになります。
「2つのプロパティを設定したいから `Dim arr(2)` にしよう」とやると、要素数が合わずに `Type mismatch` や範囲外エラーが発生します。配列の要素数は扱うセルの数と厳密に一致させてください。

5. おわりに:ここをクリアすれば、あなたはもう中級者

お疲れ様でした!今回は `Shape.SetFormulasU` を用いた複数幾何図形への動的パラメータ連動について解説しました。

「画面上の図形をマウスでポチポチ動かすだけの自動化」から、「数式とオブジェクトの寿命(ライフサイクル)をコードで完全統制する自動化」へ。この視点を持てば、複雑なダイアグラム生成、ネットワーク図の自動レイアウト、プラント設計のCAD的なアプローチなど、あなたのVisio VBAスキルは圧倒的な領域に到達します。

ぜひ実際の業務や制作物で試してみてください。「ここをもっとこうしたい!」という疑問があれば、いつでもまた扉を叩いてくださいね。エンジニアとしての健闘を祈ります!

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