【入門編】【実務中級】AcadDocument.Utility.GetEntityで選択された図形が「期待する種類」か即座に判定 – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは! AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押して自動生成されたコードを眺める段階は、もう卒業しましたか?

「図形を選択させて、何らかの処理をさせたい」――実務の自動化において、これは避けて通れない王道の要件です。しかし、ここで多くの初学者が「ユーザーが意図しない図形をクリックしてしまい、VBAが盛大にエラーを吐いて止まる」という壁にぶつかります。

今日は、現場のプロが必ず書いている「ガード節(Guard Clause)」というテクニックを使って、型不一致エラーを未然に美しく防ぐ極意を授けましょう。ここをクリアすれば、あなたの書くマクロの信頼性は劇的に跳ね上がりますよ。

なぜ `GetEntity` はエラーを吐きやすいのか?

AutoCAD VBAで画面上の図形をユーザーに選ばせるとき、`AcadDocument.Utility.GetEntity` メソッドを使います。

まずは、よくある「危険なコード」を見てみましょう。

Sub DangerCode()
Dim ent As AcadEntity
Dim pt As Variant

‘ ユーザーに図形をクリックさせる
ThisDrawing.Utility.GetEntity ent, pt, “図形を選んでね: ”

‘ いきなりプロパティを触る!
MsgBox “選ばれたのは ” & ent.Layer & ” レイヤーの図形です。”
End Sub

一見、問題なさに見えますよね? しかし、このコードには2つの爆弾が隠されています。

1. 空振り爆弾: ユーザーが図形ではなく、何もない黒い空間(モデル空間の何もない場所)をクリックした場合、`ent` には何も格納されず(Nothingのまま)、次の行で実行時エラー「オブジェクト変数または With ブロック変数が見つかりません。」が発生してマクロが強制終了します。
2. 種類違い爆弾: 開発者が「ポリライン(Polyline)」を選ばせるつもりで書いたのに、ユーザーがうっかり「文字(Text)」や「ブロック(BlockReference)」をクリックしてしまった場合、後続の処理で「そんなプロパティやメソッドはない!」と怒られます。

実務で動かすツールにおいて、「ユーザーが絶対にミスをしない」という性善説は捨てなければなりません。予期せぬ入力から身を守る盾、それがガード節です。

解決策:ガード節で「不審者」を華麗に弾き返す

では、プロのエンジニアが現場で書く、堅牢(ロバスト)なコードの全貌をお見せします。

Sub SafeGetPolyline()
Dim ent As AcadEntity
Dim pt As Variant

On Error GoTo ErrorHandler ‘ 万が一のエラー対策

‘ 1. 図形の選択を促す(プロンプト付き)
ThisDrawing.Utility.GetEntity ent, pt, “【処理対象】ポリラインを選択してください: ”

‘ — 【ガード節①】そもそも何か選択されたか?(空振りチェック) —
If ent Is Nothing Then
MsgBox “図形が選択されませんでした。”, vbExclamation, “中断”
Exit Sub
End If

‘ — 【ガード節②】期待する種類(ObjectName)か? —
‘ ポリラインの内部名(ObjectName)は “AcDbPolyline” です
If ent.ObjectName <> “AcDbPolyline” Then
MsgBox “選択された図形の種類が違います!” & vbCrLf & _
“選ばれたのは [” & ent.ObjectName & “] です。”, _
vbCritical, “型不一致エラー”
Exit Sub
End If

‘ ==========================================
‘ ここから下は、安全が完全に保証された聖域
‘ ==========================================
MsgBox “正常にポリラインが選択されました! 処理を続行します。”, vbInformation, “成功”

‘ 例:ポリライン特有の処理をここに書く
‘ Dim pline As AcadPolyline
‘ Set pline = ent
‘ Debug.Print pline.Length

Exit Sub

ErrorHandler:
‘ ユーザーがESCキーで選択をキャンセルした場合などのエラー処理
If Err.Number = -2147352567 Then
‘ キャンセルの場合は静かに終了
Exit Sub
Else
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub

コードの核心:ObjectNameの正体を見抜け

このコードの最大のキモは、`ent.ObjectName` による判定です。

AutoCADの図形オブジェクトは、それぞれ固有の「内部名(C++のクラス名のようなもの)」を持っています。VBAの型(`TypeName` や `TypeOf`)で判定する方法もありますが、AutoCADのCOMインターフェースにおいては、`ObjectName` プロパティを見るのが最も確実で確実なアプローチです。

実務でよく使う代表的な `ObjectName` の一覧を頭の片隅に入れておきましょう。

| 欲しい図形 | ObjectName の文字列 |
| :— | :— |
| 2Dポリライン / LWポリライン | `”AcDbPolyline”` または `”AcDb2dPolyline”` |
| 線分 (Line) | `”AcDbLine”` |
| 円 (Circle) | `”AcDbCircle”` |
| 文字 (Text / MText) | `”AcDbText”` / `”AcDbMText”` |
| ブロック参照 (BlockReference) | `”AcDbBlockReference”` |
| ハッチング (Hatch) | `”AcDbHatch”` |

例えば、ブロック参照(外部参照やダイナミックブロック)を選ばせたいなら、ガード節を `If ent.ObjectName <> “AcDbBlockReference” Then` に書き換えるだけです。これだけで、意図しない図形の混入を完全にシャットアウトできます。

現場で役立つエンジニアの知恵:なぜ「手前」で弾くのか?

初心者のうちは、コードの長さにビビって「とりあえずメインの処理を書いて、うまくいったらラッキー」と思いがちです。しかし、コードが複雑になればなるほど、エラーが発生したときのデバッグ(原因究明)地獄に苦しむことになります。

  • 処理の浅い段階(入口)で例外や不適合を弾く(Guard Clause)
  • 奥深いメインのロジックには「正しいデータだけが流れてくる」状態を作る

これが、大規模なAutoCADマクロやアドイン開発を破綻させないための、世界共通の鉄則です。

「ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ!」
ユーザーからの予期せぬ入力を恐れない、強くて美しいマクロを、ぜひあなたの設計図書にも取り入れてみてください。日々の定型業務が、さらにストレスフリーになりますよ!

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