Visio VBAの極意:ShapeSheetセルへの高速アクセスをマスターする!
「マクロの記録」から一歩踏み出し、Visio VBAの世界をもっと深く、もっと速く使いこなしたい皆さん、こんにちは!世界最高峰の業務自動化エンジニア、そしてVisio VBAとAPI仕様の熟知したチーフアーキテクトとして、今日は皆さんのVisio VBAスキルを劇的に向上させる「極意」をお伝えします。
特に、大量のシェイプのプロパティを高速に設定したい、そんな悩みを抱えている方はいませんか?ご安心ください。この記事を読み終える頃には、皆さんはVisio VBAのオブジェクトモデルの核心に触れ、ShapeSheetセルへのアクセス方法を劇的に改善する「高速インデックスアクセス」のマスターになっているはずです。
1. なぜShapeSheetセルへのアクセス速度が重要なのか?
Visio VBAでシェイプを操作する際、その見た目や振る舞いを決定づけるのがShapeSheetです。ShapeSheetは、Excelのシートに似た構造を持ち、セクション、行、列で構成され、各セルにプロパティ値が格納されています。
例えば、シェイプの幅を100mmに設定したい場合、ShapeSheetの「Shape Transform」セクションにある「Width」セルを操作することになります。
一般的に、ShapeSheetセルにアクセスするには、`Shape.CellsU(“CellName”)` のように、セルの名前(文字列)を指定する方法がよく使われます。これは直感的で分かりやすいのですが、大量のシェイプに対してこの方法を繰り返すと、Visioが毎回セルの名前を検索する必要があり、処理に時間がかかってしまうのです。
想像してみてください。1000個のシェイプの幅をすべて100mmに設定するのに、毎回「Width」という文字列を検索していたら、かなりの時間をロスしてしまいますよね。
2. 隠された秘密兵器:CellsRowIndex と CellsColumnIndex
そこで登場するのが、今日の主役、「Shape.CellsRowIndex」と「Shape.CellsColumnIndex」です。これらは、ShapeSheetのセクション、行、列を数値インデックスで直接指定するための強力なメソッドです。
文字列検索のオーバーヘッドをなくし、数値で直接指定することで、処理速度を劇的に向上させることができます。これは、まるで巨大な図書館で本を探すときに、本のタイトル(文字列)で探すのではなく、棚番号(数値インデックス)で直接指定するようなものです。圧倒的なスピードの違いがありますよね!
3. ShapeSheetの構造を理解する:セクション、行、列
CellsRowIndexとCellsColumnIndexを効果的に使うためには、ShapeSheetの構造を理解することが不可欠です。
- セクション (Section): 同じ種類のプロパティをまとめたものです。「Shape Transform」(シェイプの変形)、「Geometry」(ジオメトリ)、「Protection」(保護)などが代表的です。
- 行 (Row): セクション内の個々の項目です。例えば、「Shape Transform」セクションには、「Width」、「Height」、「Angle」といった行があります。
- 列 (Column): 行の各プロパティの要素です。例えば、「Width」行には、数値(値)、単位(Unit)、式(Formula)といった列があります。
| セクション | 行 | 列 |
| :—————– | :——- | :——- |
| Shape Transform | Width | Value |
| | | Unit |
| | | Formula |
| | Height | Value |
| | | Unit |
| | | Formula |
| | Angle | Value |
| | | Unit |
| | | Formula |
4. CellsRowIndex と CellsColumnIndex の使い方
これらのメソッドは、`CellsSRC(SectionType, RowType, ColumnType)`という形で使われます。
- `SectionType`: セクションの種類を表す定数(例: `visSectionObject`、`visSectionTransform`)。
- `RowType`: 行の種類を表す定数(例: `visRowXFormName`、`visRowWidth`)。
- `ColumnType`: 列の種類を表す定数(例: `visColumnWidth`、`visColumnHeight`)。
これらの定数は、VBAエディタのオブジェクトブラウザ(F2キー)で「Visio Type Library」を展開すると確認できます。
例:シェイプの幅を取得する
Sub GetShapeWidthByIndex()
Dim shp As Visio.Shape
Dim pg As Visio.Page
Dim doc As Visio.Document
Dim widthCell As Visio.Cell
Dim width As Double
‘ 現在アクティブなドキュメントとページを取得
Set doc = Visio.ActiveDocument
Set pg = doc.ActivePage
‘ 例として、ページ上の最初のシェイプを取得
‘ 実際には、操作したいシェイプを適切に取得してください
If pg.Shapes.Count > 0 Then
Set shp = pg.Shapes(1)
‘ CellsSRC を使用して Width セルにアクセス
‘ visSectionTransform (セクション: Shape Transform)
‘ visRowXFormName (行: XForm.Name) – これはWidth, Height, Angleなどを含む行のタイプ
‘ visColumnWidth (列: Width)
Set widthCell = shp.CellsSRC(visSectionObject, visRowXFormName, visColumnWidth)
‘ セルの値を取得
width = widthCell.ResultIU ‘ ResultIU はインチ単位で値を取得します
MsgBox “シェイプの幅 (インチ): ” & width
Else
MsgBox “ページにシェイプがありません。”
End If
‘ オブジェクトの解放
Set widthCell = Nothing
Set shp = Nothing
Set pg = Nothing
Set doc = Nothing
End Sub
例:シェイプの幅を設定する (CellsU と CellsSRC の比較)
まずは、おなじみの`CellsU`を使った場合です。
Sub SetShapeWidth_CellsU()
Dim shp As Visio.Shape
Dim pg As Visio.Page
Dim doc As Visio.Document
Dim startTime As Double
Dim endTime As Double
Dim i As Long
‘ 現在アクティブなドキュメントとページを取得
Set doc = Visio.ActiveDocument
Set pg = doc.ActivePage
‘ 例として、100個のダミーシェイプを作成
For i = 1 To 100
Set shp = pg.DrawRectangle(1, 1, 2, 2) ‘ 適当な位置に描画
‘ CellsU を使用して幅を設定
shp.CellsU(“Width”).Formula = “2 in” ‘ 2インチに設定
Set shp = Nothing ‘ 次のシェイプのために解放
Next i
MsgBox “CellsU で100個のシェイプの幅を設定しました。”
Set pg = Nothing
Set doc = Nothing
End Sub
次に、`CellsSRC`を使って高速化した場合です。
Sub SetShapeWidth_CellsSRC()
Dim shp As Visio.Shape
Dim pg As Visio.Page
Dim doc As Visio.Document
Dim widthCell As Visio.Cell
Dim i As Long
‘ 現在アクティブなドキュメントとページを取得
Set doc = Visio.ActiveDocument
Set pg = doc.ActivePage
‘ 画面更新を一時停止して、さらに高速化
Visio.Application.ScreenUpdating = False
Visio.Application.ActiveWindow.Page.PageSheet.CellsSRC(visSectionPageLayout, visRowPageLayout, visColumnPageScale).ResultIU = 1 ‘ 必要に応じてページスケールなども調整
‘ 例として、100個のダミーシェイプを作成
For i = 1 To 100
Set shp = pg.DrawRectangle(1, 1, 2, 2) ‘ 適当な位置に描画
‘ CellsSRC を使用して Width セルにアクセス
‘ visSectionObject (セクション: Shape Transform)
‘ visRowXFormName (行: XForm.Name)
‘ visColumnWidth (列: Width)
Set widthCell = shp.CellsSRC(visSectionObject, visRowXFormName, visColumnWidth)
‘ セルの値を設定 (インチ単位で「2 in」を設定)
widthCell.Formula = “2 in”
Set widthCell = Nothing ‘ 次のシェイプのために解放
Set shp = Nothing ‘ 次のシェイプのために解放
Next i
‘ 画面更新を再開
Visio.Application.ScreenUpdating = True
MsgBox “CellsSRC で100個のシェイプの幅を設定しました。”
Set pg = Nothing
Set doc = Nothing
End Sub
5. 処理速度の比較と注意点
実際に、大量のシェイプ(例えば1000個や10000個)に対して`CellsU`と`CellsSRC`で同じ処理を行った場合、`CellsSRC`の方が数倍から数十倍速く処理が完了するはずです。この差は、シェイプの数が増えれば増えるほど顕著になります。
注意点
- 定数の把握: `CellsSRC`を使うには、セクション、行、列の定数を把握する必要があります。最初は少し戸惑うかもしれませんが、よく使うものは覚えるか、オブジェクトブラウザで確認しながら進めましょう。
- コードの可読性: `CellsSRC`は、`CellsU`に比べてコードが少し読みにくくなる場合があります。コードのコメントをしっかり書くなど、可読性を意識することが大切です。
- パフォーマンスのトレードオフ: ほんの数個のシェイプを操作するだけであれば、`CellsU`でも十分です。しかし、大量のシェイプを繰り返し操作するような場面では、`CellsSRC`のメリットは絶大です。
6. 実際の開発現場での応用例
この`CellsSRC`を活用した高速アクセス手法は、以下のような場面で非常に役立ちます。
- 図面自動生成: 大量の図形を生成し、それぞれの位置、サイズ、色などを一括で設定する場合。
- データ連携: データベースやExcelから読み込んだデータに基づいて、Visio図面のプロパティを更新する場合。
- 複雑な図形の編集: ジオメトリ情報などを数値で直接操作し、精密な形状変更を行う場合。
- パフォーマンスが求められるアドイン開発: ユーザーにストレスを与えない、サクサク動くアドインを作成する場合。
まとめ:ここをクリアすれば、Visio VBAの基本はバッチリ!
いかがでしたでしょうか?今日は、Visio VBAでShapeSheetセルに高速にアクセスするための「極意」、`CellsRowIndex`と`CellsColumnIndex`の活用法について解説しました。
`CellsU`の分かりやすさも重要ですが、パフォーマンスが求められる場面では、`CellsSRC`を使いこなすことが、Visio VBAマスターへの確実な一歩となります。最初は少し難しく感じるかもしれませんが、このテクニックを習得すれば、皆さんのVisio VBA開発の可能性は大きく広がります。
ぜひ、この記事で紹介したコード例を参考に、ご自身のプロジェクトで試してみてください。そして、この知識を武器に、あなたのVisio VBAスキルを次のレベルへと引き上げてくださいね!
もし、「こんな場面でも使えるの?」といった疑問や、「もっと詳しく知りたい!」というリクエストがあれば、ぜひコメントで教えてください。皆さんのVisio VBAライフを、これからも全力でサポートしていきます!
