Visio VBAを制する:FSO再帰処理による「全VSDX一括PDF変換」の極意
業務自動化の世界において、Visioは「図面」という非構造化データを扱うという性質上、自動化の難易度が極めて高い部類に入ります。特に「フォルダ階層を潜り抜けて全ファイルをPDFへ変換する」というタスクは、一見単純ですが、適当に書けばメモリリークやプロセス残留の温床となります。
今回は、現場のエンジニアが直面する「なぜか途中で止まる」「Visioの裏プロセスが消えない」といったトラブルを未然に防ぐ、堅牢かつ再帰的なファイル走査ロジックを伝授します。
—
なぜFSOと再帰処理を選ぶのか?
よくある「Dir関数で頑張る」コードは、サブフォルダの階層が深くなるとスタックオーバーフローやロジックの複雑化を招きます。一方、`Scripting.FileSystemObject (FSO)` は、フォルダ構造をオブジェクトとして扱うため、再帰呼び出しとの相性が抜群です。
今回の設計の肝は、「疎結合なエラーハンドリング」と「Visioアプリケーションのライフサイクル管理」です。
堅牢なPDF変換ツールの実装コード
このコードは、指定ルートディレクトリ配下の全VSDXを探索し、同一階層にPDFを生成します。
Option Explicit
‘ 参照設定: Microsoft Scripting Runtime が必要
Sub BatchConvertVisioToPDF()
Dim fso As New FileSystemObject
Dim rootFolder As String
‘ ユーザーにフォルダを選択させる(FileDialogの使用を推奨)
rootFolder = “C:\Target\Drawings” ‘ 実際にはダイアログで取得してください
If Not fso.FolderExists(rootFolder) Then Exit Sub
‘ 再帰処理の開始
ProcessFolder fso.GetFolder(rootFolder)
MsgBox “全ファイルのPDF変換処理が完了しました。”, vbInformation
End Sub
Private Sub ProcessFolder(folder As Folder)
Dim subFolder As Folder
Dim file As file
Dim doc As Visio.Document
‘ 現在のフォルダ内のファイルを処理
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Path)) = “vsdx” Then
On Error Resume Next ‘ 個別ファイルの失敗で全体を止めない
Set doc = Visio.Application.Documents.Open(file.Path)
If Err.Number = 0 Then
‘ PDFエクスポート(第3引数はPDF保存オプション)
doc.ExportAsFixedFormat visFixedFormatPDF, _
Replace(file.Path, “.vsdx”, “.pdf”), _
visDocFromPages, visDocAllPages
doc.Close
Else
Debug.Print “Error processing: ” & file.Path
End If
On Error GoTo 0
Set doc = Nothing
End If
Next
‘ サブフォルダを再帰的に走査
For Each subFolder In folder.SubFolders
ProcessFolder subFolder
Next
End Sub
—
プロフェッショナルが守るべき3つの設計原則
1. Visioインスタンスの「閉じ方」に命を懸ける
Visioのオートメーションにおいて最も多い失敗は、`doc.Close` を忘れること、あるいはエラー発生時にプロセスが残存することです。必ず `On Error` を適切に配置し、ループの各イテレーションで `Set doc = Nothing` を明示してください。これを怠ると、メモリを食いつぶし、数千ファイルの変換途中でOSごとハングアップします。
2. ファイルパスのバリデーション
`Replace(file.Path, “.vsdx”, “.pdf”)` という書き方は、フォルダ名に `.vsdx` が含まれているような特殊なケースで誤作動します。実務では `fso.BuildPath` と `fso.GetParentFolderName` を組み合わせ、パス操作を確実に管理してください。
3. 大量処理時のUI応答性
今回のような長時間実行されるスクリプトでは、`DoEvents` を適宜挟むことで、OSが「応答なし」と判断するのを防ぎます。進捗をステータスバーに出力する実装を加えるだけで、ユーザーの不安感は劇的に解消されます。
—
最後に:なぜ「動けばいい」ではいけないのか
業務自動化ツールは、一度動けば終わりではありません。ファイルの命名規則が変わったとき、権限エラーが発生したとき、あるいはVisioのバージョンが上がったとき。そのたびに改修を迫られるのがツール開発の宿命です。
今回紹介した「FSOによる再帰構造」と「エラーを局所化する設計」は、どんな大規模なファイル群に対しても適用できる、まさに「開発者としての教養」とも呼べるパターンです。
あなたの自動化ツールが、ただの「動くコード」から、現場を支える「堅牢なエンジン」へと昇華されることを期待しています。何か技術的な壁にぶつかったら、いつでも戻ってきてください。
