【PowerPoint VBA】その「ActiveWindow.Selection」は地雷原だ――アドインを死なせないための堅牢なガード句設計
業務効率化ツールを配布し、チームの生産性を向上させる。その志は尊い。しかし、あなたが書いたそのコード、「ユーザーがテキストボックスを編集中にボタンを押した瞬間」にスタックトレースを吐いて沈黙する準備ができていないか?
`ActiveWindow.Selection.Type` を無防備に参照することは、崖っぷちで目隠しをして踊るようなものだ。本稿では、プロフェッショナルとして「エラーを回避する」のではなく「状態を厳密に定義して制御する」ための、極限まで堅牢なガード句の設計論を授ける。
—
なぜ「ActiveWindow」を信じてはいけないのか
PowerPointのオブジェクトモデルにおいて、`Selection` は極めて不安定な存在だ。ユーザーのUI操作一つで、そのプロパティは刻一刻と変貌する。
1. Selectionの種類が不定: `ppSelectionSlides`(スライド選択)と `ppSelectionShapes`(図形選択)では、アクセスできるプロパティが全く異なる。
2. テキスト編集モード: テキストボックス内でカーソルが点滅している状態は、通常のシェイプ選択とは別次元の「編集モード」だ。ここで `ShapeRange` を叩けば、VBAは即座に音を上げて例外を投げる。
3. 非アクティブなウィンドウ: アドイン実行時に、そもそもウィンドウが存在しない(あるいはバックグラウンド処理中)というエッジケースを考慮していないツールは、現場では「壊れている」と見なされる。
—
守護神となる「ガード句」の設計パターン
堅牢なアドインには、処理を開始する前に必ず「現在の状態がこの処理に適しているか」を判定するガード句が必要だ。
以下のコードは、単なる判定ではなく、どのフェーズでエラーが起きるかを事前に特定するプロダクションコードのテンプレートである。
‘ —————————————————————————–
‘ 堅牢な処理のためのガード句テンプレート
‘ —————————————————————————–
Public Sub ExecuteProfessionalTask()
‘ 1. ウィンドウの存在確認
If ActiveWindow Is Nothing Then
MsgBox “対象となるプレゼンテーションが開かれていません。”, vbCritical
Exit Sub
End If
‘ 2. Selectionの状態を厳密に判定
Dim sel As Selection
Set sel = ActiveWindow.Selection
‘ テキスト編集中などの「不適格な状態」を排除
If sel.Type = ppSelectionNone Then
MsgBox “何も選択されていません。”, vbExclamation
Exit Sub
End If
‘ 処理の内容に応じて必要な選択状態を定義する
Select Case sel.Type
Case ppSelectionShapes
‘ 図形に対する操作を記述
ProcessShapes sel.ShapeRange
Case ppSelectionSlides
‘ スライドに対する操作を記述
ProcessSlides sel.SlideRange
Case ppSelectionText
‘ テキスト編集中の制御(重要:ここを無視するとエラーになる)
MsgBox “テキスト編集中は操作できません。図形を選択してください。”, vbInformation
Case Else
MsgBox “未対応の選択状態です。”, vbExclamation
End Select
End Sub
—
プロフェッショナルのための「3つの絶対鉄則」
現場で配布するツールを「バグ知らず」にするために、以下の設計思想を骨の髄まで叩き込んでほしい。
1. 「想定外」を排除する `On Error Resume Next` の正しい使い方
「エラーを無視する」ために `On Error Resume Next` を使うのは素人の所業だ。プロは「特定の行だけリスクを限定し、直後に判定を行う」ために使用する。
On Error Resume Next
Dim sld As Slide
Set sld = ActiveWindow.View.Slide ‘ ここで失敗するリスクがある
On Error GoTo 0 ‘ 即座に解除する
If sld Is Nothing Then
‘ 代替処理または終了
End If
2. データベース・外部ファイル連携の罠
アドインから外部リソースを叩く場合、`ActivePresentation.Path` を信じてはいけない。未保存の新規ファイルであれば空文字列が返り、パス解決で例外が発生する。
- 対策: `Len(ActivePresentation.Path) > 0` を確認し、未保存なら保存を促す、あるいは一時フォルダを割り当てる等の処理をガード句に組み込むこと。
3. ユーザー体験(UX)への配慮
ツールが止まった理由を「実行時エラー: 91」と表示させないこと。それはユーザーに対する侮辱だ。
- 「何が起きたか」
- 「どうすれば解決するか(例:図形を選択してから実行してください)」
この2点を明示するメッセージを出すことこそが、真の意味での堅牢な業務ツールである。
—
結びに:エンジニアの誇り
PowerPoint VBAは、制約が多く不自由な世界だ。しかし、だからこそ「いかにしてその制約をハックし、盤石な基盤を構築するか」という設計者の腕が試される。
今回紹介したガード句は、単なるコードの断片ではない。「ユーザーをエラーという名の混乱から守るための防波堤」だ。配布したアドインが、誰の手にも触れられずゴミ箱に行くか、現場の必須ツールとして愛用されるか。その分かれ道は、こうした細部への執念にある。
さあ、あなたのコードを「堅牢なプロダクト」へと昇華させよう。質問があればいつでも来い。さらに深い領域までガイドしてやる。
