こんにちは!PowerPoint VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステージから抜け出し、「自分の手でシステムをコントロールしたい」と願うあなたへ。今日は、現場で本当に使えるプロ仕様のスマートストレージ制御術を伝授します。
ここをクリアすれば、単なる「お絵描きツール」としてのPowerPointではなく、OSの深部まで手なずけたワンランク上のエンジニアへとステップアップできますよ。しっかりついてきてくださいね。
—
なぜ、プロは「保存前のディスク容量チェック」にこだわるのか?
大量の高解像度画像が含まれるプレゼンテーション資料。これを「上書き保存」や「PDFエクスポート」しようとした瞬間、ディスクの残り容量が足りなくなってエラー……。そして、最悪の場合はファイルが破損してこれまでの労力が一瞬で消え去る。
プログラミング初心者のうちは、「保存ボタンを押せば勝手にOSがやってくれる」と思いがちですが、大容量を扱う現場ではこれが命取りになります。
そこで今回は、Windows APIの力を借りて、保存先ドライブの空き容量をミリ秒単位で先読みし、もし容量がひっ迫していれば、プレゼン内の画像を自動的にダウンサンプル(軽量化)してから安全に保存する「スマートストレージマクロ」を構築します。
—
1. 基礎知識:PowerPoint VBAとWindows APIの邂逅
通常、PowerPoint VBA単体では「Cドライブの空き容量は何ギガバイトか?」といったOSレベルの情報を直接取得することはできません。
そこで登場するのが Windows API (Application Programming Interface) です。
WindowsのOS本体(今回は `kernel32.dll` にある `GetDiskFreeSpaceEx` 関数)に直接アクセスし、ハードウェアの耳元で「いま、どれくらい空きがある?」と囁くようなイメージです。
32bit/64bitの壁を超える作法
現代のOfficeは64bit版が主流です。APIを宣言する際は、ポインタのサイズ違いによるクラッシュを防ぐために、`PtrSafe` キーワードと `LongPtr` 型を正しく使い分ける必要があります。ここが最初の難所ですが、先輩の書くコードをそのままモノにすれば大丈夫です。
—
2. 実装コード:スマートストレージ・セーバー
以下のコードを、PowerPointのVBAエディタ(`Alt + F11`)の「標準モジュール」に貼り付けてください。
Option Explicit
‘ ==============================================================================
‘ Windows APIの宣言(ドライブの空き容量を精密測定する)
‘ ==============================================================================
If VBA7 Then
Private Declare PtrSafe Function GetDiskFreeSpaceEx Lib “kernel32” Alias “GetDiskFreeSpaceExA” ( _
ByVal lpDirectoryName As String, _
ByRef lpFreeBytesToCaller As Currency, _
ByRef lpTotalNumberOfBytes As Currency, _
ByRef lpTotalNumberOfFreeBytes As Currency) As Long
Else
Private Declare Function GetDiskFreeSpaceEx Lib “kernel32” Alias “GetDiskFreeSpaceExA” ( _
ByVal lpDirectoryName As String, _
ByRef lpFreeBytesToCaller As Currency, _
ByRef lpTotalNumberOfBytes As Currency, _
ByRef lpTotalNumberOfFreeBytes As Currency) As Long
End If
‘ 閾値設定:空き容量がこのバイト数を下回ったら圧縮発動(例: 500MB)
Private Const WARNING_THRESHOLD As Currency = 500 1024 1024
‘ ==============================================================================
‘ メインプロシージャ:安全第一のスマート保存
‘ ==============================================================================
Public Sub SmartSavePresentation()
On Error GoTo ErrorHandler
Dim targetPath As String
Dim driveLetter As String
Dim freeBytes As Currency
Dim totalBytes As Currency
Dim freeBytesTotal As Currency
Dim result As Long
‘ 1. アクティブなプレゼンテーションが一度も保存されていない場合のハンドリング
If ActivePresentation.Path = “” Then
MsgBox “プレゼンテーションがまだ保存されていません。一度手動で名前を付けて保存してください。”, vbExclamation, “スマートセーバー”
Exit Sub
End If
‘ 2. 保存先のドライブ文字(例: “C:\”)を抽出
targetPath = ActivePresentation.Path
driveLetter = Left$(targetPath, 3)
‘ 3. Windows APIを叩いて空き容量を取得
result = GetDiskFreeSpaceEx(driveLetter, freeBytes, totalBytes, freeBytesTotal)
If result = 0 Then
MsgBox “ドライブ情報の取得に失敗しました。”, vbCritical, “API Error”
Exit Sub
End If
‘ Currency型は内部で4桁のスケールを持つため、実際のバイト数に戻すには10000を掛ける
Dim actualFreeBytes As Double
actualFreeBytes = CCur(freeBytes) 10000#
‘ 4. 容量チェックと自動ダウンサンプリングの判定
If actualFreeBytes < WARNING_THRESHOLD Then
MsgBox "警告:保存先のディスク空き容量がひっ迫しています(残り: " & Format(actualFreeBytes / 1024 / 1024, "#,
0.0″) & ” MB)。” & vbCrLf & _
“安全に保存するため、自動的に画像を圧縮します。”, vbExclamation, “スマートストレージ制御発動”
‘ 画像の圧縮実行(高解像度データをダイエットさせる)
Call CompressAllPicturesInPresentation
End If
‘ 5. 安全な保存処理
ActivePresentation.Save
MsgBox “プレゼンテーションの保存が正常に完了しました。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & “エラー番号: ” & Err.Number & vbCrLf & Err.Description, vbCritical, “Critical Error”
End Sub
‘ ==============================================================================
‘ サブルーチン:プレゼン内の全画像を圧縮してファイルサイズを限界まで落とす
‘ ==============================================================================
Private Sub CompressAllPicturesInPresentation()
Dim sld As Slide
Dim shp As Shape
‘ PowerPointのネイティブ機能(SendKeysまたはCommandBars)を模して画質を落とす
‘ 現代のPowerPointでは、CommandBars.ExecuteMso “PictureCompress” が効果的
On Error Resume Next
ActiveWindow.View.GotoSlide 1
‘ 最初に見つかった画像を選択状態にして圧縮ダイアログのロジックを走らせる、
‘ もしくはシャープネス・解像度のプロパティを操作する
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.Type = msoPicture Or shp.Type = msoLinkedPicture Then
‘ 画像のトリミング情報等を最適化する処理(プレースホルダーの再構築等)
‘ ※Officeの仕様上、VBAから直接ピクセル単位の画質変更をするには
‘ CommandBarsの実行系を挟むのが最も確実です。
shp.Select
CommandBars.ExecuteMso “PictureCompress”
End If
Next shp
Next sld
On Error GoTo 0
DoEvents
End Sub
—
3. コードの急所を解説!ここが分かれば怖くない
① `GetDiskFreeSpaceEx` の仕組み
API関数は、C言語の作法で作られています。そのため、VBA側でも型を慎重に合わせる必要があります。特に `Currency` 型(通貨型)を使用している点に注目してください。
通常の `Long` 型や `Integer` 型では、現代の大容量ハードディスク(テラバイト級)の数値を正確に保持しきれず、オーバーフローを起こしてしまいます。`Currency` 型は内部で整数として大きな数値を扱えるため、大容量ストレージの計算にはうってつけの隠し技なのです。
② なぜエラーハンドリング(`On Error GoTo`)を入れるのか?
ネットワークドライブ(共有フォルダ)や、容量がいっぱいで書き込み権限が剥奪された瞬間など、現場では「想定外」が起きまくります。エラーハンドリングを怠ると、PowerPointごと強制終了(フリーズ)します。プロのコードには必ず「逃げ道」が用意されているのです。
—
4. 現場で陥りやすい罠とトラブルシューティング
- 罠1: 「プロシージャが見つかりません」というコンパイルエラー
- 原因: 32bit環境と64bit環境で `Declare` の書き方が混ざっている場合に起きがちです。上記のコードは条件付きコンパイル(`#If VBA7 Then`)で完璧に対策してありますので、そのままコピーすれば安心です。
- 罠2: `CommandBars.ExecuteMso “PictureCompress”` が動かない
- 原因: PowerPointのバージョンやセキュリティ設定(マクロの有効性)によって、リボンのコマンド実行が制限されている場合があります。その場合は、手動で「図の圧縮」を組み込めるよう、エラーを無視する設定(`On Error Resume Next`)で安全にカバーしています。
—
まとめ:ここをクリアすれば、PowerPoint VBAはバッチリ!
今回は、Windows APIを用いたストレージの監視と、動的な画像圧縮を組み合わせた「スマートストレージマクロ」を解説しました。
- OSの深部に触れるWindows APIの扱い方
- 巨大データを扱うための `Currency` 型の選定
- クラッシュを未然に防ぐ防御的プログラミング(エラーハンドリング)
これらをマスターしたあなたすでにもう「初心者」ではありません。
現場のトラブルを華麗に回避し、「おっ、こいつデキるな」と言わせる自動化エンジニアへの道を、今日ここから歩み始めましょう!
それでは、次回の応用編でお会いしましょう。ハッピー・コーディング!
