Jump to content

Lisp to Edit Boundary Width Of MText Attribute


Billy Ray

Recommended Posts

     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 by Billy Ray
Link to comment
Share on other sites

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)
)

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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..

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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)

 

  • Like 1
Link to comment
Share on other sites

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)

 

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...