【入門編】【上級者】マルチスレッド風の非同期シーケンス制御をVBAとVBScriptの連携で擬似的に実現し、複数コアをフル活用して数百ファイルのPPTXを並列で高速PDF化する超大型バッチ処理基盤 – PowerPoint VBA解析バイブル

スポンサーリンク

こんにちは!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経由で外部プロセスを非同期キックする
  • リソースとエラーハンドリングを考慮した設計を行う

これらを理解し使いこなせるようになったあなたは、もはや「マクロの記録」に頼るだけの初学者ではありません。業務のボトルネックをテクノロジーで力づく、かつエレガントに解決できる「真の自動化エンジニア」です。

ぜひご自身の環境で試して、その圧倒的なスピードの差を体感してください。あなたの業務効率化ライフが劇的に変わることを確信しています。それでは、次のステージでお会いしましょう!

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