Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Difficulties getting insert point for mtext or text

19 REPLIES 19
Reply
Message 1 of 20
smaher12
971 Views, 19 Replies

Difficulties getting insert point for mtext or text

I just can not figure out for the life of me why the following will not work if text is selected. If mtext is selected it works great. Please advise.

 

(defun C:ww ()
  (setq OS (getvar "OSMODE"))
  (setvar "OSMODE" 16384)

 

  (setq txttmp (getstring (strcat "\nEnter Prefix <" (cond (pfix) ("UP-")) ">: ")))
  (setq pfix (cond ((/= txttmp "") (strcase txttmp)) (pfix) ("UP-")))
  (setq no# (getint "\nEnter number: "))

    (while
      (setq esel (entsel "\nSelect text: "))

       (if (= (cdr (assoc 0 (entget (car esel)))) "TEXT")
         (setq ipt (cdr (assoc 11 (entget (car esel)))))
       )
       (if (= (cdr (assoc 0 (entget (car esel)))) "MTEXT")
         (setq ipt (cdr (assoc 10 (entget (car esel)))))
       )

      (setq jus (cdr (assoc 71 (entget (car esel)))))
      (command "erase" esel "")

      (setq no#t (strcat pfix (rtos no# 2 0)))
  (if (/= esel nil)(prntcad))
         (setq no# (1+ no#))
    ); while
 (princ)
)

(defun prntcad ()

     (entmake
       (list
         (cons 0 "MTEXT")
         (cons 100 "AcDbEntity")
         (cons 100 "AcDbMText")
         (cons 8 "S-Anno-Text")  ;layer
         (cons 7 "Standard")
         (cons 71 jus)           ;justify
         (cons 72 5)
         (cons 73 1)
         (cons 10 ipt)           ;insert point
         (cons 50 0)             ;angle
         (cons 40 10)            ;size
         (cons 41 0.0)           ;textbox width
         (cons 1 no#t)
       )
     )
  (setvar "OSMODE" OS)
)

19 REPLIES 19
Message 2 of 20
_Tharwat
in reply to: smaher12

As a quick look , The enmake function makes MTEXT and not TEXT (cons 0 "MTEXT")

 

EDIT : WRONG GUESS

Message 3 of 20
smaher12
in reply to: _Tharwat

I was just thinking that it take the insert point and justification of the selected text, erase it, and put the new mtext in it's place.

Message 4 of 20
_Tharwat
in reply to: smaher12

What does that code do ?

 

The insertion point of TEXT entity is also 10 and not 11 although you should add the code 11 to let get the code working .

 

(setq ipt (cdr (assoc 11 (entget (car esel)))))

Message 5 of 20
Kent1Cooper
in reply to: smaher12


@smaher12 wrote:

I just can not figure out for the life of me why the following will not work if text is selected. If mtext is selected it works great. Please advise.

 

....

         (setq ipt (cdr (assoc 11 (entget (car esel)))))
....

      (setq jus (cdr (assoc 71 (entget (car esel)))))
....


The (assoc 71) value for plain Text is not the justification [that's a combination of the 72 & 73 values], but has to do with backwards- or upsidedown-ness.  The insertion point for plain Text is (assoc 10) if it's Left-justified, but (assoc 11) for all other justifications.  The (assoc 11) value is always 0,0,0 for Left-justified, so in that case it's possible that it's making something but putting it outside your viewing area, provided the (assoc 71) part isn't causing it to fail.

Kent Cooper, AIA
Message 6 of 20
smaher12
in reply to: _Tharwat


@_Tharwat wrote:

What does that code do ?

 


I can have drawing with 50 numbered items with a prefix and then somewhere down the line 5 items could be added/subtracted. Now I'm stuck renumbering half the items and unfortunately TCOUNT does not cut it for me.

 

So I thought I could come up with something that would ask for the prefix, what number to start with, select the existing text or mtext, erase it, replace it with the new prefixed number as a mtext.

Message 7 of 20
smaher12
in reply to: Kent1Cooper


@Kent1Cooper wrote:
The (assoc 71) value for plain Text is not the justification [that's a combination of the 72 & 73 values], but has to do with backwards- or upsidedown-ness.  The insertion point for plain Text is (assoc 10) if it's Left-justified, but (assoc 11) for all other justifications.  The (assoc 11) value is always 0,0,0 for Left-justified, so in that case it's possible that it's making something but putting it outside your viewing area, provided the (assoc 71) part isn't causing it to fail.

Well this is what I was able to figure out. Let me know your thoughts. Thanks!

 

(defun C:ww ()

 (setq txttmp (getstring (strcat "\nEnter Prefix <" (cond (pfix) ("UP-")) ">: ")))
 (setq pfix (cond ((/= txttmp "") (strcase txttmp)) (pfix) ("UP-")))
 (setq no# (getint "\nEnter number: "))
  
  (while
    (and
      (setq esel (entsel "\nSelect text: "))
        (= nil)
    )
     (setq edata (cdr (assoc 0 (entget (car esel)))))
    
     (if (= edata "TEXT")(txt))
     (if (= edata "MTEXT")(mtxt))
  )
 (princ)
)

(defun txt ()
   (setq ti (cdr (assoc 10 (entget (car esel)))))
   (setq thj (cdr (assoc 72 (entget (car esel)))))
   (setq tvj (cdr (assoc 73 (entget (car esel))))) 
   (setq no#t (strcat pfix (rtos no# 2 0)))

     (if (/= esel nil)(txtprnt))
       (setq no# (1+ no#))
 (princ)
)

(defun mtxt ()
   (setq mti (cdr (assoc 10 (entget (car esel)))))
   (setq mtj (cdr (assoc 71 (entget (car esel)))))  
   (setq no#t (strcat pfix (rtos no# 2 0)))

     (if (/= esel nil)(mtxtprnt))
       (setq no# (1+ no#))
 (princ)
)

(defun txtprnt ()
    (command "erase" esel "")
  (entmake
    (list
      (cons 0 "TEXT")
      (cons 8 "S-Anno-Text")
      (cons 72 thj)
      (cons 73 tvj)
      (cons 10 ti)
      (cons 11 ti)            ;insert point
      (cons 50 0)             ;angle
      (cons 40 10)            ;size
      (cons 1 no#t)
    )
  )
 (princ)
)

(defun mtxtprnt ()
    (command "erase" esel "")
  (entmake
    (list
      (cons 0 "MTEXT")
      (cons 100 "AcDbEntity")
      (cons 100 "AcDbMText")
      (cons 8 "S-Anno-Text")
      (cons 7 "Standard")
      (cons 71 mtj)           ;justify
      (cons 72 5)
      (cons 73 1)
      (cons 10 mti)           ;insert point
      (cons 50 0)             ;angle
      (cons 40 10)            ;size
      (cons 41 0.0)           ;textbox width
      (cons 1 no#t)
    )
  )
 (princ)
)

 

 

Message 8 of 20
bobdobbs
in reply to: smaher12

Maybe keep the existing entity and just replace the GROUP CODE 1 value with the new value. That way you don't have to worry about justification or anything.

 

I use this bit of code all the time. It'll do text, mtext, and attributes.

 

It DOES NOT prefix or anything but, you could add that pretty easily. It's just an example of what I'm talking about.

 

(It's messy and lame but, it works)

 

(defun c:renum ( / enlist nxtxt)
  (setvar "cmdecho" 0)
  (setq cnt (GETINT "T#: "))
  (setq enlist(entget (car (nentsel "\n Select attrib to renum: "))))
  (while enlist
  (if (OR (= "ATTRIB" (cdr (assoc 0 enlist))) (= "TEXT" (cdr (assoc 0 enlist)))(= "MTEXT" (cdr (assoc 0 enlist))))
  (progn
    (setq nxtxt (itoa cnt))
    (setq enlist(subst (cons 1 nxtxt) (assoc 1 enlist) enlist))
    (entmod enlist)
	(entupd (cdr (car enlist)))
	(setq cnt (+ 1 cnt))
    (setq enlist(entget (car (nentsel "\n Select next attrib to renum: "))))
	)
	(setq enlist(entget (car (nentsel "\n Select next attrib to renum: "))))
  )
  )
  (setvar "cmdecho" 1)
  (princ)
)

 

Message 9 of 20
Kent1Cooper
in reply to: smaher12


@smaher12 wrote:
....

Well this is what I was able to figure out. Let me know your thoughts. Thanks!

....


As bobdobbs suggests, since you appear to be keeping a lot of their characteristics [entity type, insertion point, justification], and a lot of what you want at specific values [height, rotation, style, layer, incrementing the integer part, etc.] are the same for both entity types, you should probably just keep the selected objects and substitute just what you want at specific values.  Try this [untested]:

 

(defun C:ww (/ txttmp no# esel edata etype no#t)
  (setq
    txttmp (getstring (strcat "\nEnter Prefix <" (cond (pfix) ("UP-")) ">: "))
    pfix (cond ((/= txttmp "") (strcase txttmp)) (pfix) ("UP-"))
    no# (getint "\nEnter number: ")
  ); setq
  (while
    (setq esel (entsel "\nSelect text: "))
    (setq
      edata (entget (car esel))
      etype (cdr (assoc 0 edata))
    ); setq
    (if (member etype '("TEXT" "MTEXT"))
      (progn
        (setq
          no#t (strcat pfix (rtos no# 2 0))
          edata (subst '(8 . "S-Anno-Text") (assoc 8 edata) edata); force Layer
          edata (subst '(7 . "Standard") (assoc 7 edata) edata); force Style
          edata (subst '(50 . 0.0) (assoc 50 edata) edata); force Rotation
          edata (subst '(40 . 10.0) (assoc 40 edata) edata); force Height
          edata (subst (cons 1 no#t) (assoc 1 edata) edata); force Content

          no# (1+ no#)
        ); setq
        (if (= etype "MTEXT")
          (setq
            edata (subst '(72 . 5) (assoc 72 edata) edata); force Drawing Direction
            edata (subst '(73 . 1) (assoc 73 edata) edata); force Line Spacing
            edata (subst '(41 . 0.0) (assoc 41 edata) edata); force Box Width
          ); setq
        ); if
        (entmod edata)
      ); progn
    ); if
  ); while
  (princ)
); defun

 

Those (setq edata (subst... things could be replaced by (vla-put... functions instead, if you don't mind the extra step of converting the Text/Mtext to VLA objects.

Kent Cooper, AIA
Message 10 of 20
Kent1Cooper
in reply to: bobdobbs


@bobdobbs wrote:

.... 

I use this bit of code all the time. It'll do text, mtext, and attributes.

 

It DOES NOT prefix or anything ....

 

(It's messy and lame but, it works)

.... 


A less messy and lame way to do that [untested], particularly in:

:: the entity type test;

:: not needing the [nearly] identical prompt spelled out three times;

:: not bothering with CMDECHO, since there are no (command) functions to echo or not.

 

(defun c:renum (/ cnt esel enlist nxtxt)
  (setq cnt (GETINT "T#: "))
  (while
    (setq esel (nentsel "\nSelect Text/Mtext/Attrib to renumber: "))
    (setq
      ent (car esel)
      enlist (entget ent)
    ); setq
    (if (member (cdr (assoc 0 enlist)) '("ATTRIB" "TEXT" "MTEXT"))
      (progn
        (setq
          nxtxt (itoa cnt)
          enlist (subst (cons 1 nxtxt) (assoc 1 enlist) enlist)
          cnt (+ 1 cnt)
        ); setq
        (entmod enlist)
        (entupd ent); may not be necessary, in which case you could skip the ent variable...
      ); progn
    ); if
  ); while
  (princ)
); defun

 

[It could actually be made to include the word "next" in the prompt, but only after the first time, as in your original, if that's important.]

Kent Cooper, AIA
Message 11 of 20
smaher12
in reply to: Kent1Cooper


@Kent1Cooper wrote:

As bobdobbs suggests, since you appear to be keeping a lot of their characteristics [entity type, insertion point, justification], and a lot of what you want at specific values [height, rotation, style, layer, incrementing the integer part, etc.] are the same for both entity types, you should probably just keep the selected objects and substitute just what you want at specific values.

  

Those (setq edata (subst... things could be replaced by (vla-put... functions instead, if you don't mind the extra step of converting the Text/Mtext to VLA objects.


I was thinking the same thing. I just didn't know how to code it. I love what you have put together. Thank you so much. I'm hoping to learn alot from it.

 

Regarding the Text/Mtext to VLA objects, I really don't know where to begin. I need to pick up a book on figuring out that vla-put stuff. Any recommendations? 

Message 12 of 20
hmsilva
in reply to: smaher12

smaher12,
if I understood well, you only want to change the text contents...
try this

 

   (defun c:test (/ txttmp pfix no# ss obj)
    (vl-load-com)
    (setq txttmp (getstring (strcat "\nEnter Prefix <" (cond (pfix) ("UP-"))">: "))
	  pfix	 (cond ((/= txttmp "") (strcase txttmp)) (pfix) ("UP-"))
	  no#	 (getint "\nEnter number: ")
    ); setq
    (while
      (setq ss (ssget "+.:S" '((0 . "*TEXT"))))
       (setq obj  (vlax-ename->vla-object (ssname ss 0))
	     no#t (strcat pfix (rtos no# 2 0))
       ); set
       (vlax-put obj 'textstring no#t)
       (vlax-release-object obj)
       (setq no# (1+ no#)
	     ss	 nil
       ); set
    ); while
  ); test

 

Henrique

 

EESignature

Message 13 of 20
smaher12
in reply to: hmsilva


@hmsilva wrote:

smaher12,
if I understood well, you only want to change the text contents...
try this


Very nice indeed. Thank you.  Do you know how to loop back to (setq ss if ss is nil or not text/mtext?

Message 14 of 20
hmsilva
in reply to: smaher12

smaher12, wrote:

Very nice indeed. Thank you.  Do you know how to loop back to (setq ss if ss is nil or not text/mtext?

 

 

I think that is what you want...

 

(defun c:test (/ txttmp pfix no# ss obj)
  (vl-load-com)
  (setq	txttmp (getstring (strcat "\nEnter Prefix <" (cond (pfix) ("UP-"))">: "))
	pfix   (cond ((/= txttmp "") (strcase txttmp)) (pfix) ("UP-"))
	no#    (getint "\nEnter number: ")
	); setq
  (setvar "errno" 0)
  (while
    (while
      (and
	(/= (getvar "errno") 52) (not ss)
      ); and
       (setq ss (ssget "+.:S" '((0 . "*TEXT"))))
    ); while
     (setq obj	(vlax-ename->vla-object (ssname ss 0))
	   no#t	(strcat pfix (rtos no# 2 0))
     ); set
     (vlax-put obj 'textstring no#t)
     (vlax-release-object obj)
     (setq no# (1+ no#)
	   ss  nil
     ); set
     (setvar "errno" 0)
  ); while
); test

 

hope that helps

 

Henrique

EESignature

Message 15 of 20
bobdobbs
in reply to: Kent1Cooper

Oh yeah, that's way better. Thanks to Kent1Cooper.

 

(Any interest in helping my Mandelbrot set draw faster ... hmmmm?)

Message 16 of 20
smaher12
in reply to: hmsilva


@hmsilva wrote:

I think that is what you want...

hope that helps

Henrique


Thank you. Short and sweet. I like it alot. I can't believe how short that is.

I was playing around with it and noticed that the prefix always returns to the default <UP-> instead of retaining in memory the last value entered by the user. Do you know why the last prefix value entered is lost now? Is it something to do with (vlax-release-object obj)

Message 17 of 20
Kent1Cooper
in reply to: smaher12


@smaher12 wrote:
....

I ... noticed that the prefix always returns to the default <UP-> instead of retaining in memory the last value entered by the user. Do you know why the last prefix value entered is lost now? Is it something to do with (vlax-release-object obj)


It's because you have pfix listed as a localized variable, which means it ceases to exist when the routine closes.  Take it out of the list in the top line and it will stay [for the current editing session].

Kent Cooper, AIA
Message 18 of 20
hmsilva
in reply to: smaher12

You're welcome, smaher12

 

replace

 

(defun c:test (/ txttmp pfix no# ss obj);I declared the variable pfix temporary...

 

for

 

(defun c:test (/ txttmp no# ss obj)

 

Henrique

EESignature

Message 19 of 20
smaher12
in reply to: hmsilva

Perfecto! Holy cow I didn't even know that the localized variable section was even that important. I thought it was just something to help the programmer see what variables are being used therfore I always left it as ().

 

Thank you all for everything. It amazes me how you guys come up with this stuff on the fly.

Message 20 of 20
Kent1Cooper
in reply to: smaher12


@smaher12 wrote:

Perfecto! Holy cow I didn't even know that the localized variable section was even that important. I thought it was just something to help the programmer see what variables are being used therfore I always left it as ().

 

Thank you all for everything. It amazes me how you guys come up with this stuff on the fly.


You're welcome.  I would like to make explicit, in case it matters to you, that the latest several versions, which keep everything about the selected Text/Mtext except for its text content only, are not quite the same in their end result as what you originally started with.  Your original [and my Reply in Message 9] did not necessarily retain the selected object's Layer, Style, Rotation or Height, but imposed the "S-Anno-Text" Layer, "Standard" Style, 0 Rotation, and Height of 10 on it, substituting those values if different from whatever the original had for them.  The latest code does not do the same, which is fine if you don't need it to, but if you do, you can just add a few more (vlax-put... lines to it with the appropriate properties.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost