混在するスライドの「境界」を制する:VBAによるPDF自動分割・最適化アーキテクチャ
現場の泥臭い要求ほど、エンジニアの真価が問われるものはない。「横向きのプレゼン資料の中に、なぜかA4縦の補足資料が混ざっている。これをそれぞれ別のPDFにしてくれ」。この一見単純な要求は、PowerPointのオブジェクトモデルとPDFレンダリングエンジンの深淵を覗く入り口となる。
本稿では、単なるオートメーションの域を超え、メモリリークを許さず、システム資源を枯渇させない「堅牢な分割処理」の極意を伝授する。
—
1. 混在レイアウトの検知:論理的境界の特定
PowerPointにおいて「向き」は`PageSetup`のプロパティとしてスライド単位ではなくマスター(あるいはスライドサイズ設定)単位で管理される。しかし、実務上の「混在」は、「スライドサイズが異なるスライドを無理やり1ファイルに押し込んでいる」という状況を指す。
この際、`Slide.Master.Width`と`Height`を比較するだけでは不十分だ。我々は、`PageSetup`の継承関係を追い、各スライドがどの「セクション」や「サイズ設定」に属しているかを判定しなければならない。
—
2. 実装コード:メモリ安全な分割アルゴリズム
VBAのガーベッジコレクションは非常に遅い。明示的な`Nothing`の代入は宗教論争だが、巨大なプレゼンテーションを扱う際、COM参照の解放を怠ると、`ppExport`時にプロセスがハングアップする。
以下のコードは、スライドの縦横比を比較し、動的にPDFを生成するアーキテクチャだ。
Option Explicit
‘ 伝説のアーキテクトによる、メモリ安全なPDF分割エンジン
Public Sub ExportSplitPDFsByOrientation()
Dim pptApp As Object: Set pptApp = Application
Dim pres As Presentation: Set pres = pptApp.ActivePresentation
Dim sld As Slide
Dim tempPres As Presentation
Dim i As Long
‘ 出力パスの定義(環境に合わせて適宜調整)
Dim pathLandscape As String: pathLandscape = pres.Path & “\Landscape_Output.pdf”
Dim pathPortrait As String: pathPortrait = pres.Path & “\Portrait_Output.pdf”
‘ 分割用の空プレゼンをメモリ上に生成
Dim presL As Presentation, presP As Presentation
Set presL = pptApp.Presentations.Add(msoFalse)
Set presP = pptApp.Presentations.Add(msoFalse)
‘ スライドを判定して一時プレゼンへ複製
For Each sld In pres.Slides
If sld.Master.Width > sld.Master.Height Then
sld.Copy
presL.Slides.Paste
Else
sld.Copy
presP.Slides.Paste
End If
Next sld
‘ 出力実行とメモリ解放のルーチン
Call SafeExport(presL, pathLandscape)
Call SafeExport(presP, pathPortrait)
‘ オブジェクトの明示的解放(プロセスを確実に終了させる)
presL.Close
presP.Close
Set presL = Nothing
Set presP = Nothing
MsgBox “分割出力が完了しました。”
End Sub
Private Sub SafeExport(targetPres As Presentation, filePath As String)
If targetPres.Slides.Count > 0 Then
‘ ppFixedFormatTypePDFを利用した高速レンダリング
targetPres.SaveAs filePath, ppSaveAsPDF
End If
End Sub
—
3. シニアエンジニアが意識すべき「隠れた罠」
① COMオブジェクトのライフサイクル管理
`Application.Presentations.Add`で生成したインスタンスは、プログラム終了までメモリに居座る。`Close`を呼ぶだけでは不十分なケースが多い。特に大規模な画像を含むPPTXの場合、メモリの断片化が致命的となる。必要であれば、Windows APIの `CoFreeUnusedLibraries` を呼び出すレベルの配慮が必要だ。
② PDFエンジンとフォントの埋め込み
`SaveAs`によるPDF出力は、背後でOSの印刷ドライバと連動している。環境依存のフォントが含まれている場合、出力されたPDFが文字化けするリスクがある。これを防ぐには、事前に`ExportAsFixedFormat`メソッドを用い、`EmbedTrueTypeFonts`プロパティを制御するのが定石だ。
③ システム間連携の拡張性
もしこの処理を自動化サーバー(タスクスケジューラ等)で動かすなら、`DisplayAlerts = ppAlertsNone` を忘れず設定せよ。ダイアログが一つ表示されるだけで、自動化プロセスは永久停止する。
—
結論:コードは「対話」である
自動化とは、ただ単にマウス操作を代替することではない。対象となるドキュメントの構造、メモリの呼吸、そしてOSとの対話である。
今回紹介したコードは、あくまで「骨子」だ。本番環境では、これに加えてエラーハンドリング(`On Error GoTo`によるスタックトレースの保存)を実装し、どのスライドで変換に失敗したかをログに出力する仕組みを組み込むこと。それが、真の「業務自動化エンジニア」として、保守運用フェーズで生き残るための最低条件である。
さあ、退屈な手作業をコードで塗り替え、システム管理者としての誇りを取り戻そう。質問があればいつでも歓迎する。ただし、基本のリファレンスを読まないような甘い質問は受け付けない。
