こんにちは、若きエンジニアの皆さん。Visio VBAの世界へようこそ。
マクロの記録を卒業し、自分の手でコードを書き始めたあなたは、今まさに「Visioを真に操る」ための入り口に立っています。
今日は、プロの現場でも意外と知られていない、しかし習得すれば「Visio VBAの魔術師」へと一気に駆け上がれる特別なテクニックを伝授しましょう。
テーマは、ShapeSheetの「Scratch Section(スクラッチ・セクション)」をVBAから動的に操る方法です。
「計算用の作業場所」をスマートに作り、使い倒し、そして美しく去る。この一連の作法をマスターすれば、あなたのプログラムは格段にスマートで堅牢なものになりますよ。
—
1. なぜ「Scratch Section」が必要なのか?
Visioの図形(Shape)の裏側には、ShapeSheetというExcelのような表が隠れています。図形の幅、高さ、色、さらには複雑な幾何学計算まで、すべてはこのシートの数式で決まります。
通常、VBAで複雑な計算(例:複数の図形との距離計算や、特定の角度に基づく座標算出)を行うとき、多くの人はVBAの変数だけで完結させようとします。しかし、それには2つの問題があります。
1. 再計算の同期: 図形が動いたとき、VBAを再度動かさないと計算結果が更新されない。
2. 管理の煩雑さ: 複雑な数式をVBA内で文字列としてこねくり回すと、コードの可読性が落ちる。
ここで登場するのがScratch Sectionです。ここは、図形の中に一時的に作れる「計算用ホワイトボード」のような場所。
VBAからこのホワイトボードに数式を書き込み、計算はVisio本体(ShapeSheetエンジン)に任せ、結果だけを受け取る。使い終わったら消す。
これが、図形を汚さずに高度な処理を行うプロの流儀です。
—
2. 実践:Scratch Sectionを動的に操るフロー
それでは、具体的なコードの流れを見ていきましょう。
以下の3ステップを意識してください。
1. セクションの存在確認と作成: 必要に応じてScratchセクションを追加する。
2. 行の追加と数式の注入: 計算用の行を作り、数式(Formula)をセットする。
3. 計算結果の取得と後片付け: 結果を読み取り、不要になったら行を削除する。
【サンプルコード】動的に計算用セルを作成して距離を求める
このコードは、選択した図形に一時的な計算行を追加し、特定の計算(ここでは例として幅と高さの対角線の長さを計算)を行わせるものです。
Public Sub SmartScratchCalculation()
Dim vsoShape As Visio.Shape
Dim rowIdx As Integer
Dim diagonalLength As Double
‘ 1. 対象の図形を取得(現在選択している最初の図形)
If ActiveWindow.Selection.Count = 0 Then
MsgBox “図形を選択してください。”
Exit Sub
End If
Set vsoShape = ActiveWindow.Selection(1)
‘ — ここからが魔法の始まりです —
‘ 2. Scratchセクションがあるか確認し、なければ作成する
‘ visSectionScratch = 5
If Not vsoShape.SectionExists(visSectionScratch, visExistsAnywhere) Then
vsoShape.AddSection visSectionScratch
End If
‘ 3. 新しい行を追加する
‘ AddRowの戻り値は追加された行のインデックスです
rowIdx = vsoShape.AddRow(visSectionScratch, visRowLast, visTagDefault)
‘ 4. Scratchセルに数式を書き込む
‘ ここでは「幅^2 + 高さ^2 の平方根(=対角線)」を求める数式をセット
‘ CellsSRC(セクション, 行, 列) を使うのがプロの書き方です
vsoShape.CellsSRC(visSectionScratch, rowIdx, visScratchX).FormulaU = “SQRT(Width^2 + Height^2)”
‘ 5. 計算結果をVBA側で受け取る
‘ Resultは数式が評価された後の「値」を返します
diagonalLength = vsoShape.CellsSRC(visSectionScratch, rowIdx, visScratchX).Result(visInches)
‘ 結果を表示
MsgBox “この図形の対角線の長さは: ” & diagonalLength & ” インチです。”
‘ 6. 【重要】後片付け:使い終わった行を削除して図形を綺麗に保つ
‘ これを忘れると、実行するたびに行が増えてしまいます
vsoShape.DeleteRow visSectionScratch, rowIdx
‘ もしセクションが空になったら、セクション自体も消すとより美しい
If vsoShape.RowCount(visSectionScratch) = 0 Then
vsoShape.DeleteSection visSectionScratch
End If
Debug.Print “計算完了。図形はクリーンな状態です。”
End Sub
—
3. ここがポイント!解説と注意点
なぜ `CellsSRC` を使うのか?
初心者の方は `vsoShape.Cells(“Scratch.X1”)` と名前で指定したくなりますが、動的に行を増減させる場合、名前による指定は不安定になりがちです。
`CellsSRC(Section, Row, Column)` は、数値(インデックス)で直接場所を叩くため、高速でミスが起きにくい、エンジニアにとっての「黄金律」です。
陥りやすいエラー:インデックスの管理
`AddRow` で返ってくるインデックスを必ず変数(上記の `rowIdx`)に格納してください。「1行目だから 0 だろう」と決め打ちするのは危険です。既存のScratch行がある場合、新しい行の番号は変わるからです。
パフォーマンスの重み
VBAから図形の `Cells` にアクセスするのは、実は少しコスト(処理時間)がかかる動作です。
大量の図形に対してこの処理を行う場合は、一図形ごとにセクションを作って消すよりも、「計算が必要な間だけ行を作り、最後に一気に消す」という設計にすると、目に見えて動作が軽くなります。
—
4. 応用へのステップ
今回は簡単な対角線の計算でしたが、Scratch Sectionの真価は「一時的な参照」にあります。
- ある図形が別の図形に重なっているか?
- 接続されているコネクタの合計の長さは?
- 親シェイプのサイズに合わせた複雑な比率計算
これらをVBAのコード内で `If` や `For` を駆使して書く代わりに、ShapeSheetの数式としてScratchに放り込むのです。Visioの強力な計算エンジンを「外部計算機」として利用する贅沢な手法、それがこのScratch活用術です。
—
最後に:Visio VBAを学ぶあなたへ
マクロの記録で生成されるコードは、いわば「足跡」です。しかし、あなたが今学んでいるのは「歩き方」そのものです。
Scratch Sectionを自在に操れるようになれば、図形の中に「一時的な思考領域」を持たせることができるようになります。これは、単なる自動化を超えて、「賢い図形」を動的に生成していることに他なりません。
「ここをクリアすれば、Visio VBAの基本はバッチリですよ」。
自信を持って、次のコードを書いてみてください。あなたの描く図形が、もっと自由に、もっとスマートに動き出すはずです。
応援しています!
