Object Collections - Part 2
- See also:
- Object Collections - Part 1
On the first page we looked at changing all the Layers Color property using the repeat
command. Here's a much easier and quicker way :
(defun laycol1 ()
(vl-load-com)
(setq acadDocument (vla-get-activedocument (vlax-get-acad-object)))
(setq theLayers (vla-get-layers acadDocument))
(vlax-for item theLayers
(vla-put-color item 3)
)
(princ)
);defun
vlax-for
allows you to loop through each item in the collection, without having to count the number of objects and doing away with the need for loop control. This is the same method I used in the tempList
function that we used earlier on in this tutorial.
Here's another example. Would you like to ensure that all your Layers are On before performing a certain function? Have a look at this :
(defun layeron () (vl-load-com) (setq acadDocument (vla-get-activedocument (vlax-get-acad-object))) (setq theLayers (vla-get-layers acadDocument)) (vlax-for item theLayers (vlax-put-property item "LayerOn" ':vlax-true) );vlax-for (princ) );defun
One word of warning. Do not add or remove objects whilst iterating through a collection. This can and will cause errors.
One of the most powerful commands in our collections arsenal is the vlax-map-collection
function. If you are not familiar with the mapcar
and lambda
functions, I suggest you read my tutorial on these functions which you can find here.
Load and run this in the Visual Lisp Editor :
(defun layer-dump ()
(vl-load-com)
(setq theList '())
(setq acadDocument (vla-get-activedocument (vlax-get-acad-object)))
(setq theLayers (vla-get-layers acadDocument))
(vlax-map-collection theLayers 'vlax-dump-object)
(princ)
);defun
This will dump all properties of all the Layer objects in your drawing to the console screen.
You are not limited to Visual Lisp functions within a vlax-map-collection
call. You can also use your own user defined function. Let's say for some reason we wanted to make a list of all Layers in your drawing, switch all Layers On and change every Layer in the drawing to Color "5". This is how you could do it :
(defun layerMap () (vl-load-com) (setq theList '()) (setq acadDocument (vla-get-activedocument (vlax-get-acad-object))) (setq theLayers (vla-get-layers acadDocument)) (vlax-map-collection theLayers 'layer-mod) (princ) );defun (defun layer-mod (theLayer) (setq dwgName (vlax-get-property theLayer 'Name)) (setq theList (append (list dwgName) theList)) (setq theList (reverse theList)) (vlax-put-property theLayer "LayerOn" ':vlax-true) (vla-put-color thelayer 5) );defun
As you can see, each Layer object is passed to the function layer-mod
as the argument. You could also write this as an inline function using lambda
:
(defun layerMap1 () (vl-load-com) (setq theList '()) (setq acadDocument (vla-get-activedocument (vlax-get-acad-object))) (setq theLayers (vla-get-layers acadDocument)) (vlax-map-collection theLayers '(lambda (theLayer) (setq dwgName (vlax-get-property theLayer 'Name)) (setq theList (append (list dwgName) theList)) (setq theList (reverse theList)) (vlax-put-property theLayer "LayerOn" ':vlax-true) (vla-put-color thelayer 5) );lambda );vlax-map-collection (princ) );defun
Want to add to a collection? Let's add a new Layer to our drawing :
(defun layerAdd ()
(vl-load-com)
(setq acadDocument (vla-get-activedocument (vlax-get-acad-object)))
(setq theLayers (vla-get-layers acadDocument))
(setq newLayer (vla-add theLayers "Steel"))
(vla-put-color newLayer 5)
(vla-put-linetype newLayer "Dashed2")
(princ)
);defun
This routine creates a new Layer named "Steel" with Color "5" and a Linetype of "Dashed2". If the Layer already exists, this routine simply does nothing.
To delete a Layer from the collection, simply use the delete
method :
_$ (vla-delete newLayer)
Be careful though, if any objects within your drawing are referencing this Layer, you will get an error :
_$ (vla-delete newLayer)
; error: Automation Error. Object is referenced by other object(s)
Right, I've had enough of talking about collections. Now I'm going to check out my beer collection. It's not very big as I only collect the full ones. The empty ones I throw away. Ta, ta for now…