【実務・中級編】Document.NameとDocument.FullNameの違いを活用した未保存ドキュメントの安全な検出と自動退避処理 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAの深淵:未保存ドキュメントを「死なせない」ための堅牢な資産防衛術

業務自動化の現場において、最も防ぐべきは「想定外の実行時エラー」によるデータ喪失だ。特にVisioのVBAを開発する際、多くのエンジニアが「ドキュメントの保存状態」を軽視し、無防備なコードを書いては、ユーザーからの「動かない」「データが消えた」という報告に頭を抱えることになる。

今日は、Visioオブジェクトモデルの根幹である`Document.Name`と`Document.FullName`の差異を突き詰め、「未保存ドキュメントを安全に保護する」ための極限の設計を伝授する。

1. なぜ「FullName」のチェックが必要なのか

Visio VBAにおいて、ドキュメントオブジェクトを扱う際に最も注意すべきは、そのドキュメントが「ファイルシステム上のどこに存在するか」という情報だ。

  • `Document.Name`: ドキュメントのタイトル(例: `Drawing1.vsdx`)。これはOS上のファイルパスとは無関係で、Visio内部の管理名に過ぎない。
  • `Document.FullName`: OS上のフルパス(例: `C:\Work\Schema.vsdx`)。

ここが重要だ。
一度も保存されていない新規ドキュメント(Drawing1など)の場合、`FullName`は「ファイル名そのもの」を返す。一方で、一度でも保存されたドキュメントは「パスを含む完全な文字列」を返す。

多くのエンジニアが犯すミスは、`Name`プロパティだけで比較を行い、保存先が未定義のドキュメントに対してファイル操作(保存やパス取得)を強行し、実行時エラーを引き起こすことだ。

2. 安全な自動退避処理の設計思想

堅牢なツールを作るには、以下の「防衛的プログラミング」の原則を守る必要がある。

1. 保存先の分離: 未保存ならユーザーにディレクトリを選択させるか、規定のテンポラリへ強制退避させる。
2. パスの整合性確認: `FullName`の中に、OSが許容しない文字が含まれていないか、あるいは空ではないかを必ず判定する。
3. 例外の局所化: ファイルIOが発生する箇所は、必ずエラーハンドリングで囲む。

3. 実装:プロダクションコード例

以下は、ドキュメントの状態を判定し、未保存であれば自動保存を促す、あるいは安全なディレクトリへ退避させるための実用コードだ。

‘ @description: ドキュメントの保存状態を判定し、未保存の場合は安全に退避する
‘ @author: Chief Architect
Public Sub SafelySaveDocument(doc As Visio.Document)
Dim targetPath As String

‘ エラーハンドリングの開始
On Error GoTo ErrHandler

‘ Name と FullName を比較することで、未保存状態を検知する
‘ 未保存の場合、FullName はパスを含まないファイル名のみを返すことが多い
‘ より厳密には、InStr でパス区切り文字(\)が含まれるかを確認する
If InStr(doc.FullName, “\”) = 0 Then
‘ 未保存ドキュメントと判定
Debug.Print “未保存ドキュメントを検出: ” & doc.Name

‘ ユーザー定義の退避ディレクトリ
targetPath = Environ(“USERPROFILE”) & “\Desktop\VisioBackup_” & Format(Now, “yyyymmdd_hhnnss”) & “.vsdx”

‘ 強制保存処理
doc.SaveAsEx targetPath, visSaveAsWS
Debug.Print “自動退避が完了しました: ” & targetPath
Else
‘ 既存ファイルは上書き保存(必要に応じてバックアップロジックを追加)
doc.Save
Debug.Print “既存ドキュメントを保存しました: ” & doc.FullName
End If

Exit Sub

ErrHandler:
MsgBox “ドキュメントの保存に失敗しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “システムエラー”
End Sub

4. プロの現場で生き残るための「鉄則」

1. 「なぜか動かない」を排除する

`doc.FullName`を判定する際、ネットワークドライブ上のドキュメントや、OneDrive上の同期中ファイルは、タイミングによってパスの解決が遅れることがある。上記コードのように`InStr`でパス区切り文字を探す手法は、OSのAPIよりも直感的で、かつ軽量だ。

2. データベース連携時の落とし穴

もしVisioをDBのフロントエンドとして使うなら、`Document.FullName`をレコードのキーにしてはならない。ドキュメントの名前変更や移動で整合性が崩れるからだ。必ず`Document.ID`(存在すれば)や、ドキュメントの`CustomProperty`(ドキュメント情報)にGUIDを埋め込む設計にせよ。

3. 保守性を高めるためのアーキテクチャ

このロジックをモジュール内に散らばらせてはいけない。「DocumentManager」クラスのようなラッパーを作り、そこにこの判定ロジックをカプセル化するのだ。そうすれば、将来的に「特定のフォルダに自動バックアップする」という要件が増えた際も、修正は1箇所で済む。

最後に:エンジニアとしての矜持

コードは書くことよりも、「書いた後の崩壊」を防ぐことの方が遥かに難しい。
今回紹介した`FullName`の活用は、Visioオートメーションにおける「最初の関門」に過ぎないが、ここを疎かにするエンジニアは、いつか必ず致命的なデータ消失を招く。

「動くコード」ではなく、「壊れない設計」を目指せ。それが、君が現場で頼られる自動化アーキテクトになるための最短ルートだ。

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