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.
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) )
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"
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")
@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
Things like this ...... ?
(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) )
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.
@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
(command "._attedit" "N" "N" "template" "MYDWGSTATUS" "*" "" "DEFINITIEF")
thats sorta what i mean with simple thanks anyways
@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.
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
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.
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?
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
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
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) ) ) ) ) )
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
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.