【入門編】【上級者】FSOとAPIを駆使し、ネットワーク共有フォルダ内のPPTXファイルを排他制御(使用中ロック)を考慮して安全に一括PDF変換する堅牢スクリプト – PowerPoint VBA解析バイブル

スポンサーリンク

共有フォルダの「編集中エラー」を完全回避せよ:PowerPoint VBAによる堅牢なPDF一括変換術

こんにちは。業務自動化の現場で血と汗を流してきたエンジニアとして、今日は少し「プロの領域」に踏み込んだ話をしましょう。

「共有フォルダにある数百のPPTXをPDFに変換したい」——よくある依頼ですが、これをただのループで回すと必ず地獄を見ます。誰かがファイルを開いているときにスクリプトが走り出し、PowerPointが「読み取り専用」のダイアログを出して停止する……。 この「沈黙のフリーズ」こそが、自動化の最大の敵です。

今日は、FSO(FileSystemObject)とAPI的な視点を取り入れ、「使用中ならスキップする」という排他制御を備えた堅牢な自動化スクリプトの組み方を伝授します。

—

1. なぜ「マクロの記録」だけでは足りないのか?

「マクロの記録」で生成されるコードは、あくまで「今、目の前にある操作」をなぞるだけです。しかし、業務自動化の真髄は「異常系(エラー)をいかにエレガントに握りつぶすか」にあります。

共有フォルダでの作業で考慮すべきは以下の3点です。
1. 排他制御: 誰かが編集中か?(ロックファイルの有無)
2. メモリ管理: 巨大なプレゼン資料を閉じる際、メモリリークを起こしていないか?
3. 可視性: どこで失敗し、何が成功したのか?(ログ出力)

これらをクリアするだけで、あなたのコードは「おもちゃ」から「業務インフラ」へと進化します。

—

2. 堅牢なPDF一括変換スクリプト

このスクリプトは、ファイルを開く前に「書き込み権限があるか」を簡易的にテストすることで、ダイアログによる停止を未然に防ぎます。

Option Explicit

‘ 必要な参照設定: Microsoft Scripting Runtime (FSO)
Sub RobustPdfConverter()
Dim fso As Object, folder As Object, file As Object
Dim pptApp As Object, pptPres As Object
Dim targetFolder As String, logFile As String

‘ 設定
targetFolder = “C:\Shared\Reports\” ‘ 共有フォルダパス
logFile = targetFolder & “conversion_log.txt”

Set fso = CreateObject(“Scripting.FileSystemObject”)
Set folder = fso.GetFolder(targetFolder)

‘ ログ初期化
Open logFile For Output As #1

‘ PPTアプリケーションをバックグラウンドで起動
Set pptApp = CreateObject(“PowerPoint.Application”)

For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Name)) = “pptx” Then
‘ 【重要】排他制御: ファイルが開けるかテスト
If IsFileLocked(file.Path) Then
Print #1, Now & ” [SKIP] 使用中: ” & file.Name
Else
On Error Resume Next
Set pptPres = pptApp.Presentations.Open(file.Path, , , False)
If Err.Number = 0 Then
pptPres.SaveAs Replace(file.Path, “.pptx”, “.pdf”), 32 ‘ 32 = ppSaveAsPDF
pptPres.Close
Print #1, Now & ” [SUCCESS] 変換完了: ” & file.Name
Else
Print #1, Now & ” [ERROR] 開けません: ” & file.Name
End If
On Error GoTo 0
End If
End If
Next

pptApp.Quit
Close #1
MsgBox “全処理が終了しました。ログを確認してください。”
End Sub

‘ ファイルがロックされているかを確認する関数
Function IsFileLocked(filePath As String) As Boolean
Dim fnum As Integer
On Error Resume Next
fnum = FreeFile()
Open filePath For Binary Access Read Write Lock Read Write As #fnum
Close #fnum
IsFileLocked = (Err.Number <> 0)
On Error GoTo 0
End Function

—

3. コードの「魂」を解説する

① なぜ `IsFileLocked` 関数が必要なのか?

PowerPointはファイルを開く際、ロックされていると「読み取り専用で開きますか?」というダイアログを強制的に表示します。このダイアログが出る時点でスクリプトは止まってしまいます。
この関数は、「そのファイルを独占的に開けるか?」を事前にテストするという、OSのファイルシステムレベルでのチェックを行っています。これにより、実行中に止まることは物理的にありえなくなります。

② `CreateObject` の重要性

`PowerPoint.Application` を新しく生成し、`False` 引数で非表示(ウィンドウを表示しない)にしています。これにより、PC上で資料を閲覧しているユーザーの邪魔をせず、バックグラウンドで高速に処理を回すことができます。

③ ログ出力の哲学

現場で一番怖いのは「結局、何が終わって何が終わっていないのか分からない」ことです。テキストファイルに結果を書き出すことで、翌朝に「どのファイルが失敗したか」を一目で特定できます。これが運用を支えるエンジニアの矜持です。

—

4. 最後に:ここをクリアすれば「脱・初心者」

このコードのポイントは、「エラーを予測し、先に手を打つ」という点です。

  • 「エラーが起きたらどうしよう」ではなく、
  • 「そもそもエラーが起きない状況をどう作るか」

この思考プロセスが身につくと、あなたのVBAは劇的に安定します。まずはこのコードを、自分の管理するフォルダで試してみてください。エラー処理の美しさに気づいたとき、あなたはもう立派な自動化エンジニアの仲間入りです。

何か詰まったら、いつでも質問してくださいね。応援しています!

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