Visio VBAの深淵:全ドキュメント一括PDF変換を「事故ゼロ」で実装する極意
業務自動化エンジニアとして断言する。Visioの自動化において、「とりあえず動くコード」と「プロダクション(現場)品質のコード」には、天と地ほどの開きがある。
多くの初心者が陥る罠は、`Documents`コレクションを安易にループさせ、保存のたびに例外で止まる、あるいは既存の保存状態を破壊して元に戻せなくなるケースだ。本稿では、ファイルシステムを汚染せず、堅牢に全ドキュメントをPDF化する「プロの設計」を伝授する。
1. なぜ「単純なループ」ではいけないのか
`Documents`コレクションをループさせる際、以下の視点が欠けていると必ず事故が起きる。
- 名前空間とパスの不整合: 未保存(New Drawing)状態のファイルにはフルパスが存在しない。これを無視してPDF出力しようとすれば、即座にエラーでスクリプトは停止する。
- ファイル拡張子の置換ミス: `Replace`関数で単純に`.vsdx`を`.pdf`に置換するようなコードは、パスの途中に`.vsdx`が含まれている場合に致命的なバグを引き起こす。
- イベントの干渉: 保存時の確認ダイアログや、外部参照リンクの更新確認がプロセスを停止させる。これらをいかに無効化するかが、自動化の生命線だ。
—
2. 実装コード:プロダクションレベルのPDFエクスポート
以下のコードは、単にPDFを保存するだけでなく、パスの存在確認、保存先パスの動的生成、およびエラーハンドリングを標準装備している。
Option Explicit
‘ ———————————————————
‘ 機能: 開いている全VisioドキュメントをPDFとしてエクスポート
‘ 備考: 未保存ファイルは「デスクトップ」に保存する設計
‘ ———————————————————
Public Sub ExportAllDocumentsToPDF()
Dim doc As Visio.Document
Dim targetPath As String
Dim fileNameOnly As String
Dim desktopPath As String
‘ 1. エラーハンドリングの要:予期せぬ停止を防ぐ
On Error GoTo ErrorHandler
‘ 画面更新を停止してパフォーマンスを最大化
Application.ScreenUpdating = False
desktopPath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\”
For Each doc In Application.Documents
‘ 2. パスの有無による保存先の切り分け
If doc.Path <> “” Then
‘ 保存済みファイルは同一フォルダに保存
targetPath = Left(doc.FullName, InStrRev(doc.FullName, “.”)) & “pdf”
Else
‘ 未保存ファイルはデスクトップへ(ファイル名はドキュメント名を使用)
targetPath = desktopPath & doc.Name & “.pdf”
End If
‘ 3. PDFエクスポート実行
‘ VisFixedFormatType.visFixedFormatPDF = 1
‘ 指定したパスへPDFとして出力
doc.ExportAsFixedFormat 1, targetPath
Debug.Print “Success: ” & doc.Name & ” -> ” & targetPath
Next doc
CleanExit:
Application.ScreenUpdating = True
Exit Sub
ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
Resume CleanExit
End Sub
—
3. 開発現場で生き残るための設計思想
① `InStrRev` を使い倒せ
パス操作において、文字列置換は禁忌だ。`InStrRev`を使用して「最後のドット(.)」の位置を特定し、そこから文字列を切り出すのが唯一の正解である。これにより、フォルダ名に`.vsdx`が含まれていても、絶対的な安定性を担保できる。
② パフォーマンスの重みを知る
`Application.ScreenUpdating = False` は単なる飾りに見えるかもしれないが、大量の図面を処理する際、再描画のオーバーヘッドは無視できない。数百枚単位の図面を扱うエンジニアであれば、この一行の有無が完了までの時間を分けることを知っているはずだ。
③ ユーザー体験(UX)への配慮
自動化ツールは「動けばいい」ものではない。処理中であることをユーザーに通知したり、成功したのか失敗したのかを `Debug.Print` でイミディエイトウィンドウに吐き出したりする。こうした細かい「痕跡」を残すことが、後の保守・障害切り分けにおいて君を救うことになる。
結びに:自動化は「責任」である
VisioのVBAは、ドキュメントのライフサイクルを直接制御する強力な武器だ。その分、設計が甘ければシステム全体を破壊しかねない。
今回紹介したロジックは、そのまま大規模なドキュメント管理システムの一部として組み込める構成にしている。次はこれを応用し、特定のプロパティ(図面プロパティ)を参照してPDFの保存先をDBと連携させるなど、さらなる高度化を目指してほしい。
コードは嘘をつかない。君が書いたロジックの深さが、そのまま業務の品質に直結するのだ。幸運を祈る。
