Mtext editing

Mtext editing

zph
Collaborator Collaborator
1,307 Views
18 Replies
Message 1 of 19

Mtext editing

zph
Collaborator
Collaborator

I am having issues with editing an Mtext value.

 

Variable ssText is a selection set containing one MTEXT entity.

Variable ssList is the result of (entget (ssname ssText 0)).

Variable nVal is the new text value.

 

I've attempted both of the following options without success.

 

(1)

(entmod (setq ssList (subst (cons 1 nVal) (assoc 1 ssList) ssList)))

 

(2)

(vlax-for x ssText (vla-put-textstring (vlax-ename->vla-object (ssname x 0)) nVal))

 

Where am I messing up?

0 Likes
Accepted solutions (1)
1,308 Views
18 Replies
Replies (18)
Message 2 of 19

Kent1Cooper
Consultant
Consultant

Are there any messages?

 

How are you setting nVal?  For instance, if it's numerical, and you're getting it with (getreal) or (getint) or (getdist), it would need to be converted to the text-string equivalent before you could substitute it in.

 

In your second attempt, (vlax-for) requires a VLA-object-style collection, not a regular selection set. But with only one thing, you don't need that -- try something like:

 

(vla-put-textstring (vlax-ename->vla-object (ssname ssText 0)) nVal)

 

Kent Cooper, AIA
0 Likes
Message 3 of 19

dbroad
Mentor
Mentor

The error probably occurs before those snippets.

 

If the selection set was found by (setq ssText (ssget '((0 . "Mtext")))) then option 1 should work assuming

1. sstext wasn't empty.

2. you properly filtered the selection set (see above).

3. nval is properly bound to a string.

 

Option 2 will only work if you get the activeX selection set. Assuming that ssText was the last selection

 

(vlax-for x (vla-get-activeselectionset(vla-get-activedocument(vlax-get-acad-object))) blah blah blah)

 

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 4 of 19

zph
Collaborator
Collaborator

I actually tried your suggestion prior to posting, but that one didn't work either.

 

I've attached the routine.

0 Likes
Message 5 of 19

dbroad
Mentor
Mentor

You're program appears to be copying and then exploding the mtext.  Once that's done, any reference to the original selected entity is made invalid.

Architect, Registered NC, VA, SC, & GA.
Message 6 of 19

zph
Collaborator
Collaborator

You're right. *facepalm*

 

Do you have any recommendations on how I could go about creating a selection set with the 'copy' of the original, instead of the original?

0 Likes
Message 7 of 19

pbejse
Mentor
Mentor

@zph wrote:

I am having issues with editing an Mtext value.

 

Variable ssText is a selection set containing one MTEXT entity.

Variable ssList is the result of (entget (ssname ssText 0)).

Variable nVal is the new text value.

 

I've attempted both of the following options without success.

 la-object (ssname x 0)) nVal))

 

Where am I messing up?


 

number (1) should work

 

(setq nval "banana")
(if (setq ssText (ssget '((0 . "MTEXT"))))


(repeat (sslength ssText)
       (setq ssList (entget (ssname ssText 0)))
       (entmod (subst (cons 1 nVal) (assoc 1 ssList) ssList))
       (ssdel (ssname ssText 0) ssText)
      )
)

One thing though, you don't  really need to assign the list to a variable unless you are modifying the entity's definition data many times over. Also, consider DXF 3  (250 characters) when using the above method.

 

number (2) on the other hand will not work if the variable  ssText remains as an Type: Pickset (selection set), instead convert the pickset to a Type: VLA-object.

 

(if (ssget '((0 . "MTEXT")))
      (progn
            (vlax-for
                   x  (setq ssText
                                 (vla-get-ActiveSelectionSet
                                       (vla-get-ActiveDocument
                                             (vlax-get-acad-object))))
                  (vla-put-textstring x nVal)
                  )
            (vla-delete ssText)
            )
      )

HTH

 

EDIT: Oh my, I'm 5 posts too late. 

EDIT: Saw the attachment just now, please tell us what is the intent after Mtext selection?

 

 

 

0 Likes
Message 8 of 19

dbroad
Mentor
Mentor

It depends.  I haven't read enough of your code to interpret the overall goal.  It's cut up into external subroutines that share data without passing arguments.

 

If your intent is to work with the copies and preserve the original, I would have ordinarily recommended (setq txts (vlax-invoke obj 'explode)) where obj is your mtext entity.  But mtext doesn't support the explode method.

 

If you copy mtext (to preserve the original) and then get the last object (entlast) and then explode it with the explode command, then the individual parts of the mtext copy would be accessible with (ssget "p") but that would not be the same as exploding the original mtext entity and then expecting the ename to still be available.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 9 of 19

zph
Collaborator
Collaborator

The goal is to modify an MTEXT substring's width factor (based upon a selection point location within the MTEXT bounding box) to fit within the MTEXT's defined width.

0 Likes
Message 10 of 19

zph
Collaborator
Collaborator

I moved the (command "erase" cSS "") after the entmod code the routine successfully finishes without error.

 

 

Second problem though...the Mtext value isn't updated with the value of 'nVal'...it remains the same.

0 Likes
Message 11 of 19

Kent1Cooper
Consultant
Consultant

I haven't studied the routine in depth either, but....

 

I can easily imagine that if there is any formatting for properties other than Width factor, or already a Width factor component, it could throw the whole thing off, because of the way such formatting codes can be embedded within each other's "territory" in various different ways, depending on how the formatting was done.

 

If there aren't other formatting components, and since part of your process includes Exploding Mtext, can you perhaps just use plain Text instead of Mtext?  It would be infinitely easier to adjust its width factor.

Kent Cooper, AIA
0 Likes
Message 12 of 19

dbroad
Mentor
Mentor

If changing the width factor of part of the mtext string is your stated goal, then the entire program should be scrapped.  There is no need to explode mtext or make copies.  Instead, do a string substitution instead of a string replacement.  If you explode mtext into parts, then the field codes that control varying width factors are in separate strings from what they apply to.

 

Look into vl-string-subst and vl-string-search.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 13 of 19

zph
Collaborator
Collaborator

Kent,

 

Yes, I agree and you are correct.

 

However, the MTEXT entities must be preserved.  I want to be able to adjust text width factors (to fit) without having to open up the text editor for each MTEXT entity.

0 Likes
Message 14 of 19

zph
Collaborator
Collaborator

@dbroad @Kent1Cooper

 

I've attached a test file and the newer version of the routine so you can see what I'm trying to do.  Select the bottom left MTEXT object and then select a point on the 2nd line of text.

 

Also, the only formatting codes that should be in the original MTEXT value are "\\W" and "\\P"...any others can be, and probably should be, stripped away.

0 Likes
Message 15 of 19

christopher.l.evans
Advocate
Advocate
0 Likes
Message 16 of 19

zph
Collaborator
Collaborator

Entmakex, with same other changes to the code structure, was the ticket.

 

I will probably spend some time later adding some conditions to expand text widths and optimizing the code, but for now...it'll do 🙂

 

Thanks for your help, guys!

 

Cheers!

0 Likes
Message 17 of 19

zph
Collaborator
Collaborator

Good day guys!

 

So, I have been using this routine flawlessly for quite a while now.  I'd stumbled upon some time to improve it and I've been attempting to place a loop in the routine and allow for selection with multiple entities.

 

I'm posting about it because unexpected behavior is presenting itself.  I've attached the routine and a test file.

 

When I select only one MTEXT entity, the result is a successful modification.

However, when I select all MTEXT entities, all but one of the entities are deleted.

 

I've been scratching my head on this for a while.  The "cSS" selection set variable seems to be the suspect, but I've checked it out and it appears innocent...

 

Do you guys have any ideas?

 

Thanks!

~Z

0 Likes
Message 18 of 19

ВeekeeCZ
Consultant
Consultant
Accepted solution

You need to reset your cntr inside your sub.


Anyway, I would recommend to use the repeat. It's sort of bullet-proof. The index setting is always the same, at the beginning of a loop, you'll never forget. 

 

(if (setq ss (ssget))
  (repeat (setq i (sslength ss))
    (setq ent (ssname ss (setq i (1- i))))))

 

Message 19 of 19

zph
Collaborator
Collaborator

BeeKeeCZ,

 

Thank you; you nailed it!

 

Man, it is times like these I feel like such a noob hahaha.

 

Thanks again, Master!

 

/r

~Z

0 Likes