【入門編】文書メタデータの双方向同期:BuiltInDocumentPropertiesとCustomDocumentProperties – Visio VBA解析バイブル

スポンサーリンク

こんにちは! Visio VBAの世界へようこそ。
マクロの記録ボタンを押すだけの自動化から一歩抜け出し、「自分の手でVisioを自在にコントロールしたい」と願うあなたへ。

今回は、実務でめちゃくちゃ重宝する「文書メタデータの双方向同期」をテーマに解説していきます。
図面枠(タイトルブロック)に書かれている「図面番号」や「作成者」といったテキストと、VisioのファイルプロパティをVBAでガッチリ連動させるテクニックです。

ここをクリアすれば、Visio VBAのオブジェクトモデルの基礎はバッチリですよ!
一緒に、ワンランク上のエンジニアへの階段を登っていきましょう。

なぜ「メタデータ同期」が必要なのか?

実務でこんな面倒な作業をしたことはありませんか?

  • 図面を修正するたびに、図面枠の「改訂日」や「バージョン」をテキストボックスで手打ちで直している。
  • ファイルプロパティの「タイトル」や「会社名」にも同じような情報を入力しているのに、二重管理になっていて不整合が起きる。

これ、VBAで完全自動化できます。

Visioのファイルには、最初から用意されている「標準プロパティ(`BuiltInDocumentProperties`)」と、自分で自由に追加できる「カスタムプロパティ(`CustomDocumentProperties`)」が存在します。

これらと、ページ上の図形(Shape)のテキストをVBAで双方向(行きも帰りも)に同期させることで、「図面枠を書き換えればファイルプロパティも更新される」「プロパティを書き換えれば図面枠がパッと変わる」という、プロ仕様のスマートな図面管理システムが構築できるのです。

Visioオブジェクトモデルの基本と全体像

まずは、Visio VBAの階層構造(オブジェクトモデル)を頭に叩き込みましょう。Visioの世界は、ロシアの民芸品「マトリョーシカ」のように、大きな箱の中に小さな箱が入っています。

Application (Visioアプリ全体)
┗ Document (開いているファイル)
┣ BuiltInDocumentProperties / CustomDocumentProperties (メタデータ)
┗ Page (図面のページ)
┗ Shape (図面枠や個々の図形)

今回のミッションは、Document(メタデータ)とShape(図面枠の文字)の橋渡しをすることです。

実践コード:図面プロパティと図形テキストの同期マクロ

それでは、開発の現場でそのままコピペして使える実用的なコードをお見せします。
今回は、カスタムプロパティである「DRAWING_NO(図面番号)」を例にして、「図形からプロパティへ反映する方向」「プロパティから図形へ反映する方向」の両方を実装します。

VisioのVBE(Alt + F11)を開き、標準モジュールに以下のコードを貼り付けてください。

Option Explicit

‘ ==============================================================================
‘ テーマ: 文書メタデータの双方向同期
‘ 概要 : 図面枠のテキストとカスタム文書プロパティを同期させる
‘ ==============================================================================

‘ 【方向①】図形(図面枠)のテキストを、カスタム文書プロパティに書き込む
Sub SyncShapeToProperty()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim customProps As Visio.DocumentProperties
Dim propName As String
Dim targetText As String

‘ 設定値の定義
propName = “DrawingNumber” ‘ カスタムプロパティの名前
Set vsoPage = ActivePage

On Error GoTo ErrorHandler

‘ 1. 対象となる図形を取得(ここでは分かりやすく “TitleBox” という名前の図形を想定)
‘ ※実際の現場では、シェイプシートの特定セルやMasterIDで判定することもあります
Set vsoShape = vsoPage.Shapes(“TitleBox”)
targetText = Trim(vsoShape.Text)

‘ 2. ドキュメントのカスタムプロパティコレクションを取得
Set customProps = ActiveDocument.CustomDocumentProperties

‘ 3. プロパティが存在するかチェックし、なければ新規追加、あれば更新
If PropertyExists(customProps, propName) Then
customProps(propName).Value = targetText
MsgBox “プロパティを更新しました: ” & targetText, vbInformation, “同期完了”
Else
‘ 文字列型(visPropertyTypeString = 1)としてプロパティを追加
customProps.Add propName, visPropertyTypeString, False, targetText
MsgBox “カスタムプロパティを新規作成し、同期しました: ” & targetText, vbInformation, “作成&同期完了”
End If

Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “同期エラー”
End Sub

‘ 【方向②】カスタム文書プロパティの値を、図形(図面枠)のテキストに反映する
Sub SyncPropertyToShape()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim customProps As Visio.DocumentProperties
Dim propName As String
Dim propValue As String

propName = “DrawingNumber”
Set vsoPage = ActivePage

On Error GoTo ErrorHandler

‘ 1. カスタムプロパティが存在するか確認
Set customProps = ActiveDocument.CustomDocumentProperties
If Not PropertyExists(customProps, propName) Then
MsgBox “同期対象のカスタムプロパティ ‘” & propName & “‘ が存在しません。”, vbExclamation, “エラー”
Exit Sub
End If

‘ プロパティの値を取得
propValue = CStr(customProps(propName).Value)

‘ 2. 図形(図面枠)のテキストに代入
Set vsoShape = vsoPage.Shapes(“TitleBox”)
vsoShape.Text = propValue

MsgBox “図形テキストをプロパティの値に更新しました: ” & propValue, vbInformation, “同期完了”
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “同期エラー”
End Sub

‘ 【ヘルパー関数】指定したプロパティ名が存在するか判定する
Function PropertyExists(props As Visio.DocumentProperties, name As String) As Boolean
Dim prop As Visio.DocumentProperty
PropertyExists = False

For Each prop in props
If StrComp(prop.Name, name, vbTextCompare) = 0 Then
PropertyExists = True
Exit For
End If
Next prop
End Function

コードのポイントと、初心者がハマりやすい罠

このコードには、実務で必ず直面する「落とし穴」を防ぐための知見が詰まっています。いくつか重要なポイントを解説します。

1. プロパティが「無い」場合のハンドリング

`CustomDocumentProperties` は、最初から目当てのプロパティが入っているとは限りません。存在しないプロパティの `.Value` を読み書きしようとすると、容赦なく実行時エラー(エラー45Dなど)が発生します。
そのため、上記のコードでは `PropertyExists` というヘルパー関数を挟み、「なければ新規作成する、あれば更新する」という安全な設計(イデポテントな設計)にしています。

2. `.Text` の操作における注意点

Visioの図形に `.Text = “hoge”` と代入するとき、その図形がテキスト編集モードに入っていたり、保護(Protection)がかかっていたりするとエラーになります。
実務で図面枠を扱う際は、あらかじめ図形のシェイプシートでテキスト編集が許可されているか、あるいは図形名(`Shapes(“TitleBox”)` 部分)が正しくついているかを確認することが鉄則です。

現場で役立つ発展的アドバイス

ここから先は、チーフアーキテクトからのさらなるエールです。

実際の現場では、ボタンをポチポチ押して同期させるだけでなく、「ドキュメントを保存する瞬間(`DocumentBeforeSave` イベント)」などに、この同期処理をバックグラウンドで走らせるのが究極の姿です。
「保存したんだから、プロパティと図面枠の文字のズレはシステムが勝手に直してくれている」という状態を作れヒューマンエラーはゼロになります。

Visio VBAは、オブジェクトの寿命やイベントのフックなど、少しクセはありますが、マスターすればあなたの仕事のスピードを何倍にも跳ね上げてくれる最強の相棒になります。

「ここをクリアすれば、Visio VBAの基本はバッチリですよ!」
ぜひ今回のコードをご自身の環境で試して、自動化の爽快感を味わってみてください。それでは、次の自動化の旅でお会いしましょう!

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