はじめに:静的なスライドショーの限界を超えろ
会議やプレゼンの現場で、こんな非効率なやり取りを見たことはないだろうか。
「今回の参加者は経営層なので、技術的な詳細スライド(No.12〜25)はスキップして、総括と財務インパクトだけに絞りましょう」
「では、事前に別バージョンのファイルを作っておきます……(別名保存ポチー)」
ナンセンスだ。スライドの数が膨大になればなるほど、ファイルの分散、修正漏れの温床、そしてバージョン管理の破綻という「VBAエンジニアの悪夢」が現実のものとなる。
真の自動化エンジニアであれば、「マスターデータ(全スライド)は1つに統合し、目的に応じたビュー(カスタムスライドショー)をコードで動的に錬成して即座に上映する」べきだ。
今回は、PowerPoint VBAにおける隠れたキーパーツである `SlideShowSettings` と `NamedSlideShows` オブジェクトを極限まで使いこなし、実務の現場で即座に使える堅牢な動的カスタムスライドショー構築術を伝授する。
—
1. 圧倒的な実務優位性:なぜ `NamedSlideShows` なのか
PowerPointの標準機能にも「カスタムスライドショー」の手動作成機能はある。しかし、あれは人間の手作業を前提としたおもちゃに過ぎない。
ビジネスの現場では、以下のような動的な要求が常に発生する。
- Excelのマスターリストや、スライド内の特定の「タグ(シェイプ名やテキスト)」を読み取り、合致するページだけを自動抽出したい。
- 参加者の権限や持ち時間(15分版、30分版)に応じて、上映構成を1秒で再構築したい。
- 一過性のショーが終わったら、不要な設定をクリーンアップし、ファイルにゴミを残したくない。
これらを完全に自動化できるのが、`Presentation.SlideShowSettings` を起点としたVBAアプローチだ。
—
2. 堅牢な設計のためのアーキテクチャ
実務で動くコードを書くためには、PowerPoint特有の「オブジェクトのライフサイクル」を意識しなければならない。特に `NamedSlideShows` を操作する際は、以下の3点に細心の注意を払う必要がある。
1. 同名カスタムショーの衝突回避
既存の同名ショーが残っている状態で新規作成を試みると、ランタイムエラーや予期せぬ挙動を引き起こす。必ず「存在確認・削除(イミテーションの排除)」から入る。
2. インデックスの罠
スライドコレクションのインデックス(`Slide.SlideIndex`)は、ユーザーの並び替えによって容易に変動する。特定のスライドを指定する際は、必ず固有の `SlideID` またはタグベースで識別せよ。
3. エラーハンドリングと状態の復元
スライドショー実行中に予期せぬエラーが発生した場合、PowerPointの表示モードが中途半端な状態で固まることがある。`.Run` メソッドを叩く前の状態を担保する設計が不可欠だ。
—
3. プロダクションコード:動的カスタムスライドショー生成&実行エンジン
以下のコードは、スライドのノート(Notes)や特定のテキストフレームに特定のキーワード(例: `[Exec]`)が含まれているページだけを抽出し、一時的なカスタムスライドショーを動的に生成して即座に上映する実務レベルのモジュールである。
Option Explicit
‘ ==============================================================================
‘ モジュール名: modDynamicSlideShow
‘ 概要 : 特定条件(タグやキーワード)に合致するスライドを動的に抽出し、
‘ カスタムスライドショーとして即座に上映するプロフェッショナル向けコード
‘ ==============================================================================
Public Sub LaunchTargetedSlideShow()
Dim targetPresentation As Presentation
Set targetPresentation = ActivePresentation
‘ 1. 定数の定義
Const SHOW_NAME As String = “Dynamic_Auto_Show”
Const SEARCH_KEYWORD As String = “[Exec]” ‘ 抽出条件となるキーワード
Dim slideList() As String
ReDim slideList(0)
Dim slideCount As Long
slideCount = 0
Dim sld As Slide
Dim i As Long
On Error GoTo ErrorHandler
‘ 2. 条件に合致するスライドの抽出(スライドノートまたはタイトルを走査)
For Each sld In targetPresentation.Slides
If IsTargetSlide(sld, SEARCH_KEYWORD) Then
ReDim Preserve slideList(slideCount)
‘ SlideIDではなく、カスタムショー登録にはスライド名(例: “Slide3”)を使用する
slideList(slideCount) = sld.Name
slideCount = slideCount + 1
End If
Next sld
‘ 抽出ヒットチェック
If slideCount = 0 Then
MsgBox “条件に合致するスライドが見つかりませんでした。” & vbCrLf & _
“検索キーワード: ” & SEARCH_KEYWORD, vbExclamation, “自動化エンジン”
Exit Sub
End If
‘ 3. 既存の同名カスタムスライドショーが存在する場合は事前に破棄(ゴミを残さない)
Call RemoveExistingCustomShow(targetPresentation, SHOW_NAME)
‘ 4. 新規カスタムスライドショーの動的構築
Dim targetShows As NamedSlideShows
Set targetShows = targetPresentation.SlideShowSettings.NamedSlideShows
‘ Array変数をVariants型にキャストして渡すのがポイント
Dim varSlides As Variant
varSlides = slideList
targetShows.Add Name:=SHOW_NAME, SafeSlideIDs:=varSlides
‘ 5. スライドショーの設定と実行
With targetPresentation.SlideShowSettings
.ShowType = ppShowTypeSpeaker ‘ 発表者ビュー
.LoopUntilStopped = False
.AdvanceMode = ppSlideAdvanceUseSlideTimings
.RangeType = ppShowNamedSlideShow ‘ カスタムショーを指定
.SpecifiedNamedShow = SHOW_NAME ‘ 対象のカスタムショー名
‘ 実行
.Run
End With
CleanUp:
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Number & ” – ” & Err.Description, vbCritical, “致命的エラー”
Resume CleanUp
End Sub
‘ ==============================================================================
‘ 補助関数: スライドが抽出対象か判定する
‘ ==============================================================================
Private Function IsTargetSlide(targetSlide As Slide, keyword As String) As Boolean
IsTargetSlide = False
‘ 条件A: スライドのノートテキスト内にキーワードが含まれるか
Dim notesText As String
On Error Resume Next
notesText = targetSlide.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
On Error GoTo 0
If InStr(1, notesText, keyword, vbTextCompare) > 0 Then
IsTargetSlide = True
Exit Function
End If
‘ 条件B: スライド内の特定の図形(タイトル等)に含まれるか(必要に応じて拡張)
Dim shp As Shape
For Each shp In targetSlide.Shapes
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
If InStr(1, shp.TextFrame.TextRange.Text, keyword, vbTextCompare) > 0 Then
IsTargetSlide = True
Exit Function
End If
End If
End If
Next shp
End Function
‘ ==============================================================================
‘ 補助手続き: 同名カスタムショーの安全な削除
‘ ==============================================================================
Private Sub RemoveExistingCustomShow(pres As Presentation, showName As String)
Dim nss As NamedSlideShow
On Error Resume Next
Set nss = pres.SlideShowSettings.NamedSlideShows(showName)
On Error GoTo 0
If Not nss Is Nothing Then
nss.Delete
End If
End Sub
—
4. チーフアーキテクトからの実践的アドバイス
上記のコードをそのままプロジェクトに組み込むだけで、単なる「スライドの束」が「動的なプレゼンテーション・プラットフォーム」へと生まれ変わる。しかし、これをさらに実務で洗練させるための視点を授けよう。
外部データ(ExcelやDB)との連携
今回のコードではスライド内のテキスト(`[Exec]`)を判定基準にしたが、これを拡張して「実行直前にExcelから今日の出席者リストを読み込み、対応するアジェンダのスライド番号だけを配列に格納して `NamedSlideShows.Add` する」というアーキテクト構成にすれば、究極のダイナミック・プレゼンテーションが完成する。
クリーンアップの重要性
カスタムスライドショー(`NamedSlideShows`)のデータは、実は `.pptx` ファイルのメタデータとして保存される。つまり、コードで動的生成したショーをそのまま放置してファイルを上書き保存すると、無駄なゴミデータがファイル内に蓄積し肥大化の原因となる。
必要であれば、スライドショー終了後のイベント(`Application_SlideShowEnd`)をフックし、プログラム側で自動的にカスタムショーを削除する仕組みまで作り込むのが、真に洗練されたプロの仕事である。
—
おわりに:コードでプレゼンを支配せよ
手作業でのスライド選別や、何種類もの派生ファイル管理は今日で終わりにするべきだ。
PowerPoint VBAのオブジェクトモデルを正しく理解し、メモリとアプリケーションのライフサイクルをコントロール下に入れれば、プレゼンテーションの運用コストは劇的にゼロへと近づく。
あなたの手元にあるその退屈な定型業務を、鮮やかなコードで今すぐ自動化してほしい。
