Billy Ray Posted May 29, 2019 Posted May 29, 2019 (edited) EAttedit, Battman, etc. all work by navigating to Text Options and typing in a new boundary width but if one has many DWG's to update ... a Lisp or Script would be useful. Not sure if it's possible but I always appreciate any help. The issue is an MText attribute in a Title Block named Stamp_Description has a set boundary width that is too wide. Having a Lisp routine that will prompt for the Attribute Tag Name and then prompt for the new Boundary Width would be very useful. I could run it in a Batch and update all DWG's in a folder. I've searched for an hour online and have not found a solution. Again this attribute is MText not single line and I would like a way to change the boundary width of it ... not the Text width. Thanks for any help or suggestions! Edited May 29, 2019 by Billy Ray Quote
ronjonp Posted May 29, 2019 Posted May 29, 2019 Try this: (defun c:foo (/ _foo tag s w) (defun _foo (blk tag w) (foreach x (vlax-invoke blk 'getattributes) (and (vlax-write-enabled-p x) (= (strcase tag) (strcase (vla-get-tagstring x))) (= -1 (vlax-get x 'mtextattribute)) (vla-put-mtextboundarywidth x w) ) ) ) (if (and (setq tag (getstring "\nEnter tag string: ")) (setq w (getdist "\nEnter width of boundary: ")) (setq s (ssget ":L" '((0 . "insert") (66 . 1)))) ) (foreach o (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))) (_foo (vlax-ename->vla-object o) tag w) ) ) (princ) ) Quote
dlanorh Posted May 29, 2019 Posted May 29, 2019 The boundary width of an MText attribute can be accessed using the "MTextBoundaryWidth" property of the attribute if the "MTextAttribute" property is true (i.e. it is :vlax-true or -1) (vl-load-com) (defun c:MTAW ( / c_doc c_blks t_blk t_tag bwidth bfound tfound) (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) c_blks (vla-get-blocks c_doc) t_blk "PUT BLOCK NAME HERE" t_tag (getstring "\nEnter Attribute Tag Name : ") );end_setq (initget 5) (setq bwidth (getreal "\nEnter New Boundary Width : ")) (vlax-for blk c_blks (cond ( (= (strcase (vlax-get-property blk 'name)) (strcase t_blk)) (setq bfound t) (vlax-for item blk (cond ( (and (= (vlax-get-property item 'objectname) "AcDbAttributeDefinition") (= (vlax-get-property item 'mtextattribute) :vlax-true) (= (strcase (vlax-get-property item 'tagstring)) (strcase t_tag)) );end_and (setq tfound t) (vlax-put-property item 'mtextboundarywidth bwidth) ) );end_cond );end_for ) );end_cond );end_for (if tfound (vl-cmdf "attsync" "N" t_blk)) (cond ( (and bfound tfound) (alert (strcat "Boundary Width of Attribute " t_tag "\nin Block " t_blk " set to : " (rtos bwidth 2 3)))) ( (not bfound) (alert (strcat "Block " t_blk "NOT found in drawing"))) ( (not tfound) (alert (strcat "Attribute " t_tag "NOT found in BLOCK " t_blk))) );end_cond );end_defun Code not tested as I only have an LT version of AutoCAD with me at the moment. You will need to insert the correct block name in place of "PUT BLOCK NAME HERE" It works by altering the block definition in the block table, hence the "attsync" towards the end. The boundary width prompt will allow 0 (zero) or a positive real number. The block name and tag name can be upper or lower case. It is set up for a single use in a single drawing If you want to batch run this from a script you will need to hard code the "t_tag" and "bwidth" variables and remove the whole of the last condition statement. I don't run any "ODBX" routines so couldn't say if this will work within that enviroment, but again you would have to remove the last condition statement. Other wiser heads could probably As a stand alone single use Quote
Billy Ray Posted May 29, 2019 Author Posted May 29, 2019 1 hour ago, ronjonp said: ronjonp, Thank you this works, however one has to select the attribute which is not always in the same place so it cannot be utilized in a batch.. Quote
Billy Ray Posted May 29, 2019 Author Posted May 29, 2019 1 hour ago, dlanorh said: dlanorh, Thank you this works well, only issue is it appears to attsync the attribute. After updating the width the attribute moves to a different place in the DWG. Not sure how to change that... 1 hour ago, dlanorh said: The boundary width of an MText attribute can be accessed using the "MTextBoundaryWidth" property of the attribute if the "MTextAttribute" property is true (i.e. it is :vlax-true or -1) Code not tested as I only have an LT version of AutoCAD with me at the moment. You will need to insert the correct block name in place of "PUT BLOCK NAME HERE" It works by altering the block definition in the block table, hence the "attsync" towards the end. The boundary width prompt will allow 0 (zero) or a positive real number. The block name and tag name can be upper or lower case. It is set up for a single use in a single drawing If you want to batch run this from a script you will need to hard code the "t_tag" and "bwidth" variables and remove the whole of the last condition statement. I don't run any "ODBX" routines so couldn't say if this will work within that enviroment, but again you would have to remove the last condition statement. Other wiser heads could probably As a stand alone single use Quote
ronjonp Posted May 29, 2019 Posted May 29, 2019 6 minutes ago, Billy Ray said: Thank you this works, however one has to select the attribute which is not always in the same place so it cannot be utilized in a batch.. My bad. I was under the impression you had a better understanding of how to modify code to do what you want. Give below a try: (defun foo (/ _foo tag s w) ;; _FOO takes 3 arguments, a block a tag name and a width value (defun _foo (blk tag w) (foreach x (vlax-invoke blk 'getattributes) (and (vlax-write-enabled-p x) (= (strcase tag) (strcase (vla-get-tagstring x))) (= -1 (vlax-get x 'mtextattribute)) (vla-put-mtextboundarywidth x w) ) ) ) ;; Changed selection to _X to grab everything (if (setq s (ssget "_X" '((0 . "insert") (66 . 1)))) (foreach o (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))) ;; Hardcoded values change to suit (_foo (vlax-ename->vla-object o) "YOURTAGHERE" 10) ) ) (princ) ) (foo) 1 Quote
ronjonp Posted May 30, 2019 Posted May 30, 2019 Or if you want something a little bit more user friendly, add arguments to 'foo' and call like so: (defun foo (tag width / tag s w) (if (setq s (ssget "_X" '((0 . "insert") (66 . 1)))) (foreach o (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))) (foreach x (vlax-invoke o 'getattributes) (and (vlax-write-enabled-p x) (= (strcase tag) (strcase (vla-get-tagstring x))) (= -1 (vlax-get x 'mtextattribute)) (vla-put-mtextboundarywidth x width) ) ) ) ) (princ) ) ;; Sub above fed with tag you want to look for and width to apply (foo "yourtagnamehere" 8) Quote
Billy Ray Posted May 30, 2019 Author Posted May 30, 2019 3 hours ago, ronjonp said: Or if you want something a little bit more user friendly, add arguments to 'foo' and call like so: Thank you Ron! Actually... I'm an idiot . In my haste I didn't properly edit the code. The first one you made works great I just added the "All" option for selection and it runs smoothly as a batch. The autorun was nice too. Thank you very much for the help! Quote
ronjonp Posted May 30, 2019 Posted May 30, 2019 13 minutes ago, Billy Ray said: Thank you Ron! Actually... I'm an idiot . In my haste I didn't properly edit the code. The first one you made works great I just added the "All" option for selection and it runs smoothly as a batch. The autorun was nice too. Thank you very much for the help! Hahaha .. glad we got it sorted. Quote
Recommended Posts
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.