Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lisp to change atribute

17 REPLIES 17
Reply
Message 1 of 18
Anonymous
2694 Views, 17 Replies

Lisp to change atribute

I have been looking round but only seam to find complicated long lisp programs to change an attributes value. To me it seams like it would be a quite simple task dose anyone know a way of doing this.

17 REPLIES 17
Message 2 of 18
CADaSchtroumpf
in reply to: Anonymous

I don't know if this code is complicated for you ...

If you want try.

 

(defun c:editextatt ( / js ename nw_str)
  (vl-load-com)
  (setq js
    (ssget "_+.:e:s"
      '(
        (-4 . "<OR")
          (0 . "*TEXT,MULTILEADER,ATTDEF")
          (-4 . "<AND")
            (0 . "INSERT") (66 . 1)
          (-4 . "AND>")
        (-4 . "OR>")
      )
    )
  )
  (cond
    (js
      (setq ename (vlax-ename->vla-object (ssname js 0)))
      (cond
        ((vlax-property-available-p ename 'TextString)
          (setq nw_str (getstring (strcat "\nNew texte for " (vlax-get ename 'TextString) ": ")))
          (if (/= nw_str "")
            (vlax-put ename 'TextString nw_str)
          )
        )
        (T
          (mapcar 
            '(lambda (att)
              (setq nw_str (getstring (strcat "\nNew texte for " (vlax-get att 'TextString) ": ")))
              (if (/= nw_str "")
                (vlax-put att 'TextString nw_str)
              )
            )
            (vlax-invoke ename 'GetAttributes)
          )
        )
      )
    )
  )
  (prin1)
)

 

Message 3 of 18
Anonymous
in reply to: CADaSchtroumpf

This is nice but its not as far as I want to go. Simply put I want to create a toolbar button (linked with a lisp) that searches for all attributes named MYATTRIBUTE and changes there value to "HELLOWORLD"

Message 4 of 18
CADaSchtroumpf
in reply to: Anonymous

GATTE in expresstools make this for all tags !

 

Another form of previous code?

Isn't a command but a function with arguments for to find and replace text

(defun my_replace_text (new_string old_string / js n ename)
  (vl-load-com)
  (defun string-subst (nam_obj / value_string nbs tmp_nbs)
    (setq value_string (vlax-get nam_obj 'TextString) nbs 0)
    (while nbs
      (if (setq nbs (vl-string-search old_string value_string (setq tmp_nbs nbs)))
        (setq
          value_string (vl-string-subst new_string old_string value_string tmp_nbs)
          nbs (1+ nbs)
        )
      )
    )
    (vlax-put nam_obj 'TextString value_string)
  )
  (setq js
    (ssget "_X"
      '(
        (-4 . "<OR")
          (0 . "*TEXT,MULTILEADER,ATTDEF")
          (-4 . "<AND")
            (0 . "INSERT") (66 . 1)
          (-4 . "AND>")
        (-4 . "OR>")
      )
    )
  )
  (cond
    (js
      (repeat (setq n (sslength js))
        (setq ename (vlax-ename->vla-object (ssname js (setq n (1- n)))))
        (cond
          ((vlax-property-available-p ename 'TextString)
            (string-subst ename)
          )
          (T
            (mapcar 
              '(lambda (att)
                (string-subst att)
              )
              (vlax-invoke ename 'GetAttributes)
            )
          )
        )
      )
    )
  )
  (prin1)
)

 Careful: case sensitive

Call exemple: (my_replace_text "HELLOWORLD" "BYEBYE")

Message 5 of 18
pbejse
in reply to: Anonymous


@Anonymous wrote:

This is nice but its not as far as I want to go. Simply put I want to create a toolbar button (linked with a lisp) that searches for all attributes named MYATTRIBUTE and changes there value to "HELLOWORLD"


Another  <an old one>

 

(defun repatt (tg Val / ss a )
      (vl-load-com)
      (if (ssget "_X" '((0 . "INSERT")(66 . 1)))
          (progn
                (vlax-for itm (setq ss (vla-get-activeselectionset
                                    (vla-get-activedocument
                                          (vlax-get-acad-object))))
                 (if (and (setq a  (mapcar (function
                                    (lambda (j)
                                          (list (vla-get-tagstring j)
                                                j)))
                              (vlax-invoke itm 'Getattributes)))
                     (setq a (assoc (strcase tg) a))
                          )
                     (vla-put-textstring  (cadr a) val)))
                (vla-delete ss)
                )
          )
      (princ)
      )

 

 

(repatt "MYATTRIBUTE" "HELLOWORLD")

 

HTH

Message 6 of 18
_Tharwat
in reply to: Anonymous

Things like this ...... ? Smiley Wink

 

(defun c:Test (/ e i n sn ss)
  ;;; Tharwat 27. march. 2012 ;;;
  (if (setq ss (ssget "_x" '((0 . "INSERT") (66 . 1))))
    (repeat (setq i (sslength ss))
      (setq sn (ssname ss (setq i (1- i))))
      (setq n (entnext sn))
      (while
        (not
          (eq (cdr (assoc 0 (setq e (entget n))))
              "SEQEND"
          )
        )
         (if (eq (strcase (cdr (assoc 1 e))) "MYATTRIBUTES")
           (entmod (subst (cons 1 "HELLOWORLD") (assoc 1 e) e))
         )
         (setq n (entnext n))
      )
    )
    (princ)
  )
  (princ)
)

 

Message 7 of 18
scot-65
in reply to: Anonymous

We had such instance where a attribute block with a date stamp required updating on all pages.

From the help of this group, I was able to create such a routine you are asking for.

 

First order of business is to manually select and update the target attribute.

Next is to run this routine, select this attribute, and all attributes with this same name,

in the same-name block will update. Give it a try and see if this is what you want.

 

UPA - Update Attribute.

 

???

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 8 of 18
pbejse
in reply to: scot-65


@scot-65 wrote:

First order of business is to manually select and update the target attribute.

Next is to run this routine, select this attribute, and all attributes with this same name,

in the same-name block will update. Give it a try and see if this is what you want.

 

UPA - Update Attribute. 

 



One suggestion: [To account for Anonymous Name]

 

 With the introduction of Dynamic Blocks, this line doesnt cut it anymore.

(setq s (ssget  "_X" (list (cons 0 "INSERT") (cons 2 bn) (cons 66 1))))

 

Change it to

(setq s (ssget "x" (list (cons 0 "INSERT") (cons 2 (strcat bn ",`*U*")) (cons 66 1))))

 

And if by somehow there are other blocks that contains the same tag name but diffrent block name

 

(setq bn (cdr (assoc 2 (entget (car a))))) ;block name

to

(setq bn (_effname (car a)))

 

and wrap with this

(if (eq (_effname  a) bn)(progn   

(setq b (entget a))......

......

......

);while
         );progn
       );if

 

Add these lines on the top of the code

 

(defun c:UPA ( / a b bn bt bv s n f )(vl.-load-com)

(vll-load-com)

(defun *error* (msg)
  (setq a nil b nil bn nil bt nil bv nil s nil n nil f nil)(princ) )

(setq _effname (lambda (k)
                 (vla-get-Effectivename
                       (vlax-ename->vla-object k))))

(while........

 

 

 

HTH

Message 9 of 18
Anonymous
in reply to: pbejse

(command "._attedit" "N" "N" "template" "MYDWGSTATUS" "*" "" "DEFINITIEF")

 

thats sorta what i mean with simple thanks anyways

 

Message 10 of 18
pbejse
in reply to: Anonymous


@Anonymous wrote:

(command "._attedit" "N" "N" "template" "MYDWGSTATUS" "*" "" "DEFINITIEF")

 

thats sorta what i mean with simple thanks anyways

 


Simple indeed.

 

No worries, were just trying to provide you with generic lisp routines so wyou will be able to use for diffrent Tag/Block names without modifying the main routine.

 

Anyhoo. Glad you figured out a solution

 

Good for you Caddie.

Message 11 of 18
Ian_Bryant
in reply to: Anonymous

Hi,

(command "._attedit" "N" "N" "template" "MYDWGSTATUS" "*" "" "DEFINITIEF")

works fine if the attributes in question have null values. If they already have values

the string "DEFINITIEF" will be appended to the front of the existing strings.

 

To get over this using the attedit command you could try something like:

 (progn (command "._attedit" "Y" "template" "MYDWGSTATUS" "*"
                             "C" "_non" (getvar "extmax") "_non" (getvar "extmin"))
             (while (> (getvar "CMDACTIVE") 0) (command "V" "R" "HELLOWORLD" "N"))
             (princ)
)

 

If the block "template" is a dynamic block you could change the string "template" to "*"

as long as the tag "MYDWGSTATUS" is unique to the block "template".

 

Regards Ian

 

Message 12 of 18
Anonymous
in reply to: Ian_Bryant

yeah I noted that so your solution is a nice addition i was handeling the situation by doing the following.

 

			;FILTERING ALL MYDWGSTATUS ATTRIBUTE VALUES TO EMPTY BLANK TEXT...
			(command "._attedit" "N" "N" "A4LANDSCAPE" "MYDWGSTATUS" "*" "TER KONTROLE" "")
			(command "._attedit" "N" "N" "A4LANDSCAPE" "MYDWGSTATUS" "*" "TER BEOORDELING" "")
			(command "._attedit" "N" "N" "A4LANDSCAPE" "MYDWGSTATUS" "*" "DEFINITIEF" "")
			(command "._attedit" "N" "N" "A4LANDSCAPE" "MYDWGSTATUS" "*" "1e OPZET" "")

			;RESETTING THE MYDWGSTATUS ATTRIBUTE VALUE TO TER KONTROLE...
			(command "._attedit" "N" "N" "A4LANDSCAPE" "MYDWGSTATUS" "*" "" "TER KONTROLE")

 this works limitedly for my situation as the attribute can only be one of 5 entrys.

Message 13 of 18
Anonymous
in reply to: Anonymous

Better yet this questions in strong relation to the next.

 

How do I ( if possible) automate a loginname to be used in an atribute so that only the attrbute and block being inserted change rather then all the atributes found over the entier drawing (already inserted).

 

this is somthing i havent found out the answer to yet?

Message 14 of 18
_Tharwat
in reply to: Anonymous

Using command call into lisp is not that good idea if you have to much things to do by one command name , try my code or the rest of gents whom posted their code for you which is much more better and faster than the one you are trying to do with command line . 

 

Anyway , to get loginname ,,,

 

(getvar 'loginname)

 Good luck

Message 15 of 18
Ian_Bryant
in reply to: Ian_Bryant

Hi,

the attedit command with crossing selection editd the last added item first,

so you could try for e.g.

(progn
 (command "._attedit" "Y" "template" "MYLOGINNAME" "*"
          "C" "_non" (getvar "extmax") "_non" (getvar "extmin"))
 (if (> (getvar "CMDACTIVE") 0)
     (command "V" "R" (getvar "LOGINNAME")))
 (while (> (getvar "CMDACTIVE") 0) (command "N"))
 (princ)
)

 

Ian


 

Message 16 of 18
dbroad
in reply to: Anonymous

 

It seems strange to ask for help, get good help and then complain that the help is too complicated and propose another inferior solution using command methods.

 

Here is my solution to the original re-stated problem:  find all instances of attributes with a particular tag and change the text value.

 

 

(vl-load-com)
;;Change attribute value
;;Example:  (chgatt "mark" "newtext")
;;DC Broad  2012
(defun chgatt (tag value)
  (setq tag (strcase tag))
  (if
    (ssget "x" '((0 . "insert") (66 . 1)))
     (vlax-for n (vla-get-activeselectionset
		   (vla-get-activedocument (vlax-get-acad-object))
		 )
       (foreach	m (vlax-invoke n 'getattributes)
	 (if (= (vla-get-tagstring m) tag)
	   (vla-put-textstring m value)
	 )
       )
     )
  )
)
Architect, Registered NC, VA, SC, & GA.
Message 17 of 18
Anonymous
in reply to: dbroad

Method to my madness; I love all the really sophisticated solutions that work perfectly which members reply with, though why I want simple is for two reasons,.

 

#1: then I can keep up with what's going on rather then develop a copy and past startup routine, (helps me to learn, self taught you see)

 

#2: I see routines pages and pages long when most of it is usually overkill lisping and a simple line works just as well, be it the orthodox way or not

Message 18 of 18
Anonymous
in reply to: CADaSchtroumpf

The code CADaStroumph provided (see below)

 

works for me however I have multiple attributes and I only want to edit one attribute. I will not need user input as I will be editing the attribute it is installed. thanks for any input.

 

(defun c:editextatt ( / js ename nw_str)
  (vl-load-com)
  (setq js
    (ssget "_+.:e:s"
      '(
        (-4 . "<OR")
          (0 . "*ATTDEF")
          (-4 . "<AND")
            (0 . "INSERT") (66 . 1)
          (-4 . "AND>")
        (-4 . "OR>")
      )
    )
  )
  (cond
    (js
      (setq ename (vlax-ename->vla-object (ssname js 0)))
      (cond
        ((vlax-property-available-p ename 'TextString)
          (setq nw_str (getstring (strcat "\nNew texte for " (vlax-get ename 'TextString) ": ")))
          (if (/= nw_str "")
            (vlax-put ename 'TextString nw_str)
          )
        )
        (T
          (mapcar
            '(lambda (att)
              (setq nw_str (getstring (strcat "\nNew texte for " (vlax-get att 'TextString) ": ")))
              (if (/= nw_str "")
                (vlax-put att 'TextString nw_str)
              )
            )
            (vlax-invoke ename 'GetAttributes)
          )
        )
      )
    )
  )
  (prin1)
)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report