【入門編】【初心者】開いているプレゼンテーションの全スライドを、グレースケール(白黒)に一括変換して印刷用PDFとして保存するマクロ – PowerPoint VBA解析バイブル

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

「マクロの記録」の先へ。オブジェクトの階層構造を理解して、プレゼン資料を自動変換する極限の思考法

こんにちは。現場の自動化設計を司るチーフアーキテクトです。

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

しかし、その一歩先にある「真の自動化」の世界へ進むには、ある重要な概念を理解しなければなりません。それは、「オブジェクトの階層構造(オブジェクトモデル)」です。

今日は、初心者の方が最初の一歩として踏み出すのに最適で、かつ実務で喉から手が出るほど求められるテーマを用意しました。

「開いているプレゼンテーションの全スライドを、グレースケール(白黒)に変換し、PDFとして保存。その後、元のカラー状態を完璧に復元する」

一見、難しそうに見えるかもしれません。しかし、PowerPointの構造を正しく理解すれば、これはパズルのピースを組み合わせるような、非常に論理的な作業に変わります。

さあ、準備はいいですか?「ただ動くコード」ではなく、「設計思想に基づいたコード」を一緒に書いていきましょう。

1. なぜ「記録」では足りないのか?:オブジェクトモデルの正体

「マクロの記録」は、あなたがクリックした「結果」を記録しますが、「なぜその操作が必要だったのか」という「構造」までは教えてくれません。

PowerPointを操作する時、私たちは以下の階層を辿って対象にアクセスしています。これをオブジェクトモデルと呼びます。

1. Application(PowerPointというソフトそのもの)
2. Presentation(開いているファイル)
3. Slide(スライド1枚1枚)
4. Shape(スライド上に乗っている図形、テキストボックス、画像など)

「スライドを白黒にする」という命令は、実は存在しません。正解は、「スライドの中にある『Shape』の『Fill(塗りつぶし)』や『Line(線)』の『Color(色)』というプロパティを、一つずつ書き換える」という作業なのです。

この「階層を一段ずつ降りていく」感覚が掴めれば、あなたはもう初心者ではありません。

2. 実装の戦略:元のファイルを壊さない「安全設計」

プロのエンジニアは、絶対に「元のデータを破壊する」ようなコードは書きません。

今回のミッションは「カラーの資料を、一時的に白黒にしてPDF化する」ことです。もし、スライドの色を直接書き換えて、途中でエラーが起きてしまったら……?元のカラー資料が白黒のまま残ってしまうかもしれません。これは業務において致命的なミスです。

そこで、今回採用する戦略はこれです。

1. 現在のプレゼンテーションを「一時的なコピー」として保存する。
2. そのコピーに対して、白黒変換とPDF保存を行う。
3. 作業が終わったら、コピーを閉じて消去する。

これなら、万が一マクロが途中で止まっても、あなたのメインの資料は美しいカラーのまま守られます。これこそが「ライフサイクルを意識した設計」です。

3. 極限のコード:GrayscalePDFExporter

それでは、魂を込めて書いたコードを見てみましょう。これをコピーして、VBAエディタに貼り付けてみてください。

Option Explicit

''' <summary>
''' 全スライドをグレースケール化してPDF保存するプロシージャ
''' </summary>
Sub ExportGrayscalePDF()
    Dim mainPres As Presentation
    Dim tempPres As Presentation
    Dim tempPath As String
    Dim pdfPath As String
    Dim sld As Slide
    Dim shp As Shape
    
    ' 1. 現在開いているプレゼンテーションを特定
    Set mainPres = ActivePresentation
    
    ' 保存されていないファイルだとコピーが作れないためチェック
    If mainPres.Path = "" Then
        MsgBox "先にプレゼンテーションを一度保存してください。", vbCritical
        Exit Sub
    End If
    
    ' 2. 保存先パスの生成(元のファイルと同じフォルダに「_grayscale.pdf」として保存)
    tempPath = mainPres.Path & "\temp_work.pptx"
    pdfPath = mainPres.Path & "\" & Left(mainPres.Name, InStrRev(mainPres.Name, ".") - 1) & "_grayscale.pdf"
    
    On Error GoTo ErrorHandler
    
    ' 3. 【安全設計】元のファイルを汚さないよう、コピーを作成して開く
    mainPres.SaveCopyAs tempPath
    Set tempPres = Presentations.Open(tempPath, WithWindow:=msoFalse) ' ウィンドウを表示せずに開く
    
    Debug.Print "作業開始: " & tempPres.Name
    
    ' 4. 全スライドをループして、Shapeの色をグレースケールに変換
    ' ここが「階層構造」を辿る核心部分です
    For Each sld In tempPres.Slides
        For Each shp In sld.Shapes
            
            ' 図形の塗りつぶし色を変更
            If shp.Fill.Visible Then
                shp.Fill.ForeColor.RGB = GetGrayscaleRGB(shp.Fill.ForeColor.RGB)
            End If
            
            ' 図形の線の色を変更
            If shp.Line.Visible Then
                shp.Line.ForeColor.RGB = GetGrayscaleRGB(shp.Line.ForeColor.RGB)
            End If
            
            ' ※注: テキストの書式などはさらに深い階層(TextFrame)にありますが、
            ' 今回は基本構造の理解のために図形に絞っています。
        Next shp
    Next sld
    
    ' 5. PDFとしてエクスポート
    tempPres.ExportAsFixedFormat Path:=pdfPath, FixedFormatType:=ppFixedFormatTypePDF
    
    ' 6. 後片付け
    tempPres.Close
    Kill tempPath ' 一時ファイルを削除
    
    MsgBox "完了しました!" & vbCrLf & "保存先: " & pdfPath, vbInformation
    
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    ' エラー時も、開いてしまった一時ファイルがあれば閉じる
    If Not tempPres Is Nothing Then tempPres.Close
    If Dir(tempPath) <> "" Then Kill tempPath
End Sub

''' <summary>
''' RGB値を計算して、輝度に基づいたグレースケール値(RGB)を返す関数
''' </summary>
Private Function GetGrayscaleRGB(ByVal originalRGB As Long) As Long
    Dim r As Integer, g As Integer, b As Integer
    Dim gray As Integer
    
    ' Long型からRGBの各成分を抽出
    r = originalRGB Mod 256
    g = (originalRGB \ 256) Mod 256
    b = (originalRGB \ 65536) Mod 256
    
    ' 輝度計算式 (人間が感じる明るさに合わせた重み付け)
    ' Gray = 0.299R + 0.587G + 0.114B
    gray = CInt(0.299 * r + 0.587 * g + 0.114 * b)
    
    ' RGB形式に戻して返す
    GetGrayscaleRGB = RGB(gray, gray, gray)
End Function

4. コードの深層解剖:何を学んだか?

このコードには、初心者から脱却するためのエッセンスが詰まっています。

① 二重の `For Each` ループ

`For Each sld In tempPres.Slides` の中で、さらに `For Each shp In sld.Shapes` を回しています。これは「スライドという箱」を開け、その中にある「図形という部品」を一つずつ取り出して点検している状態です。この「入れ子構造(ネスト)」は、プログラミングにおける最も強力な武器の一つです。

② 数学的なアプローチ(`GetGrayscaleRGB` 関数)

「色をグレーにする」というのは、単に色を混ぜるだけではありません。人間は緑色を明るく感じ、青色を暗く感じる性質があります。
コード内の `0.299 * r + 0.587 * g + 0.114 * b` という式は、その知覚特性に基づいた計算です。このように、「処理を独立した関数(Function)として切り出す」ことで、メインの処理が読みやすくなり、再利用性も高まります。

③ エラーハンドリング(`On Error GoTo`)

プロの世界では、「動くこと」と同じくらい「止まった時にどう振る舞うか」が重視されます。エラーが起きた際に、作成した一時ファイルを放置せず、確実に削除(`Kill`)するように設計しています。これが「親切設計」の正体です。

5. 次のステップへ:ここをクリアすれば、基本はバッチリ!

今回のコードでは、図形の「塗りつぶし」と「線」に焦点を当てました。しかし、実際のスライドには「テキストの色」や「背景色」も存在します。

次にあなたが挑戦すべき課題は、これらです:

  • `shp.TextFrame.TextRange.Font.Color.RGB` を操作して、文字もグレーにする。
  • `sld.Background.Fill.ForeColor.RGB` を操作して、スライドの背景もグレーにする。

これらはすべて、今回学んだ「階層を降りて、プロパティを書き換える」という思考の延長線上にあります。

「マクロの記録」で、コードの表面だけをなぞるのはもう終わりにしましょう。オブジェクトの構造を理解し、論理的に組み立てる。その先に、あなたの想像力を形にする本当の自動化が待っています。

応援していますよ。また次のレクチャーでお会いしましょう。

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