【実務・中級編】【タスクバーのクリーン化】大量のプレゼンを並列処理する際にタスクバーのアイコン氾濫を防ぐ、”Application.ShowWindowsInTaskbar”の動的制御テクニック – PowerPoint VBA解析バイブル

スポンサーリンク

【タスクバーのクリーン化】大量プレゼン一括処理時のアイコン氾濫と描画遅延を極限まで抑え込むVBA制御術

大量のPowerPointファイルをシステムからバッチ出力したり、数百枚の提案書から特定データを抽出して集計したりする自動化ツールを開発したことがあるだろうか。

その際、誰もが直面する「最悪のユーザー体験」がある。
マクロを実行した瞬間、タスクバーにPowerPointのアイコンが猛烈な勢いで増殖し、画面が激しくフラッシュし、PCの動作が極端に重くなる現象だ。

最悪の場合、OSの描画リソース(GDIオブジェクト)を使い果たしてPowerPointごと強制終了(クラッシュ)する。

「動くだけのコード」を書く素人プログラマは、これを「スペックの限界」と言い訳する。だが、我々プロフェッショナルは違う。PowerPointが持つウィンドウ制御メカニズムを完全に掌握し、タスクバーを美しくクリーンに保ったまま、バックグラウンドで超高速に処理を完遂させる。

今回は、この描画負荷とタスクバーの氾濫を極限まで抑え込む`Application.ShowWindowsInTaskbar`の動的制御テクニックについて、実戦的なアーキテクチャと共に解説する。

1. なぜタスクバーが氾濫するのか? その致命的な弊害

PowerPointのデフォルトの挙動では、プレゼンテーションファイル(`Presentation` オブジェクト)を1つ開くたびに、対応するウィンドウ(`DocumentWindow` オブジェクト)が生成され、OSのタスクバーに個別のアイコンとして登録される。

これは人間のマルチタスクには便利だが、VBAによるバッチ処理(一括処理)においては「百害あって一利なし」である。

描画負荷とメモリリークのメカニズム

1. OSの描画オーバーヘッド: ウィンドウが生成・表示されるたびに、Windowsのデスクトップウィンドウマネージャー(DWM)はタスクバーのサムネイル描画やアニメーション処理を行う。これがCPU/GPUに莫大な負荷をかける。
2. GDIリソースの枯渇: Windowsは各ウィンドウに対して描画用のリソース(GDIオブジェクト)を割り当てる。数百ものファイルを連続処理すると、ガベージコレクション(メモリ解放)が追いつかず、GDIリソースが枯渇して描画が崩壊する。
3. ユーザーの作業妨害: 処理中にユーザーが別のアクティブウィンドウ(ExcelやTeamsなど)で作業しようとしても、PowerPointが最前面に割り込んできたり、フォーカスを奪ったりして作業を完全に妨害する。

これを解決するのが、PowerPointアプリケーションの隠れたプロパティ `Application.ShowWindowsInTaskbar` である。

2. 核心:`ShowWindowsInTaskbar` と `WithWindow` の二重盾

タスクバーの氾濫を防ぐための戦略は、単一のプロパティ操作だけでは完成しない
以下の「二重の盾」を組み合わせるのが、プロフェッショナルが採用する堅牢な設計パターンである。

第1の盾:`Application.ShowWindowsInTaskbar = False`

PowerPointアプリケーション全体に対し、「個別のプレゼンテーションをタスクバーに表示しない」よう命じる。
これを `False` に設定すると、どれだけ多くのプレゼンテーションを開いても、タスクバーにはメインのPowerPointアイコン(またはアクティブな1枚)しか表示されなくなる。

第2の盾:`Presentations.Open` の `WithWindow` 引数を `msoFalse` にする

そもそもウィンドウ自体を生成せずに、ファイル構造(DOM)だけをメモリにロードするテクニックだ。

‘ ウィンドウを生成せずに裏で開く
Set pptPres = Presentations.Open(FileName:=”C:\Temp\target.pptx”, WithWindow:=msoFalse)

この2つを組み合わせることで、「画面更新を発生させず、タスクバーも汚さず、メモリ上だけで高速に処理を回す」という極限のバックグラウンド処理が可能になる。

3. 実践:ステート(状態)の保存と復元という「黄金律」

ここで絶対にやってはならない、素人コードの典型例を示そう。

‘ 悪いコードの典型例(真似してはいけない)
Sub BadExample()
Application.ShowWindowsInTaskbar = False
‘ 何らかの処理
‘ エラーが起きると、設定が False のまま放置され、
‘ ユーザーが手動でPowerPointを使うときにタスクバーにファイルが出なくなる!
End Sub

`ShowWindowsInTaskbar` はアプリケーション共通の設定(グローバルステート)である。
マクロ実行中にエラーが発生して途中で処理が落ちた場合、この設定が `False` のまま残ってしまう。すると、ユーザーが普段通りにPowerPointを開いた際、「ファイルを2つ開いているのにタスクバーに1つしか出ない!壊れた!」という大クレームに発展する。

プロフェッショナルが書くコードは、「サンドイッチパターン(State Save & Restore)」を徹底する。
処理開始前の設定値を退避し、いかなる致命的エラーが発生しようとも、`Finally`(VBAでは `CleanUp` ラベル)で必ず元の状態に復元する

4. プロダクション環境仕様の実装コード

以下に、実務でそのまま利用できる、極めて堅牢な「一括処理テンプレートマクロ」を示す。
ファイル一覧の取得から、エラーハンドリング、ステートの復元、ゾンビプロセスの防止までを網羅している。

Option Explicit

”’

”’ 指定フォルダ内のすべてのPowerPointファイルをタスクバーを汚さずに高速一括処理する
”’

Public Sub BulkProcessPresentations()
Dim targetFolder As String
targetFolder = “C:\Temp\Slides\” ‘ ※環境に合わせて変更してください(末尾は「\」)

‘ ターゲットフォルダの存在確認
If Dir(targetFolder, vbDirectory) = “” Then
MsgBox “指定されたフォルダが存在しません: ” & targetFolder, vbCritical, “エラー”
Exit Sub
End If

‘ — グローバルステートの退避用変数 —
Dim originalShowInTaskbar As Boolean
Dim originalWindowState As PpWindowState

‘ — PowerPointオブジェクトマネジメント —
Dim pptApp As PowerPoint.Application
Set pptApp = PowerPoint.Application

‘ 1. 現在のユーザー設定(ステート)を保存
originalShowInTaskbar = pptApp.ShowWindowsInTaskbar

‘ 2. 高速化とサイレント化のための状態遷移
pptApp.FPSOn = False ‘ 描画フレームレート制御をオフ(非公開プロパティ、環境により無視されるが念のため)
pptApp.ShowWindowsInTaskbar = False

‘ ※PowerPoint VBAには「Application.ScreenUpdating = False」が存在しないため、
‘ ウィンドウの最小化や非表示化を組み合わせて描画を抑制する。

Dim fileName As String
fileName = Dir(targetFolder & “.ppt”) ‘ ppt, pptx, pptm を対象とする

‘ エラーハンドリングの強制開始
On Error GoTo ErrorHandler

Dim openedPres As PowerPoint.Presentation
Dim processedCount As Long
processedCount = 0

Do While fileName <> “”
Dim fullPath As String
fullPath = targetFolder & fileName

‘ 3. 「WithWindow:=msoFalse」でウィンドウを作らずにメモリ上にロード
‘ これにより、タスクバーへの露出だけでなく、画面への描画自体を完全にスキップする
Set openedPres = pptApp.Presentations.Open( _
FileName:=fullPath, _
ReadOnly:=msoTrue, _
WithWindow:=msoFalse)

‘ — [ビジネスロジックの実行領域] ————————————-
‘ ここに各プレゼンテーションに対する処理を記述する
‘ 例: テキストの置換、スライドのPDFエクスポート、統計情報の取得など

‘ (例として、スライド数をイミディエイトウィンドウに出力)
Debug.Print “処理中: ” & openedPres.Name & ” (スライド数: ” & openedPres.Slides.Count & “)”

‘ ———————————————————————-

‘ 4. 確実に保存せずに閉じる(編集した場合は、事前にSaveするかSaveChanges:=msoTrueにする)
openedPres.Close
Set openedPres = Nothing ‘ 確実にオブジェクト参照を解放

processedCount = processedCount + 1
fileName = Dir() ‘ 次のファイルへ
Loop

MsgBox processedCount & ” 件のプレゼンテーション処理が正常に完了しました。”, vbInformation, “処理完了”

CleanUp:
‘ 5. [最重要] どんな状況でも必ず元のユーザー設定に復元する
On Error Resume Next ‘ 復元処理中のエラーで無限ループに入るのを防ぐ

If Not openedPres Is Nothing Then
openedPres.Close
Set openedPres = Nothing
End If

‘ ステートの復元
pptApp.ShowWindowsInTaskbar = originalShowInTaskbar

‘ ガベージコレクションの強制(参照カウンタのクリア)
Set pptApp = Nothing
Exit Sub

ErrorHandler:
‘ エラー情報の記録
Dim errDetail As String
errDetail = “エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description & vbCrLf & _
“発生ファイル: ” & fileName

MsgBox “処理中に致命的なエラーが発生しました。設定を復元して終了します。” & vbCrLf & vbCrLf & errDetail, vbCritical, “システムエラー”

Resume CleanUp
End Sub

5. ディープダイブ:なぜ `WithWindow:=msoFalse` だけでは不十分なのか?

「`WithWindow:=msoFalse` で開くなら、`ShowWindowsInTaskbar = False` は不要ではないか?」

そう考える開発者は、PowerPointの「アドイン」や「ユーザーフォーム」の挙動、そして他システム(Excel VBAやAccess、C#など)からPowerPointをCOMコンポーネントとして自動操作する際の仕様を見落としている。

理由1:サードパーティ製アドインの挙動

PowerPointにインストールされている一部のアドイン(Think-CellやAcrobat PDF Makerなど)は、プレゼンテーションが `WithWindow:=msoFalse` で開かれたとしても、内部的にフックを検知して強制的にバックグラウンドで隠しウィンドウをアクティブ化することがある。この際、`ShowWindowsInTaskbar` が `True` のままだと、一瞬だけタスクバーにアイコンが出現して消える「ちらつき(Flicker)」が発生する。これを根絶するために、グローバルな設定変更が必要なのだ。

理由2:エラー発生時の「ゴーストウィンドウ」化

マクロが途中でクラッシュし、`msoFalse` で開いたオブジェクトの参照が失われた(Orphaned Objectになった)場合、そのプレゼンテーションはメモリ上に「ゴースト」として残る。
`ShowWindowsInTaskbar` が `True` だと、このゾンビ化したプレゼンテーションが突如タスクバーに出現し、クリックしても開けない「開かずのウィンドウ」としてデスクトップを汚染する。`False` に設定しておくことで、万が一のクラッシュ時にもユーザーのデスクトップ環境に「見えないゴミ」を露出させずに済む。

6. まとめ:美学なきコードにプロの価値はない

大量のデータを処理するシステムを作るとき、多くのプログラマは「処理スピード」と「ロジックの正確さ」だけに目を奪われがちだ。

しかし、真のプロフェッショナルは「実行中のOS全体の美しさと安定性」にも責任を持つ。

マクロを走らせた途端、タスクバーがドラムロールのように激しく波打ち、PCのファンが悲鳴を上げるようなツールは、ユーザーに「壊れるのではないか」という不安を与える。

今回紹介した `ShowWindowsInTaskbar` の動的制御と `WithWindow:=msoFalse` のサンドイッチパターンを実装することで、あなたの作成するツールは「静かに、エレガントに、そして圧倒的に高速に」タスクを遂行するようになる。

コードの美しさは、そのままシステムの堅牢性に直結する。ぜひ、あなたのプロジェクトの標準テンプレートとして組み込んでほしい。

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