【入門編】【実務中級】AcadDocument.Utility.GetEntityで選択ミスを許容する「リトライ・ループ」の実装:実務で使える堅牢な選択ツール – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは、自動化の深淵へようこそ。私はこれまで数えきれないほどのAutoCADアドインを設計し、現場の「あ、止まった」という溜息を「おぉ、動いた!」という歓喜に変えてきました。

マクロの記録を卒業し、いよいよ自分の手でコードを書き始めたあなた。素晴らしい一歩です。しかし、実務で自作ツールを使い始めると、必ずと言っていいほど直面する「最初の壁」があります。

それは、「ユーザーが図形選択をミスした瞬間に、プログラムがエラーで止まってしまう」という問題です。

今日は、AutoCAD VBAの基礎でありながら、プロの道具にするための必須テクニック「`GetEntity`のリトライ・ループ」について、その真髄を伝授しましょう。ここを乗り越えれば、あなたのツールは「壊れない、信頼される道具」へと進化します。

1. なぜ「GetEntity」はすぐに機嫌を損ねるのか?

AutoCAD VBAで図形を一つ選択させる際、最もよく使われるのが `AcadDocument.Utility.GetEntity` メソッドです。

このメソッドは非常に強力ですが、実は非常に繊細(デリケート)です。

  • 図形のない「空の空間」をクリックした
  • 右クリックやESCキーでキャンセルした
  • 図形が重なっていて、うまく掴めなかった

こうした「日常茶飯事の操作ミス」が起きた瞬間、`GetEntity` は即座にランタイムエラーを吐き出し、マクロの実行を強制終了させてしまいます。

「あ、間違えた」でツールが消えてしまう。 これでは現場のプロは使ってくれません。だからこそ、私たちエンジニアが「優しく包み込むようなコード」を書いてあげる必要があるのです。

2. 鉄壁の「リトライ・ループ」構造を理解する

エラーを回避し、正しい図形が選ばれるまで何度でも問いかける。この構造を「リトライ・ループ」と呼びます。

ロジックの肝は、以下の3点です。

1. `On Error Resume Next`: エラーが起きてもプログラムを止めない「盾」を構える。
2. `Do…Loop`: 正解に辿り着くまで無限に繰り返す「根性」を持たせる。
3. `Err.Number` のチェック: 失敗した理由を確認し、リセットする。

それでは、実務でそのまま使える「黄金のテンプレート」を見てみましょう。

3. 【実践コード】不屈のGetEntity実装

以下のコードは、ユーザーが円(AcadCircle)を正しく選択するまで決して諦めない、堅牢な実装例です。

Sub RobustSelectionTool()
Dim returnObj As AcadObject
Dim basePnt As Variant
Dim isSelected As Boolean

‘ 初期化:まだ選択されていない状態
isSelected = False

‘ プロンプト(指示文)を工夫してユーザーに安心感を与える
On Error Resume Next ‘ ここからエラーの「盾」を有効にする

Do
‘ 1. エラー情報をクリア(前回の失敗を忘れる)
Err.Clear

‘ 2. 図形の選択を試みる
ThisDrawing.Utility.GetEntity returnObj, basePnt, vbCrLf & “円を選択してください(空クリックで再試行 / ESCで終了): ”

‘ 3. エラー判定
If Err.Number <> 0 Then
‘ エラーが発生した場合(空クリックやESC)

‘ もしESCキー等で中断したい場合の処理(任意)
‘ ※実務では無限ループを防ぐため、特定の条件でExit Subさせるのが親切です
If Err.Description Like “キャンセル” Or Err.Number = -2147352567 Then
MsgBox “操作がキャンセルされました。”, vbInformation, “終了”
Exit Sub
End If

‘ 空クリックなどの場合は、メッセージを出してループを続行
ThisDrawing.Utility.Prompt vbCrLf & “【エラー】図形を認識できませんでした。もう一度クリックしてください。”

Else
‘ 4. 図形が選ばれたが、それが「求めている種類」かチェック
If TypeOf returnObj Is AcadCircle Then
‘ 円が選ばれたので、ループを抜ける
isSelected = True
Else
‘ 違う図形(線や文字)だった場合
ThisDrawing.Utility.Prompt vbCrLf & “それは ” & returnObj.ObjectName & ” です。円を選んでください!”
End If
End If

Loop Until isSelected = True

‘ エラーハンドリングを通常に戻す
On Error GoTo 0

‘ — ここから本来の処理 —
returnObj.Highlight True ‘ 選ばれた図形を光らせる(視覚的フィードバック)
MsgBox “素晴らしい!半径 ” & Format(returnObj.Radius, “0.00”) & ” の円が選択されました。”, vbInformation
returnObj.Highlight False

End Sub

4. このコードの「ここ」がプロの知恵

① `Err.Clear` の重要性

ループの冒頭で `Err.Clear` を呼んでいますね。これがないと、一度発生したエラー番号が残り続け、2回目以降に正しく選択しても「まだエラー中だ」と誤認してしまいます。「過去を清算してから次に挑む」。これは自動化の鉄則です。

② `TypeOf` による型検定

`GetEntity` は「何かしらの図形」を返しますが、それが「円」なのか「線」なのかまでは指定できません。実務では、円を選んでほしいのに線が選ばれると、その後の処理(例:半径を取得する)で結局エラーになります。
`If TypeOf returnObj Is AcadCircle` と書くことで、「型まで含めた完璧なバリデーション」が可能になります。

③ ユーザーへのフィードバック

`ThisDrawing.Utility.Prompt` を使い、コマンドラインに「なぜ失敗したのか」を表示しています。ユーザーは「なぜマクロが進まないのか」が分からないと不安になります。親切なメッセージは、ツールの品質そのものです。

5. 陥りやすいエラー:無限ループの罠

このリトライ・ループを実装する際、一つだけ注意点があります。それは「逃げ道」を作っておくことです。

もしユーザーが「あ、やっぱりこのマクロやめたい」と思ったとき、ESCキーを押してもループが回り続けると、AutoCAD自体を強制終了するしかなくなります。
上記のサンプルコードでは、`Err.Description` を見てキャンセルを検知し、`Exit Sub` する仕組みを入れています。これは、現場で「止まらなくなった!」というクレームを防ぐための、私からのささやかなプレゼントです。

結びに:掌握への道

`AcadDocument.Utility.GetEntity` を自在に操れるようになると、ユーザーとの対話型ツールが作れるようになります。それは単なる「自動処理」を超えて、「人間とCADが協調して働く仕組み」への入り口です。

今回の「リトライ・ループ」は、VBAの基礎でありながら、実務レベルのコードには欠かせない極めて重要なパーツです。これが書ければ、あなたのVBAスキルは「初級」を脱し、現場を支える「中級エンジニア」の領域に足を踏み入れたと言っても過言ではありません。

次は、複数の図形を一括で扱う `SelectionSet`(選択セット)の世界があなたを待っています。

一歩ずつ、しかし確実に、AutoCADをあなたの指先に馴染ませていきましょう。応援していますよ!

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