@_gile wrote:
Hi,
Here's a litlle example with a selection filter.
IMO such comparison example is enough to explain why we prefer use (ssegt ...) even when we want to process the selection set with vla* functions.
@_gile, while your example shows that it's easier to work with (ssget) than ActiveX selection sets, that's only true if one doesn't use helper functions.
Building and using libraries of helper functions is how most programmers typically work. They don't always code directly to 'bare metal' (e.g., use only built-in APIs), they typically rely on libraries of helper functions to simplify common operations.
For example, below are some of the helper functions I wrote long ago to work with Xrecords via ActiveX, rather than using (entmod). The same helper functions are also useful for building selection set filters for ActiveX selection sets, but that wasn't their main purpose.
So, using one of the helper functions below, your "pure ActiveX" example becomes:
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq filter (alist->variant '((0 . "LINE") (8 . "42"))))
(setq ss (vla-Add (vla-get-SelectionSets doc) "SelectionSet"))
(vla-SelectOnScreen ss (car filter) (cadr filter))
(vlax-for obj ss
;; do some stuff
)
(vla-Delete ss)
Of course, main reason why I've always avoided using ActiveX selection sets, is the bad design that requires us to add and delete them.
;; Convert a list to a variant. If the
;; the variant type is not vlax-vbvariant
;; the list must be homogenous.
;;
;; (list->variant <list> <variantType>)
(defun list->variant (alist vartype)
(vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray
vartype
(cons 0 (1- (length aList)))
)
aList
)
)
)
;; Convert a list to a variant and
;; convert all sublists to 3d points
;; Support for sublists is limited
;; to 3d point lists.
(defun list->variant-rec (alist vartype)
(vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray
vartype
(cons 0 (1- (length aList)))
)
(mapcar
'(lambda (item)
(if (listp item)
(vlax-3d-point item)
item
)
)
aList
)
)
)
)
;; Convert an association list (e.g., like
;; that returned by (entget), etc.), to a
;; list of two variants, the first representing
;; the CAR's of the alist (the dxf codes) and
;; the second representing the CDR's of the
;; alist (the dxf data).
(defun alist->variant (alist)
(list
(list->variant (mapcar 'car alist) vlax-vbInteger)
(list->variant-rec (mapcar 'cdr alist) vlax-vbVariant)
)
)
;; Convert two variants or safearrays representing the
;; contents of an association list to an association list.
;; The first argument holds the dxf codes and the second
;; holds the dxf data:
(defun variant->alist (varCode varData)
(mapcar 'cons
(get-variant-value varCode)
(get-variant-value varData)
)
)
;; Recursively convert a safearray or a variant to a lisp
;; type, or return the argument if it is already a lisp type.
(defun get-variant-value (data)
(cond
( (eq (type data) 'safearray)
(mapcar 'get-variant-value (vlax-safearray->list data)))
( (eq (type data) 'variant)
(if (eq vlax-vbarray (logand vlax-vbarray (vlax-variant-type data)))
(get-variant-value (vlax-variant-value data))
(vlax-variant-value data)
)
)
( (listp data)
(mapcar 'get-variant-value data)
)
(t data)
)
)
;; Set the XRecord data of an AcadXRecord
;; via ActiveX, from an associaton list:
(defun setXRecordData (xrecord alist)
(apply 'vla-setXRecordData
(cons xrecord (alist->variant alist))
)
)
;; Get the data of an AcadXRecord via ActiveX,
;; and return it as an association list:
(defun getXRecordData (obj / keys values)
(vla-getXRecordData obj 'keys 'values)
(if (and keys values)
(variant->alist keys values)
)
)
;;
;; Example:
;;
;; (setq alist
;; '(
;; (1 . "Hello")
;; (10 2.0 4.0 8.0)
;; (40 . 2.5)
;; (70 . 99)
;; )
;; )
;;
;; (setq data (alist->variant alist))
;;
;; Returns: (#<variant 8194 ...> #<variant 8204 ...>)
;;
;; (apply 'variant->alist data)
;;
;; Returns: ((1 . "Hello") (10 2.0 4.0 8.0) (40 . 2.5) (70 . 99))