【実務・中級編】【中級者】容量の大きいPPTXファイルを、挿入された画像を圧縮しながら別名で保存してファイルサイズを軽量化するマクロ – PowerPoint VBA解析バイブル

スポンサーリンク

PowerPointの肥大化を葬る:画像圧縮と最適化を極めるVBAアーキテクチャ

現場のエンジニアが陥る最大の罠は、「PowerPointのファイルサイズは、ただの保存操作では制御できない」という事実を軽視することだ。高解像度画像を貼り付ければ、スライドの枚数に関わらずファイルは膨れ上がる。そして、その肥大化したメモリを抱えたままVBAを叩けば、いずれメモリリークや意図しないクラッシュを招く。

今日は、場当たり的なマクロではなく、「堅牢性」と「再利用性」を担保したプロフェッショナルな画像圧縮・最適化ツールの設計思想を伝授する。

—

1. なぜ「単純なSaveAs」ではいけないのか

多くの初心者は `ActivePresentation.SaveAs` を呼ぶだけで満足するが、それだけでは画像データは圧縮されない。PowerPointが内部で抱える高解像度の生データは、明示的に「圧縮コマンド」をトリガーしない限り、そのままファイルに書き込まれる。

我々が採用すべきは、CommandBars.ExecuteMso を用いたUIスレッドへの介入だ。しかし、これには明確な弱点がある。非同期的な挙動を取ることがあり、連続して呼び出すと制御不能になる。これを安全に制御するアーキテクチャが必要だ。

—

2. 堅牢な圧縮・最適化エンジンの設計

以下のコードは、以下の設計指針に基づいている。
1. 安全性: ファイルを上書きせず、必ず別名で保存する。
2. 整合性: `DoEvents` を適切に配置し、OSとの同期ズレを防ぐ。
3. 保守性: 設定値を定数で管理し、環境の変化(パスや圧縮率)に即座に対応する。

プロダクションコード:OptimizePresentation.vba

Option Explicit

‘ 肥大化したプレゼンテーションを圧縮し、別名で保存するプロフェッショナル・メソッド
Public Sub CompressAndSavePresentation()
Dim sourcePath As String
Dim targetPath As String
Dim fso As Object

Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 現在のファイルパスを取得
sourcePath = ActivePresentation.FullName
If sourcePath = “” Then
MsgBox “先にファイルを保存してください。”, vbCritical
Exit Sub
End If

‘ 保存先の生成(_optimizedを付与)
targetPath = fso.BuildPath(fso.GetParentFolderName(sourcePath), _
fso.GetBaseName(sourcePath) & “_optimized.” & fso.GetExtensionName(sourcePath))

On Error GoTo ErrorHandler

‘ 1. まず一度別名で保存して状態を確定させる
ActivePresentation.SaveCopyAs targetPath

‘ 2. 保存したファイルを開き直して操作対象にする
Dim targetPres As Presentation
Set targetPres = Presentations.Open(targetPath)
targetPres.Windows(1).Activate

‘ 3. 画像圧縮コマンドを叩く (PictureCompressDialog)
‘ ※注意: “PicturesCompress”はPowerPointのバージョンにより引数が異なる場合がある
‘ ここでは最も汎用的なダイアログをトリガーする方法を採用
Application.CommandBars.ExecuteMso “PicturesCompress”

‘ 4. 圧縮ダイアログの処理待ち(ここはUI操作のため、ユーザーへの配慮が必要)
MsgBox “画像圧縮の設定ダイアログが表示されます。” & vbCrLf & _
“「OK」を押して処理を完了してください。”, vbInformation

‘ 5. 最適化して保存
targetPres.Save
targetPres.Close

MsgBox “最適化が完了しました: ” & vbCrLf & targetPath, vbInformation
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub

—

3. 実務で「生き残る」ための3つの鉄則

このコードをそのまま使うだけでなく、以下の「現場の知見」を付け加えてほしい。

① CommandBars.ExecuteMsoの危うさ

`ExecuteMso` は本来の「ボタンクリック」をエミュレートする。そのため、PCの処理速度や環境によっては、コマンドが完了する前に次のコードが走ってしまうことがある。本番環境で自動化を極めるなら、`SendKeys` でダイアログ内の「OK」を自動送信する手法もあるが、推奨はしない。UI制御は常に「人間が介在する余地」を残すのが、バグを生まないエンジニアの矜持だ。

② ファイルロックとメモリ管理

`Presentations.Open` した後は、必ず `Close` を行うこと。大規模なPPTXを扱う際、メモリ上に複数のプレゼンテーションが残留すると、Office全体のパフォーマンスが低下する。常に `Set targetPres = Nothing` で明示的にオブジェクトを開放する癖をつけよ。

③ データベース連携への拡張性

もしこのマクロをDB連携ツールの一部にするなら、ファイルパスを引数で受け取る `Sub` に書き換えるべきだ。`ActivePresentation` に依存する設計は、将来的に「別プロセスからバッチ処理で一括変換したい」という要求が来た瞬間に破綻する。

—

最後に:エンジニアとしての指針

「コードを書くこと」は手段であって目的ではない。あなたの仕事は、重い資料を待たされる同僚の時間を奪還することだ。

今回紹介したコードは、あくまで「爆弾」を解体するための安全装置である。これをベースに、あなたの業務環境に合わせて、フォルダ内の全PPTXを一括処理するループ処理を追加するなり、ログ出力機能を追加するなりして、最強の自動化ツールに昇華させてほしい。

技術は使う者の器で決まる。このコードが、あなたの自動化の旅路の一助となることを願う。

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