選択セット

追加

AutoLISP関数
(ssadd [ename [ss]])
ename:【図形名】
ss:選択セット
【選択セット】に【図形名】を追加、または新しい【選択セット】を作成します。
戻り値:選択セット、またはnil

ssadd 関数は、【選択セット】に【図形名】を追加します。【選択セット】が指定されていなければ、新しい【選択セット】を作成します。

ename 引数は追加する【図形名】を、ss は【図形名】が追加される【選択セット】を指定します。ともに指定されなければ空の【選択セット】が作成されます。ename 引数の【図形名】が既に【選択セット】に存在する場合は無視されます。

戻り値は【選択セット】を返します。エラーが発生した場合は nil を返します。

$ (ssadd)⏎              ;空の選択セットを作成
<Selection set: 2>
_$ (ssadd (entlast)) ⏎  ;「最後の図形」を含んだ選択セットを作成
<Selection set: 4>

除去

AutoLISP関数
(ssdel ename ss)
ename:【図形名】
ss:選択セット
【選択セット】から図形を除去します。
戻り値:選択セット、またはnil

ssdel 関数は、【選択セット】から【図形名】を除去します。

ename 引数は除去する【図形名】を、ss 引数には【選択セット】を指定します。

戻り値は該当【図形名】を除去した【選択セット】を返します。【選択セット】に【図形名】がもともと存在しなかった場合は nil を返します。

_$ (setq ss (ssadd (entlast)))⏎        ;「最後の図形」を含む選択セットを作成
<Selection set: 8>
_$ (sslength ss) ⏎                     ;選択セットのメンバー数は1
1
_$ (ssdel (entlast) ss) ⏎              ;選択セットから「最後の図形」を除去
<Selection set: 8>
_$ (sslength ss) ⏎                     ;選択セットのメンバー数は0
0

検索

AutoLISP関数
(ssmemb ename ss)
ename:【図形名】
ss:選択セット
指定された【図形名】が【選択セット】に含まれるか調べます。
戻り値:【図形名】、またはnil

ssmemb 関数は、指定された【図形名】が【選択セット】に含まれていれば、【図形名】をそのまま返します。含まれていなければnilを返します。

次のプログラムは、実行された段階で選択されていた図形の【選択セット】を作成します。その後、表示をリセットして、ユーザーに図形を選ぶように指示し、選択された図形が最初の【選択セット】に含まれるか否かを表示します。

(if (setq sset (cadr (ssgetfirst)))
  (progn
    (sssetfirst nil)
    (while
      (setq ename (car (entsel "\nオブジェクトを選択(選択なしで終了):")))
       (if (ssmemb ename sset)
	 (prompt "\n選択セットのメンバーです。")
	 (prompt "\n選択セットのメンバーではありません。")
       )
    )
  )
  (prompt "\n図形を選択してから実行してください。")
)

実行すると、以下のような表示になります。

オブジェクトを選択(選択なしで終了):     ;図形を選択
選択セットのメンバーです。
オブジェクトを選択(選択なしで終了):     ;図形を選択
選択セットのメンバーではありません。
オブジェクトを選択(選択なしで終了):     ;空クリック

選択セット作成時の注意点

【選択セット】作成時も、ユーザー入力関数での注意点と同じことが言えます。すなわち、空選択の場合、ESC キーの場合、ロック図形選択の場合の三つです。

同じように ssget 関数をラップする ssgetException 関数を用意します。onEmpty 引数は何も選択されなかった場合に評価されます。onException 引数はユーザーが ESC キーを押した場合に評価されます。allowLocked 引数が nil の場合は、ロックされた図形は選択セットから除去され、その結果、空の選択セットとなった場合は onEmpty 引数が評価されます。

(defun ssgetException:removeLockedObj:sub (index / ename)
  (if (<= 0 index)
    (progn (if (not (vlax-write-enabled-p (setq ename (ssname $ss index))))
             (ssdel ename $ss)
           )
           (ssgetException:removeLockedObj:sub (1- index))
    )
  )
)

(defun ssgetException:removeLockedObj ($ss)
  (ssgetException:removeLockedObj:sub (1- (sslength $ss)))
)

(defun ssgetException (args onEmpty onException allowLocked / $error)
  (if (vl-catch-all-error-p (setq $error (vl-catch-all-apply 'ssget args)))
    (eval onException)
    (if
      (or (null $error)
          (and (not allowLocked)
               (zerop (progn (ssgetException:removeLockedObj $error) (sslength $error)))
          )
      )
       (eval onEmpty)
       $error
    )
  )
)

具体的な使い方は以下の通りです。下の例では、onEmpty 引数が評価されると、空の【選択セット】が返るようにして試しています。

_$ (ssgetException nil '(ssadd) nil nil) ⏎ ; 図形選択
<Selection set: 4f>
_$ (ssgetException nil '(ssadd) nil nil) ⏎ ; 空選択→空の選択セット
<Selection set: 52>
_$ (ssgetException nil '(ssadd) nil nil) ⏎ ; ESCキー
nil
_$ (ssgetException nil '(ssadd) nil nil) ⏎ ; ロック図形のみ選択された→空の選択セット
<Selection set: 57>

選択セットは、インデックスでアクセスするもので関数型言語のスタイルにはなじみにくいものです。選択セットを LISP のリストに変換するサポート関数を用意しておくと有用です。ssToList関数が本体で、再帰的に選択セットをリストへと構成します。

(defun ssToList:sub (ss index numOfEntity /)
  (if (< index numOfEntity)
    (append (list (ssname ss index)) (ssToList:sub ss (1+ index) numOfEntity))
  )
)

(defun ssToList (ss /)
  (if ss
    (ssToList:sub ss 0 (sslength ss))
  )
)