SSGET by VLxxxx and ENLAST by VL

SSGET by VLxxxx and ENLAST by VL

devitg
Advisor Advisor
3,387 Views
13 Replies
Message 1 of 14

SSGET by VLxxxx and ENLAST by VL

devitg
Advisor
Advisor

Once upon a time , I read at the AUGI magazine, about that VL it is not the best way to do SSGET, and now as a simple whish I want to do a SSGET "W" or "C" , or what ever  by two point given by the

 

(VLA-GETBOUNDINGBOX OBJ 'DL 'UR)

Guess obj is a circle and inside "CROSS" or part "WINDOW" is a TEXT . 

 

Or obj is a polyline and do a "CP" "WP" or whatever [sel-method]

 

At such article , the author said that to do SELECTION SET by VL it is not a good , or confortable way , and better use SSGET with  

 traditional XY points . 

 

maybe time as changed the concept. 

 

At the same time I wonder how to get the last OBJECT added to the dwg by a VLA-ADDxxxx 

 

Thanks in advance . 

 

 

 

0 Likes
Accepted solutions (2)
3,388 Views
13 Replies
Replies (13)
Message 2 of 14

Shneuph
Collaborator
Collaborator

Looks like you can do it.  Just have to convert safearrays to lists for the points:

 

(sssetfirst nil (ssget "_W" (vlax-safearray->list DL) (vlax-safearray->list UR)))

To get the last entered object you probably still want to use (entlast):

(setq obj (vlax-ename->vla-object (entlast)))
---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Message 3 of 14

Shneuph
Collaborator
Collaborator

I think VL version of entlast is basically:

'(vlax-dump-object
  (vla-item
    (vla-get-modelspace
      (vla-get-activedocument
	(vlax-get-acad-object)
	)
      )
    (1- (vla-get-count ms)
	)
    )
 ' )

That is of course if the last object was inserted into model space.  Maybe someone else knows of an easier way.

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Message 4 of 14

john.uhden
Mentor
Mentor

To me it's like asking how to sink a screw with a chainsaw or maybe how to eat soup with a knife and fork.

John F. Uhden

0 Likes
Message 5 of 14

devitg
Advisor
Advisor

Hi all. It was just a question . Of course I know the way in plain LISP .  Thanks all you. 

 

0 Likes
Message 6 of 14

phanaem
Collaborator
Collaborator

Just a few remarks

- first, get the Collection of all selection sets: (setq ssc (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))))

- add a new selection set. In VL, a selection set must have a name, unlike the vanilla lisp.  (setq new_ss (vla-add ssc "My_Selection_set")). Beside the selection sets you create, in the collection you might find some other selections like: "CURRENT", "PICKFIRST" etc

- add objects to the new selection by various methods:

    - Select -> by Windows, Crossing, Previous, Last, All

    - SelectAtPoint

    - SelectByPolygon -> by Fence, WindowsPolygon or CrossPolygon

    - SelectOnScreen

 

Then you have to learn about Clear, Delete or Erase methods and the difference between them.

 

For your second question, use (setq last_obj (vla-Add....

0 Likes
Message 7 of 14

devitg
Advisor
Advisor

What about filters. _?

 

It is possible?

 

Any way I will follow the tips I read so long ago . 

Using SSGET 

 

 

 

0 Likes
Message 8 of 14

phanaem
Collaborator
Collaborator

@devitg wrote:

What about filters. _?

 

It is possible?

 

Any way I will follow the tips I read so long ago . 

Using SSGET 

 

 


 

I thought you are looking for the ActiveX alternative, no matter what. Of course SSGET is easier, so go for it.

And yes, it's possible to use filters.

0 Likes
Message 9 of 14

_gile
Consultant
Consultant
Accepted solution

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.

 

"Pure ActiveX"

 

(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq filterType
       (vlax-make-variant
	 (vlax-safearray-fill
	   (vlax-make-safearray vlax-vbinteger '(0 . 1))
	   '(0 8)
	 )
       )
)
(setq filterData
       (vlax-make-variant
	 (vlax-safearray-fill
	   (vlax-make-safearray vlax-vbvariant '(0 . 1))
	   '("LINE" "42")
	 )
       )
)
(setq ss (vla-Add (vla-get-SelectionSets doc) "SelectionSet"))
(vla-SelectOnScreen ss filterType filterData)
(vlax-for obj ss
  ;; do some stuff
)
(vla-Delete ss)

Equivalent using ssget:

 

(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
(if (ssget '((0 . "LINE") (8 . "0")))
  (progn
    (vlax-for obj (setq ss (vla-get-ActiveSelectionSet doc)))
    ;; do some stuff
    (vla-Delete ss)
  )
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 of 14

ActivistInvestor
Mentor
Mentor
Accepted solution

@_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))

 

Message 11 of 14

devitg
Advisor
Advisor

Thanks. At last , is is possible. Not to be used, as SSGET is simple. 

0 Likes
Message 12 of 14

devitg
Advisor
Advisor

Some times a not so clever  question , bring us some light. 

 

 

0 Likes
Message 13 of 14

_gile
Consultant
Consultant

@ActivistInvestor wrote:
@_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. 



I think I know that and I extensively use helper libraries in my work (which is now more .NET than LISP).

I have published some piece of LISP libraries I thaught usefull here (including one "AutomationHelpers.lsp"), but I never encounter a situation where I absolutely needed to build an ActiveX selection set (other than with GetActiveSelectionSet).

 

And your example using helpers remains a little more verbose and, IMO, less easier than simply using (ssget).

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 14 of 14

ActivistInvestor
Mentor
Mentor

@_gile wrote:

@ActivistInvestor wrote:
@_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. 



I think I know that and I extensively use helper libraries in my work (which is now more .NET than LISP).

I have published some piece of LISP libraries I thaught usefull here (including one "AutomationHelpers.lsp"), but I never encounter a situation where I absolutely needed to build an ActiveX selection set (other than with GetActiveSelectionSet).

 

And your example using helpers remains a little more verbose and, IMO, less easier than simply using (ssget).

 


Hi @_gile.  The point was that the "pure Active" example you posed is much more 'verbose' than it could have been if you used helper functions, which most would agree is how it should be done.

 

Also, I don't think people reading this board are here to learn how to write 'code examples that are suitable for discussion group posts'.

 

They are here to learn how to code, and how to do it properly and productively, using best-practices. So what you show, and what you do in your own work may be vastly different, but the issue with all 'long-hand' code examples that use no helper APIs, that we routinely see posted here, is that it gives people who are learning the wrong idea about how sound and productive coding should be done.

 

 

 

0 Likes