こんにちは!PowerPoint VBAの世界へようこそ。
マクロの記録ボタンを押すだけの自動化から一歩抜け出し、「自分の手でプレゼンテーションを自在にコントロールしたい」と願うあなたへ。
今回は、実務の現場で絶大な効果を発揮する「セクション単位の構造化エクスポートツール」の作り方を解説します。
何十ページ、何百ページもある巨大なプレゼンテーション資料。「第1章だけ別のチームに共有したい」「章ごとにファイルを分割して整理したい」そんなとき、手動でスライドを選んで別名保存を繰り返していませんか?
プロのエンジニアなら、こんな単純作業は一瞬でVBAに片付けさせましょう。
ここをクリアすれば、PowerPoint VBAのオブジェクト構造の基本はバッチリです。一緒に温かく、そして深く学んでいきましょう!
—
1. なぜ「セクション分割」なのか?(VBAの恩恵)
PowerPointには、スライドをグループ化する「セクション」という機能があります。
このセクション情報をVBAから操作できるようになると、プレゼンテーションを「単なるスライドの集まり」ではなく、「意味のある構造体」として扱えるようになります。
しかし、PowerPoint VBAはExcel VBAに比べてネット上の情報が少なく、戸惑うことも多いはずです。特に「どのオブジェクトをどう辿ればいいのか(オブジェクト階層)」でつまずきがちです。
今回のツールを通じて、「マスターすべきVBAの3大原則」が自然と身につきます。
1. 現在開いているプレゼンテーション(ActivePresentation)の正確な捉え方
2. セクションという特殊なグループを走査(ループ)する方法
3. スライドを安全に別ファイルへ切り出し、ナンバリングして保存する手順
—
2. 開発の全体像とコードの設計図
まずは、今回作成するマクロの動きをイメージしてください。
1. 実行確認: 現在開いているファイルにセクションが存在するかチェックする。
2. ループ処理: 先頭のセクションから最後のセクションまで順番に見ていく。
3. スライドの特定: そのセクションに含まれる「最初のスライドの番号」と「スライドの枚数」を算出する。
4. 新規作成とコピー: 新しいプレゼンテーションを作成し、該当するスライドをごっそりコピーする。
5. 保存: 元のファイルの保存場所(パス)を自動取得し、連番付きのファイル名で保存する。
言葉で書くと難しそうですが、コードにすると非常に洗練されたものになります。
—
3. 実装コード:セクション分割エクスポートマクロ
以下のコードを、PowerPointのVBAエディタ(`Alt` + `F11` で起動)の標準モジュールに貼り付けてください。
Sub ExportPresentationsBySection()
‘ —————————————————————–
‘ 処理名: セクション単位の構造化エクスポートツール
‘ 概要 : アクティブなプレゼンテーションのセクションを検出し、
‘ 章ごとに個別のPPTXファイルとしてナンバリング保存します。
‘ —————————————————————–
‘ エラーハンドリングの準備
On Error GoTo ErrorHandler
Dim srcPres As Presentation
Set srcPres = ActivePresentation
‘ 1. 保存先が確保されているか(一度も保存していない新規ファイルではないか)チェック
If srcPres.Path = “” Then
MsgBox “このプレゼンテーションはまだ保存されていません。” & vbCrLf & _
“一度適当な場所に保存してからマクロを実行してください。”, vbExclamation, “保存エラー”
Exit Sub
End If
Dim sectionCount As Long
sectionCount = srcPres.SectionProperties.Count
If sectionCount = 0 Then
MsgBox “このプレゼンテーションにはセクションが設定されていません。”, vbExclamation, “セクション確認”
Exit Sub
End If
Dim i As Long
Dim secName As String
Dim startSlide As Long
Dim slideCount As Long
Dim newPres As Presentation
Dim savePath As String
Dim baseName As String
Dim ext As String
Dim fso As Object
‘ ファイル名と拡張子を分離するための準備(FileSystemObject使用)
Set fso = CreateObject(“Scripting.FileSystemObject”)
baseName = fso.GetBaseName(srcPres.Name)
ext = “.” & fso.GetExtensionName(srcPres.Name)
‘ 画面描画を停止して処理を高速化
With Application
.ScreenUpdating = msoFalse
End With
‘ 2. セクションごとのループ処理
For i = 1 To sectionCount
‘ セクション名を取得
secName = srcPres.SectionProperties.Name(i)
‘ セクションの開始スライド番号を取得
startSlide = srcPres.SectionProperties.FirstSlide(i)
‘ セクション内のスライド枚数を取得
‘ ※最後のセクションの場合は、「全体の枚数 – 開始位置 + 1」で計算します
If i < sectionCount Then
slideCount = srcPres.SectionProperties.FirstSlide(i + 1) - startSlide
Else
slideCount = srcPres.Slides.Count - startSlide + 1
End If
' 3. 新規プレゼンテーションを作成(元のスライドサイズを引き継ぐため、空のプレを生成)
Set newPres = Presentations.Add(msoTriStateTrue)
newPres.PageSetup.SlideWidth = srcPres.PageSetup.SlideWidth
newPres.PageSetup.SlideHeight = srcPres.PageSetup.SlideHeight
' 4. 対象のスライド範囲を新規ファイルにコピー
srcPres.Slides.Range(Array(GetSlideRangeArray(startSlide, slideCount))).Copy
' 新規プレゼンテーションのデフォルトで作成される不要な1枚目のスライドを削除するため、
' 貼り付けてから最初のスライドを消す、またはペースト時に調整します。
' ※PowerPoint VBAではPaste前後にスライド調整が必要です。
newPres.Slides(1).Delete ' デフォルトスライドの削除
newPres.Windows(1).View.Paste
' 5. ナンバリング付きで保存
' 例: 元ファイル名_01_セクション名.pptx
Dim formattedIndex As String
formattedIndex = Format(i, "00") ' "01", "02" とゼロ埋め
' ファイル名に使えない文字(パスカル文字等)を簡易置換する場合はここでケア
Dim safeSecName As String
safeSecName = ReplaceInvalidChars(secName)
savePath = srcPres.Path & "\" & baseName & "_" & formattedIndex & "_" & safeSecName & ext
newPres.SaveAs savePath
newPres.Close
Next i
' 画面描画の再開
Application.ScreenUpdating = msoTrue
MsgBox "すべてのセクションの切り出しが完了しました!" & vbCrLf & _
"保存先: " & srcPres.Path, vbInformation, "処理成功"
Exit Sub
ErrorHandler:
Application.ScreenUpdating = msoTrue
MsgBox "予期せぬエラーが発生しました。" & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"エラー内容: " & Err.Description, vbCritical, "致命的なエラー"
End Sub
' -----------------------------------------------------------------
' 補助関数: 指定した開始位置と枚数からスライド番号の配列を作る
' -----------------------------------------------------------------
Function GetSlideRangeArray(startIdx As Long, count As Long) As Variant
Dim arr() As Long
ReDim arr(0 to count - 1)
Dim j As Long
For j = 0 To count - 1
arr(j) = startIdx + j
Next j
GetSlideRangeArray = arr
End Function
' -----------------------------------------------------------------
' 補助関数: ファイル名に使えない禁則文字を全角などに置換する
' -----------------------------------------------------------------
Function ReplaceInvalidChars(ByVal txt As String) As String
txt = Replace(txt, "\", "¥")
txt = Replace(txt, "/", "/")
txt = Replace(txt, ":", ":")
txt = Replace(txt, "", "*")
txt = Replace(txt, "?", "?")
txt = Replace(txt, """", """)
txt = Replace(txt, "<", "<")
txt = Replace(txt, ">“, “>”)
txt = Replace(txt, “|”, “|”)
ReplaceInvalidChars = txt
End Function
—
4. コードの深掘りポイント(知的なエンジニアへのステップ)
ここでは、中級者を目指すあなたが「おっ」と唸るような、PowerPoint特有のポイントを解説します。
① `SectionProperties` という強力な武器
Excelには「シート」がありますが、PowerPointには「セクション」という論理的な区切りがあります。
`ActivePresentation.SectionProperties` を使うことで、セクションの数(`Count`)、名前(`Name`)、そしてそのセクションが「何枚目のスライドから始まるか(`FirstSlide`)」を完全に把握できます。
特に `FirstSlide(i + 1) – startSlide` という引き算で、そのセクションに何枚のスライドが含まれているかを割り出すアルゴリズムは、実務の自動化で非常によく使うテクニックです。
② スライドの範囲指定と `Array`
`srcPres.Slides.Range(Array(…))` という記述に注目してください。
PowerPoint VBAでは、連続した複数のスライドをまとめてコピーしたいとき、配列(Array)の中にスライド番号を詰めて渡す必要があります。この補助関数 `GetSlideRangeArray` が、その面倒な配列生成を裏でスマートにこなしてくれています。
③ ファイル名禁則文字のガード
セクション名に「Q&A」や「1. 概要」といった文字が入ることはよくあります。Windowsのファイル名に使えない記号(`\` や `:` など)が含まれていると、`SaveAs` メソッドで容赦なくエラーが起きて止まってしまいます。
それを防ぐのが `ReplaceInvalidChars` 関数です。実務で耐えうる堅牢なマクロにするためには、こうした「例外への備え」が欠かせません。
—
5. 陥りやすいエラーと回避のコツ
- 「このプレゼンテーションはまだ保存されていません」と怒られる
- 原因: 新規作成して一度も名前を付けて保存していない状態(パスが空)では、ファイルの保存場所(`srcPres.Path`)が取得できません。
- 対策: 必ず一度デスクトップなどに保存してからマクロを実行してください。
- 実行時に画面がチラチラして遅い
- コード内の `Application.ScreenUpdating = msoFalse` によって描画を止めていますが、万が一エラーで途中で止まった場合に画面が真っ暗なままになることがあります。その場合は、イミディエイトウィンドウで `Application.ScreenUpdating = True` と入力して実行すれば元に戻ります。
—
6. まとめ
お疲れ様でした!今回は、セクション情報を読み解き、章ごとに美しいナンバリングファイルへと構造化エクスポートする実用ツールを作成しました。
ここをクリアしたあなたなら、PowerPointのオブジェクトモデル(Presentation, SectionProperties, SlideRange)の扱いに自信が持てたはずです。
日々の面倒な手作業をコードで自動化し、クリエイティブで本質的な仕事に集中する――それこそが、私たちが目指すエンジニアの姿です。
ぜひ現場の業務に組み込んで、周囲をあっと言わせる自動化を体験してください!
