TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Coder on June 02, 2011, 12:43:46 PM
-
Hello .
I am trying to change the color of entities in the selected block or blocks , but it returns ; error: bad argument type: VLA-object collection:
Could anyone help me with it please ?
(defun c:blk (/ Doc Blks sel ents)
(vl-load-com)
(setq Doc (vla-get-ActiveDocument (vlax-get-acad-object)))
(vla-StartUndoMark Doc)
(if (ssget "_:L" '((0 . "INSERT")))
(progn
(vlax-for Blks (setq sel
(vla-get-activeselectionset
(vla-get-activedocument (vlax-get-acad-object))
)
)
(vlax-for ents Blks
(vla-put-color ents 256)
)
)
)
(princ)
)
(vla-delete sel)
(vla-regen Doc acActiveViewport)
(vla-EndUndoMark Doc)
(princ)
)
-
Hi,
You cannot access to the components (entities) of a block reference (excepted attributes).
You can change the color of the block reference if the components of the block definition are in ByBlock color.
If you want to change the color of a block entities, you must d it in the block definition (this will affect all references).
-
Hi,
If you want to change the color of a block entities, you must d it in the block definition (this will affect all references).
Thank you Gile .
Yes I want to change the block entities to be by layer .
I have no complete idea about it .
-
You need to iterate through the objects in the block definition, consider this example perhaps:
(defun c:test ( / blockentity ) (vl-load-com)
(if
(and
(setq blockentity (car (entsel "\nSelect Block: ")))
(eq "INSERT" (cdr (assoc 0 (entget blockentity))))
)
(vlax-for object
(vla-item
(vla-get-blocks
(vla-get-activedocument (vlax-get-acad-object))
)
(cdr (assoc 2 (entget blockentity)))
)
(vla-put-color object acbylayer)
)
)
(princ)
)
-
Thanks Lee .
Its great , and how to make it with *ssget* please ?
Many thanks
-
You would only need to iterate through the objects in each Block Definition and all Inserts (References) are updated following modification of the Definition.
Hence, create a SelectionSet of Inserts, iterate through the SelectionSet and, for each Insert, check its name against a list of block definitions already processed, if it doesn't appear in the list, process the block definition (as I have demonstrated above) and add the name of the block to the list; otherwise, move onto the next block in the Selection.
Lee
-
Watch out for dynamic blocks (name) and XRefs (if you don't want them altered).
-
Its great , and how to make it with *ssget* please ?
Hi, try this
(defun c:foo (/ Blks sel)
(if (ssget "_:L" '((0 . "INSERT")))
(progn
(vlax-for Blks (setq sel
(vla-get-activeselectionset
(vla-get-activedocument (vlax-get-acad-object))
)
)
)
(vlax-map-collection sel 'putcolor)
)
)
)
(defun putcolor (ent / vla item)
(setq vla (vla-get-name ent))
(vlax-for item (vla-get-blocks
(vla-get-activedocument (vlax-get-acad-object))
)
(if (= vla (vla-get-name item))
(progn
(vlax-for ent item
(vla-put-color ent 255)
)
)
)
)
)
-
Yarik,
Be aware that your code iterates through the SelectionSet twice (the first time doesn't do anything), furthermore, it iterates through each block definition for every insert in the drawing (when this only needs to happen once), and will iterate through the block collection for every insert (you could use vla-item to get the block definition).
The following code is what my previous post was hinting at, also incorporating Alan's suggestion to exclude XRefs:
([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] blockcollection blockdefinition blockname i processedblocks selectionset ) ([color=BLUE]vl-load-com[/color])
([color=BLUE]setq[/color] BlockCollection
([color=BLUE]vla-get-blocks[/color]
([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color]))
)
)
([color=BLUE]if[/color] ([color=BLUE]setq[/color] SelectionSet ([color=BLUE]ssget[/color] '((0 . [color=MAROON]"INSERT"[/color]))))
([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] SelectionSet))
([color=BLUE]setq[/color] BlockName ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 2 ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] SelectionSet ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))))))
([color=BLUE]if[/color] ([color=BLUE]not[/color] ([color=BLUE]member[/color] BlockName ProcessedBlocks))
([color=BLUE]progn[/color]
([color=BLUE]setq[/color] BlockDefinition ([color=BLUE]vla-item[/color] BlockCollection BlockName))
([color=BLUE]if[/color] ([color=BLUE]eq[/color] [color=BLUE]:vlax-false[/color] ([color=BLUE]vla-get-isxref[/color] BlockDefinition))
([color=BLUE]vlax-for[/color] object BlockDefinition
([color=BLUE]vla-put-color[/color] object [color=BLUE]acbylayer[/color])
)
)
([color=BLUE]setq[/color] ProcessedBlocks ([color=BLUE]cons[/color] BlockName ProcessedBlocks))
)
)
)
)
([color=BLUE]princ[/color])
)
-
Thanks lee, your code works fine
what about this??
(defun c:foo (/ Blks sel)
(if (ssget "_:L" '((0 . "INSERT")))
(progn
(setq sel
(vla-get-activeselectionset
(vla-get-activedocument (vlax-get-acad-object))
)
)
(vlax-map-collection sel 'putcolor)
)
)
)
(defun putcolor (ent / vla item)
(setq vla (vla-get-name ent))
(vlax-for item (vla-get-blocks
(vla-get-activedocument (vlax-get-acad-object))
)
(if (= vla (vla-get-name item))
(progn
(vlax-for ent item
(vla-put-color ent 255)
)
)
)
)
)
-
Thanks lee, your code works fine
what about this??
Slightly better, but you are still processing the block definitions for each and every Insert in the drawing, when this needs to only happen once for each block name.
-
Thanks lee, your code works fine
what about this??
Slightly better, but you are still processing the block definitions for each and every Insert in the drawing, when this needs to only happen once for each block name.
And creating the block collection for each entity.
-
Thanks lee, your code works fine
what about this??
Slightly better, but you are still processing the block definitions for each and every Insert in the drawing, when this needs to only happen once for each block name.
And creating the block collection for each entity.
Ooh missed that! - but yeah, big no no :-P
-
:oops: :cry: Thanks guys for your comments
In this way
(defun c:foo (/ sel item nam)
(if (ssget '((0 . "INSERT")))
(progn
(setq sel
(vla-get-activeselectionset
(vla-get-activedocument (vlax-get-acad-object))
)
)
(vlax-for blk sel
(setq nam (vla-get-name blk)
item (vla-item
(vla-get-blocks
(vla-get-activedocument (vlax-get-acad-object))
)
nam
)
)
(vlax-for ent item
(vla-put-color ent 255)
)
)
)
)
)
Its alright??
-
You're still processing the block definition for each Insert selected, which may result in a block definition being processed more than once. Also, you are still retrieving the Block Collection for every block in the selection.
-
Perhaps a little pseudo code would help paint a clearer picture. 8-)
-
I tried to write my earlier code as verbose and clear as possible to show the method (http://www.theswamp.org/screens/leemac/facepalm.gif)
-
Many thanks Lee
You code its very clear , I'm just learning but very slowly
:-)
-
Yarik,
Be aware that your code iterates through the SelectionSet twice (the first time doesn't do anything), furthermore, it iterates through each block definition for every insert in the drawing (when this only needs to happen once), and will iterate through the block collection for every insert (you could use vla-item to get the block definition).
The following code is what my previous post was hinting at, also incorporating Alan's suggestion to exclude XRefs:
([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] blockcollection blockdefinition blockname i processedblocks selectionset ) ([color=BLUE]vl-load-com[/color])
([color=BLUE]setq[/color] BlockCollection
([color=BLUE]vla-get-blocks[/color]
([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color]))
)
)
([color=BLUE]if[/color] ([color=BLUE]setq[/color] SelectionSet ([color=BLUE]ssget[/color] '((0 . [color=MAROON]"INSERT"[/color]))))
([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] SelectionSet))
([color=BLUE]setq[/color] BlockName ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 2 ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] SelectionSet ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))))))
([color=BLUE]if[/color] ([color=BLUE]not[/color] ([color=BLUE]member[/color] BlockName ProcessedBlocks))
([color=BLUE]progn[/color]
([color=BLUE]setq[/color] BlockDefinition ([color=BLUE]vla-item[/color] BlockCollection BlockName))
([color=BLUE]if[/color] ([color=BLUE]eq[/color] [color=BLUE]:vlax-false[/color] ([color=BLUE]vla-get-isxref[/color] BlockDefinition))
([color=BLUE]vlax-for[/color] object BlockDefinition
([color=BLUE]vla-put-color[/color] object [color=BLUE]acbylayer[/color])
)
)
([color=BLUE]setq[/color] ProcessedBlocks ([color=BLUE]cons[/color] BlockName ProcessedBlocks))
)
)
)
)
([color=BLUE]princ[/color])
)
That's really great Lee .
The way you named the variables is very useful for me to understand the process of the routine .
Great thanks .
-
That's really great Lee .
The way you named the variables is very useful for me to understand the process of the routine .
Excellent, that was my intention :-)