Visio VBAの深淵:読み取り専用オープンと排他制御の「鉄則」
現場でVisioの自動化を任されたエンジニアが最初にぶつかる壁、それが「ファイルロック」だ。他者が編集中でも情報を吸い上げたい、しかし処理結果は別名で保存して安全に配布したい。この要件を甘く見ると、現場では「実行時エラー1004:ファイルにアクセスできません」という呪いのメッセージが飛び交うことになる。
今日は、中級者から一歩抜け出し、堅牢なプロダクションコードを書くための「排他制御の作法」を伝授する。
—
1. なぜ「そのまま」開くのが危険なのか
`Documents.Open` を何も考えずに実行するコードは、プロの現場では「バグの温床」だ。
Visioファイル(VSDX)は裏側でZIP構造を持つXMLの塊であり、開く際には一時ファイル(`~$`で始まるロックファイル)が生成される。このプロセスの裏側を理解せず、無邪気にファイルを操作すれば、メモリリークやGhostプロセスの温床となる。
堅牢な設計の要諦
1. Read-Onlyによる強制的な読み込み: `visOpenRO` モードを明示せよ。
2. イベントの抑止: `Application.ScreenUpdating` や `EventEnabled` を切ることで、意図しない再計算や再描画によるクラッシュを防ぐ。
3. 保存先の分離: 読み取り元と保存先を論理的に切り離す。
—
2. 実装:堅牢なデータ抽出&別名保存テンプレート
このコードは、読み取り専用で開き、必要な情報を抽出した後、別のディレクトリへ安全に書き出すための「雛形」だ。
Option Explicit
”’
”’
Public Sub ProcessVisioDocument(ByVal sourcePath As String, ByVal destPath As String)
Dim vsoApp As Visio.Application
Dim vsoDoc As Visio.Document
‘ 1. アプリケーション設定の退避(パフォーマンスと安定性)
Dim oldScreenUpdating As Boolean
oldScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
‘ 2. Read-Onlyで開く(visOpenRO = 1)
‘ 他者が編集中でも排他ロックを回避して読み込む
Set vsoDoc = Application.Documents.OpenEx(sourcePath, Visio.VisOpenSaveArgs.visOpenRO)
‘ — ここに抽出ロジックを記述 —
Debug.Print “Processing: ” & vsoDoc.Name
‘ —————————-
‘ 3. 別名で保存(上書き保存ではなく、新規保存とする)
‘ ファイルが既に存在する場合の整合性を考慮
vsoDoc.SaveAsEx destPath, Visio.VisSaveAsArgs.visSaveAsRelative
GoTo Cleanup
ErrorHandler:
MsgBox “致命的なエラー: ” & Err.Description, vbCritical
Cleanup:
‘ 4. 必ずリソースを解放する
If Not vsoDoc Is Nothing Then
vsoDoc.Close
Set vsoDoc = Nothing
End If
Application.ScreenUpdating = oldScreenUpdating
End Sub
—
3. 現場で「死なない」ためのアーキテクチャ・アドバイス
① パス解析の厳密化
`destPath` に指定する文字列が正しいか、ディレクトリが存在するかを事前に `Scripting.FileSystemObject` でチェックしろ。VBAはパスの不備に対して非常に無頓着だが、OSは冷酷だ。
② ファイルロックの「回避」と「待機」
もし読み取り専用で開けない場合(排他的なロックがかかっている場合)、`Err.Number` を拾って `Sleep` 関数で数秒待機し、再試行するループを実装するのがプロの流儀だ。単純なエラー終了は、多忙な現場では「不親切なツール」の烙印を押される。
③ データベース連携の注意点
抽出したデータをDB(SQL ServerやAccess)に投げる場合、「Visioを開いている時間」を極限まで短くせよ。
Visioのオブジェクトモデルをループで回すのは遅い。一度 `Document.Pages` や `Shapes` から必要な属性(ShapeID, Text, Custom Property)を配列やコレクションに格納し、Visioを閉じてからDB処理を行うのが「高パフォーマンス設計」の基本だ。
—
最後に:エンジニアとしての矜持
Visio VBAは、古臭い言語と見なされることもある。だが、高度な自動化を実装しようとすれば、それは立派な「システム統合」だ。
「とりあえず動く」コードではなく、「誰がどのタイミングで実行しても、環境を汚さず、安全に終了する」コードを書くこと。それができるかどうかが、ただの作業者と、信頼される自動化エンジニアの境界線である。
さあ、このコードをベースに、君の現場の「非効率」を根絶やしにしてくれ。健闘を祈る。
