Is it possible to rename Tags in Blocks using AutoLisp?
|
Hi,
You can get ideas from this little routine
If you don't want to use command, replace:Code:(defun rename-tag (blockname oldtag newtag / def ent loop elst) (if (setq def (tblsearch "BLOCK" blockname)) (progn (setq ent (cdr (assoc -2 def)) loop T ) (while (and ent loop) (setq elst (entget ent)) (if (and (= (cdr (assoc 0 elst)) "ATTDEF") (= (cdr (assoc 2 elst)) (strcase oldtag)) ) (progn (entmod (subst (cons 2 newtag) (assoc 2 elst) elst)) (setq loop nil) ) ) (setq ent (entnext ent)) ) (command "_attsync" "_n" blockname) ) ) (princ) )
byCode:(command "_attsync" "_n" blockname)
Code:(if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 blockname)))) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) att (entnext ent) ) (while att (setq elst (entget att)) (= (cdr (assoc 0 elst)) "ATTRIB") (if (and (= (cdr (assoc 0 elst)) "ATTRIB") (= (cdr (assoc 2 elst)) (strcase oldtag)) ) (entmod (subst (cons 2 (strcase newtag)) (assoc 2 elst) elst) ) ) (setq att (entnext att)) ) ) )
Last edited by 'gile'; 2008-02-08 at 04:43 PM.
Another way using Visual LISP functions
Code:(defun rename-tag (blockname oldtag newtag) (vl-load-com) (or *acad* (setq *acad* (vla-get-ActiveDocument (vlax-get-acad-object))) ) (if (tblsearch "BLOCK" blockname) (progn (vlax-for obj (vla-item (vla-get-Blocks *acad* ) blockname ) (if (and (= (vla-get-ObjectName obj) "AcDbAttributeDefinition") (= (strcase oldtag) (vla-get-Tagstring obj)) ) (vla-put-TagString obj (strcase newtag)) ) ) (if (ssget "_X" (list '(0 . "INSERT") (cons 2 blockname))) (vlax-for ref (vla-get-ActiveSelectionSet *acad* ) (foreach att (vlax-invoke ref 'getAttributes) (if (= (strcase oldtag) (vla-get-Tagstring att)) (vla-put-TagString att (strcase newtag)) ) ) ) ) ) ) (princ) )
gile,
Instead of using ssget to find all the inserted blocks, you can grab that information from the dxf information of the block definition. Just an FYI..
Code:(defun ReturnInsertedEnames (BlkName / EnameList) (foreach lst (entget (cdr (assoc 330 (entget (tblobjname "block" BlkName))))) (if (equal (car lst) 331) (setq EnameList (cons (cdr lst) EnameList)) ) ) EnameList )Code:(defun c:Test () (ReturnInsertedEnames (cdr (assoc 2 (entget (car (entsel "\n Select block: ")))))) )
Tim, that's perfect
Thanks
Here is my 2¢ (just an extension of your function)
to select blocks on particular sheet
Usage :Code:(defun ReturnInsertedEnamesOnLayout (BlkName LayoutName / EnameList) (foreach lst (entget (cdr (assoc 330 (entget (tblobjname "block" BlkName))))) (if (equal (car lst) 331) (if (eq LayoutName (cdr (assoc 410 (entget (cdr lst))))) (setq EnameList (cons (cdr lst) EnameList)) ) ) ) EnameList )
~'J'~Code:(ReturnInsertedEnamesOnLayout (cdr (assoc 2 (entget (car (entsel "\n Select block: "))))) "Layout1")
Very nice Tim !!!
I didn't know this, and I thank you very much to share this trick.
You're welcome, both. I just share what little I know, and hope it is useful to others.
Tim,
I notice that if some bloc have been erased from the drawing, their enames still appear in the list.
Just for fun, another way to write the routine
Code:(defun ReturnInsertedEnames (BlkName) (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 331)) (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" BlkName)))) ) ) ) )
Good catch. I would have to think that has something to do with being able to undo everything. Maybe there should be a check to make sure you only get non-erased entity names.
Code:(defun ReturnInsertedEnames (BlkName) (vl-remove-if 'vlax-erased-p (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 331)) (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" BlkName))))) ) ) ) )