TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: A_LOTA_NOTA on October 06, 2010, 01:24:19 PM
-
How do you search for an attribute tag if you don't know what the name of the block is going to be?
-
You either search the block definitions to see if they are have the attribute, then grab the inserts from there. Or you search the drawing checking each insert.
-
Here's how I've done it, but I'm sure there are better ways:
(setq att_tag1 (ssget "x" '((2 . "wutthenameoftheatttagis"))))
-
Here's how I've done it, but I'm sure there are better ways:
(setq att_tag1 (ssget "x" '((2 . "wutthenameoftheatttagis"))))
This will only work with attribute definitions that have not been added to a block. Plus it is not limited to attributes.
-
Perhaps flick through the INSERTs?
(defun GetAttrib ( att / ss )
(if (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1))))
(
(lambda ( i / a e n l )
(while (and (not a) (setq e (ssname ss (setq i (1+ i)))))
(if (not (member (setq n (cdr (assoc 2 (entget e)))) l))
(progn (setq l (cons n l))
(while
(not
(eq "SEQEND"
(cdr
(assoc 0
(setq l
(entget
(setq e (entnext e))
)
)
)
)
)
)
(if (eq att (cdr (assoc 2 (entget e)))) (setq a n))
)
)
)
)
a
)
-1
)
)
)
Returns block name, but could return whatever is needed really.
-
This will give you a vla list of attributes matching the tagname.
(defun GetTagList (tagname / Doc layout i atts tag str taglist)
(setq Doc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vlax-for layout (vla-get-layouts Doc)
(vlax-for i (vla-get-block layout)
(if (= (vla-get-objectname i) "AcDbBlockReference")
(if (and
(= (vla-get-hasattributes i) :vlax-true)
(safearray-value
(setq atts
(vlax-variant-value
(vla-getattributes i)
)
)
)
)
(foreach tag (vlax-safearray->list atts)
(if (= (strcase tagname) (strcase (vla-get-tagstring tag)))
(setq taglist (append taglist (list tag)))
)
)
)
)
)
)
taglist
)
-
Here's how I've done it, but I'm sure there are better ways:
(setq att_tag1 (ssget "x" '((2 . "wutthenameoftheatttagis"))))
This will only work with attribute definitions that have not been added to a block. Plus it is not limited to attributes.
I see... shoulda looked at my 10 year old code a bit closer. I used some convoluted means of grabbing known att values at some point.
-
Perhaps flick through the INSERTs?
(defun GetAttrib ( att / ss )
(if (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1))))
(
(lambda ( i / a e n l )
(while (and (not a) (setq e (ssname ss (setq i (1+ i)))))
(if (not (member (setq n (cdr (assoc 2 (entget e)))) l))
(progn (setq l (cons n l))
(while
(not
(eq "SEQEND"
(cdr
(assoc 0
(setq l
(entget
(setq e (entnext e))
)
)
)
)
)
)
(if (eq att (cdr (assoc 2 (entget e)))) (setq a n))
)
)
)
)
a
)
-1
)
)
)
Returns block name, but could return whatever is needed really.
How could this be changed so I could pass it the new value for the att also? It already does all the work of finding the tag it might as well update it also. I tried to do it but I get lost in the "lambda" maybe some comments would help so I better understand what it's doing.
-
Bear in mind that the INSERT in which the tag is found will just be the first one that it comes across in the SelectionSet - this may not be consistent everytime.
Would you be looking to update the attribute value for every INSERT?
-
Bear in mind that the INSERT in which the tag is found will just be the first one that it comes across in the SelectionSet - this may not be consistent everytime.
Would you be looking to update the attribute value for every INSERT?
Yes, every INSERT would be great.
-
Something like this perhaps then:
(defun SetAttribValue ( Tag Value / ss )
(if (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1))))
(
(lambda ( i / e l )
(while (setq e (ssname ss (setq i (1+ i))))
(while
(not
(eq "SEQEND"
(cdr
(assoc 0
(setq l
(entget
(setq e (entnext e))
)
)
)
)
)
)
(if (eq Tag (cdr (assoc 2 l)))
(entupd
(cdr
(assoc -1
(entmod
(subst (cons 1 Value) (assoc 1 l) l)
)
)
)
)
)
)
)
t
)
-1
)
)
)
-
I playing catch up, :-)
;; From Tag name return ename list
(defun ssGetAttr ( attTag / ss i ename lst)
(vl-load-com)
(if (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1))))
(progn
(setq i -1)
(while (setq ename (ssname ss (setq i (1+ i))))
(foreach att (vlax-invoke (vlax-ename->vla-object ename) "getattributes")
(if (= (vla-get-tagstring att) attTag)
(setq lst (cons ename lst))
)
)
)
)
)
lst
)
-
Mind you there is no error checking. 8-)
;; Given a Tag name update the text value
(defun AttrUpdate ( attTag NewValue / ss i ename lst)
(vl-load-com)
(if (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1))))
(progn
(setq i -1)
(while (setq ename (ssname ss (setq i (1+ i))))
(foreach att (vlax-invoke (vlax-ename->vla-object ename) "getattributes")
(if (= (vla-get-tagstring att) attTag)
(progn
(vla-put-textstring att NewValue)
(vla-update att)
(vla-update (vlax-ename->vla-object ename))
(setq lst (cons ename lst))
)
)
)
)
)
)
lst
)
-
Here is my routine:
(defun UpdateAtt (tagstring newvalue / newvalue ss1 tagstring)
(if (setq tagstring (strcase tagstring)
ss1 (ssget "X" '((0 . "INSERT") (66 . 1)))
)
(mapcar
(function (lambda (att) (vla-put-textstring att newvalue)))
(vl-remove-if-not
(function (lambda (att)
(= tagstring (strcase (vla-get-tagstring att)))
)
)
(apply
'append
(mapcar (function
(lambda (ent)
(vlax-invoke (vlax-ename->vla-object ent) 'GetAttributes)
)
)
(vl-remove-if-not
(function (lambda (x) (= 'ENAME (type x))))
(apply 'append (ssnamex ss1))
)
)
)
)
)
)
)
-
I feel left out, so here is one of my first ideas. To step through the block table getting blocks that have the attributes desired. Works with an associated list of attribute tags.
(defun UpdateAttributes ( attList / Blk FndAttList Ent Data tempList )
(while (setq Blk (tblnext "block" (not Blk)))
(setq FndAttList nil)
(setq Ent (cdr (assoc -2 Blk)))
(while Ent
(setq Data (entget Ent))
(if
(and
(= (cdr (assoc 0 Data)) "ATTDEF")
(setq tempList (assoc (cdr (assoc 2 Data)) attList))
)
(setq FndAttList (cons tempList FndAttList))
)
(setq Ent (entnext Ent))
)
(if FndAttList
(progn
(setq Blk (tblobjname "block" (cdr (assoc 2 Blk))))
(setq Blk (entget (cdr (assoc 330 (entget Blk)))))
(foreach i (cdr (member '(102 . "}") (reverse (cdr (member '(102 . "{BLKREFS") Blk)))))
(if (entget (setq Ent (cdr i)))
(while (/= (cdr (assoc 0 (setq Data (entget (setq Ent (entnext Ent)))))) "SEQEND")
(if
(and
(= (cdr (assoc 0 Data)) "ATTRIB")
(setq tempList (assoc (cdr (assoc 2 Data)) FndAttList))
)
(progn
(entmod (subst (cons 1 (cdr tempList)) (assoc 1 Data) Data))
(entupd Ent)
)
)
)
)
)
)
)
)
)
Called like
(UpdateAttributes '(("DETAIL" . "5")("SHEET" . "A-205")))