PowerPoint VBAを極める:WithEventsによる「ミリ秒精度」スライドショー監視エンジンの構築
PowerPointの標準機能には、スライドショーの経過時間を精密に制御・監視する機能は存在しません。多くの開発者は`OnTime`メソッドや、スライドの「切り替えタイミング」に依存した場当たり的な実装に終始しますが、それはプロフェッショナルな設計とは呼べません。
真に堅牢な監視システムを構築するには、`Application`オブジェクトの`WithEvents`によるイベントリスナーの掌握が不可欠です。本稿では、スライドショーの開始から終了までを完全に制御下に置き、ミリ秒単位の経過時間を取得するアーキテクチャを伝授します。
—
1. なぜ「標準機能」ではいけないのか?
PowerPointのイベントは、本来「ユーザーの操作(クリックやキー入力)」に反応するために設計されています。しかし、これをバックグラウンドの「常駐監視タスク」として利用するには、以下の3つの壁を突破しなければなりません。
1. イベントの揮発性: セッションが途切れるとクラス変数がクリアされ、監視が停止する。
2. 精度と負荷: `DoEvents`を乱用したループ処理はCPUを焼き尽くし、UIのレスポンスを悪化させる。
3. プレゼンテーションのライフサイクル: スライドショーの開始・終了時にメモリを確実に開放・再構築する設計が必要。
これらを解決するのが、カスタムクラスを活用したイベント・デリゲート設計です。
—
2. 実装:ミリ秒監視エンジン(プロダクションコード)
まずは、イベントをフックするためのクラスモジュールを作成します。
手順1:クラスモジュール「clsPPTMonitor」の作成
このクラスがプレゼンテーションのライフサイクルを監視し、スライドショーの開始を検知します。
‘ クラスモジュール名: clsPPTMonitor
Option Explicit
‘ PowerPointのアプリケーションイベントを監視
Public WithEvents App As PowerPoint.Application
‘ スライドショー開始時のイベント
Private Sub App_SlideShowBegin(ByVal Wn As SlideShowWindow)
Debug.Print “スライドショー開始: ” & Now
‘ ここでタイマー開始処理を呼び出す
Call StartTimer
End Sub
‘ スライドショー終了時のイベント
Private Sub App_SlideShowEnd(ByVal Pres As Presentation)
Debug.Print “スライドショー終了: ” & Now
‘ ここでタイマー停止処理を呼び出す
Call StopTimer
End Sub
手順2:標準モジュールでの監視エンジン実装
ここではAPIを呼び出し、高精度な経過時間を取得します。
‘ 標準モジュール: modTimer
Option Explicit
‘ Windows API: ミリ秒単位の時刻取得
Private Declare PtrSafe Function GetTickCount Lib “kernel32” () As Long
Dim Monitor As New clsPPTMonitor
Dim StartTime As Long
Dim IsRunning As Boolean
‘ 監視を開始するエントリポイント
Public Sub InitializeMonitor()
Set Monitor.App = Application
MsgBox “監視システムが起動しました。”
End Sub
Public Sub StartTimer()
StartTime = GetTickCount()
IsRunning = True
‘ 本来はここで非同期処理やログ出力のループを回す
Debug.Print “タイマー始動…”
End Sub
Public Sub StopTimer()
Dim EndTime As Long
EndTime = GetTickCount()
IsRunning = False
Debug.Print “経過時間: ” & (EndTime – StartTime) & ” ms”
End Sub
—
3. 現場で生き残るための「鉄則」
このコードを実務で運用する際、以下の3点に細心の注意を払ってください。
① インスタンスの生存期間(ライフサイクル管理)
`Monitor`変数が標準モジュール内の静的変数(あるいはグローバル)として定義されていることを確認してください。もしこれがプロシージャ内変数であれば、処理終了とともに解放され、イベントは一切発火しません。
② データベース・ログ連携の罠
スライドショー実行中にデータベースへ書き込む場合、同期処理(Sync)は厳禁です。I/O待ちが発生し、スライドの遷移がカクつきます。必ず非同期的なログバッファリングを行い、スライドショー終了後に一括コミットする設計を採用してください。
③ エラーハンドリングの極意
VBAはランタイムエラーが発生すると、`WithEvents`のコネクションが強制切断される仕様があります。監視系ツールでは、すべてのイベントハンドラに `On Error Resume Next` を適切に配置し、メインの監視ループが「死なない」ことを最優先してください。
—
結論:コードは「状態」を管理するためにある
今回紹介した設計手法は、単なるタイマー機能ではありません。PowerPointという閉じた環境に「外部的な状態監視」を持ち込むためのフレームワークです。
- 保守性の鍵: ロジックはクラスモジュールに封じ込め、外部からは`InitializeMonitor`を呼ぶだけのインターフェースにする。
- 拡張性: `App_SlideShowNextSlide`を実装すれば、スライドごとの滞在時間をミリ秒単位でDBに記録する「行動分析ツール」へ即座に進化します。
「動けば良い」コードは素人でも書けます。しかし、「イベントが途切れる可能性を考慮し、再接続のロジックまで組み込む」のが、我々プロフェッショナルの仕事です。さあ、あなたの業務自動化を次のフェーズへ引き上げてください。
