Jump to content

Lisp to change att TAG name(Not Value) with up to 13 old - new names.


callvey

Recommended Posts

Hi,

I am trying to modify a titleblock's att tag name, I have found loads of lisp routines that modify the value but cant seem to find one that can modify the name..

Is this even possible as I have read that the block has to be exploded for this to work??

Thanks

Link to comment
Share on other sites

  • Replies 33
  • Created
  • Last Reply

Top Posters In This Topic

  • Tharwat

    13

  • callvey

    11

  • johmmeke

    3

  • BIGAL

    2

Top Posters In This Topic

I tried this but it doesnt work;

 

(defun c:attr_rename_list ( / x_en enn edd ss slen ix atnam 
namelist hit blk_ent
matchname newed x) 
; Process all block instances on active drawing. Check each 
; attribute for match on first element in list below. On any
; match, rename the attribute to the new name given in the
; second element. 

; *********** ATTRIBUTE OLD versus NEW names list ******************
(setq namelist (list
; list old name and new name. Old name can contain wild cards.
(list "OLD_TAG_NAME#1" "NEW_TAG_NAME#1") ; list old name and new name. 
(list "OLD_TAG_NAME#2" "NEW_TAG_NAME#2")
(list "OLD_TAG_NAME#3" "NEW_TAG_NAME#3")
(list "OLD_TAG_NAME#4" "NEW_TAG_NAME#4")
(list "OLD_TAG_NAME#5" "NEW_TAG_NAME#5")
) ) 
; ************************************************** ********************

; Extract selection set of all block inserts on active drawing 
(setq ss (ssget "_X" '((0 . "INSERT"))))
(if (/= ss nil)
(progn
(setq slen (sslength ss))
(setq ix 0)
(while (< ix slen)
(setq blk_ent (ssname ss ix)) ; get next block insert to process 
(setq ix (1+ ix)) ; increment for next time
(setq enn (entnext blk_ent)) 
(setq edd (entget enn)) 
(while (AND enn (/= (cdr (assoc 0 edd)) "SEQEND") 
(/= (cdr (assoc 0 edd)) "INSERT") )
(if (= (cdr (assoc 0 edd)) "ATTRIB")
(progn
(setq atnam (cdr (assoc 2 edd)))
(setq hit nil)
(foreach x namelist
(if (not hit)
(progn ; no match yet, keep processing
(setq matchname (car x)) 
(if (wcmatch atnam matchname) 
(progn ; found exact match or wild-card match
; Change name now. Substitute in new name.
(setq newed (subst (cons 2 (cadr x)) (assoc 2 edd) edd)) 
(entmod newed) ; update the title block instance
(entupd blk_ent) 
(princ "\n")
(princ atnam)
(princ " --> ")
(princ (cadr x))
(setq hit 1) ; flag that found
) ) ) )
)
)
) 
; go to next sub ent in block instance and loop back up
(if (setq enn (entnext enn)) (setq edd (entget enn))) 
) ) 
(setq ss nil) ; release the selection set
)
)
(princ) ; prettier
)

Link to comment
Share on other sites

Out of curiosity, as I can undestand the reason to change the prompt and/or the default value; why would one want to change the tag which isn't visible to regular edit operations?

Link to comment
Share on other sites

The drawing is connected to a sql Database, the values are updated dynamically based on the name of the att tag. For example when I change an area/zone within the drawing it updates the value in the titleblock. some of my titleblocks read from different columns in the database, so I have to modify Att name to accommodate this.

Link to comment
Share on other sites

old tag - new tag

AREA1 - AREA13

AREA2 - AREA14

AREA3 - AREA15

AREA4 - AREA16

AREA5 - AREA17

AREA6 - AREA18

AREA7 - AREA19

AREA8 - AREA20

Link to comment
Share on other sites

All right , try this code and let me know .

 

(defun c:ChangeTags (/ *error* cmd l a)
 ;;    Tharwat 21. Mar. 2014        ;;
 (defun *error* (msg)
   (if cmd
     (setvar 'CMDECHO cmd)
   )
   (if (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")
     (princ msg)
     (princ (strcat "*** Error : " msg "***"))
   )
   (princ)
 )
 (or doc
     (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 )
 (setq cmd (getvar 'CMDECHO)
       l   '(("AREA1" . "AREA13")
             ("AREA2" . "AREA14")
             ("AREA3" . "AREA15")
             ("AREA4" . "AREA16")
             ("AREA5" . "AREA17")
             ("AREA6" . "AREA18")
             ("AREA7" . "AREA19")
             ("AREA8" . "AREA20")
            )
 )
 (setvar 'CMDECHO 0)
 (vlax-for x (vla-get-blocks doc)
   (if (and (eq :vlax-false (vla-get-isxref x))
            (eq :vlax-false (vla-get-islayout x))
       )
     (vlax-for o x
       (if (and (eq (vla-get-objectname o) "AcDbAttributeDefinition")
                (setq a (assoc (strcase (vla-get-tagstring o)) l))
           )
         (progn
           (vla-put-tagstring o (cdr a))
           (command "_.attsync" "_Name" (vla-get-name x))
         )
       )
     )
   )
 )
 (setvar 'CMDECHO cmd)
 (princ)
)
(vl-load-com)

Link to comment
Share on other sites

Fantastic stuff. really appreciate this code, ive been wheel spinning for days..I really do need to start learning this stuff:notworthy:

Link to comment
Share on other sites

Fantastic stuff. really appreciate this code, ive been wheel spinning for days..I really do need to start learning this stuff:notworthy:

 

Waw excellent . happy to hear that . :)

Link to comment
Share on other sites

I've been wondering.. I have batch run this against a list if files, manually selecting the files from a folder.Would it be possible to identify a block based upon a specific attribute value it has.? And if it has that value then change the tag string?

Link to comment
Share on other sites

You can make it work by using a script which will open the dwg make the changes then close the dwg do next and so on. To make it work you need to set the values of the attributes and pass these to the main program. For simplicity use this style Tharwart will help I am sure. You must add the defun to automatically load by adding code to acaddoc.lsp

 

(setq namelist (list
(list "OLD_TAG_NAME#1" "NEW_TAG_NAME1") 
(list "OLD_TAG_NAME#2" "NEW_TAG_NAME2")
(list "OLD_TAG_NAME#3" "NEW_TAG_NAME3")
(list "OLD_TAG_NAME#4" "NEW_TAG_NAME4")
(list "OLD_TAG_NAME#5" "NEW_TAG_NAME5")
) ) 
Open dwg1
(c:attr_rename_list)
Close Y
(setq namelist (list
(list "OLD_TAG_NAME#1" "NEW_TAG_NAME6") 
(list "OLD_TAG_NAME#2" "NEW_TAG_NAME7")
(list "OLD_TAG_NAME#3" "NEW_TAG_NAME8")
(list "OLD_TAG_NAME#4" "NEW_TAG_NAME9")
(list "OLD_TAG_NAME#5" "NEW_TAG_NAME10")
) ) 
Open dwg2
(c:attr_rename_list)
Close Y

 

Alternative would be to use pairs and make list using the defun to re-make the list.

 

(c:attr_rename_list  "OLD_TAG_NAME#1" "NEW_TAG_NAME6" "OLD_TAG_NAME#2" "NEW_TAG_NAME7" "OLD_TAG_NAME#3" "NEW_TAG_NAME8" "OLD_TAG_NAME#4" "NEW_TAG_NAME9" "OLD_TAG_NAME#5" "NEW_TAG_NAME10")

Link to comment
Share on other sites

Hi Bigal thanks for you reply. So I'm using the code that tharwat posted along with auto script to batch it. However when i use auto script i have to manually select the files that require the change. I was wondering, because the files that need updating have a unique attribute value within the block, I could somehow select all files and the batch would run only modifying those files with the unique attribute. Don't know if it's possible but worth an ask.

Thanks

Link to comment
Share on other sites

The code posted should look for a unique attribute tag so if it does not exsit it should not change anything, you could narrow the changes to only certain block names also as a extra to the ssget function to exclude blocks you do not want changed.

 

I am sure Tharwat will respond.

Link to comment
Share on other sites

Would it be possible to identify a block based upon a specific attribute value it has.? And if it has that value then change the tag string?

 

That is simply could be done the same way that I did in my posted code and change the list accordingly with a replacement of one function as you can see in the following codes .

 

Be sure to have your values in capital letters .

 

(defun c:ChangeTags (/ *error* cmd l a)
 ;;    Tharwat 24. Mar. 2014        ;;
 (defun *error* (msg)
   (if cmd
     (setvar 'CMDECHO cmd)
   )
   (if (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")
     (princ msg)
     (princ (strcat "*** Error : " msg "***"))
   )
   (princ)
 )
 (or doc (setq doc (vla-get-activedocument (vlax-get-acad-object))))
 (setq cmd (getvar 'CMDECHO)
       l   '(("VALUE1" . "AREA13") ("VALUE2" . "AREA14") ("VALUE3" . "AREA15"))
 )
 (setvar 'CMDECHO 0)
 (vlax-for x (vla-get-blocks doc)
   (if (and (eq :vlax-false (vla-get-isxref x)) (eq :vlax-false (vla-get-islayout x)))
     (vlax-for o x
       (if (and (eq (vla-get-objectname o) "AcDbAttributeDefinition")
                (setq a (assoc (strcase (vla-get-textstring o)) l))
           )
         (progn (vla-put-tagstring o (cdr a)) (command "_.attsync" "_Name" (vla-get-name x)))
       )
     )
   )
 )
 (setvar 'CMDECHO cmd)
 (princ)
)
(vl-load-com)

I am sure Tharwat will respond.

 

Thank you BIGAL for that big trust , highly appreciated . :)

Link to comment
Share on other sites

I tried that but it doesnt do what I need.

I am running this through auto-script.

So I have two types of titleblock-

I only want the routine to work on the one where

TAG NAME - VALUE

DESC2 = BASEMENT

 

So out of 1500 files 750 of them could have a value of BASEMENT for DESC2

so where DESC2 has a value of BASEMENT

 

AREA1 - AREA13

AREA2 - AREA14 etc..

 

and if it doesnt have a value of BASEMENT do nothing.

 

Hope this makes sense and thank you for help again.

Link to comment
Share on other sites

It did not work because you might not have changed the values that I included within the routine to suit your required value(s) to change the tag name when it matches , have you ?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...