Change Block Entity To Another Color

Change Block Entity To Another Color

RocksterB
Advocate Advocate
2,577 Views
28 Replies
Message 1 of 29

Change Block Entity To Another Color

RocksterB
Advocate
Advocate

I need a routine that changes all blocks in a file containing overriding colored entities from one color to another color. The routine should prompt me for both colors. This would include changing the containing nested blocks as well. Example, change color 9 to color 253. Thanks in advance.  

0 Likes
Accepted solutions (1)
2,578 Views
28 Replies
Replies (28)
Message 21 of 29

RocksterB
Advocate
Advocate

Thanks for the update. Unfortunately, I'm getting the following error message when I run the routine:

   "; error: no function definition: SSLIST"

 

0 Likes
Message 22 of 29

MrJSmith
Advocate
Advocate

My apologies. Here is the included function.

 

(defun c:BlockEntityUpdate ( / oldColor newColor blks ct ss oldTxt newTxt elist replaceAll ssList)
	(defun replaceAll (oldtext newtext textstring / i n)
		(setq n (strlen newtext))
		(while (setq i (vl-string-search oldtext textstring i))
			(setq 
			textstring (vl-string-subst newtext oldtext textstring i)
			i (+ i n))
		)
		textstring
	)
	
	(defun ssList (ss / lst ct)
		(if ss
			(progn
				(setq ct 0)
				(repeat (sslength ss)
					(setq 
						lst (cons (ssname ss ct) lst)
						ct (+ ct 1)
					)
				)
			)
		)
		lst
	)
	
	;Start Main
	(or *acdoc* (setq *acdoc* (vla-get-activedocument (vlax-get-acad-object))))
	(vla-StartUndoMark *acdoc*) ;set an undo point for quickly reverting changes
	(setq oldColor (getint "Enter number of OLD color of block entities to change from:  ")) ;old color
	(setq newColor (getint "Enter number of NEW color of block entities to change into:  ")) ;new color
	
	;Change Blocks
	(setq blks (vla-get-blocks *acdoc*)) ;vla blocks collection
	(setq ct 0) ;count for how many entities colors were changed
	(vlax-for blk blks ;loop through each block in the blocks collection
		(if (not (or (= :vlax-true (vla-get-islayout blk)) (= :vlax-true (vla-get-isxref blk)))) ;make sure not an xref or paper/model/layout block
			(vlax-for obj blk ;loop through each entity in the block
				(if (= (vla-get-color obj) oldColor) ;entity color compare
					(progn
						(vla-put-color obj newColor) ;update entity color
						(setq ct (+ ct 1)) ;count the entity color change
					)
				)
			)
		)
	)
	
	;Change Tables
	(setq ss (ssget "_X" '((0 . "ACAD_TABLE"))))
	(setq oldTxt (strcat "\\C" (itoa oldColor)))
	(setq newTxt (strcat "\\C" (itoa newColor)))
	(foreach table (sslist ss)
		(setq elist (entget table))
		(setq elist (mapcar '(lambda (x) 
			(cond
				((= 1 (car x))
					(cons 1 (replaceAll oldTxt newTxt (cdr x))) 
				)
				((= 302 (car x))
					(cons 302 (replaceAll oldTxt newTxt (cdr x)))
				)
				((= 62 (car x))
					(if (= oldColor (cdr x))
						(progn (setq ct (+ 1 ct))(cons 62 newColor))
						x
					)
				)
				(1 x)
			)
		) elist)) 
		(entmod elist)
	)
					
	(vla-regen *acdoc* acActiveViewport) ;regen the viewport to display the updates to the user
	(print (strcat "Updated " (itoa ct) " entities from color: " (itoa oldColor) " into new color: " (itoa newColor) ".")) ;notify the user of the changes
	(vla-EndUndoMark *acdoc*) ;end the undo point
	(princ)
)
0 Likes
Message 23 of 29

RocksterB
Advocate
Advocate

This iteration of the routine did get rid of the error I previously mentioned. However, it did not change the table text color at all. Never mind using the routine to fix the table text color. It was a wish request. Can you post a clean version of the routine without the table data and I'll use it just to update blocks? Thank you.

0 Likes
Message 24 of 29

MrJSmith
Advocate
Advocate

Maybe you are using a different type of table? Or the table isn't using hard coded colors? It is working for me. If you attach a simple drawing with the table you'd like to change I could take a look at it. Regardless, here is the code for just the blocks.

(defun c:BlockEntityUpdate ( / oldColor newColor blks ct)

	;Start Main
	(or *acdoc* (setq *acdoc* (vla-get-activedocument (vlax-get-acad-object))))
	(vla-StartUndoMark *acdoc*) ;set an undo point for quickly reverting changes
	(setq oldColor (getint "Enter number of OLD color of block entities to change from:  ")) ;old color
	(setq newColor (getint "Enter number of NEW color of block entities to change into:  ")) ;new color
	
	;Change Blocks
	(setq blks (vla-get-blocks *acdoc*)) ;vla blocks collection
	(setq ct 0) ;count for how many entities colors were changed
	(vlax-for blk blks ;loop through each block in the blocks collection
		(if (not (or (= :vlax-true (vla-get-islayout blk)) (= :vlax-true (vla-get-isxref blk)))) ;make sure not an xref or paper/model/layout block
			(vlax-for obj blk ;loop through each entity in the block
				(if (= (vla-get-color obj) oldColor) ;entity color compare
					(progn
						(vla-put-color obj newColor) ;update entity color
						(setq ct (+ ct 1)) ;count the entity color change
					)
				)
			)
		)
	)
			
	(vla-regen *acdoc* acActiveViewport) ;regen the viewport to display the updates to the user
	(print (strcat "Updated " (itoa ct) " entities from color: " (itoa oldColor) " into new color: " (itoa newColor) ".")) ;notify the user of the changes
	(vla-EndUndoMark *acdoc*) ;end the undo point
	(princ)
)
0 Likes
Message 25 of 29

RocksterB
Advocate
Advocate

I've attached a sample file containing two AutoCAD tables. The first gets its properties straight from the table style and the second one has a few cells with the color "RED" applied to the properties of the cells. I'm using AutoCAD 2022.

0 Likes
Message 26 of 29

MrJSmith
Advocate
Advocate
Accepted solution

That helps. Turns out there are multiple ways of changing their color. Let me know if works for you. Learning a lot about these tables. 😅

 

(defun c:BlockEntityUpdate ( / oldColor newColor blks ct ss oldTxt newTxt elist table col row replaceAll ssList numberList)
	(defun replaceAll (oldtext newtext textstring / i n)
		(setq n (strlen newtext))
		(while (setq i (vl-string-search oldtext textstring i))
			(setq 
			textstring (vl-string-subst newtext oldtext textstring i)
			i (+ i n))
		)
		textstring
	)
	
	(defun ssList (ss / lst ct)
		(if ss
			(progn
				(setq ct 0)
				(repeat (sslength ss)
					(setq 
						lst (cons (ssname ss ct) lst)
						ct (+ ct 1)
					)
				)
			)
		)
		lst
	)
	
	(defun numberList (limit / numbers i)
	  (setq numbers '())
	  (setq i 1)
	  (while (<= i limit)
		(setq numbers (cons i numbers))
		(setq i (1+ i))
	  )
	  (reverse numbers)
	)
	
	;Start Main
	(or *acdoc* (setq *acdoc* (vla-get-activedocument (vlax-get-acad-object))))
	(vla-StartUndoMark *acdoc*) ;set an undo point for quickly reverting changes
	(setq oldColor (getint "Enter number of OLD color of block entities to change from:  ")) ;old color
	(setq newColor (getint "Enter number of NEW color of block entities to change into:  ")) ;new color
	
	;Change Blocks
	(setq blks (vla-get-blocks *acdoc*)) ;vla blocks collection
	(setq ct 0) ;count for how many entities colors were changed
	(vlax-for blk blks ;loop through each block in the blocks collection
		(if (not (or (= :vlax-true (vla-get-islayout blk)) (= :vlax-true (vla-get-isxref blk)))) ;make sure not an xref or paper/model/layout block
			(vlax-for obj blk ;loop through each entity in the block
				(if (= (vla-get-color obj) oldColor) ;entity color compare
					(progn
						(vla-put-color obj newColor) ;update entity color
						(setq ct (+ ct 1)) ;count the entity color change
					)
				)
			)
		)
	)
	
	;Change Tables
	(setq ss (ssget "_X" '((0 . "ACAD_TABLE"))))
	(setq oldTxt (strcat "\\C" (itoa oldColor)))
	(setq newTxt (strcat "\\C" (itoa newColor)))
	(foreach table (sslist ss)
		(setq elist (entget table))
		(setq elist (mapcar '(lambda (x) 
			(cond
				((= 1 (car x))
					(cons 1 (replaceAll oldTxt newTxt (cdr x))) 
				)
				((= 302 (car x))
					(cons 302 (replaceAll oldTxt newTxt (cdr x)))
				)
				((= 62 (car x))
					(if (= oldColor (cdr x))
						(progn (setq ct (+ 1 ct))(cons 62 newColor))
						x
					)
				)
				(1 x)
			)
		) elist))
		(entmod elist)
		(setq table (vlax-ename->vla-object table))
		(setq col (numberList (vla-get-Columns table))
			row (numberList (vla-get-Rows table))
		)
		(foreach r row
			(foreach c col
				(setq cellColor (vlax-invoke table 'GetCellContentColor r c))
				(if (= (vla-get-colorIndex cellColor) oldColor) ;entity color compare
					(progn
						(vla-put-colorIndex cellColor newColor) ;update entity color
						(vlax-invoke table 'SetCellContentColor r c cellColor)
						(setq ct (+ ct 1)) ;count the entity color change
					)
				)
			)
		)
		
	)
	(vla-regen *acdoc* acActiveViewport) ;regen the viewport to display the updates to the user
	(print (strcat "Updated " (itoa ct) " entities from color: " (itoa oldColor) " into new color: " (itoa newColor) ".")) ;notify the user of the changes
	(vla-EndUndoMark *acdoc*) ;end the undo point
	(princ)
)

 

0 Likes
Message 27 of 29

RocksterB
Advocate
Advocate

The last is the best one. Everything seems to work. Thanks for your help with this. It will be a time saver.

Message 28 of 29

Sea-Haven
Mentor
Mentor

"Learning a lot about these tables. "

 

This may be useful.

 

Message 29 of 29

MrJSmith
Advocate
Advocate

Yeah I was only looking at properties of them, didn't realize all their info is retrieved through methods.

0 Likes