【テクニカル・上級編】【プロフェッショナル】WithEventsとPresentationオブジェクトのイベントを組み合わせた、スライドショー実行中の「ミリ秒単位」経過時間監視タイマー – PowerPoint VBA解析バイブル

スポンサーリンク

PowerPoint VBAを掌握する:ミリ秒単位の「スライドショー・イベント監視」アーキテクチャ

PowerPointの標準機能に頼る時代は終わった。プレゼンテーションの現場において、「スライドが切り替わったか」「何ミリ秒経過したか」を正確に制御したいという要求は、高度な自動化やインタラクティブなデモにおいて不可欠なピースだ。

しかし、VBAの `OnSlideShowPageChange` だけでは、イベントの捕捉が遅延し、ミリ秒単位の厳密な同期は不可能に近い。ここでは、Windows API(`Winmm.dll`)の高精度タイマーと、`WithEvents` を組み合わせた「常駐監視システム」の構築術を伝授する。

1. なぜ「標準機能」では足りないのか

PowerPointのイベントモデルは、UIスレッドの優先順位に依存する。スライド切り替えのトリガーは、描画プロセスが完了した後に発火するため、厳密な時間計測には数ミリ秒から数十ミリ秒の「ゆらぎ(ジッター)」が生じる。

シニアエンジニアとして突き詰めるべきは、「イベントを待つ」のではなく、「メモリ空間に常駐するタイマーがイベントを監視する」というアーキテクチャへの転換である。

2. 実装:高精度タイマー・イベント・コントローラー

まずは、スライドショーのライフサイクルを監視する `Class Module` を作成する。

クラスモジュール:`clsSlideShowMonitor`

‘ プロジェクト名: PPSlideController
‘ 目的: Windows APIを用いたミリ秒単位の監視とスライドショーイベントの連結
Option Explicit

Private Declare PtrSafe Function timeGetTime Lib “winmm.dll” () As Long

Public WithEvents App As Application
Private m_StartTime As Long

‘ スライドショー開始時の初期化
Private Sub App_SlideShowBegin(ByVal Wn As SlideShowWindow)
m_StartTime = timeGetTime()
Debug.Print “監視開始: ” & m_StartTime
End Sub

‘ ページ切り替え時の厳密なミリ秒計測
Private Sub App_SlideShowNextSlide(ByVal Wn As SlideShowWindow)
Dim currentTime As Long
currentTime = timeGetTime()

‘ 経過時間をミリ秒で算出
Debug.Print “切替時間: ” & (currentTime – m_StartTime) & ” ms”
End Sub

‘ 終了時のメモリ解放(重要)
Private Sub App_SlideShowEnd(ByVal Pres As Presentation)
m_StartTime = 0
End Sub

3. オブジェクトライフサイクルの管理(メモリリークの排除)

VBAにおいて最も忌むべきは、`WithEvents` オブジェクトの「ゾンビ化」だ。プレゼンテーションを閉じてもインスタンスがメモリに残り続け、次回実行時に二重イベントが発生するバグは、レガシー環境の保守担当者が最も頭を悩ませるポイントである。

標準モジュール:`modEntryPoint`

Option Explicit

Private m_Monitor As clsSlideShowMonitor

‘ シングルトンパターンで監視インスタンスを制御
Public Sub StartMonitoring()
If m_Monitor Is Nothing Then
Set m_Monitor = New clsSlideShowMonitor
Set m_Monitor.App = Application
End If
End Sub

‘ 明示的な終了処理
Public Sub StopMonitoring()
Set m_Monitor.App = Nothing
Set m_Monitor = Nothing
End Sub

4. プロフェッショナルのための深掘り考察

1. タイマーの精度とパフォーマンス

`timeGetTime` はシステム起動時からの経過時間をミリ秒で返すため、高頻度の呼び出しにも非常に軽量である。もし、より厳密なパフォーマンス計測が必要な場合は `QueryPerformanceCounter`(QPC)を検討すべきだが、VBAの実行オーバーヘッドを考慮すれば `timeGetTime` が最もバランスが良い。

2. イベントループの汚染を防ぐ

`SlideShowNextSlide` 内で重い処理(外部API呼び出しやDB書き込み)を行ってはならない。イベント内で処理を行うと、PowerPointのUIスレッドをブロックし、プレゼン自体がフリーズする。処理は必ず別スレッドまたは非同期キューへ投げる設計が、システム間連携の鉄則だ。

3. レガシー環境での保守性

64bit版Office環境では `PtrSafe` 属性が必須である。古い32bitコードをそのまま移植して「動かない」と嘆くのは素人の仕事だ。常に `VBA7` コンパイル定数を使用して、クロスプラットフォームでの互換性を担保すること。

If VBA7 Then
Private Declare PtrSafe Function timeGetTime Lib “winmm.dll” () As Long
Else
Private Declare Function timeGetTime Lib “winmm.dll” () As Long
End If

結論:自動化の真髄

スライドショーを単なる「紙芝居」として扱うのではなく、「イベントを生成するデータソース」として捉えること。この視点を持つだけで、あなたのVBAコードはスクリプトの域を超え、堅牢なミドルウェアへと昇華する。

オブジェクトの解放を怠らず、イベントの連鎖を理解し、OSの深淵(API)にアクセスする。この一連の規律こそが、我々エンジニアがプロフェッショナルとして守るべき「聖域」である。

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