LISP That modify the value of an attribute

LISP That modify the value of an attribute

cadtesthelp
Explorer Explorer
372 Views
3 Replies
Message 1 of 4

LISP That modify the value of an attribute

cadtesthelp
Explorer
Explorer

Hello everyone,

 

I am in need of a LISP routine that can modify the value of an attribute within a block. I've come across some posts on this topic, but unfortunately, I haven't been able to get it to work.

I believe it's a relatively straightforward task, but I'm still in the early stages of learning customization in AutoCAD.

 

Block Name: SD-SD
Attribute Tag: REV
Current Attribute Value: *unknown*
New Attribute Value: 2

 

Any assistance or guidance on creating such a LISP routine would be greatly appreciated. Thank you in advance.

0 Likes
Accepted solutions (1)
373 Views
3 Replies
Replies (3)
Message 2 of 4

MrJSmith
Advocate
Advocate

This is what I use.

 

;Used to access a particular item in a VBA / ActiveX Collection
(defun vlaGetItem ( col itm ) ;Collection, item looking for. I.e. (vla-get-blocks *acdoc*) "BlockName"
	(if (not (vl-catch-all-error-p (setq itm (vl-catch-all-apply 'vla-item (list col itm)))))
		itm
	)
)

;blk is vlaBlk to update
;lst is (list (AttributeTag(header) . AttributeValue))
;replaceFields - Controls if fields are update/replaced with simple text string. Pass 1 to update fields into regular text
(defun setAttributeValues ( blk lst replaceFields / itm )
	(mapcar 
		'(lambda (x) 
			(if (and 
					(or
						replaceFields
						(not (vlaGetItem (vlax-invoke x 'GetExtensionDictionary) "ACAD_FIELD"))
					)
					(setq itm (assoc (vla-get-tagstring x) lst)) 
					; (debug "itm: " itm)				
				)
				(vla-put-textstring x (cdr itm))
			)
		) (vlax-invoke blk 'getattributes)
	)
)

 

 

You need to pass it the VLA block. Numerous ways to get it but I typically do something like this.

 

;Returns the non-anoynmous name of blocks
(defun vlaBlockName (vlaBlk)  
	(if (vlax-property-available-p vlaBlk 'effectivename)
			(vla-get-effectivename vlaBlk) 
			(vla-get-name vlaBlk)
	)
)

(or *acad* (setq *acad* (vlax-get-acad-object)))
(or *acdoc* (setq *acdoc* (vla-get-ActiveDocument *acad*)))
(or doc (setq doc *acdoc*))
(vlax-for la (vla-get-layouts doc)
	(vlax-for o (vla-get-block la)
		(if
			(and 
				(= "AcDbBlockReference" (vla-get-objectname o)) ;Make sure o is a block
				(= :vlax-true (vla-get-hasattributes o)) ;Make sure o (the block) has attributes
				(= "SD-SD" (strcase (vlaBlockName o))) ;We found our block
			)
			(setAttributeValues o '(("REV" . "2")) nil)
		)
	)
)

 

 

May want to wrap it in some c: defun but that's the jist of it.

0 Likes
Message 3 of 4

Kent1Cooper
Consultant
Consultant
Accepted solution

Since an Attribute value is a property of a Block insertion, not of its definition, the Block name alone is not enough information.  Are you intending to select an insertion of the Block, or will there be only one that a routine should find, or do you want to change that Attribute value in all insertions of that Block if there are more than one?

 

If an individual insertion that you would pick, that's easy, since an Attribute's Tag constitutes a "property" of the insertion:

 

(setpropertyvalue (car (entsel "\nSelect the Block insertion: ")) "REV" "2")

 

If something else, a routine could find the Block insertion(s) easily enough and apply the same to it/them.

Kent Cooper, AIA
0 Likes
Message 4 of 4

Sea-Haven
Mentor
Mentor

So some more questions it looks like a title block thing update the revision value, so even more questions where is the "2" coming from and like Kent's questions is it in multiple layouts etc. Are they all different rev's ?

0 Likes