CorelDRAW VBAを掌握する極限の知見
第1回:実行時エラー「オブジェクト変数または With ブロック変数が見つかりません」を根絶するNothing判定の実装パターン
こんにちは。大規模なDTP自動化パイプラインや、数万点におよぶバッチ処理システムのアーキテクチャ設計を手がけている開発チームのリーダーだ。
CorelDRAW VBAの実務開発において、最も頻発し、かつ開発者を絶望の淵に追いやるエラーは何だと思う?
そう、実行時エラー 91:「オブジェクト変数または With ブロック変数が見つかりません」 だ。
素人の書いたコードは、決まってこうなっている。
‘ 【アンチパターン】根拠のない楽観視が生んだ爆弾コード
ActivePage.Layers(“MyLayer”).CreateArtisticText 0, 0, “Hello”
このコードは、”MyLayer” という名前のレイヤーが存在する奇跡的な環境でしか動かない。レイヤー名がリネームされていたり、ドキュメントの構成が変わっていたりした瞬間、容赦なくVBAの実行は停止し、エンドユーザーの画面には無機質なエラーダイアログが鎮座することになる。
プロフェッショナルな自動化エンジニアを目指すなら、「CorelDRAWのオブジェクトは、いついかなる時も、取得に失敗するもの(存在しないかもしれないもの)」という性悪説に基づいた防衛的プログラミング(Defensive Programming)を徹底しなければならない。
今回は、このエラーを完全に根絶し、実務に耐えうる極限の堅牢性を持った `Nothing` 判定とフォールバックの実装パターンを伝授する。
—
なぜその書き方は非効率(そして危険)なのか?
CorelDRAWのオブジェクトモデルは、COM(Component Object Model)のラッパーとして動作している。`ActiveDocument` や `ActivePage`、特定の名前を指定した `Layers.Item()` などのプロパティやメソッドは、対象が存在しない場合にエラーを吐くか、空のポインタ(`Nothing`)を返す。
ここでVBA特有のトラップがある。
`Set` ステートメントを使わずに直接プロパティをチェインさせたり、取得失敗の検証をスキップしてメソッドを呼び出したりすると、VBAランタイムはオブジェクトの参照解決に失敗し、容赦なくエラー91を発生させる。
さらに、業務自動化において「エラーで止まる」ことは最大の悪だ。深夜に走らせたバッチ処理が、2万枚目のドキュメントのレイヤー欠損で異常終了していたときの絶望感を想像してほしい。エラーハンドリングと厳格な `Nothing` 判定こそが、プロとアマを分かつ境界線なのだ。
—
堅牢な設計:`Is Nothing` 判定とフォールバックの黄金律
オブジェクトを取得した直後、必ず `Is Nothing` による存在確認を行う。これが鉄則だ。さらに、存在しなかった場合のフォールバック(代替処理:新規作成、処理のスキップ、ログ記録など)をセットで実装する。
以下のプロダクションコードを見てほしい。実務の現場でそのままコピー&ペーストし、即座に組み込めるレベルにまで洗練させた安全設計のテンプレートだ。
【プロダクションコード】安全なレイヤー取得とフォールバック実装
Option Explicit
Sub ProcessTargetLayerRobustly()
Dim targetDoc As Document
Dim targetPage As Page
Dim targetLayer As Layer
‘ 1. ドキュメントの存在確認(Application.Documents.Countの検証)
If Application.Documents.Count = 0 Then
MsgBox “処理対象のドキュメントが開かれていません。”, vbCritical, “致命的エラー”
Exit Sub
End If
Set targetDoc = Application.ActiveDocument
‘ 2. アクティブページの取得確認
Set targetPage = targetDoc.ActivePage
If targetPage Is Nothing Then
MsgBox “アクティブページを取得できませんでした。”, vbCritical, “エラー”
Exit Sub
End If
‘ 3. 特定名レイヤーの安全な取得(存在しない場合はNothingが返る前提で扱う)
On Error Resume Next
Set targetLayer = targetPage.Layers(“Production_Layer”)
On Error GoTo 0 ‘ エラー捕捉を速やかに復旧
‘ 4. 【極限の知見】Nothing判定とフォールバック(自動生成)
If targetLayer Is Nothing Then
‘ フォールバック処理:レイヤーが存在しないなら、新しく作成する
‘ これにより、ユーザー側の事前準備ミスによる停止を防ぐ
Set targetLayer = targetPage.CreateLayer(“Production_Layer”)
‘ レイヤー作成すら失敗した場合の二重防衛
If targetLayer Is Nothing Then
MsgBox “必須レイヤー ‘Production_Layer’ の作成に失敗しました。”, vbCritical, “システムエラー”
Exit Sub
End If
Debug.Print “フォールバック発動: レイヤーを新規作成しました。”
Else
Debug.Print “ターゲットレイヤーを正常に取得しました。”
End If
‘ 5. 安全が保証されたレイヤーに対する処理の実行
Call ExecuteDrawingLogic(targetLayer)
End Sub
Private Sub ExecuteDrawingLogic(ByRef lyr As Layer)
‘ オブジェクトが確実に存在するという前提のもとで安全に描画処理を行う
Dim sh As Shape
Set sh = lyr.CreateArtisticText(100, 100, “Automated Production Ready”, , , “Arial”, 24)
‘ 作成されたシェイプ自体のNothing判定も怠らない
If Not sh Is Nothing Then
sh.Fill.ApplyRGBFill 255, 0, 0
End If
End Sub
—
コードの解説:なぜこの書き方が最強なのか?
1. `On Error Resume Next` の限定的利用
`targetPage.Layers(“Name”)` は、指定した名前が存在しない場合にエラーを発生させることがある。そのため、この行の直前だけ一時的にエラーをバイパスし、返り値が `Nothing` になることを利用して安全にキャッチしている。
2. 広範囲なエラー抑制の禁止
プログラミング初心者によありがちな `On Error Resume Next` をモジュールの最初に入れる悪習は絶対に避けるべきだ。バグの温床になる。上記のコードのように、「検証したいピンポイントの行の直前で有効化し、直後に `On Error GoTo 0` で即座に解除する」のがプロの作法だ。
3. フォールバック(自動補完)の発動
「エラーで止める」のではなく、「無いなら作る(あるいは安全にスキップする)」というフォールバックを組み込むことで、ツールとしての信頼性(レジリエンス)が劇的に向上する。
—
ファイル・データベース連携における注意点
外部ファイル(CSVやExcel、あるいはSQLデータベース)から取得した「レイヤー名」や「ページ番号」を元にCorelDRAWを操作する場合、この `Nothing` 判定の重要性は何倍にも跳ね上がる。
外部データには、予期せぬ空白文字が含まれていたり、全角半角の揺れがあったり、そもそも存在しないデータが混ざっていたりする。
外部リソースとCorelDRAWを結合するパイプラインでは、必ず次のような防衛ラインを構築すること。
- 外部データのトリム(`Trim()` 関数等による空白除去)
- 取得試行後の厳格な `Is Nothing` チェック
- 処理に失敗したオブジェクトをスキップし、ログファイル(またはイミディエイトウィンドウ)へ詳細なエラーコンテキストを出力する仕組み
—
まとめ
CorelDRAW VBA開発において、実行時エラー91は「防ぐことができる人災」だ。
`Is Nothing` による存在確認と、それをトリガーとしたフォールバック設計をすべてのオブジェクト取得プロセスに組み込むこと。
この習慣を身につけた瞬間から、あなたの書くVBAコードは「おもちゃのスクリプト」から「プロダクションレベルの業務システム」へと進化する。
妥協のないコードで、真の自動化領域を切り拓いていってほしい。
