【テクニカル・上級編】【中級者向け】FSOとDir関数を組み合わせた、サブフォルダを含む全VSDXファイルの再帰的PDF変換ツール – Visio VBA解析バイブル

スポンサーリンク

Visio自動化の深淵:再帰的PDF変換における「メモリ管理」と「プロセス堅牢性」の極意

多くのエンジニアが「単に動くコード」を書くことに終始する中、真に堅牢なシステムを構築できる者は、背後にあるオブジェクトのライフサイクルと、OSが管理するリソースの重みを理解している。

今回は、VSDXファイルをサブフォルダまで含めてPDFへ一括変換する、実用性と堅牢性を両立させたアーキテクチャを提示する。これは単なるスクリプトではなく、数千ファイルを扱う運用に耐えうる「エンジン」の雛形である。

—

1. なぜFileSystemObject(FSO)を使うのか

レガシーな `Dir` 関数は、再帰的な探索において再入可能性(Reentrancy)に乏しく、スタックオーバーフローや予期せぬポインタの衝突を招くリスクがある。

一方、`Scripting.FileSystemObject` はオブジェクト指向の構造を持ち、メモリ管理の観点からも階層構造の走査に適している。ただし、「COMオブジェクトは呼んだら必ず殺せ」。これがメモリリークを許さないシニアエンジニアの鉄則だ。

2. アーキテクチャの核心:再帰処理とVisioのプロセス制御

Visioの `Application` オブジェクトをループ内で生成・解放し続けるのは、オーバーヘッドが大きすぎて現実的ではない。また、ファイル破損等でVisioがハングアップした場合、プロセスがゾンビとして残る。

以下のコードでは、Visioを「シングルトンに近い形」で再利用し、エラーハンドリングによって確実にプロセスを解放する設計を採用している。

実装コード:Robust VSDX to PDF Converter

Option Explicit

‘ 必要な参照設定: Microsoft Scripting Runtime, Microsoft Visio 16.0 Type Library
Private mVisApp As Visio.Application

Public Sub BatchConvertVsdxToPdf()
Dim fso As New FileSystemObject
Dim rootFolder As String

rootFolder = “C:\Target\Drawings” ‘ ルートディレクトリ

On Error GoTo ErrorHandler
Set mVisApp = New Visio.Application
mVisApp.Visible = False

ProcessFolder fso.GetFolder(rootFolder), fso

MsgBox “変換処理が完了しました。”, vbInformation

Cleanup:
‘ ゾンビプロセスを防ぐための確実な終了処理
If Not mVisApp Is Nothing Then
mVisApp.Quit
Set mVisApp = Nothing
End If
Set fso = Nothing
Exit Sub

ErrorHandler:
MsgBox “致命的なエラー: ” & Err.Description, vbCritical
Resume Cleanup
End Sub

Private Sub ProcessFolder(folder As Folder, fso As FileSystemObject)
Dim file As file
Dim subFolder As Folder

‘ 現在のフォルダ内のVSDXを処理
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Path)) = “vsdx” Then
ExportToPdf file.Path
End If
Next

‘ サブフォルダを再帰的に走査
For Each subFolder In folder.SubFolders
ProcessFolder subFolder, fso
Next
End Sub

Private Sub ExportToPdf(vsdxPath As String)
Dim doc As Visio.Document
Dim pdfPath As String

‘ ファイルパスの生成(拡張子置換)
pdfPath = Left(vsdxPath, Len(vsdxPath) – 5) & “.pdf”

Set doc = mVisApp.Documents.Open(vsdxPath)

‘ Exportメソッドの第2引数にPDF変換用フィルタを指定
‘ 16はvisFixedFormatPDF
doc.ExportAsFixedFormat 16, pdfPath, 0, 0

doc.Close
Set doc = Nothing
End Sub

—

3. シニアエンジニアが意識すべき「極限の知見」

① メモリリークを許さないオブジェクト管理

上記のコードでは、`doc.Close` の後に `Set doc = Nothing` を明示している。これはVBAのガベージコレクションを信用せず、参照カウンタを確実にデクリメントさせるための儀式だ。大規模ファイル群を処理する場合、この一行の有無が、数時間後のメモリ枯渇を引き起こすか否かを分かつ。

② Windows APIによるプロセス監視(応用編)

本番環境では、Visioが「応答なし」になるケースを想定しなければならない。より高度な実装を目指すなら、`FindWindow` や `TerminateProcess` APIを駆使し、タイムアウト監視スレッドを分離すべきだ。VBAはシングルスレッドであるが、WMI (Windows Management Instrumentation) を併用すれば、実行中の `VISIO.EXE` プロセスIDを特定し、異常終了時に強制クリーンアップを行う堅牢なラッパーを書くことができる。

③ パフォーマンスのボトルネック

`ExportAsFixedFormat` は、内部的にPDF作成ドライバを呼び出すため、ディスクI/OとCPU負荷が極めて高い。ネットワークドライブ上のファイルを処理する場合、一度ローカルテンポラリにコピーしてから変換し、結果を戻す手法を推奨する。ネットワーク越しに直接開くと、パケットロスによるVisioのクラッシュ頻度が劇的に上昇するからだ。

結びに

自動化とは、単に手作業をコードに置き換えることではない。「何が起きてもシステムが破綻しないこと」を担保する設計こそが、プロフェッショナルとアマチュアの境界線である。

このツールをベースに、ログ出力機能や、変換済みファイルの移動処理を追加し、あなたの現場にとっての「最強の自動化エンジン」へと昇華させてほしい。技術は、常に「最悪の事態」を想定した者に対してのみ、その真価を差し出すのだ。

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