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