こんにちは!PowerPoint VBAの世界へようこそ。
マクロの記録から一歩踏み出し、「自分で動かすコード」を書き始めると、なんだかワクワクしますよね。
今回は、実務でバリバリ使える「ウィンドウ制御の安全管理」という、ちょっとプロっぽいテーマでお話しします。
「長時間のバッチ処理をしている最中に、ユーザーがうっかりPowerPointのウィンドウをバッ×と閉じてしまった!」……想像するだけで冷や汗モノですよね。エラーが起きてフリーズしたり、最悪の場合はファイルが破損したりします。
でも、安心してください。ここをクリアすれば、あなたの書くマクロの「安全性」と「信頼性」は一気にプロのレベルに達します。優しく、そして本質的なところまで丁寧に解説していきますね。
—
1. PowerPoint VBAの基礎:オブジェクトの「土台」を知ろう
まず、PowerPoint VBAの全体像を軽く整理しておきましょう。
PowerPointを操作するとき、VBAの世界では以下のような階層(ツリー構造)でオブジェクトを管理しています。
- Application(アプリ全体・神様的存在)
- └ Presentations(開いているプレゼンテーションのコレクション)
- └ Windows(画面上のウィンドウのコレクション) ← ★今回主役の「窓口」
「ウィンドウ」を管理するのが `Windows` というオブジェクトです。そして、現在開いているウィンドウの数は `Application.Windows.Count` というプロパティで一発で取得できます。
なぜウィンドウの数を監視する必要があるのか?
通常、マクロが動いている最中はユーザーは操作できませんが、マルチスレッド的な処理や、ループが長引くバッチ処理の最中、あるいはユーザーが別ウィンドウを閉じようとした際など、「処理の途中で画面が消滅する」というイレギュラーは起こり得ます。
もし画面(ウィンドウ)が消えた後に、VBAが「次のスライドの色を変えて!」と命令しようものなら……PowerPointはパニックを起こし、実行時エラーを吐いて強制終了してしまいます。
これを未然に防ぐのが、「ウィンドウ監視ロジック」です。
—
2. 【実践】ウィンドウ消失をリアルタイムでトラップするコード
それでは、実際に現場で使える堅牢なコードを見てみましょう。
処理のループの中で、定期的に「まだウィンドウはあるか?」を監視し、もしユーザーがウィンドウを閉じたら、安全に処理を中断(ロールバック)する仕組みです。
Sub SafeBatchProcessing()
Dim targetWindowCount As Long
Dim i As Long
‘ 【1】処理開始時点のウィンドウ数を記憶しておく
targetWindowCount = Application.Windows.Count
If targetWindowCount = 0 Then
MsgBox “操作対象のウィンドウが存在しません。”, vbCritical
Exit Sub
End If
MsgBox “長時間のバッチ処理を開始します。” & vbCrLf & _
“※処理中にウィンドウを閉じないでください。”, vbInformation
‘ 【2】例として、長時間を要するループ処理を模擬
For i = 1 to 10
‘ ————————————————–
‘ 【重要】ループの各ステップで「ウィンドウが生存しているか」を監視
‘ ————————————————–
If Application.Windows.Count < targetWindowCount Then
' ユーザーがウィンドウを手動で閉じた、または消失した場合
GoTo UserAborted
End If
' --- ここに本来の重い処理を書く ---
' 例: ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange.Text = "処理 " & i
' 処理の重さをシミュレート(1秒待機)
Application.Wait (Now + TimeValue("0:00:01"))
' 画面を最新の状態に更新
DoEvents ' ← これが超重要!OSに制御を返し、ユーザーの操作を受け付ける
Next i
MsgBox "バッチ処理が正常に完了しました!", vbInformation
Exit Sub
UserAborted:
' 【3】緊急回避・ロールバック処理
' ウィンドウが閉じられたため、ActivePresentationなどのオブジェクト操作は厳禁!
MsgBox "警告:処理の途中でウィンドウが閉じられました。" & vbCrLf & _
"データ破損を防ぐため、処理を安全に中断しました。", vbExclamation
' 必要であればログ出力や一時ファイルのクリーンアップをここに記述
End Sub
---
3. コードのキモ:ここが分かればバッチリ!
上記のコードで、特に重要なポイントを2つ解説します。
① `DoEvents`(ドゥ・イベント)の魔法
ループの中にこっそり入っている `DoEvents`。これ、めちゃくちゃ重要です。
VBAが重い処理を黙々とこなしている最中、パソコンは他の操作を受け付けなくなります(画面が固まったようになります)。しかし `DoEvents` を挟むことで、「一瞬だけOSに主導権を渡し、ユーザーがウィンドウを閉じようとしたアクションなどを検知・処理する余裕」を与えられます。
これがないと、ウィンドウが閉じられたことすらVBAが気づくのが遅れてしまいます。
② エラーを起こさせない「引き際」
`UserAborted` ラベルに飛んだあと、`ActivePresentation` や `ActiveWindow` などのオブジェクトを触ってはいけません。すでに「それらが存在しない世界」だからです。
だからこそ、メッセージボックスを出すだけに留め、静かに処理を終わらせるのが、トラブルを防ぐ最大のコツです。
—
おわりに
今回は、`Application.Windows.Count` を監視して、ユーザーの神出鬼没な操作からマクロを守る堅牢なテクニックをご紹介しました。
「動くだけのコード」から「どんな状況でも破綻しないコード」へ。
ここをクリアできれば、もうあなたは初心者ではありません。自信を持って、実務の自動化に挑戦してくださいね。
それでは、また次回のテックでお会いしましょう!バッチリ使いこなしてくださいね。
