【入門編】【初心者】スライドタイトルを自動スキャンして「目次ページ」をプログラムで動的生成し、先頭に挿入して保存するマクロ – PowerPoint VBA解析バイブル

スポンサーリンク
スポンサーリンク

【PowerPoint VBA掌握術】「マクロの記録」を卒業し、オブジェクトを操るエンジニアへの第一歩

こんにちは。自動化の世界へようこそ。

あなたがもし、「マクロの記録」ボタンを押し、マウスで行った操作をそのままコードに書き出す段階にいるのなら、おめでとうございます。あなたは今、プログラミングという広大な大陸の入り口に立っています。

しかし、同時に一つだけ伝えておかなければならないことがあります。「マクロの記録」は、あくまで「動作の断片」を記録するだけのツールであり、「ロジック(論理)」を構築するツールではない、ということです。

記録されたコードは、多くの場合 `Select` や `Activate` という言葉で溢れています。「これを選択して、次にここを選択して……」という、人間がマウスを動かす手順をなぞっただけのコードです。これでは、スライドの枚数が変わったり、構成が変わったりした瞬間に、プログラムは脆くも崩れ去ります。

今日は、そんな「記録」の壁を突破し、PowerPointという構造(オブジェクトモデル)を直接操作して、「全スライドのタイトルを読み取り、自動で目次スライドを作成する」という、実戦的かつエレガントなコードを一緒に書いていきましょう。

ここをクリアすれば、あなたはもう「記録係」ではなく、「自動化エンジニア」の仲間入りです。

1. 思考の地図:PowerPointの「オブジェクトモデル」を知る

コードを書く前に、まず「地図」を手に入れましょう。エンジニアは、コードを書く前に「対象がどのような構造をしているか」をイメージします。

PowerPoint VBAの世界は、以下のような階層構造(オブジェクトモデル)になっています。

1. Application(PowerPointというソフトそのもの)
2. Presentation(開いているプレゼンテーション・ファイル)
3. Slide(個々のスライド)
4. Shape(スライド上に配置された図形やテキストボックス)
5. TextFrame(図形の中にある「テキストを保持する箱」)
6. TextRange(テキストの中の「文字そのもの」)

今回のミッションは、「Presentationの中にある全Slideを巡回し、各SlideのShapeの中からTitle(タイトル)を探し出し、そのTextRange(文字)を抜き出す」ことです。

この階層を一段ずつ降りていくイメージを持つことが、VBAをマスターする最大の近道です。

2. 実装:動的な目次生成マクロ

それでは、魂を込めて書いたコードを見ていきましょう。
このコードは、単に動くだけではありません。エラーを防ぎ、読み手が理解しやすい「保守性の高い」書き方を意識しています。

Option Explicit

''' <summary>
''' 全スライドのタイトルをスキャンし、先頭に目次スライドを自動生成して保存する。
''' </summary>
Sub GenerateDynamicTableOfContents()
    Dim pres As Presentation
    Dim targetSlide As Slide
    Dim tocSlide As Slide
    Dim tocShape As Shape
    Dim tocText As String
    Dim i As Integer
    Dim slideTitle As String
    
    ' 1. 対象となるプレゼンテーションをセット
    Set pres = ActivePresentation
    
    ' 2. 全スライドを巡回して、タイトルを収集する
    ' ※目次自体が重複しないよう、スライドの構成に注意してループを回します
    tocText = ""
    For i = 1 To pres.Slides.Count
        Set targetSlide = pres.Slides(i)
        
        ' スライドにタイトルが存在するかチェック
        If targetSlide.Shapes.HasTitle Then
            ' タイトルのテキストを取得
            slideTitle = targetSlide.Shapes.Title.TextFrame.TextRange.Text
            
            ' 空白でない場合のみ、目次用の文字列に追加
            ' 「スライド番号: タイトル名」の形式で蓄積
            If Trim(slideTitle) <> "" Then
                tocText = tocText & i & ". " & slideTitle & vbCrLf
            End If
        End If
    Next i
    
    ' 3. もしタイトルが一つも見つからなければ、処理を中断
    If tocText = "" Then
        MsgBox "タイトルが見つかりませんでした。スライドにタイトルを設定してください。", vbExclamation
        Exit Sub
    End If
    
    ' 4. 先頭に新しいスライド(目次用)を挿入
    ' ppLayoutText は「タイトルとコンテンツ」のレイアウト
    Set tocSlide = pres.Slides.Add(1, ppLayoutText)
    
    ' 5. 目次スライドのタイトルを設定
    tocSlide.Shapes.Title.TextFrame.TextRange.Text = "目次"
    
    ' 6. 目次スライドのコンテンツ部分に、収集したテキストを流し込む
    ' 2番目のShape(通常は本文用テキストボックス)を取得
    If tocSlide.Shapes.Count >= 2 Then
        Set tocShape = tocSlide.Shapes(2)
        tocShape.TextFrame.TextRange.Text = tocText
    Else
        MsgBox "目次スライドのレイアウト構成が特殊なため、本文の書き込みに失敗しました。", vbCritical
    End If
    
    ' 7. ファイルを保存(上書き保存)
    ' ※実務では、意図しない上書きを防ぐため、別名保存を検討することもあります
    pres.Save
    
    MsgBox "目次スライドの生成と保存が完了しました!", vbInformation
End Sub

3. プロの視点:コードの「急所」を解説する

このコードには、初心者が躓きやすいポイントを回避するための「知見」がいくつか隠されています。

① `Select` を使わない勇気

「マクロの記録」では必ず `targetSlide.Select` のようなコードが出てきます。しかし、プロは `Select` を使いません。`Select` は「画面を動かす」という重い処理を伴うため、実行速度を低下させ、予期せぬエラーの原因になります。
代わりに、`Set targetSlide = pres.Slides(i)` のように、オブジェクトを直接変数に代入して操作するのが鉄則です。

② `HasTitle` による安全装置

スライドには、タイトルが設定されていないものもあります。タイトルがないスライドに対して「タイトルを取れ!」と命令すると、VBAは「そんなものはない!」とエラーを吐いて止まってしまいます。
`If targetSlide.Shapes.HasTitle Then` という条件分岐を入れることで、プログラムの堅牢性(壊れにくさ)を高めています。

③ 文字列の蓄積(String Concatenation)

目次のテキストを作る際、ループの中で `tocText = tocText & …` と記述しています。これは、これまでの文字列に新しい行を継ぎ足していくテクニックです。`vbCrLf` は「改行」を意味する定数で、これを使うことで綺麗なリスト形式を作ることができます。

4. 陥りやすいエラーと対策

あなたがこのコードをカスタマイズする際、以下の点に注意してください。

  • 「目次自体が目次に載ってしまう」問題

今回のコードでは、まず全スライドをスキャンしてから「最後にスライドを追加」する、あるいは「スライド番号を先に確定させる」ロジックにしています。もし、スライドを追加した後に再度スキャンすると、新しく作った目次スライド自体をタイトルとして拾ってしまう「無限ループ的な重複」が起こります。

  • レイアウトの違い

`pres.Slides.Add(1, ppLayoutText)` で指定している `ppLayoutText` は、標準的な「タイトルとテキスト」のレイアウトを想定しています。もし、会社独自のテンプレートを使っていて、スライドの構造が特殊な場合、`tocSlide.Shapes(2)` で目的のテキストボックスが取れないことがあります。その場合は、`Shapes` のインデックス番号を調整する必要があります。

最後に:エンジニアへの道

いかがでしたか?
「タイトルをスキャンして、新しいスライドを作って、テキストを流し込む」

一見複雑に見えるこの動作も、オブジェクトの階層を一つずつ紐解いていけば、単純な命令の組み合わせに過ぎません。

プログラミングとは、魔法ではありません。「対象の構造を理解し、適切な命令を、適切な順番で届けること」。この本質さえ掴んでおけば、あなたはどんな自動化の壁も乗り越えていけるはずです。

さあ、次は自分でコードを少し書き換えてみてください。「フォントサイズを大きくするには?」「スライド番号を太字にするには?」……その試行錯誤の先にこそ、真のスキルが宿ります。

応援していますよ。次回の講義でお会いしましょう!

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