Author Topic: help with this routine Please  (Read 6991 times)

0 Members and 1 Guest are viewing this topic.

Coder

  • Swamp Rat
  • Posts: 827
help with this routine Please
« 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 ?

Code: [Select]
(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)
)

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: help with this routine Please
« Reply #1 on: June 02, 2011, 12:52:59 PM »
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).
Speaking English as a French Frog

Coder

  • Swamp Rat
  • Posts: 827
Re: help with this routine Please
« Reply #2 on: June 02, 2011, 01:29:06 PM »
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 .

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #3 on: June 02, 2011, 01:42:00 PM »
You need to iterate through the objects in the block definition, consider this example perhaps:

Code: [Select]
(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)
)


Coder

  • Swamp Rat
  • Posts: 827
Re: help with this routine Please
« Reply #4 on: June 02, 2011, 01:54:15 PM »
Thanks Lee .

Its great , and how to make it with *ssget* please ?

Many thanks

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #5 on: June 02, 2011, 02:05:56 PM »
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

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: help with this routine Please
« Reply #6 on: June 02, 2011, 02:21:47 PM »
Watch out for dynamic blocks (name) and XRefs (if you don't want them altered).
« Last Edit: June 02, 2011, 02:42:22 PM by alanjt »
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

yarik

  • Newt
  • Posts: 32
Re: help with this routine Please
« Reply #7 on: June 02, 2011, 02:31:33 PM »
Quote
Its great , and how to make it with *ssget* please ?

Hi, try this

Code: [Select]
(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)
)
      )
    )
  )
)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #8 on: June 02, 2011, 02:39:02 PM »
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:

Code: [Select]
([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])
)

yarik

  • Newt
  • Posts: 32
Re: help with this routine Please
« Reply #9 on: June 02, 2011, 02:58:36 PM »
Thanks lee, your code works fine

what about this??

Code: [Select]
(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)
)
      )
    )
  )
)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #10 on: June 02, 2011, 03:03:35 PM »
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.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: help with this routine Please
« Reply #11 on: June 02, 2011, 03:05:10 PM »
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.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #12 on: June 02, 2011, 03:22:56 PM »
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

yarik

  • Newt
  • Posts: 32
Re: help with this routine Please
« Reply #13 on: June 02, 2011, 03:43:25 PM »
 :oops:  :cry: Thanks guys for your comments

In this way

Code: [Select]
(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??

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #14 on: June 02, 2011, 04:00:51 PM »
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.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: help with this routine Please
« Reply #15 on: June 02, 2011, 04:57:44 PM »
Perhaps a little pseudo code would help paint a clearer picture.  8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #16 on: June 02, 2011, 05:02:39 PM »
I tried to write my earlier code as verbose and clear as possible to show the method

yarik

  • Newt
  • Posts: 32
Re: help with this routine Please
« Reply #17 on: June 02, 2011, 05:20:51 PM »
Many thanks Lee
You code its very clear , I'm just learning but very slowly

 :-)


Coder

  • Swamp Rat
  • Posts: 827
Re: help with this routine Please
« Reply #18 on: June 02, 2011, 05:53:37 PM »
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:

Code: [Select]
([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 .

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: help with this routine Please
« Reply #19 on: June 02, 2011, 06:06:54 PM »
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  :-)