How to select all entities inside of a block?

How to select all entities inside of a block?

eakos1
Advocate Advocate
5,426 Views
10 Replies
Message 1 of 11

How to select all entities inside of a block?

eakos1
Advocate
Advocate

Hello, I want to select all the objects inside the given block. 

I can find and select the needed blocks in the drawing:

 

(setq selection (ssget "X" '((0 . "INSERT") (2 . "Company_Header")) ))
(setq sslen (sslength selection))
(setq name (ssname selection 0))
..

..

If I have the name of the needed Block how can I get all SUB entities what it contains?

 

 

0 Likes
Accepted solutions (1)
5,427 Views
10 Replies
Replies (10)
Message 2 of 11

ВeekeeCZ
Consultant
Consultant
(if (setq s (ssget '((0 . "INSERT"))))
  (repeat (setq i (sslength s))
    (setq e (tblobjname "BLOCK" (cdr (assoc 2 (entget (ssname s (setq i (1- i))))))))
    (while (setq e (entnext e)) ; thru subs
      ... 
      )))

 

...well, that's too general. Since you know the name of it, just use this:

(if (setq e (tblobjname "BLOCK" "Company_Header"))
  (while (setq e (entnext e)) ; thru sub ents
    ...
    ))

 

0 Likes
Message 3 of 11

Lee_Mac
Advisor
Advisor

The ssget function will only permit you to select primary entities in all drawing layouts, not those nested within block definitions - in your example, the ssget expression will return a selection set containing all references of the Company_Header block in all drawing layouts.

 

Given a block name, you can use the tblobjname function to obtain the AcDbBlockBegin entity from the Block Table, and then use the entnext function to iterate over all entities which follow this entity in the drawing database, i.e. the components of the block definition.

 

For example, consider the following function:

(defun blockcomponents ( blk / ent rtn )
    (if (setq ent (tblobjname "block" blk))
        (while (setq ent (entnext ent))
            (setq rtn (cons ent rtn))
        )
    )
    (reverse rtn)
)

You can call the above with a given block name to return a list of entities corresponding to the components of the block definition:

_$ (blockcomponents "company_header")
(<Entity name: 7ffff7068b0> <Entity name: 7ffff7068c0> <Entity name: 7ffff7068d0>)

 

Message 4 of 11

Sea-Haven
Mentor
Mentor

Are you looking or something specific in that block if so please advise then a more appropriate answer would be provided, need a dwg with the block. Eg text in block

0 Likes
Message 5 of 11

eakos1
Advocate
Advocate

Hello,

thanks for suggestion but I’m stucked.

It seems what you sent me is working partly but finally I cannot do what I want.

 

My problem is that we have more drawing frames in one file so we have more headers what has to fill in but with the same content, like on the picture.

This is a block with attributes. I wanted create an program which can copy the info like item number, drawing number etc. and fill in the other ones except the page nummber - its different.

 

eakos1_0-1619959363790.png

 

What you give me routine is working but strangely. . I’ve filtered for "DESCRIPTION". 

 

(defun C:block_SUBs (/ s sslen nameEntity data nameBlock ent blk rtn)

 

 

   (setq s (ssget '((0 . "INSERT"))))

   (setq sslen (sslength s))

   (setq nameEntity (ssname s 0))

   (setq data (entget nameEntity))

   (setq nameBlock (cdr (assoc 2 data)))

 

   (setq blk nameBlock)

 

   (if (setq ent (tblobjname "block" blk))

      (while (setq ent (entnext ent))

                 (if (equal (cdr (assoc 2 (entget ent))) "DESCRIPTION")

                    (progn

                       (princ (nth 1 (entget ent)))

                       (princ (nth 2 (entget ent)))

                       (princ (nth 3 (entget ent)))

                       (princ (nth 4 (entget ent)))

                       (princ (nth 5 (entget ent)))

                       (princ (nth 6 (entget ent)))

                       (princ (nth 7 (entget ent)))

                       (princ (nth 8 (entget ent)))

                       (princ (nth 9 (entget ent)))

                       (princ (nth 10 (entget ent)))

                       (princ (nth 11 (entget ent)))

                       (princ (nth 12 (entget ent)))

                       (princ (nth 13 (entget ent)))

                       (princ (nth 14 (entget ent)))

                       (princ (nth 15 (entget ent)))

                       (princ (nth 16 (entget ent)))

                       (princ (nth 17 (entget ent)))

                       (princ (nth 18 (entget ent)))

                       (princ (nth 19 (entget ent)))

                       (princ (nth 20 (entget ent)))

                       (princ (nth 21 (entget ent)))

                       (princ (nth 22 (entget ent)))

                       (princ (nth 23 (entget ent)))

                       (princ (nth 24 (entget ent)))

                       (princ (nth 25 (entget ent)))

                       (princ (nth 26 (entget ent)))

                       (princ (nth 27 (entget ent)))

                       (setq rtn (cons ent rtn))

                    )

                 )

      )

   )

   (reverse rtn)

   (princ rtn)

 

   (princ)

)                                  ;end defung

 

Your routine gives me an Entity name but in ti’s data is not to find the real name what I typed into the field "Drawing". So I cannot take the data and put it in the other two blocks. 

I have an other program which can list all the parts of a block it gives me a different Entity name which contains it - marked yellow. 

eakos1_1-1619959552712.png

 

Finally I  printed the whole list without filtering what your rutine gives me and I cannot find the this Entity name at all what this other program gives me.

 

So I’m stucked to go forward with my program. 

 

0 Likes
Message 6 of 11

eakos1
Advocate
Advocate

In the maintime I've found an other function it gives the same result ☹️ not listed the necessary entities. 

 

(defun c:getblkitems (/ sel nfo items)
(if
(and
(setq sel (entsel "Select a block: "))
(= (cdr (assoc 0 (setq nfo (entget (car sel))))) "INSERT"))
(vlax-for
item
(vla-item
(vla-get-blocks
(vla-get-activedocument
(vlax-get-acad-object) ))
(cdr (assoc 2 nfo)))
(setq items (cons (vlax-vla-object->ename item) items)))
(prompt "\nNo block selected.")))

 

But this program of yours print out this entity name too. This program is little bit complicated to me, I don't know how could I change it not to print but get the entity names in a list. 

 

http://www.lee-mac.com/entitylist.html

 

0 Likes
Message 7 of 11

ВeekeeCZ
Consultant
Consultant

If you need just fill up some attributes you can use this simple approach:

 

  (if (setq s (ssget "_X" '((0 . "INSERT") (2 . "Titleblock"))))
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i))))
      (setpropertyvalue e "CREATED" "21-05-02"))) ; block's ename - tag - value

 

0 Likes
Message 8 of 11

eakos1
Advocate
Advocate

Thanks, that looks promissing. I can really fill in the values I've just tried it out. 😀

But isn't exist the opposite of setpropertyvalue to get the valuses from the first block?

0 Likes
Message 9 of 11

ВeekeeCZ
Consultant
Consultant
Accepted solution

You know what - HELP is your friend. See THIS  and scroll all the way down to see related fuctions.

 
0 Likes
Message 10 of 11

Sea-Haven
Mentor
Mentor

If I understandc orrect I wrote a copy title block in layout one the correct attributes "Road name" etc to the same title block in all other layouts useful when you make a layout with a blank company title block, the second step was do Page X of Y in all title blocks. 

 

Happy to provide something as it exists already. One question are the blocks in layouts ? Need a dwg to test and know which values to copy.

 

There is a quick way to do this using the attribute order so you would create a list (1 3 5 7) this means update the 1st the 3rd the 5th and the 7nth, nice thing is do not need to know attribute tag names, so can work with any block just need list and name of block.

0 Likes
Message 11 of 11

eakos1
Advocate
Advocate

Thank you for helping me!

I could manage to make my program. It was so easy that even a child could do it 😊

 

The getpropertyvalue and setpropertyvalue helped a lot.

 

(defun C:HEADER	(/ s sslen nameMasterEntity dataMasterEntity nameMasterBlock allHeaderSelection	sslenOther c)
   -----------------------------------------------------------
		    ;select the Master Header
   (vl-load-com)
   (setq s (ssget "_:S+." '((0 . "INSERT") (2 . "Company_Header"))))
   (setq sslen (sslength s)) ;- this is always 1
   (setq nameMasterEntity (ssname s 0))
   (setq dataMasterEntity (entget nameMasterEntity))
   (setq nameMasterBlock (cdr (assoc 2 dataMasterEntity)))
   ------------------------------------------------------------
		    ;Select all other heaters, remove the Master from the selection set
   (setq allHeaderSelection (ssget "x" '((0 . "INSERT") (2 . "Company_Header"))))
   (ssdel nameMasterEntity allHeaderSelection)
   (setq sslenOther (sslength allHeaderSelection))

   ------------------------------------------------------------
		    ;read and write the data
   (setq c 0)
   (repeat sslenOther

      (setq HeaderName (ssname allHeaderSelection c))

(setpropertyvalue	 HeaderName	 "DESCRIPTION" (getpropertyvalue nameMasterEntity "DESCRIPTION"))
(setpropertyvalue	 HeaderName	 "ITEM"	 (getpropertyvalue nameMasterEntity "ITEM"))
(setpropertyvalue	 HeaderName	 "DRAWING"	 (getpropertyvalue nameMasterEntity "DRAWING"))
(setpropertyvalue	 HeaderName	 "CUSTOMER"	 (getpropertyvalue nameMasterEntity "CUSTOMER"))
(setpropertyvalue	 HeaderName	 "ORIGINATOR" (getpropertyvalue nameMasterEntity "ORIGINATOR"))
(setpropertyvalue	 HeaderName	 "DATE_DESIGN"	 (getpropertyvalue nameMasterEntity "DATE_DESIGN"))

      (setq c (1+ c))
   )		    ;end repeat

   (princ)
)		    ;end defung

 

 

0 Likes