I'll try to show you using examples which are broken down and simplified as much as posible. Note you don't need to perform all the steps individually, some of them can be combined - I just split them so it's easier to understand.
The 1st code uses the normal lisp methods of working with selection sets. I.e. ssget, sslength, ssname. With these you usually get the ename of each entity in the selection set. As an example:
Code:
;; Initialize the counter to zero
(setq n 0)
;; Ask the user to select entities
(if (setq ss (ssget)) ;Only continue if there were any entities selected
(while (< n (sslength ss)) ;Step through entire set
(setq en (ssname ss n) ;Get the nth entity's ename from the selection set
ed (entget en) ;Get the DXF data list from the ename
eo (vlax-ename->vla-object en) ;Convert the ename to an ActiveX object
)
;; Replace the DXF data code 8 (layer) with a code pointing to layer 0
(setq ed (subst '(8 . "0") (assoc 8 ed) ed))
(entmod ed) ;Modify the entity to match the DXF list
;; Or use the ActiveX object with the vla functions.
(vla-put-LineType eo "ByLayer") ;Change the entity's line type to ByLayer
(setq n (1+ n)) ;Increment the counter
)
)
Now, you could have performed both the Layer & Linetype changes using either just the DXF list (Linetype code is 6), or the vla functions (Layer function vla-put-Layer). In some cases it's preferable to use the vla functions (e.g. when working with annotative text). In some cases you can only do things through the vla functions (e.g. changing a block reference's DB parameters).
However, the conversion from an ename to an ActiveX object takes time, a very small amount but it still takes time. Because it's inside the while loop, this small amount of time is multiplied by the number of entities selected (which could be thousands). So to get it running faster the conversion if moved outside the loop.
Code:
;; Get a reference to the ActiveX object of the AutoCAD program
(or *acad* (setq *acad* (vlax-get-acad-object)))
;; Get a reference to the ActiveX object of the current drawing
(or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
;; Ask the user to select entities
(if (and (setq ss (ssget)) ;Only continue if there were any entities selected
(setq ssA (vla-get-ActiveSelectionSet *doc*)) ;Convert to ActiveX Selection Set
)
(vlax-for eo ssA
(vla-put-Layer eo "0") ;Change the entity's line type to ByLayer
(vla-put-LineType eo "ByLayer") ;Change the entity's line type to ByLayer
)
)
So here we "convert" the lisp selection set to an ActiveX selection set. Actually we simply get a reference to the current selection set from the current drawing ... works similar to using Previous when selecting manually. This selection set object is what's called a collection - which is a special object containing a list of other objects. And thus you can use the vlax-for function to step through them all as you would use the foreach function to step through all items in a normal list.
The difference here is that you don't need a counter variable to tell ssname which number in the set you want (that's handled by vlax-for). You could have obtained the length of ssA by getting (vla-get-Count ssA) and then using a similar while loop, each time extracting one item using (vla-Item ssA n) - but why not simply use the vlax-for, it's a lot easier and performs exactly the same thing.
But the major reason for doing the conversion to an ActiveX selection set is that you obtain the ActiveX Object references directly, without further conversion. Thus the conversion happens only once and not multiplied by the length of the selection set. However, if you need to get at the DXF data list you'll then need to convert back to an ename first using (setq en (vlax-vla-object->ename eo)) and then get the DXF data (entget en).
So, if you are going to use the vla functions exclusively, the 2nd method is the most optimal - in both ease of programming as well as speed of execution. If you use the DXF functions only, then the 1st would be more efficient. If you use a combination of vla & dxf, you can pick & choose, but I think the 2nd should be very slightly faster ... unless you optimize the 1st a bit, e.g.:
Code:
;; Ask the user to select entities
(if (and (setq ss (ssget)) ;Only continue if there were any entities selected
(setq n (sslength ss)) ;And get its length
)
(while (>= (setq n (1- n)) 0) ;Step through entire set, and decrement counter
(setq en (ssname ss n) ;Get the nth entity's ename from the selection set
;; You don't need to get the DXF data list, simply create the required
;; item as below
eo (vlax-ename->vla-object en) ;Convert the ename to an ActiveX object
)
;; Replace the DXF data code 8 (layer) with a code pointing to layer 0
(entmod (list (cons -1 en) '(8 . "0"))) ;Modify the entity with new Layer
;; Or use the ActiveX object with the vla functions.
(vla-put-LineType eo "ByLayer") ;Change the entity's line type to ByLayer
)
)
As you can see, the counting variable n now steps down from the last entity in the selection set. Which means it doesn't need to query the length of ss each time. And it shouldn't make a difference, since it doesn't really matter in which order the entities are changed - only in cases where you're creating something like an incrementing text value would this become important.
The biggest saving in time for this 3rd method is that you don't obtain the DXF data list before changing the DXF data. This is usually the most time-consuming thing when working with DXF data as it extracts every little bit of data into the data list when you use entget. The ActiveX method doesn't, it only gets a reference to the object and queries only the data you tell it to through the vla-get-... methods.
But if you don't need to first check something in the DXF data, you can simply set it. Thus you create a "new" data list, with the -1 code having the ename (which you've already got) and the rest with only the values which have to change.
Of course this is a bit of a forced example, but it's only here to illustrate the reasons behind using one or the other. Both methods accomplish the same thing, they just have situations where it's better to use one than the other - speed wise.