こんにちは!PowerPoint VBAの世界へようこそ。
マクロの記録ボタンを押してコードを眺めてみる……そんな初めの一歩から、少しずつステップアップしていくと、やがてこんな壁にぶつかります。
「数百ファイルもあるPowerPointのプレゼンテーションを、全部PDFに一括変換したい……!」
これを通常のVBA(シングルスレッド)で1ファイルずつ処理していくと、CPUのコアは常に1つしか使われず、終わる頃にはコーヒーが何杯も飲めてしまうほどの時間がかかってしまいます。現代のPCにはマルチコアCPUが搭載されているのに、VBAだからといってそれを遊ばせておく手はありませんよね。
今回は、「PowerPoint VBAとVBScriptを連携させ、マルチスレッド風の非同期シーケンス制御で複数ファイルを一気に並列PDF化する超大型バッチ処理基盤」の作り方を、優しく、そして本質的なところまでしっかりと解説していきます。
ここをクリアすれば、あなたのVBAスキルは間違いなく「上級エンジニア」の領域に到達します。一緒にマスターしていきましょう!
—
なぜ通常のVBAループでは遅いのか?
PowerPoint VBAで大量のファイルを処理するとき、次のようなコードを書いたことはありませんか?
‘ 【よくある従来のコード(シングルスレッド)】
Sub ConvertToPDF_Slow()
Dim folderPath As String
Dim fileName As String
folderPath = “C:\PresentationFiles\”
fileName = Dir(folderPath & “.pptx”)
Do While fileName <> “”
‘ 1つずつ順番に開いてPDF化(前の処理が終わるまで次に行かない)
Dim pptApp As PowerPoint.Application
Set pptApp = New PowerPoint.Application
‘ …ここに保存処理…
fileName = Dir
Loop
End Sub
このアプローチの何が問題かと言うと、「前のファイルの変換が完全に終わるまで、次のファイルに手をつけられない」という直列(シーケンシャル)な構造になっている点です。8コアや16コアのCPUを積んだモンスターマシンを使っているのに、たった1つのコアしか働いていない状態なのは、宝の持ち腐れです。
そこで、「VBAから複数の外部プロセス(VBScript)を同時に裏で起動し、それぞれに別々のファイルの変換を任せる」という並列処理(マルチスレッド風)の仕組みを導入します。
—
仕組みの全体像:VBA × VBScriptの非同期連携
今回のアーキテクチャはシンプルですが強力です。
1. VBA(親): 変換したいファイルの一覧を管理し、同時に走らせるプロセス数(同時実行数)を制御します。
2. VBScript(子): VBAから「このファイルをPDFにして!」と指示を受け取り、PowerPointを裏で静かに起動してPDF変換を行い、終わったら勝手に消滅します。
3. 並列制御: これを複数同時に立ち上げることで、OSのマルチコアに仕事を分散させます。
それでは、実際に現場でそのまま使える実用コードを見ていきましょう。
—
実装コード:超高速並列PDF変換バッチ基盤
以下の2つのモジュール(またはファイル)を用意します。
1. VBScriptワーカーファイル (`ConvertWorker.vbs`)
まずは、受け取ったPowerPointファイルを1つだけPDFに変換して終了する「働き者(ワーカー)」のスクリプトをテキストファイルとして作成し、適当なフォルダ(例: `C:\Tools\ConvertWorker.vbs`)に保存します。
‘ ConvertWorker.vbs
‘ 引数(0): 変換元PPTXファイルのパス
‘ 引数(1): 保存先PDFファイルのパス
Option Explicit
If WScript.Arguments.Count < 2 Then WScript.Quit End If Dim pptPath, pdfPath pptPath = WScript.Arguments(0) pdfPath = WScript.Arguments(1) Dim pptApp, pptPres On Error Resume Next ' バックグラウンドでPowerPointを起動(画面非表示でリソースを節約) Set pptApp = CreateObject("PowerPoint.Application") ' 警告メッセージなどを非表示にする pptApp.DisplayAlerts = ppAlertsNone ' プレゼンテーションを開く(読み取り専用、ウィンドウ非表示) Set pptPres = pptApp.Presentations.Open(pptPath, True, False, False) If Err.Number = 0 Then ' PDF形式(型番: 32)で保存 ' パラメータ: パス, 形式(32=PDF), 印刷範囲など pptPres.SaveAs pdfPath, 32 pptPres.Close End If pptApp.Quit Set pptPres = Nothing Set pptApp = Nothing
2. コントローラーとなるPowerPoint VBAコード
次に、親となるVBAコードです。ここでは、WScript.Shellの`Run`メソッドを活用し、非同期でプロセスを次々と投げ続けます。
‘ =====================================================================
‘ 超高速マルチスレッド風 PDF一括変換コントローラー
‘ =====================================================================
Sub RunParallelPDFConversion()
Dim targetFolder As String
Dim outputFolder As String
Dim workerScript As String
Dim fso As Object
Dim folder As Object
Dim file As Object
Dim wsh As Object
‘ パスの設定(環境に合わせて変更してください)
targetFolder = “C:\PresentationFiles\”
outputFolder = “C:\PresentationFiles\PDFs\”
workerScript = “C:\Tools\ConvertWorker.vbs”
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set wsh = CreateObject(“WScript.Shell”)
‘ 出力先フォルダがなければ作成
If Not fso.FolderExists(outputFolder) Then
fso.CreateFolder (outputFolder)
End If
If Not fso.FolderExists(targetFolder) Then
MsgBox “対象フォルダが見つかりません: ” & targetFolder, vbCritical
Exit Sub
End If
Set folder = fso.GetFolder(targetFolder)
Dim startTime As Double
startTime = Timer
Dim fileCount As Long
fileCount = 0
‘ フォルダ内の全PPTXファイルをスキャンして非同期実行
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Name)) = “pptx” Or _
LCase(fso.GetExtensionName(file.Name)) = “ppt” Then
Dim pptPath As String
Dim pdfPath As String
Dim cmd As String
pptPath = file.Path
pdfPath = outputFolder & fso.GetBaseName(file.Name) & “.pdf”
‘ すでにPDFが存在する場合はスキップするなどの制御も可能
If Not fso.FileExists(pdfPath) Then
‘ VBScriptを非同期で呼び出すコマンドを構築
‘ 第2引数の “0” はウィンドウ非表示、”False” は非同期実行(待ち続けない)の意味
cmd = “cscript.exe //B “”” & workerScript & “”” “”” & pptPath & “”” “”” & pdfPath & “”””
‘ 非同期実行(ここに秘密があります!)
wsh.Run cmd, 0, False
fileCount = fileCount + 1
‘ デバッグ用イミディエイト出力
Debug.Print “起動中: ” & file.Name
End If
End If
Next file
MsgBox “合計 ” & fileCount & ” 件の変換プロセスをバックグラウンドに一斉送信しました!” & vbCrLf & _
“処理時間: ” & Format(Timer – Timer, “0.00”) & ” 秒 (送信完了)”, vbInformation, “爆速バッチ完了”
‘ 後片付け
Set wsh = Nothing
Set fso = Nothing
End Sub
—
ヘビーな処理をVBAの単一ループから解放し、OSのプロセス管理に委ねることで、PCのCPUコアをフル回転させることができます。
—
陥りやすい罠とエンジニアの知見(トラブルシューティング)
この高度な仕組みを実装するにあたり、現場で必ず直面する「落とし穴」と、その対策をシェアしておきます。
1. 同時実行数が多すぎてCPUがパンクする問題
数百ファイルを完全同時に投げると、PowerPointのインスタンスが数百個一気に立ち上がり、メモリが枯渇してPCがフリーズするか、途中でエラー落ちします。
- 対策: VBA側でループを回す際に、一定数(例えば4つや8つ)起動したら少し待機(`Application.Wait`など)を入れるか、プロセス監視のキューイング機構を挟むと完璧です。
2. ファイルの排他制御・競合エラー
同じファイルを誤って二重に処理しようとしたり、ネットワークドライブ上で実行した際にロックがかかることがあります。
- 対策: 変換元ファイルは必ず「ローカルの作業用フォルダ」にコピーしてから処理させる、またはVBScript側で `On Error Resume Next` を適切に配置して、1つのファイルがコケても全体が止まらない「ロバスト性(堅牢性)」を持たせることがプロの条件です。
—
まとめ:ここをクリアすれば、あなたはもうVBA初級者ではない!
今回は、PowerPoint VBAとVBScriptを組み合わせた「マルチスレッド風の非同期シーケンス制御による超高速並列PDF化バッチ処理」について解説しました。
- シングルスレッドの限界を知る
- VBAからWScript.Shell経由で外部プロセスを非同期キックする
- リソースとエラーハンドリングを考慮した設計を行う
これらを理解し使いこなせるようになったあなたは、もはや「マクロの記録」に頼るだけの初学者ではありません。業務のボトルネックをテクノロジーで力づく、かつエレガントに解決できる「真の自動化エンジニア」です。
ぜひご自身の環境で試して、その圧倒的なスピードの差を体感してください。あなたの業務効率化ライフが劇的に変わることを確信しています。それでは、次のステージでお会いしましょう!
