Author Topic: entity names of ALL blocks within a file  (Read 6758 times)

0 Members and 1 Guest are viewing this topic.

S.Langhammer

  • Guest
entity names of ALL blocks within a file
« on: January 30, 2013, 03:14:24 AM »
Greetings,
this is propably a really stupid question, that has been answered somewhere before, but I can't seem to find the answer. Or I just haven't sumbled over it yet:

How do I get the entity names of all blocks within a drawing (.dwg file) via Lisp, regardless if they are shown in the drawing at all?
I know theres a block-list, but I can't seem to work my way through it properly. All code examples I found so far deliver ether the block name or the effective block name. Those aren't actually helping me, I'd need the entity Name (dxf group code -1) so i can load the dxf code block and read the information i want from it

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: entity names of ALL blocks within a file
« Reply #1 on: January 30, 2013, 04:01:36 AM »
2 scenarios with 2 variants:

1a: You want the block definition. Use tblnext to step through each block definition in the file. This returns the DXF list as if you did an entget on the block definition's ename. If you want the block definition's ename, then use tblobjname instead. To get at the stuff inside that block, the 1st object's ename would be in the -2 item of the block definition's dxf list. From that simply use entnext to step through them all.

1b: Use the ActiveX Blocks collection of the ActiveDocument object. Step through it using vlax-for. Each block contains a collection of objects - again vlax-for through these. Note this method will also iterate through the *Model Space and the *Paper Space blocks - as well as most of the unnamed blocks - the tblnext method won't.

2a: You want all the block references placed in the drawing. Then use ssget to select all INSERT objects. This will give a selection set of all inserts placed in model / paper space.

2b: Similar to 1b step through all block definitions in the Blocks collection, then step through their contents finding all AcDbBlockReference objects. This way it finds all references since you would handle the model / paper space the same way as any other block definition.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: entity names of ALL blocks within a file
« Reply #2 on: January 30, 2013, 08:35:14 AM »
You may modify this to fit your needs.
Code - Auto/Visual Lisp: [Select]
  1. ;;  CAB 01/30/2013
  2. (defun c:GetBlockENames (/ adoc name lst)
  3.   (vl-load-com)  
  4.   (vlax-for blk (vla-get-blocks adoc)
  5.     ;; Exclude model and paper spaces, xref and anonymus blocks
  6.     (if (and  (equal (vla-get-IsLayout blk) :vlax-false)
  7.               (equal (vla-get-IsXref blk) :vlax-false)
  8.               (/= (substr (vla-get-Name blk) 1 1) "*"))
  9.          (setq lst (cons (vlax-vla-object->ename blk) lst))
  10.       )
  11.     )
  12.   lst
  13. )
« Last Edit: January 30, 2013, 08:42:07 AM by CAB »
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.

S.Langhammer

  • Guest
Re: entity names of ALL blocks within a file
« Reply #3 on: January 31, 2013, 05:00:31 AM »
@cab
perfect! thanks^^
« Last Edit: January 31, 2013, 05:20:49 AM by S.Langhammer »

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: entity names of ALL blocks within a file
« Reply #4 on: January 31, 2013, 07:35:44 AM »
Since you require entity names, it seems to me more suitable to use Vanilla AutoLISP for this task; though, are you looking for the BLOCK entities (AcDbBlockBegin) or BLOCK_RECORD entities (AcDbBlockTableRecord)? CAB's function will return the latter.

Here are some alternatives using Vanilla AutoLISP:

For BLOCKS:
Code - Auto/Visual Lisp: [Select]
  1. (defun _getblockenames ( / d n r )
  2.     (while (setq d (tblnext "BLOCK" (null d)))
  3.         (if (wcmatch (setq n (cdr (assoc 2 d))) "~`**")
  4.             (setq r (cons (tblobjname "BLOCK" n) r))
  5.         )
  6.     )
  7.     r
  8. )

For BLOCK_RECORDS:
Code - Auto/Visual Lisp: [Select]
  1. (defun _getblockrecordenames ( / d n r )
  2.     (while (setq d (tblnext "BLOCK" (null d)))
  3.         (if (wcmatch (setq n (cdr (assoc 2 d))) "~`**")
  4.             (setq r (cons (cdr (assoc 330 (entget (tblobjname "BLOCK" n)))) r))
  5.         )
  6.     )
  7.     r
  8. )

rkmcswain

  • Swamp Rat
  • Posts: 978
Re: entity names of ALL blocks within a file
« Reply #5 on: April 06, 2016, 03:55:04 PM »
Quote from: Lee Mac
Here are some alternatives using Vanilla AutoLISP:

For BLOCKS:
Code - Auto/Visual Lisp: [Select]
  1. (defun _getblockenames ( / d n r )
  2.     (while (setq d (tblnext "BLOCK" (null d)))
  3.         (if (wcmatch (setq n (cdr (assoc 2 d))) "~`**")
  4.             (setq r (cons (tblobjname "BLOCK" n) r))
  5.         )
  6.     )
  7.     r
  8. )



Lee Mac... in your spare time... LOL....  I'd like to see your ideas on sorting the output of this function so that when the output list is iterated, the block names are in alphabetical order.


Cheers   :angel:


ronjonp

  • Needs a day job
  • Posts: 7531
Re: entity names of ALL blocks within a file
« Reply #6 on: April 06, 2016, 04:15:19 PM »
Here's one way:
Code - Auto/Visual Lisp: [Select]
  1. (defun _getblockenames (/ d n r)
  2.   (while (setq d (tblnext "BLOCK" (null d)))
  3.     (if   (wcmatch (setq n (cdr (assoc 2 d))) "~`**")
  4.       (setq r (cons (tblobjname "BLOCK" n) r))
  5.     )
  6.   )
  7. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

rkmcswain

  • Swamp Rat
  • Posts: 978
Re: entity names of ALL blocks within a file
« Reply #7 on: April 07, 2016, 07:24:12 AM »
No, that only sorts by the entity name, not the block name.

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: entity names of ALL blocks within a file
« Reply #8 on: April 07, 2016, 08:24:38 AM »
Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun _getblockenames ( / d l n r )
  2.     (while (setq d (tblnext "BLOCK" (null d)))
  3.         (if (wcmatch (setq n (cdr (assoc 2 d))) "~`**")
  4.             (setq r (cons (tblobjname "BLOCK" n) r)
  5.                   l (cons n l)
  6.             )
  7.         )
  8.     )
  9.     (mapcar '(lambda ( n ) (nth n r)) (vl-sort-i l '<))
  10. )

rkmcswain

  • Swamp Rat
  • Posts: 978
Re: entity names of ALL blocks within a file
« Reply #9 on: April 07, 2016, 08:45:03 AM »
Much better. I was adding the block names to the list (var=r) and then using that to sort.

In both cases, the sort is by case (i.e.: A-B-C-a-b-c), but I'm not terribly concerned about that.

Thanks!

ronjonp

  • Needs a day job
  • Posts: 7531
Re: entity names of ALL blocks within a file
« Reply #10 on: April 07, 2016, 09:09:08 AM »
No, that only sorts by the entity name, not the block name.
My bad .. I just sorted what the function returned.


Maybe this:
Code - Auto/Visual Lisp: [Select]
  1. (defun _getblockenames (/ d n r)
  2.   (while (setq d (tblnext "BLOCK" (null d)))
  3.     (if (wcmatch (setq n (cdr (assoc 2 d))) "~`**")
  4.       (setq r (cons (tblobjname "BLOCK" n) r))
  5.     )
  6.   )
  7.     r
  8.     '(lambda (a b) (< (strcase (cdr (assoc 2 (entget a)))) (strcase (cdr (assoc 2 (entget b))))))
  9.   )
  10. )
  11. ;; (mapcar '(lambda (x) (cdr (assoc 2 (entget x)))) (_getblockenames))
« Last Edit: April 07, 2016, 09:24:48 AM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: entity names of ALL blocks within a file
« Reply #11 on: April 07, 2016, 12:17:00 PM »
You're welcome  :-)

In both cases, the sort is by case (i.e.: A-B-C-a-b-c), but I'm not terribly concerned about that.

Change:
Code - Auto/Visual Lisp: [Select]
  1. l (cons n l)

to:
Code - Auto/Visual Lisp: [Select]
  1. l (cons (strcase n) l)

For a case-insensitive sort.

rkmcswain

  • Swamp Rat
  • Posts: 978
Re: entity names of ALL blocks within a file
« Reply #12 on: April 07, 2016, 12:32:43 PM »



You are the man ! 

mailmaverick

  • Bull Frog
  • Posts: 495
Re: entity names of ALL blocks within a file
« Reply #13 on: April 15, 2016, 06:10:05 AM »
2 scenarios with 2 variants:

1a: You want the block definition. Use tblnext to step through each block definition in the file. This returns the DXF list as if you did an entget on the block definition's ename. If you want the block definition's ename, then use tblobjname instead. To get at the stuff inside that block, the 1st object's ename would be in the -2 item of the block definition's dxf list. From that simply use entnext to step through them all.

1b: Use the ActiveX Blocks collection of the ActiveDocument object. Step through it using vlax-for. Each block contains a collection of objects - again vlax-for through these. Note this method will also iterate through the *Model Space and the *Paper Space blocks - as well as most of the unnamed blocks - the tblnext method won't.

2a: You want all the block references placed in the drawing. Then use ssget to select all INSERT objects. This will give a selection set of all inserts placed in model / paper space.

2b: Similar to 1b step through all block definitions in the Blocks collection, then step through their contents finding all AcDbBlockReference objects. This way it finds all references since you would handle the model / paper space the same way as any other block definition.

Dear IRNEB, excellent explanation !!!! Thanks a lot. !!!