PowerPoint自動化の深淵:プロセス死を許さない「ウォッチドッグ」による堅牢なバッチ処理設計
業務自動化の現場で最も忌むべきは、PowerPointが「応答なし」の闇に消え、バッチ処理全体がデッドロックに陥ることだ。
多くのエンジニアは単一のVBAマクロを走らせることに終始する。しかし、数千枚単位のプレゼンテーションをPDF化したり、外部DBと同期させたりする際、PowerPointのCOMオブジェクトは必ずと言っていいほど寿命を迎える。
本稿では、PowerPointの不安定さを前提とした「ウォッチドッグ(番犬)パターン」による、極限まで堅牢な自動化アーキテクチャを伝授する。
—
1. なぜ「同期実行」は死を招くのか
PowerPointの自動化において、`Presentation.SaveAs` や `Export` はリソースを激しく消費する。メモリリークやCOMのスタックオーバーフローにより、プロセスがフリーズするのは必然である。
単一のVBAスクリプトでこれを制御しようとすると、例外処理(`On Error Resume Next`)の限界を超え、VBA環境ごとハングアップする。これを防ぐ唯一の解は、「制御側(コントローラー)」と「実行側(ワーカー)」を明確に分離することだ。
2. アーキテクチャの核心:ウォッチドッグ・パターンの設計
今回は、VBA(メイン)からPowerShellを非同期的に呼び出し、PowerPointの生存監視とタイムアウト強制終了を行う構成をとる。
- コントローラー(VBA): タスクのキューを管理し、PowerShellに実行命令を飛ばす。
- ワーカー(PowerPointインスタンス): 実際の変換処理を担当。
- ウォッチドッグ(PowerShell): 別プロセスで待機。指定時間内に処理が終わらない場合、該当するプロセスをPID単位でKILLし、強制的に次のタスクへ移行させる。
—
3. 実装:プロセス監視を行うウォッチドッグ・エンジン
このコードは、PowerPointのプロセスを監視し、指定秒数以上応答がない場合に強制終了させるPowerShellスクリプトだ。これをVBAから呼び出す。
PowerShell側 (Watchdog.ps1)
引数: $TargetPID, $TimeoutSeconds
param([int]$pidToWatch, [int]$timeout)
$startTime = Get-Date
while ((Get-Process -Id $pidToWatch -ErrorAction SilentlyContinue)) {
if (((Get-Date) – $startTime).TotalSeconds -gt $timeout) {
Write-Host “Timeout! Killing process $pidToWatch”
Stop-Process -Id $pidToWatch -Force
exit 1
}
Start-Sleep -Seconds 2
}
exit 0
—
4. 実装:VBAからの非同期制御コード
メインとなるVBAからは、`WScript.Shell` の `Run` メソッドを使い、非同期でウォッチドッグを起動する。
Sub BatchProcessWithWatchdog()
Dim pptApp As Object
Dim pptPres As Object
Dim shell As Object
Dim cmd As String
Dim timeoutSec As Integer: timeoutSec = 60 ‘ 1分で応答なければ強制終了
Set shell = CreateObject(“WScript.Shell”)
‘ 1. PowerPointインスタンスを個別に作成
Set pptApp = CreateObject(“PowerPoint.Application”)
‘ 2. ウォッチドッグを起動(非同期実行)
‘ 引数: PowerShellパス, 監視対象PID, タイムアウト秒
cmd = “powershell.exe -WindowStyle Hidden -File “”C:\Scripts\Watchdog.ps1″” ” & pptApp.ProcessID & ” ” & timeoutSec
shell.Run cmd, 0, False
‘ 3. 重い処理を実行
On Error Resume Next
Set pptPres = pptApp.Presentations.Open(“C:\Target\HeavyFile.pptx”)
pptPres.SaveAs “C:\Output\Result.pdf”, 32 ‘ 32 = ppSaveAsPDF
‘ 4. 後処理
If Not pptPres Is Nothing Then pptPres.Close
pptApp.Quit
Set pptPres = Nothing
Set pptApp = Nothing
MsgBox “処理完了またはウォッチドッグによる強制終了が実行されました。”
End Sub
—
5. プロダクション環境での重要注意点
このアーキテクチャを採用する上で、必ず押さえておくべき「現場の知恵」が3つある。
1. PIDの競合を避けよ: 複数のPowerPointインスタンスを同時に扱う場合、必ず `CreateObject` で独立したプロセスを生成すること。`GetObject` で既存のプロセスにアタッチするのは避けるべきだ。
2. 一時ファイルの掃除: 強制終了が発生すると、PowerPointは `~$FileName.pptx` のようなロックファイルを残す。バッチの開始時に `Dir` 関数でこれらのゴミファイルを削除するルーチンを必ず実装すること。
3. イベントログの活用: ウォッチドッグがプロセスをKILLした際、どのファイルでフリーズしたのかをテキストログに残すこと。これは運用保守において「なぜ止まったか」を追跡するための唯一の証拠となる。
結論
PowerPoint VBAによる自動化は、本来「不安定な対象」を扱う高等技術である。標準的なループ処理だけで満足せず、「プロセスは必ず死ぬ」という前提で外側から監視する。この視点こそが、真の自動化エンジニアと、単なるコード書きを分かつ境界線だ。
さあ、あなたの自動化バッチに「番犬」を飼い、深夜のハングアップから解放されよう。
