CorelDRAW VBAの「選択状態」を支配する:ゼロ除算を超える堅牢なオブジェクト制御
CorelDRAWのVBA開発において、初心者が最初に直面する「壁」がある。それは、`ActiveSelection`に依存したスクリプトが、ユーザーの気まぐれな選択解除によっていとも簡単にクラッシュする現象だ。
「何も選択されていない」という状態は、単なるNULLではない。CorelDRAWの内部オブジェクトモデルにおける「存在しないもの」に対する無策なアクセスは、メモリ保護違反の入り口であり、レガシーシステムの信頼性を損なう最大の要因だ。
今回は、この「選択状態の判定」を、単なるif文で終わらせず、アーキテクトの視点から「堅牢な制御」へと昇華させる極意を伝授する。
—
1. 初学者が陥る罠:ActiveSelectionへの無防備なアクセス
多くの初心者は、以下のようにコードを書く。
‘ 危険なコード例
Sub BadPractice()
‘ もし何も選択されていなければ、ここで例外(エラー)が発生する
MsgBox ActiveSelection.Shapes.Count
End Sub
これは、CorelDRAWのオブジェクトモデルが`ActiveSelection`を「現在フォーカスがあるオブジェクトの集合」として評価するためだ。選択がない場合、`ActiveSelection`は`Nothing`ではなく、不正なポインタを参照しようとする。
2. チーフアーキテクトによる「防御的プログラミング」の真髄
エラーを回避するだけでなく、「ユーザーに何を期待させるべきか」を設計に組み込むことが重要だ。`ActiveSelection.Shapes.Count`を用いるのは定石だが、これをラップし、再利用可能な関数として定義する。
‘ 堅牢な選択状態判定関数
Public Function GetSelectedShapes() As ShapeRange
‘ ActiveSelectionRange を使うのがCorelDRAW VBAの正解
‘ 選択状態がない場合、Countが0の空のRangeが返るため、安全
Dim sr As ShapeRange
Set sr = ActiveSelectionRange
If sr.Count = 0 Then
‘ ここでカスタム例外やログを吐き出す設計にする
Debug.Print “Warning: No objects selected.”
Set GetSelectedShapes = Nothing
Else
Set GetSelectedShapes = sr
End If
End Function
3. メモリ管理とオブジェクトのライフサイクル
VBA(特にCorelDRAWの環境)では、オブジェクトの参照を放置するとメモリリークの原因となる。特に大量のベクターデータをループ処理する場合、明示的な解放は必須だ。
Sub RobustProcess()
Dim sr As ShapeRange
Dim shp As Shape
Set sr = GetSelectedShapes()
‘ ガード節:早期リターンでインデントを深くしない
If sr Is Nothing Then Exit Sub
‘ ここで処理を実行
For Each shp In sr
‘ 処理内容…
Next shp
‘ オブジェクトの明示的解放(VBAの作法)
Set shp = Nothing
Set sr = Nothing
End Sub
4. 極限の視点:システム間連携とレガシー保守への備え
もし君がこのコードを、さらに大規模な自動化システムに組み込むのであれば、次の3点に注意せよ。
- Windows APIの活用: ユーザーがCorelDRAW以外のウィンドウをアクティブにしている場合、`ActiveSelection`は不安定になることがある。`GetForegroundWindow` 等のAPIを用い、CorelDRAWがアクティブであることを保証するチェックを入れるのが、真のプロフェッショナルだ。
- イベントドリブンへの移行: 可能であれば、マクロを手動実行させるのではなく、`Document.OnShapeCreate`などのイベントハンドラを監視し、選択状態が変わるたびにバックグラウンドでステータスを更新する構成を推奨する。
- エラーハンドリングの抽象化: `On Error GoTo` を多用するのではなく、オブジェクトの状態を常にクエリ(問い合わせ)できる「ステート管理オブジェクト」を作れ。
まとめ:技術は「守り」から始まる
CorelDRAW VBAにおいて、シェイプの選択状態を判定することは、単なるエラー回避ではない。「システムが制御不能になる境界線」をどこに引くかというアーキテクチャの意思表示だ。
初心者はコードを書き散らすが、熟練者はコードが「動かなくなる状態」をあらかじめ定義する。この堅牢な基礎があれば、どんな複雑なベクター変換エンジンも、安定して稼働し続けるはずだ。
諸君、コードを書く前に、まずは「オブジェクトが何もない世界」を想像することから始めてみてほしい。それがエンジニアとしての第一歩だ。
