PowerPoint VBAの「死」を制御せよ:エンタープライズ級PDF一括変換のための堅牢なエラーハンドリング設計
業務自動化の現場において、PowerPointのPDF一括変換は「最も単純だが、最も裏切られる」処理の一つです。数百のファイルを自動処理させている最中、深夜3時に「書き込み権限エラー」や「ディスク容量不足」で全プロセスが停止し、翌朝に絶望する。そんな経験は、もう終わりにしましょう。
本稿では、単なるVBAコードの解説ではなく、「例外を握りつぶさない」「運用可能なログを吐く」「再開性を考慮する」という、プロフェッショナルな設計思想を実装に落とし込みます。
—
1. なぜ「雑なエラーハンドリング」が現場を殺すのか
一般的なVBAのチュートリアルでは `On Error Resume Next` を多用しますが、これは「トラブルの痕跡を隠蔽する」最悪のアンチパターンです。
エンタープライズ環境で求められるのは、「何が起きたか」ではなく「どのファイルが、どのスライドで、なぜ止まったのか」というコンテキストです。以下の設計思想を、あなたのコードの背骨としてください。
- 完全な例外捕捉: 特定の処理ブロックごとにエラーハンドラを局所化し、全体を停止させない。
- 状態の可視化: ログは「いつ」「どこで」「何が」をCSV形式で出力し、後続のダッシュボードや追跡調査に耐えうる形式にする。
- リソースの解放: エラー発生時に必ずオブジェクト(Presentation, Application)を適切にクローズし、メモリリークやファイルロックを防止する。
—
2. 実装:堅牢な一括変換アーキテクチャ
以下のコードは、単なる変換機能ではありません。「失敗を記録し、次のファイルへ進む」という強靭なループ構造を持ったプロダクションコードです。
Option Explicit
‘ ログファイル出力先(適宜変更)
Private Const LOG_FILE_PATH As String = “C:\Logs\Conversion_Error_Log.csv”
‘ メイン処理:フォルダ内の全PPTXをPDF変換
Public Sub BatchConvertPPTXtoPDF(ByVal targetFolder As String)
Dim fso As Object: Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim folder As Object: Set folder = fso.GetFolder(targetFolder)
Dim file As Object
‘ ログファイルの初期化(ヘッダー)
InitLogFile
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Name)) = “pptx” Then
‘ 個別処理を呼び出す
ConvertSingleFile file.Path
End If
Next file
End Sub
‘ ファイル単位のエラーハンドリング
Private Sub ConvertSingleFile(ByVal filePath As String)
Dim pptApp As Presentation
On Error GoTo ErrorHandler
‘ ファイルを開く(読み取り専用で開き、ロックを回避)
Set pptApp = Presentations.Open(FileName:=filePath, ReadOnly:=msoTrue, WithWindow:=msoFalse)
‘ PDFエクスポート
pptApp.ExportAsFixedFormat Left(filePath, InStrRev(filePath, “.”) – 1) & “.pdf”, ppFixedFormatTypePDF
pptApp.Close
Exit Sub
ErrorHandler:
‘ エラーが発生した場所と内容をログに出力
WriteLog Err.Number, Err.Description, filePath
‘ オブジェクトの安全な解放
If Not pptApp Is Nothing Then pptApp.Close
On Error GoTo 0
End Sub
‘ ログ出力関数
Private Sub WriteLog(ByVal errNum As Long, ByVal errDesc As String, ByVal filePath As String)
Dim fileNum As Integer
fileNum = FreeFile
Open LOG_FILE_PATH For Append As #fileNum
Print #fileNum, Now & “,” & filePath & “,” & errNum & “,” & “””” & errDesc & “”””
Close #fileNum
End Sub
Private Sub InitLogFile()
If Dir(LOG_FILE_PATH) = “” Then
Dim fileNum As Integer
fileNum = FreeFile
Open LOG_FILE_PATH For Output As #fileNum
Print #fileNum, “Timestamp,FilePath,ErrNumber,ErrDescription”
Close #fileNum
End If
End Sub
—
3. この設計における「プロの着眼点」
① `WithWindow:=msoFalse` の魔力
VBAでPowerPointを操作する際、ウィンドウを表示すると動作が重くなるだけでなく、フォーカスを奪い合ってフリーズの原因になります。必ず非表示で開きましょう。
② ファイルロックへの対策
`ReadOnly:=msoTrue` を指定することで、他のユーザーがファイルを開いている場合でも、読み込み権限さえあれば変換処理を続行できます。業務を止めないための鉄則です。
③ なぜ CSV ログなのか
データベース(SQL Server等)に直接書き込むのは、ネットワーク切断時にロギング自体が失敗するリスクがあります。まずはローカルのCSVに確実に出力し、その後の分析はPower Queryで読み込むのが、最も保守性が高く、エンジニアとしての責任を果たせる設計です。
—
4. 最後に:自動化の真髄
「コードが動くこと」は通過点に過ぎません。真の自動化エンジニアは、「自動化が失敗した瞬間のこと」を設計します。
今回提供したエラーハンドリングを導入することで、あなたのツールは「動くか分からないブラックボックス」から、「結果を説明できるプロフェッショナルなツール」へと進化します。まずはこのテンプレートを自身の環境に組み込み、ログが吐き出される様子を確認してください。
運用担当者が、エラーログを見て「ああ、このファイルが壊れていたのか」と即座に判断できる。それこそが、私たちが目指すべき「真の自動化」の姿です。
