I have a lisp function that is updating attribute values on a newly inserted block. The lisp function uses entget to read the attribute. Then it plugs a new value into the assoc 1 using subst, then uses entmod to update the attribute's value. It all works fine except that the attribute loses its style, i.e. assoc 7, somehow. If I do an entget on the attribute right after the entmod the assoc 7 is nil. The symptom on the drawing is that the attribute value is not visible until I close and open the drawing.
This only happens on a newly inserted block on existing drawings. If I close the drawing and reopen it then the lisp function works fine. Or If I insert the same block on a new drawing it all works fine.
Anyone have any ideas on what would cause the assoc 7 to go missing after an entmod to change the attribute value?
Regards,
Pat Murnen
Solved! Go to Solution.
Solved by PatMurnen_Adsk. Go to Solution.
Hi,
Looks interesting, can you post the code? also is the block a dynamic one or just a standar block?. I remember something about the order of particular elements in the "entmoded" list in order to AutoCAD accept the changes, but I'm not sure if it's the case.
Gaston Nunez
@Anonymous wrote:
Anyone have any ideas on what would cause the assoc 7 to go missing after an entmod to change the attribute value?
Regards,
Pat Murnen
I rarely use entmod/subst apporach for attributes, at any rate. Have not seen attributes behave that way before.
Is your lisp part of a reactor? or insert the block normally then run the lisp routine?
Hi Pat,
According to the DXF Reference (AutoCAD 2009), group code 7 is optional on ATTRIB entities.
Does group code 7 exist in the DXF codes of the attribute you are modifying?
Do you do an entupd on the attribute entity after you entmod the new DXF list with the new value?
Regards,
Trevor
Thanks for all the responses.
The workflow is this -
The drawing already contains the title block which is a standard block with attributes.
I delete the block and purge the drawing. The purge gets a bunch of text styles that are only used on the title block.
I insert my changed title block manually using the INSERT command.
I then run my lisp program that updates the attributes on the title block I just inserted.
I have some standard values I want to update so I use this code to update the attributes passing the desired values -
(defun update_attr ( att new en / flag ed tst )
; att = attrib Tag name
; new = the new value for that attribute
; en is the newly inserted title block
(while (AND (setq en (entnext en))
(setq ed (entget en))
(= (cdr (assoc 0 ed)) "ATTRIB")
(/= (cdr (assoc 0 ed)) "SEQEND")
(/= (cdr (assoc 0 ed)) "INSERT"))
(setq tst (cdr (assoc 2 ed))) ; attribute Tag name
(if (= tst att) ; found the attribute
(progn
(setq ed (subst (cons 1 new) (assoc 1 ed) ed)) ; substitute in the new value
(entmod ed)
(entupd en)
) ) ) )
If the attributes use the Standard text style all is fine. But if they use text styles that are only present on the block then there is the problem. I guess these text styles are defined when the block is inserted since they were purged when I deleted the original block. If I close and then reopen the drawing before reinserting the title block all is fine.
Regards,
Pat
Hi,
I have no idea why the attribute is losing the style as the new insert should import the style to the database. Any way, I have this to update attributes values, just give it a try:
;;Use: (UpdateAttVal (car(entsel)) "A-Valid-Tag" "New Value") ;;Need a previous call to (vl-load-com) (defun UpdateAttVal(blkEnt Tag newVal /blkObj attCollection attRefArray dim n ii attRef attTag) (setq blkObj (vlax-ename->vla-object blkEnt)) (setq attCollection (vlax-invoke-method blkObj 'GetAttributes)) (setq attRefArray (vlax-variant-value attObjlist)) (setq dim (vlax-safearray-get-dim attRefArray)) (setq n (vlax-safearray-get-u-bound attRefArray dim)) (setq ii 0) (while (<= ii n) (setq attRef (vlax-safearray-get-element attRefArray ii)) (setq AttTag (vlax-get-property attRef 'TagString)) (if (= tag attTag) (progn (vlax-put-property attref 'TextString newVal) (setq ii (+ n 1)) ) (setq ii (+ ii 1)) ) ) (princ) )
Gaston Nunez
Thanks I will give this a try.
Is the crossed out variable supposed to be attCollection?
;;Use: (UpdateAttVal (car(entsel)) "A-Valid-Tag" "New Value") ;;Need a previous call to (vl-load-com) (defun UpdateAttVal(blkEnt Tag newVal /blkObj attCollection attRefArray dim n ii attRef attTag) (setq blkObj (vlax-ename->vla-object blkEnt)) (setq attCollection (vlax-invoke-method blkObj 'GetAttributes)) (setq attRefArray (vlax-variant-valueattObjlist)) (setq dim (vlax-safearray-get-dim attRefArray)) (setq n (vlax-safearray-get-u-bound attRefArray dim)) (setq ii 0) (while (<= ii n) (setq attRef (vlax-safearray-get-element attRefArray ii)) (setq AttTag (vlax-get-property attRef 'TagString)) (if (= tag attTag) (progn (vlax-put-property attref 'TextString newVal) (setq ii (+ n 1)) ) (setq ii (+ ii 1)) ) ) (princ) )
Argh...
There is a typo in the local parameter list : /blkObj should be: / blkObj
Gaston Nunez
Yeah it works with those changes! Thanks. Reproducde here so can mark this as Solution.
;;Use: (UpdateAttVal (car(entsel)) "A-Valid-Tag" "New Value")
;;Need a previous call to (vl-load-com)
(defun UpdateAttVal(blkEnt Tag newVal / blkObj attCollection attRefArray dim n ii attRef attTag)
(setq blkObj (vlax-ename->vla-object blkEnt))
(setq attCollection (vlax-invoke-method blkObj 'GetAttributes))
(setq attRefArray (vlax-variant-value attCollection))
(setq dim (vlax-safearray-get-dim attRefArray))
(setq n (vlax-safearray-get-u-bound attRefArray dim))
(setq ii 0)
(while (<= ii n)
(setq attRef (vlax-safearray-get-element attRefArray ii))
(setq AttTag (vlax-get-property attRef 'TagString))
(if (= tag attTag)
(progn
(vlax-put-property attref 'TextString newVal)
(setq ii (+ n 1))
)
(setq ii (+ ii 1))
)
)
(princ)
)
I had the exact same problem, try to recover the file dwg and possibly the dwt you use to create new dwgs.
Good idea since the problem doesn't happen on new drawings. So maybe something on the existing drawings.
Thanks,
Pat