ユーザー選択されたオブジェクトを取得する|AutoCAD VBAマクロの作成方法

VBAマクロは実行ボタンを押して完結するものもあれば、ユーザーが「このオブジェクトに対して処理を行いたい」とオブジェクトを入力して処理を行うものもあります。そういった場合にユーザーが選択したオブジェクトをどのように取得するかを理解しておく必要があります。

そこで、本ページではユーザーが選択したオブジェクトをVBA内で取得する方法を解説していきます。
本ページで学べる内容は以下のとおりです。

 SelectionSetオブジェクトについて
 対話的にユーザーが選択したオブジェクトを取得する方法

SelectionSetオブジェクト

AutoCAD内で選択されているオブジェクトは選択セットというオブジェクトに格納されます。
選択セットはSelectionSetオブジェクトという型で、Documentオブジェクト直下に属するSelectionSetsコレクションのItemメソッドを使うか、DocumentオブジェクトのActiveSelectionSetメソッドやPickfirstSelectionSetメソッドを使うことでアクセスすることができます。

   選択セットの取得 

Dim oSelSet As AcadSelectionSet
Set oSelSet = ThisDrawing.SelectionSets.Item(0)    ‘①(CURRNET)
Set oSelSet = ThisDrawing.SelectionSets.Item(1)
    ‘②(PICKFIRST)
Set oSelSet = ThisDrawing.ActiveSelectionSet          ‘①(CURRNET)
Set oSelSet = ThisDrawing.PickfirstSelectionSet
       ‘②(PICKFIRST)

選択セットはデフォルトで2つ用意されており、1つは「CURRENT」という名前の①で取得できる選択セット、もう1つは「PICKFIRST」という名前の②で取得できる選択セットです。

現在、選択状態になっているオブジェクトは「PICKFIRST」に格納されますが、[VBA マクロ実行]のコマンドでマクロを実行すると現在の選択がすべて自動的に解除されてしまうため、マクロ実行前に事前選択されているオブジェクトを取得することはできません。(VBEから実行する場合は取得可能)

Visual LISPと組み合わせることで、事前に選択されているオブジェクトを取得することが可能ですが、VBAだけではそのようなオブジェクトの取得は難しいです。したがって、通常はVBAマクロを実行した後に、ユーザーに対話的にオブジェクトを選択してもらい、ユーザーが選択したオブジェクトを入力としてコードの処理を行うのが一般的です。(詳しくは後述の内容を参照下さい)
 

上記の通り、選択セットはデフォルトで2種類用意されていますが、SelectionSetsコレクションのAddメソッドを使うことで新規作成することも可能です。作成できるSelectionSetは最大128個です。

   選択セットの新規作成 

Dim oSelSet As AcadSelectionSet
Set oSelSet = ThisDrawing.SelectionSets.Add(“NAME”) ‘新規作成
Call oSelSet.Delete                                                             ‘削除

新規作成する選択セットは重複しない任意の名称を付与することができます。また、新規作成した選択セットは処理が完全に終了した後もドキュメント内に残り続けます。選択セットは「Delete」メソッドで削除可能なので、処理として不要になったら忘れず削除するよう心掛けておく必要があります。

SelectOnScreenを使ったユーザー入力

選択セットでは、ユーザーにどのオブジェクトを取得したいかをVBAマクロの処理の途中で選ばせるような、いわゆる”対話的”な処理が可能です。対話的にユーザーが選択したオブジェクトを取得するにはSelectionSetオブジェクトのSelectOnScreenメソッドを使って下記のように記載します。

   SelectOnScreenメソッド 

 Set oSelSet = ThisDrawing.ActiveSelectionSet
oSelSet.SelectOnScreen     
‘ユーザー入力フェーズ
 
Dim oEntity As AcadEntity
For Each oEntity In oSelSet
        ‘ユーザー選択オブジェクト(oEntity)を使った処理
Next

上記コードの処理が実行されると、AutoCAD上ではユーザーのオブジェクト選択待ち状態(アイコンが□)へと移行します。ユーザーはオブジェクトを選択(複数選択も可)して[Enter]キーを押すか、[Esc]キーを押して選択をキャンセルするのいずれかのアクションが可能です。VBA上ではユーザーがいずれかのアクションを行うまで次の処理に進まず待機されます。

オブジェクトが選択された場合はoSelSetに全て格納され、Itemメソッドを使ってアクセスすることができます。キャンセルされた場合はoSelSetに何も格納されないため、「If oSelSet.Count = 0 Then」とすることで選択されていない判定をすることができます。

ActiveSelectionSetは過去の情報を保持したままになっていることもあるため、SelectOnScreenメソッドの実行直前にClearメソッドでCURRENTの選択セット内を空にしておくと処理が安定します。
(過去情報が残っていると選択していなくてもoSelSet.Count<>0となってしまうため)
 

サンプルコード

下記はユーザーが選択したオブジェクトすべてのオブジェクトタイプをイミディエイトウィンドウに出力するためのサンプルコードです。下記コードを実行後、AutoCADのアイコンが□になるのでオブジェクトを選択し、[Enter]キーを押すことで選択したオブジェクトすべてのオブジェクトの型を列挙させることができます。[Esc]キーを押した場合は「選択なし」という文字列が出力されます。

UserFormを使ったユーザー入力

SelectOnScreenメソッドは特にメッセージ等が表示されずにいきなりユーザー選択のフェーズに移るため、VBAマクロの中身を何も知らないユーザーからすると何を選択すればよいのかわかりません。個人で作って個人で使うマクロの場合はSelectOnScreenメソッドでも問題ないですが、複数の人に共有して皆で使うマクロの場合はUI(ユーザーインターフェース)を用意するのが鉄板です。

VBAではUserFormというUIを簡単に作成することが出来ます。UserFormはボタンやラベル、リストなどのコントロールを自由に配置してオリジナルのダイアログウィンドウを作成することができます。

現在選択されているオブジェクトは「PICKFIRST」のセット内に格納されるため、UserFormのボタンが押された時に「PICKFIRST」を確認すれば現在選択されているオブジェクトをすべて取得することができます。ボタンが押されるまでユーザーは好きに選択の状態を変更することができるため、SelectOnScreenメソッドとは違い選択の間違いを修正することもできます。

   PICKFIRST内のオブジェクト取得 

Set oSelSet = ThisDrawing.PickfirstSelectionSet
 
Dim oEntity As AcadEntity
For Each oEntity In oSelSet
        ‘ユーザー選択オブジェクト(oEntity)を使った処理
Next

 
サンプルコード

下記はUserFormを使って現在選択されている全てのオブジェクトのオブジェクトタイプをイミディエイトウィンドウに出力するためのサンプルコードです。上側のコードブロックの内容をThisDrawingのコードに、下側のコードブロックの内容をUserFormのコードにコピペすることで実行が可能です。UserFormを作成する必要があるのでコメント文を参考にUserFormを作成してください。

UserForm上のボタンをクリックしたとき、選択状態のオブジェクトすべての取得が可能です。
※UserFormの作り方はExcel VBAと同じなので検索して出てくる情報を参照下さい。

まとめ

今回の内容をまとめると以下のとおりです。

 選択されたオブジェクトは選択セット(SelectionSetオブジェクト)内に情報が保持される
選択セットには「CURRENT」「PICKFIRST」の2種類のセットが用意されている
現在選択中のオブジェクトは「PICKFIRST」に格納される
選択セットは新規作成もできる (不要になったら削除も必要)

SelectOnScreenメソッドを使うことで対話的にユーザーが選択したオブジェクトを取得可能
 UserFormを利用することでも対話的にユーザー選択オブジェクトの取得が可能

開発者としてはとりあえず「CURRENT」と「PICKFIRST」の2つの選択セットのいずれかにアクセスすれば、選択されているオブジェクトの取得ができるということさえ理解できていれば問題ないです。ユーザーが選択したオブジェクトを取得する方法としてUtilityオブジェクトのGetEntityを使うなどその他の取得方法も用意されていますが、それらは追々理解していけば良い内容です。

UserFormとPICKFIRSTを使った入力が最もユーザーにやさしく安定しているので、ツールとしてしっかりとしたものを作る場合はこの手法でユーザー入力機能を実装することをおすすめします。
 

メインページへ戻る
 

 関連書籍

icon-share-square Autodesk公式リンク

参考:概要 – 選択セットを使用する(VBA/ActiveX)

AutoCAD, VBA

Posted by Lic