Making a table from dynamic blocks in a drawing, referencing visibility state and one particular attribute

Making a table from dynamic blocks in a drawing, referencing visibility state and one particular attribute

wsonnek
Contributor Contributor
3,230 Views
58 Replies
Message 1 of 59

Making a table from dynamic blocks in a drawing, referencing visibility state and one particular attribute

wsonnek
Contributor
Contributor

I'm working on yet another lisp (y'all got me hooked, I swear) that's attempting to take all the blocks in a drawing and make a table with them. I started with the two lisps linked below - the first one was almost exactly what I wanted for a table, but didn't handle the dynamic blocks well. The second counted dynamic blocks, but didn't have a way to make a good table. I tried to combine them and kinda wrecked it. Either way, neither of them allowed for counting based on the SIZE attribute, which is kind of important.

 

Basically, I have a ton of different 2D valves in a drawing. The valves are dynamic so I can switch between types (ball, globe, gate, etc) in-place without messing with the size. The size is an attribute (2", 3", 1/2", etc) for the block. There are a few stand-alone valves that I also need to count. I want the table to be "Block Name" "Block Type" (that's the visibility state) "Block Size" (attribute). That way I can quickly tally up what I've got in the drawing  and figure out how many 2" ball valves I need, 3" butterfly valves, etc.

 

Thoughts?

 

https://www.lee-mac.com/dynamicblockcounter.html

https://www.lee-mac.com/blockcounter.html

 

0 Likes
Accepted solutions (1)
3,231 Views
58 Replies
Replies (58)
Message 41 of 59

cadffm
Consultant
Consultant

Edit what Sea-Haven suggest,

 

add another line, marked here

cadffm_0-1740737499008.png

 

And it will count Your blocks without attribut and visibility informations.

 

 

But you talked about a Valve table, your sample block is not a Valve, so why should this Tool for these blocks too?

 

Thumb up to start wirh Lisp books and tutorials, in few years you are able to edit such code by your own

and later you will write them from scratch.

 

Sebastian

0 Likes
Message 42 of 59

wsonnek
Contributor
Contributor

I have some 3D valves, I'm just not comfortable sharing those online so I shared the Tees instead. The 3D valves don't have attributes but some are dynamic. I thought by taking this that I'd be able to count both the regular and dynamic blocks and just leave the visibility states and size attribute blank if they don't exist. Does that kinda make sense? Maybe I'm over-complicating this.

0 Likes
Message 43 of 59

cadffm
Consultant
Consultant

Hi,

 

>>I have some 3D valves, I'm just not comfortable sharing those online so I shared the Tees instead.

Okay, that will explain it.

 

 

>>Does that kinda make sense?

Yes and the solution is explained above.

Create a copy of your .lsp file,

edit waht Sea-Heaven wrote

add what I showed above (yellow marked part) wrote

save .lsp, APPLOAD this .lsp, test it.

 

Sebastian

0 Likes
Message 44 of 59

wsonnek
Contributor
Contributor

I deleted the 66.1, added the new line, and tried to import, but I got a syntax error. I think there needs to be another argument for ssget?

 

;**********************************************************************************************************************************************************************
;
; 	'add_valves_table' custom command for ws
;	komondormrex, feb, 2025
;	totally free of lm
;
;**********************************************************************************************************************************************************************

(defun get_text_length (text_string text_size / dtext_box_list)
	(if (= "" text_string)
		0
		(progn
			(setq dtext_box_list (textbox (list '(0 . "TEXT") (cons 1 text_string) (cons 7 (getvar 'textstyle)) (cons 40 text_size))))
			(+ (* 2 text_size) (- (caadr dtext_box_list) (caar dtext_box_list)))
		)
	)
)

;**********************************************************************************************************************************************************************

(defun add_table_from_list (table_list table_headers / table_text_size table_object row_index column_index columns_widths)
	(if (null table_text_size_saved) (if (zerop (getvar 'measurement)) (setq table_text_size_saved (/ 3.5 25.4)) (setq table_text_size_saved 3.5)))
  	(if (null (setq table_text_size (getreal (strcat "\nEnter table data text size <" (rtos table_text_size_saved) ">: "))))
  		(setq table_text_size table_text_size_saved)
  		(setq table_text_size_saved table_text_size)
  	)
  	(setq table_object (vla-addtable (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
  										 (vlax-3d-point (getpoint "\nSet table insertion point (Left Upper Corner): "))
  										 (+ 2 (length table_list)) 																					;	number of rows
  										 (length table_headers) 																					;	number of columns
  										 (* 2.5 table_text_size)             																		;	row height
  										 1

  						  )
  		   row_index -1
  		   column_index -1
  	)
	(vla-deleterows table_object 0 1)
	(vla-put-regeneratetablesuppressed table_object :vlax-true)
	(mapcar '(lambda (list_member) (vl-catch-all-apply 'vla-setcolumnwidth (list table_object (car list_member) (cadr list_member))))
			 (mapcar '(lambda (column_width) (list (setq column_index (1+ column_index)) column_width))
					  (setq columns_widths (mapcar '(lambda (string) (get_text_length string table_text_size)) table_headers))					;	width of column 0 thru last
			 )
	)
	(setq table_list (cons table_headers (mapcar '(lambda (row) (append (car row) (list (itoa (cdr row))))) table_list)))
	(foreach row table_list
		(setq column_index -1
			  row_index (1+ row_index)
			  columns_widths (mapcar 'max columns_widths (mapcar '(lambda (string) (get_text_length string table_text_size)) row))
		)
		(foreach column row
			(vla-settext table_object row_index (setq column_index (1+ column_index)) (nth column_index row))
			(if (and (> row_index 0) (zerop column_index))
				(vla-setcellalignment table_object row_index column_index acmiddleleft)
				(vla-setcellalignment table_object row_index column_index acmiddlecenter)
			)
			(vla-setcelltextheight table_object row_index column_index table_text_size)
			(vla-setrowheight table_object row_index (* 2.5 table_text_size))
		)
	)
	(setq column_index -1)
	(mapcar '(lambda (list_member) (vl-catch-all-apply 'vla-setcolumnwidth (list table_object (car list_member) (cadr list_member))))
			 (mapcar '(lambda (column_width) (list (setq column_index (1+ column_index)) column_width))
					  columns_widths
			 )
	)
	(vla-put-regeneratetablesuppressed table_object :vlax-false)
)

;******************************************************************************************************************************************************************************

(defun parse_list (_list / unique_list old_member)
	(foreach _member _list (if (not (member _member unique_list)) (setq unique_list (append unique_list (list _member)))))
	(setq unique_list (mapcar '(lambda (_member) (cons _member 0)) unique_list))
	(foreach _member _list
		(if (setq old_member (assoc _member unique_list))
				(setq unique_list (subst (cons (car old_member) (1+ (cdr old_member))) old_member unique_list))
		)
	)
)

;******************************************************************************************************************************************************************************

(defun get_the_valve (/ insert_sset valve_list size_attribute vis_property vis_property_value)
	(prompt "\nPick the valves to be listed in a table...")
	(if (setq insert_sset (ssget '((0 . "insert"))))  selects all attibuted inserts
		(setq valve_list (parse_list
				   			(vl-remove nil
			       				(mapcar '(lambda (insert) (if (and (vl-some '(lambda (attribute) (= "SIZE" (vla-get-tagstring (setq size_attribute attribute))))
				   				               			    	       	 	 (vlax-invoke insert 'getattributes)
				   				           			           	   )	;checks if there is "SIZE" tagged attribute in insert
				   					                               (if (vl-some '(lambda (dyn_property) (= "Visibility1" (vla-get-propertyname (setq vis_property dyn_property))))
				   									    	     	 			 (vlax-invoke insert 'getdynamicblockproperties)
				   									       			   )	;checks if there is "Visibility1" dynamic property in insert
				   									       			   (setq vis_property_value (vlax-get vis_property 'value))
				   									       			   (setq vis_property_value "")
				   								           		   )
			       				                    	      )
				   							      	      	  (list (vla-get-effectivename insert) vis_property_value (vla-get-textstring size_attribute))
				   							      	      	  (list (vla-get-effectivename insert) "-" "-")
			       				           	           	  )
				   					    )
				   					    (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex insert_sset))))
				   				)
		           			)
			         	 )
		)
    )
)

;******************************************************************************************************************************************************************************

(defun c:add_valves_table (/ valves_list)
	(if (setq valves_list (get_the_valves))
		(add_table_from_list valves_list '("Block Name" "Block Type" "Size" "Count"))
	)
	(princ)
)

;******************************************************************************************************************************************************************************

 

0 Likes
Message 45 of 59

komondormrex
Mentor
Mentor

komondormrex_0-1740753804488.png

 

Message 46 of 59

wsonnek
Contributor
Contributor

wsonnek_0-1740755732701.png

 

0 Likes
Message 47 of 59

cadffm
Consultant
Consultant
Accepted solution

1. you merged parts from different postings!

2. Your error don't match your posted code

 

Here we go

I took YOUR posted code

and added the ; as komondormex said

 

and changed the functionname (your function named like the old version, i didn't checked the reason and the content of the old vs new)

 

if get_the_valve is defined, you can't start get_the_valveS

if get_the_valveS is defined, you can't start get_the_valve

 

cadffm_0-1740757762948.png

 

 

 

;**********************************************************************************************************************************************************************
;
; 	'add_valves_table' custom command for ws
;	komondormrex, feb, 2025
;	totally free of lm
;
;**********************************************************************************************************************************************************************

(defun get_text_length (text_string text_size / dtext_box_list)
	(if (= "" text_string)
		0
		(progn
			(setq dtext_box_list (textbox (list '(0 . "TEXT") (cons 1 text_string) (cons 7 (getvar 'textstyle)) (cons 40 text_size))))
			(+ (* 2 text_size) (- (caadr dtext_box_list) (caar dtext_box_list)))
		)
	)
)

;**********************************************************************************************************************************************************************

(defun add_table_from_list (table_list table_headers / table_text_size table_object row_index column_index columns_widths)
	(if (null table_text_size_saved) (if (zerop (getvar 'measurement)) (setq table_text_size_saved (/ 3.5 25.4)) (setq table_text_size_saved 3.5)))
  	(if (null (setq table_text_size (getreal (strcat "\nEnter table data text size <" (rtos table_text_size_saved) ">: "))))
  		(setq table_text_size table_text_size_saved)
  		(setq table_text_size_saved table_text_size)
  	)
  	(setq table_object (vla-addtable (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
  										 (vlax-3d-point (getpoint "\nSet table insertion point (Left Upper Corner): "))
  										 (+ 2 (length table_list)) 																					;	number of rows
  										 (length table_headers) 																					;	number of columns
  										 (* 2.5 table_text_size)             																		;	row height
  										 1

  						  )
  		   row_index -1
  		   column_index -1
  	)
	(vla-deleterows table_object 0 1)
	(vla-put-regeneratetablesuppressed table_object :vlax-true)
	(mapcar '(lambda (list_member) (vl-catch-all-apply 'vla-setcolumnwidth (list table_object (car list_member) (cadr list_member))))
			 (mapcar '(lambda (column_width) (list (setq column_index (1+ column_index)) column_width))
					  (setq columns_widths (mapcar '(lambda (string) (get_text_length string table_text_size)) table_headers))					;	width of column 0 thru last
			 )
	)
	(setq table_list (cons table_headers (mapcar '(lambda (row) (append (car row) (list (itoa (cdr row))))) table_list)))
	(foreach row table_list
		(setq column_index -1
			  row_index (1+ row_index)
			  columns_widths (mapcar 'max columns_widths (mapcar '(lambda (string) (get_text_length string table_text_size)) row))
		)
		(foreach column row
			(vla-settext table_object row_index (setq column_index (1+ column_index)) (nth column_index row))
			(if (and (> row_index 0) (zerop column_index))
				(vla-setcellalignment table_object row_index column_index acmiddleleft)
				(vla-setcellalignment table_object row_index column_index acmiddlecenter)
			)
			(vla-setcelltextheight table_object row_index column_index table_text_size)
			(vla-setrowheight table_object row_index (* 2.5 table_text_size))
		)
	)
	(setq column_index -1)
	(mapcar '(lambda (list_member) (vl-catch-all-apply 'vla-setcolumnwidth (list table_object (car list_member) (cadr list_member))))
			 (mapcar '(lambda (column_width) (list (setq column_index (1+ column_index)) column_width))
					  columns_widths
			 )
	)
	(vla-put-regeneratetablesuppressed table_object :vlax-false)
)

;******************************************************************************************************************************************************************************

(defun parse_list (_list / unique_list old_member)
	(foreach _member _list (if (not (member _member unique_list)) (setq unique_list (append unique_list (list _member)))))
	(setq unique_list (mapcar '(lambda (_member) (cons _member 0)) unique_list))
	(foreach _member _list
		(if (setq old_member (assoc _member unique_list))
				(setq unique_list (subst (cons (car old_member) (1+ (cdr old_member))) old_member unique_list))
		)
	)
)

;******************************************************************************************************************************************************************************

(defun get_the_valve (/ insert_sset valve_list size_attribute vis_property vis_property_value)
	(prompt "\nPick the valves to be listed in a table...")
	(if (setq insert_sset (ssget '((0 . "insert")))) ; selects all attibuted inserts
		(setq valve_list (parse_list
				   			(vl-remove nil
			       				(mapcar '(lambda (insert) (if (and (vl-some '(lambda (attribute) (= "SIZE" (vla-get-tagstring (setq size_attribute attribute))))
				   				               			    	       	 	 (vlax-invoke insert 'getattributes)
				   				           			           	   )	;checks if there is "SIZE" tagged attribute in insert
				   					                               (if (vl-some '(lambda (dyn_property) (= "Visibility1" (vla-get-propertyname (setq vis_property dyn_property))))
				   									    	     	 			 (vlax-invoke insert 'getdynamicblockproperties)
				   									       			   )	;checks if there is "Visibility1" dynamic property in insert
				   									       			   (setq vis_property_value (vlax-get vis_property 'value))
				   									       			   (setq vis_property_value "")
				   								           		   )
			       				                    	      )
				   							      	      	  (list (vla-get-effectivename insert) vis_property_value (vla-get-textstring size_attribute))
				   							      	      	  (list (vla-get-effectivename insert) "-" "-")
			       				           	           	  )
				   					    )
				   					    (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex insert_sset))))
				   				)
		           			)
			         	 )
		)
    )
)

;******************************************************************************************************************************************************************************

(defun c:add_valves_table (/ valves_list)
	(if (setq valves_list (get_the_valve))
		(add_table_from_list valves_list '("Block Name" "Block Type" "Size" "Count"))
	)
	(princ)
)

;*******************************************************************************************************************

 

Sebastian

0 Likes
Message 48 of 59

Sea-Haven
Mentor
Mentor

As you mentioned if your starting to look at more block names in particular dynamic blocks, you may need a cond that looks at 'effectivename' and matches then say look for a tagname or a dynamic property name. 

 

Re blank entries just a comment I have a sort & count blocks with attributes the blocks can have no attributes or more than the 5 I look at as part of the count match, so for a non its result is (Blkname "-" "-" "-" "-" "-") I pad the resulting list to make all sub lists the same length.

0 Likes
Message 49 of 59

wsonnek
Contributor
Contributor

BEAUTIFUL!!!!!! This is exactly what I needed. Thank you all so much!!!!!

0 Likes
Message 50 of 59

komondormrex
Mentor
Mentor

that is the most funny thing to make Seb the solver imo 🤣🤣🤣🤣🤣 cause it totally is my code)))

Message 51 of 59

wsonnek
Contributor
Contributor

Whoops, sorry, I didn't see the name! I think I can move it if you repost?

0 Likes
Message 52 of 59

cadffm
Consultant
Consultant

This seems to be a trend at the moment

Sebastian

0 Likes
Message 53 of 59

komondormrex
Mentor
Mentor

vulturing, to be exact?

0 Likes
Message 54 of 59

cadffm
Consultant
Consultant

I think you can mark multiple replies and perhaps, you can remove them too - but I am not sure.

 

@komondormrex 

Oh, questions come up and after the first answer, 3-4 other users come along and write exactly the same thing.
It's not the first person who gets tagged, often not the person with the best explanation, but simply the last poster.

All of this is normal, but in the last few weeks I've noticed it again.

Sebastian

0 Likes
Message 55 of 59

komondormrex
Mentor
Mentor

do you really believe you have solved this kb request, just curious?

0 Likes
Message 56 of 59

cadffm
Consultant
Consultant

Hi, komondormrex, I think I can tell from your question that you seem to have completely misunderstood something.
Please excuse me, this is probably due to my very limited ability with the English language.

 

I helped the OP with a modification to extend the code and a second time with using the forum.
No, I don't think I answered the original question of this thread, but I have no idea why you're asking.

 

 

 
 

 

 

Sebastian

0 Likes
Message 57 of 59

wsonnek
Contributor
Contributor

The only reason I marked the solution above as accepted was that it had the whole working code. I apologize, I didn't check to see who did the final version. @komondormrex if you repost with the whole code, I can credit you for it. You did 95% of it and I really appreciate it. @cadffm thank you for your help as well!

0 Likes
Message 58 of 59

komondormrex
Mentor
Mentor

@wsonnek

you must have been kidding) it's 99.9%. and if you look carefully at the subject of your post it will totally clear the case. but whatever)

@cadffm

you and people like you are the main reason to hide the original text code behind compiling, otherwise there will be always mess like that)

0 Likes
Message 59 of 59

wsonnek
Contributor
Contributor

I apologize and I would like to credit you with the solution. If you can repost it I will. I would like to mark the solution in one place so anyone who's looking for it can easily find it.

0 Likes