AutoCAD VBA 図形オブジェクトを取得/選択するメソッド

# はじめに

AutoCAD VBAによる図形オブジェクトの選択には、単一オブジェクトの選択と複数オブジェクトの選択があります。
単一オブジェクトの選択では、図形オブジェクトそのものを画面上でマウスクリックして選択します。
複数オブジェクトの選択では、画面上でマウスクリックやドラッグで選択したり、VBAコードのみで選択することが出来ます。また、フィルタを設定することで特定の図形タイプやプロパティに合致するものを選択することもできます。

# 1. 図形オブジェクトの取得と選択の違い

前項では単に「図形の選択」と書きましたが、細かいことをいうと、これには「図形の取得」と「図形の選択」の両方が含まれます。
<font color='hotpink'>※この節の内容を理解されている方は読み飛ばしてください</font>

## 1-1. 図形の取得
「図形の取得」は単にオブジェクト変数にオブジェクトが格納されるだけです。自動でSelectionSetオブジェクトに格納もされることもありませんし、「画面上で選択状態」にもなっていません。

## 1-2. 図形の選択

### 1-2-1. 選択セット(SelectionSetオブジェクト)への格納
「選択セットへの格納」は、メソッドで選択された図形オブジェクト群がSelectionSetオブジェクトに格納されます。SelectionSetオブジェクトは図形オブジェクト(IAcadEntityインタフェースに属する各オブジェクト)のまとまりを表すコレクションです。

### 1-2-2. 画面上での選択状態
「画面上での選択状態」は文字通りです。その状態になっていれば VBAではない通常のコマンド操作が可能という状態です。
 ~~私が今まで調べたところでは、SendCommandメソッドでSELECTコマンドを使うことで画面上での選択状態にすることができました。~~ 出来たり出来なかったり……

# 2. 単一の図形オブジェクトを取得するメソッド

## Utility.GetEntity メソッド

画面上でマウスでクリックした単一の図形オブジェクトを取得するメソッドです。
定義したオブジェクト変数に格納するのみで、選択セットが自動的に作られることはありません。実行後に `Debug.Print ActiveDocument.SelectionSets.Count` しても、結果は ` 0 ` でした。
また、マウスでクリックした座標も同時に取得します。

```text:AutoCAD VBA
  説明
    画面上でマウスでクリックした単一の図形オブジェクトを取得する (※ 選択 ではない)
    ※ クリックした座標も取得する

  構文
    Utility.GetEntity Object, PickedPoint [, Prompt]

  戻り値
    なし  ※ ただし、引数による戻り値が含まれる 

  引数による戻り値
    第1引数 Object | 第2引数 PickedPoint

  引数
    Object      (As IAcadEntity) : [出力] 選択した図形オブジェクト
                                   ※ IAcadEntity : IAcadLine, IAcadCircle など

    PickedPoint (As Variant)     : [出力] クリックした点を表す 3D_WCS座標
                                   ※ Variant/Double 3要素(X,Y,Z)の1次元配列 arr(0 To 2)

    Prompt      (As String)      : [入力] 実行時にプロンプトに表示される文字列
```


# 3. 複数の図形オブジェクトを選択するメソッド

## 3-1. SelectionSet.Select メソッド

5つのモードに対応する選択メソッドで、画面上の操作は伴いません。
選択フィルタを使用しない場合は通常のコマンド操作と大差ありませんが、フォーマットが決まっている図面などでの自動化が期待されます。
選択フィルタを使用する場合は、クイック選択のようなことも可能ですし、複雑な選択も一度で出来ます。ただし、公式リファレンスのサンプルコードの方法ではフィルタを作成するのが少々面倒くさいです。

```text:AutoCAD VBA
  説明
    指定のモードでオブジェクトを選択して選択セットに格納する
  
  構文
    SelectionSet.Select Mode [, Point1][, Point2][, FilterType , FilterData]

  戻り値
    なし  ※ 指定した SelectionSet オブジェクトに格納されます
    
  引数
    Mode           (As AcSelect) : [入力] 対象となる図形オブジェクト群
 
          Name              Value  Description
      acSelectionSetWindow      0  窓       2点で定義される矩形内部に完全に含まれる図形オブジェクト
      acSelectionSetCrossing    1  交差     2点で定義される矩形内部および交差する図形オブジェクト
      acSelectionSetPrevious    3  直前     直前の選択セットに含まれる図形オブジェクト
      acSelectionSetLast        4  最後     現在の図面で最後に作成した(一番最新の)図形オブジェクト
      acSelectionSetAll         5  すべて   すべての図形オブジェクト

    Point1, Point2 (As Variant)  : [入力] 矩形の開始点と終了点を表す 3D_WCS座標
                                   ※ Variant/Double 3要素(X,Y,Z)の1次元配列
                                   ※ 窓と交差では必須

    FilterType     (As Variant)  : [入力] 使用フィルタのタイプを指定するDXFグループコード
                                   ※ Variant/Integer (1次元配列)

    FilterData     (As Variant)  : [入力] 使用フィルタタイプに対応する値
                                   ※ Variant (1次元配列)
```

## 3-2. SelectionSet.SelectAtPoint メソッド

指定した点を通る単一の図形オブジェクトを選択するメソッドです。
(私には)いまいち使いどころが分かりませんが、なんらかの自動化に使えるような気がします。

```text:AutoCAD VBA
  説明
    指定した点を通る単一の図形オブジェクトを選択セットに格納する
  
  構文
    SelectionSet.SelectAtPoint Point [, FilterType , FilterData]

  戻り値
    なし  ※ 指定した SelectionSet オブジェクトに格納されます
    
  引数
    Point      (As Variant)  : [入力] 点を表す 3D_WCS座標
                               ※ Variant/Double 3要素(X,Y,Z)の1次元配列

    FilterType (As Variant)  : [入力] 使用フィルタのタイプを指定するDXFグループコード
                               ※ Variant/Integer (1次元配列)

    FilterData (As Variant)  : [入力] 使用フィルタタイプに対応する値
                               ※ Variant (1次元配列)
```

## 3-3. SelectionSet.SelectByPolygon メソッド

3つ以上の点群で構成されるポリゴン内または交差する図形を選択するメソッドです。
点群を構成する配列が、一般的な2次元配列ではなく、X,Y,Zの3要素が連続する1次元配列であるところが最初分かりづらいところでした。

```text:AutoCAD VBA
  説明
    3つ以上の点群で構成されるポリゴン(フェンス)内または交差する図形を選択セットに格納する
  
  構文
    SelectionSet.SelectBtPolygon Mode , PointList [, FilterType , FilterData]

  戻り値
    なし  ※ 指定した SelectionSet オブジェクトに格納されます
    
  引数
    Mode           (As AcSelect) : [入力] 対象となる図形オブジェクト群
 
          Name                   Value  Description
      acSelectionSetFence            2  フェンス     フェンスと交差するすべての図形オブジェクト
      acSelectionSetWindowPolygon    6  ポリゴン窓   ポリゴン内に完全に含まれる図形オブジェクト
      acSelectionSetCrossingPolygon  7  ポリゴン交差 ポリゴン内および交差する図形オブジェクト

    PointsList (As Variant)  : [入力] ポリゴンを定義する点群を表す 3D_WCS座標
                               ※ Variant/Double 3要素(X,Y,Z)が連続する1次元配列
                                  例. 点数がn個のとき arr(0 To 3*n-1)
                                  ★. arr(0 To n, 0 To 2) のような2次元配列ではありません！

    FilterType (As Variant)  : [入力] 使用フィルタのタイプを指定するDXFグループコード
                               ※ Variant/Integer (1次元配列)

    FilterData (As Variant)  : [入力] 使用フィルタタイプに対応する値
                               ※ Variant (1次元配列)
```


## 3-4. SelectionSet.SelectOnScreen メソッド

```text:AutoCAD VBA
  説明
    画面上でマウスによる図形オブジェクト選択操作をして選択セットに格納する
    ※ クリック、窓、フェンス、投げ縄選択 などが可能
  
  構文
    SelectionSet.SelectOnScreen [FilterType , FilterData]

  戻り値
    なし  ※ 指定した SelectionSet オブジェクトに格納されます
    
  引数
    FilterType (As Variant)  : [入力] 使用フィルタのタイプを指定するDXFグループコード
                               ※ Variant/Integer (1次元配列)

    FilterData (As Variant)  : [入力] 使用フィルタタイプに対応する値
                               ※ Variant (1次元配列)
```

# 4. まとめ

前節までに各メソッドを説明してきましたが、ここではシチュエーションごとにまとめていきます。

## 4-1. 画面上の操作で図形オブジェクトを取得または選択

|対象図形オブジェクト|単一|複数|
|:-|:-:|:-:|
|Method|`Utility.GetEntity`|`SelectionSet.SelectOnScreen`|
|取得/選択|取得|選択セットに格納|
|Filter|－|○ (Option)|
|マウス操作|クリック|クリック, ドラッグ|
|画面上で選択状態|×|×|

## 4-2. 指定した点で構成される範囲内の図形オブジェクトを選択

|範囲|点|矩形|ポリゴン|
|:-|:-:|:-:|:-:|
|Method|`.SelectAtPoint`|`.Select`|`.SelectByPolygon`|
|Mode|－|`acSelectionSetWindow`<br>`acSelectionSetCrossing`|`acSelectionSetFence`<br>`acSelectionSetWindowPolygon`<br>`acSelectionSetCrossingPolygon`|
|指定点数|1|2|3以上|
|交差|○|○|○|
|内部|－|○|○|
|Filter|○ (Option)|○ (Option)|○ (Option)|

## 4-3. その他

|範囲|全体|最新(単一)|直前の選択セット|
|:-|:-:|:-:|:-:|
|Method|`.Select`|`.Select`|`.Select`|
|Mode|`acSelectionSetAll`|`acSelectionSetLast`|`acSelectionSetPrevious`|
|交差|○|○|○|
|内部|－|○|○|
|Filter|○ (Option)|○ (Option)|○ (Option)|

# おわりに

ここまで、図形オブジェクトを取得または選択するメソッドについて説明しました。公式のリファレンスよりも分かりやすいように心がけました。
今回は、サンプルコードは載せていませんが、別の記事でなるべく分かりやすいものを載せたいと思います。

### 選択フィルタを作成するFunctionの記事
https://qiita.com/sewege11/items/ede36073251e05e41c63

https://qiita.com/sewege11/items/a1865544f79e220374e5

https://qiita.com/sewege11/items/78b529f118ff28c478a7