【入門編】【中級者】複数のプレゼンテーションを一括オープンし、指定した文字列を一括置換した上で、元のフォーマットを保持したまま一斉に上書き保存する検索置換ツール – PowerPoint VBA解析バイブル

スポンサーリンク

こんにちは!PowerPoint VBAの世界へようこそ。
マクロの記録ボタンを押したはいいものの、「あれ、生成されたコードがなんだか難解だぞ…」「複数のファイルを一括で処理したいのに、どう書けばいいかわからない」と立ち止まっていませんか?

大丈夫。ここをクリアすれば、あなたも立派な業務自動化エンジニアの仲間入りです。

今回は、実務で本当によくある「複数ファイルの一括検索・置換・上書き保存」というテーマに挑みます。年度更新やクライアント名の変更で、何十個ものPowerPointファイルを1つずつ開いてコピペして…なんて、もう残業の元。VBAのエンジンをフル回転させて、一瞬で終わらせちゃいましょう。

先輩エンジニアが、裏側の仕組みや陥りやすい罠も含めて優しく手取り足取り解説しますね。

—

1. なぜ「複数ファイルの一括処理」でつまずくのか?

PowerPoint VBAの基本は、Excel VBAとよく似ています。しかし、PowerPoint特有の「オブジェクトの構造」と「ライフサイクル(開いて閉じる)」を理解していないと、ファイルが壊れたり、メモリがパンクしたりする原因になります。

特に、検索・置換を行うときは以下の3点を押さえることが極意です。

1. ファイル(Presentation)の正しい開き方と閉じ方
2. テキストボックス(Shape)の階層構造の深さ
3. 「余計なウィンドウを表示しない(高速化と安定化)」のテクニック

これらをすべて盛り込んだ「実戦でそのまま使えるプロのコード」を次章で公開します。

—

2. 実装コード:一括検索・置換ツール

以下のコードを、Excelの標準モジュール(または適当なPowerPointのVBAエディタ)に貼り付けてください。今回は安全かつ確実な運用のため、「操作するファイルを格納するフォルダを指定し、その中にあるすべての `.pptx` を一網打尽にする」設計にしています。

Option Explicit

‘ =================================指定フォルダ内のPPTXを一括置換するメインプロシージャ=================================
Sub BatchSearchAndReplace()
Dim fso As Object
Dim targetFolder As Object
Dim targetFile As Object
Dim pptApp As PowerPoint.Application
Dim targetPres As Presentation

‘ 検索ワードと置換ワードの設定
Dim searchWord As String
Dim replaceWord As String

searchWord = “【旧クライアント名】” ‘ ← ここを変更
replaceWord = “【新クライアント名】” ‘ ← ここを変更

‘ ユーザーにフォルダを選択させる
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
fd.Title = “置換したいPowerPointファイルが入っているフォルダを選んでください”

If fd.Show <> -1 Then Exit Sub ‘ キャンセルされたら終了

Dim folderPath As String
folderPath = fd.SelectedItems(1) & “\”

‘ FileSystemObjectでフォルダ内のファイルを走査
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set targetFolder = fso.GetFolder(folderPath)

Dim fileCount As Long
fileCount = 0

‘ 画面描画を停止してマクロの実行速度を劇的に上げる(お作法!)
With Application
.ScreenUpdating = False
End With

‘ フォルダ内の全ファイルをループ
For Each targetFile In targetFolder.Files
‘ 拡張子が .pptx のファイルのみを対象にする(一時ファイル “~$” は除外)
If LCase(fso.GetExtensionName(targetFile.Name)) = “pptx” _
And Left(targetFile.Name, 2) <> “~$” Then

‘ プレゼンテーションを開く
‘ ※ Presentations.Open の引数: (FileName, ReadOnly, Untitled, WithWindow)
‘ WithWindow:=msoFalse にすることで、画面をチラつかせずに裏で高速処理します
Set targetPres = Presentations.Open(FileName:=targetFile.Path, _
ReadOnly:=msoFalse, _
Untitled:=msoFalse, _
WithWindow:=msoFalse)

‘ メインの置換処理を実行
Call ReplaceTextInPresentation(targetPres, searchWord, replaceWord)

‘ 変更を保存して閉じる
targetPres.Save
targetPres.Close

fileCount = fileCount + 1
End If
Next targetFile

‘ 画面描画を復元
Application.ScreenUpdating = True

‘ 完了メッセージ
MsgBox “処理が完了しました!” & vbCrLf & _
“処理したファイル数: ” & fileCount & “件”, vbInformation, “一括置換ツール”

‘ オブジェクトの解放
Set targetPres = Nothing
Set targetFolder = Nothing
Set fso = Nothing
End Sub

‘ =================================プレゼンテーション内の文字列を置換するサブルーチン=================================
Private Sub ReplaceTextInPresentation(pres As Presentation, sWord As String, rWord As String)
Dim sld As Slide
Dim shp As Shape
Dim trng As TextRange

‘ 1. 通常のスライドをループ
For Each sld In pres.Slides
‘ スライド上のシェイプ(図形・テキストボックスなど)をループ
For Each shp In sld.Shapes
Call ProcessShape(shp, sWord, rWord)
Next shp
Next sld

‘ 2. マスタービュー(スライドマスター・レイアウト)内のテキストも忘れないように網羅
Dim cMaster As Design
For Each cMaster In pres.Designs
For Each shp In cMaster.SlideMaster.Shapes
Call ProcessShape(shp, sWord, rWord)
Next shp
For Each shp In cMaster.TitleMaster.Shapes
Call ProcessShape(shp, sWord, rWord)
Next shp
Next cMaster

End Sub

‘ =================================シェイプの種類に応じた再帰的テキスト置換=================================
Private Sub ProcessShape(shp As Shape, sWord As String, rWord As String)
On Error Resume Next ‘ 万が一テキストを持たないシェイプでエラーが出ても止まらないようにする

‘ テキストフレームを持っているか?
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
Set trng = shp.TextFrame.TextRange
‘ 文字列の置換実行
trng.Replace FindWhat:=sWord, ReplaceWhat:=rWord, WholeWords:=False, MatchCase:=False
End If
End If

‘ グループ化されているシェイプ(GroupShape)の場合の再帰処理
If shp.Type = msoGroup Then
Dim subShp As Shape
For Each subShp In shp.GroupItems
Call ProcessShape(subShp, sWord, rWord)
Next subShp
End If

‘ テーブル(表)の中のテキスト処理
If shp.HasTable Then
Dim r As Long, c As Long
Dim tbl As Table
Set tbl = shp.Table
For r = 1 To tbl.Rows.Count
For c = 1 To tbl.Columns.Count
If tbl.Cell(r, c.Shape.TextFrame.HasText) Then ‘ 念のため
tbl.Cell(r, c.Shape.TextFrame.TextRange.Replace FindWhat:=sWord, ReplaceWhat:=rWord, WholeWords:=False, MatchCase:=False)
End If
Next c
Next r
End If

On Error GoTo 0
End Sub

—

3. コードの心臓部:ここがプロのこだわりポイント

初心者から一歩抜け出すために、このコードに隠された「エンジニアのこだわり」をいくつか解説しておきます。

① `WithWindow:=msoFalse` でバックグラウンド処理

PowerPointのマクロで最も時間がかかる原因の一つが「スライドが画面に描画される視覚的コスト」です。`Presentations.Open` の引数に `WithWindow:=msoFalse` を渡すことで、PowerPointのウィンドウを表示させずにバックグラウンド(メモリ上)だけでファイルを開いて閉じることができます。画面がパチパチ切り替わらないので、見ていてストレスフリーですし圧倒的に高速です。

② スライドマスターやグループ化への配慮

PowerPointの厄介なところは、「テキストが普通のスライドだけでなく、スライドマスターやグループ化された図形、さらには表(テーブル)の中に隠れている」という点です。
今回のコードでは、`ProcessShape` サブルーチンの中でグループ化(`msoGroup`)やテーブル(`HasTable`)を網羅し、さらにマスタービュー(`pres.Designs`)までしっかりスキャンするように設計しています。「置換したはずなのに、タイトルロゴ付近の文字だけ変わってない…!」というよくある失敗を防ぎます。

③ 一時ファイル(`~$`)の華麗なスルー

WindowsでPowerPointファイルを開いている最中、同じ名前の頭に `~$` がついた隠しファイルが自動生成されます。これをうっかりプログラムが読み込もうとすると、「ファイルがロックされています」というお馴染みのエラーにぶつかります。
コード内の `If Left(targetFile.Name, 2) <> “~$”` というガード条件によって、このトラブルをスマートに回避しています。

—

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

開発現場でこのツールを動かすときに、よくあるトラブルシューティングをまとめておきます。

  • Q. 「コンパイルエラー: ユーザー定義型は定義されていません」と言われます。
  • A. PowerPointのVBAエディタ(VBE)で実行していますか? あるいはExcelから動かす場合は、VBEの「ツール」>「参照設定」から 「Microsoft PowerPoint XX.X Object Library」 にチェックが入っているか確認してください。
  • Q. 置換されたはずの文字が、一部の図形で変わっていません。
  • A. その文字が「テキストボックス」ではなく「ワードアート」や「画像データ(OCRが必要なもの)」になっている可能性があります。また、テキストが途中で改行コードや書式の都合で分断されていると、一括置換にヒットしない場合があります。

—

まとめ

今回は、複数のプレゼンテーションを一括オープンし、指定した文字列を元のフォーマットを保持したまま一斉に上書き保存する検索置換ツールを解説しました。

ここをクリアすれば、PowerPoint VBAの「ファイルのライフサイクル管理」「シェイプの階層構造(グループやテーブル)」の基本はバッチリです!

手作業で数時間かかっていた絶望的なコピペ作業を、この数行のスクリプトに置き換えて、ぜひあなたの自由な時間を手に入れてください。それでは、次のオートメーションの世界でお会いしましょう!

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