Jump to content

How to pop up an alert with a TEXT/MTEXT's property values in AutoLISP?


AeJay

Recommended Posts

I am trying to create a function wherein it would ask a user to select a text (either TEXT/MTEXT) then it would simply alert the value of that TEXT/MTEXT's color, layer, contents, and height which are stated in the properties.

 

I have this code but an error of "Program ERROR: bad argument type: stringp nil"
 

				(defun c:textprop()
				  (setq textobj (car (entsel "\nSelect text or mtext: ")))
				  (if (and textobj (member (cdr (assoc 0 (entget textobj))) '("TEXT" "MTEXT")))
					(progn
					  (setq textinfo (entget textobj))
					  (setq textvalue (assoc 1 textinfo))
					  (setq textheight (assoc 40 textinfo))
					  (setq textcolor (assoc 62 textinfo))
					  (setq textlayer (assoc 8 textinfo))
					  (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight) "\nColor: " textcolor "\nLayer: " textlayer)))
					(alert "Please select a valid text or mtext object."))
				  (princ))

 

Link to comment
Share on other sites

Got it to work. It seems that colors appear as text in the properties tab but are actually stored as numbers, like how Cyan is equal to 4. Thus, I had to use itoa to convert the integer of Cyan(4) into a string. But how about if I wanted it to output "Cyan" instead of the integer "4"?

 

				(defun c:selecttext(/ textinfo textvalue textheight textcolor textlayer textobj)
				  (setq textobj (car (entsel "\nSelect text or mtext: ")))
				  (if (and textobj (member (cdr (assoc 0 (entget textobj))) '("TEXT" "MTEXT" "ATTRIB")))
					(progn
					  (setq textinfo (cdr (entget textobj)))
					  (setq textvalue (cdr (assoc 1 textinfo)))
					  (setq textheight (cdr (assoc 40 textinfo)))
					  (setq textcolor (cdr (assoc 62 textinfo)))
					  (setq textlayer (cdr (assoc 8 textinfo)))
					  (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight) "\nColor: " (itoa textcolor) "\nLayer: " textlayer)))
					(alert "Please select a valid text or mtext object."))
				  (princ))

 

Link to comment
Share on other sites

Ok my take on question 1 redid code to cater for text color is by layer. There is no 62 dxf for bylayer. 

 

(defun c:textprop( / textobj textinfo textvalue textcolor textlayer)
(setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
(if (= textobj nil)
  (alert "A text type object was not picked ")
  (progn
    (setq textinfo (entget textobj))
    (setq textvalue (cdr (assoc 1 textinfo)))
    (setq textheight (cdr (assoc 40 textinfo)))
	(setq textlayer (cdr (assoc 8 textinfo)))
    (if (= (setq textcolor (cdr (assoc 62 textinfo))) nil)
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) "\nColor: " "Bylayer" "\nLayer: " textlayer))
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) "\nColor: " (rtos textcolor 2 0) "\nLayer: " textlayer))
    )
  )
)
(princ)
)
(c:textprop)

 

Re do a color need a cond. So replace the 2nd Alert with a cond, have a go. Inside a progn so 2nd alert still works inside that progn.

 

Noticed the 1st attempt did not have the cdr's.

 

If your happy can use "*TEXT" but it will find Dtext and Rtext. But we never used them so maybe ok.

 

I have a get properties lisp, just pick an object and you determine what you want returned so for say a circle would be centre point and radius, like you for a text return what is needed, there is another lisp out there that returns more items than I have done. 

 

 

 

 

Pline line arc props.lsp

Edited by BIGAL
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

58 minutes ago, BIGAL said:

Ok my take on question 1 redid code to cater for text color is by layer. There is no 62 dxf for bylayer. 

 

(defun c:textprop( / textobj textinfo textvalue textcolor textlayer)
(setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
(if (= textobj nil)
  (alert "A text type object was not picked ")
  (progn
    (setq textinfo (entget textobj))
    (setq textvalue (cdr (assoc 1 textinfo)))
    (setq textheight (cdr (assoc 40 textinfo)))
	(setq textlayer (cdr (assoc 8 textinfo)))
    (if (= (setq textcolor (cdr (assoc 62 textinfo))) nil)
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) "\nColor: " "Bylayer" "\nLayer: " textlayer))
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) "\nColor: " (rtos textcolor 2 0) "\nLayer: " textlayer))
    )
  )
)
(princ)
)
(c:textprop)

 

Re do a color need a cond. So replace the 2nd Alert with a cond, have a go. Inside a progn so 2nd alert still works inside that progn.

 

Noticed the 1st attempt did not have the cdr's.

 

If your happy can use "*TEXT" but it will find Dtext and Rtext. But we never used them so maybe ok.

 

I have a get properties lisp, just pick an object and you determine what you want returned so for say a circle would be centre point and radius, like you for a text return what is needed, there is another lisp out there that returns more items than I have done. 

 

 

 

 

Pline line arc props.lsp 3.7 kB · 1 download

Regarding int to color. I am again having the stringp nil error with this code I tried:
 

(defun c:textprop( / textobj textinfo textvalue textcolor textlayer nColor)
(setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
(if (= textobj nil)
  (alert "A text type object was not picked ")
  (progn
    (setq textinfo (entget textobj))
    (setq textvalue (cdr (assoc 1 textinfo)))
    (setq textheight (cdr (assoc 40 textinfo)))
	(setq textlayer (cdr (assoc 8 textinfo)))
    (if (= (setq textcolor (cdr (assoc 62 textinfo))) nil)
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) "\nColor: " "Bylayer" "\nLayer: " textlayer))
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) (setq nColor(itoa textcolor))
      (cond
		((= nColor 1)(strcat "\nColor: " "RED"))
		((= nColor 2)(strcat "\nColor: " "YELLOW"))
		((= nColor 3)(strcat "\nColor: " "GREEN"))
		((= nColor 4)(strcat "\nColor: " "CYAN"))
		((= nColor 5)(strcat "\nColor: " "BLUE"))
		((= nColor 6)(strcat "\nColor: " "MAGENTA"))
		((= nColor 7)(strcat "\nColor: " "WHITE"))
	  )
	  "\nLayer: " textlayer))
    )
  )
)
(princ)
)

 

I also tried with same error of stringp nil:
 

(defun c:textpropz( / textobj textinfo textvalue textcolor textlayer nColor)
(setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
(if (= textobj nil)
  (alert "A text type object was not picked ")
  (progn
    (setq textinfo (entget textobj))
    (setq textvalue (cdr (assoc 1 textinfo)))
    (setq textheight (cdr (assoc 40 textinfo)))
	(setq textlayer (cdr (assoc 8 textinfo)))
    (if (= (setq textcolor (cdr (assoc 62 textinfo))) nil)
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) "\nColor: " "Bylayer" "\nLayer: " textlayer))
      (alert (strcat "Text contents: " textvalue "\nHeight: " (rtos textheight 2 1) (setq nColor(itoa textcolor))
      (cond
		((equal nColor 1)("\nColor: " "RED"))
		((equal nColor 2)("\nColor: " "YELLOW"))
		((equal nColor 3)("\nColor: " "GREEN"))
		((equal nColor 4)("\nColor: " "CYAN"))
		((equal nColor 5)("\nColor: " "BLUE"))
		((equal nColor 6)("\nColor: " "MAGENTA"))
		((equal nColor 7)("\nColor: " "WHITE"))
	  )
	  "\nLayer: " textlayer))
    )
  )
)
(princ)
)

 

Edited by AeJay
  • Like 1
Link to comment
Share on other sites

Coming along way @AeJay for only 22 posts.

 

to simplify things

(setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
(if (= textobj nil)
>>
(if (setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
or
(if textobj

with two or more string side by side you can just join them into one
...(rtos textheight 2 1) "\nColor: " "Bylayer" "\nLayer: " textlayer))
...(rtos textheight 2 1) "\nColor: Bylayer \nLayer: " textlayer))

 

I think your code would error or not display if selecting text that its color isn't 1-7

 

again from above  join strings into one.

((= nColor 1)(strcat "\nColor: " "RED"))
can just be
((= nColor 1) "\nColor: RED")

 

My code keeps everything in a list. so their is only the selection set and the data variable.

 

Entget

((-1 . <Entity name: 3eed7ec0>) (0 . "TEXT") (5 . "71") (330 . <Entity name: 3e488ae0>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (370 . -1) (100 . "AcDbText") (10 5.59944594793636 4.30743710947954 0.0) (40 . 0.2) (1 . "asdfasdfsdaf") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . "AcDbText") (73 . 0))

 

Becomes 

(8 . "0") (62 . 1) (40 . 0.2) (1 . "asdfasdfsdaf")

 

Then values are put into list data

'("0" 1 0.2 "asdfasdfsdaf")

'(Layer color height textstring)

 

finally

image.png.9eb8198d29c6b628c959a1ac71c7eb8b.png

 

(defun c:ttp (/ ss data)
  (while (setq ss (ssget "_+.:E:S" '((0 . "TEXT,MTEXT")))) ;while to allow you to keep selecting in the same command.
    (setq data (mapcar 'cdr (vl-remove-if-not '(lambda (x) (or (= (car x) 1) (= (car x) 40) (= (car x) 62) (= (car x) 8))) (entget (ssname ss 0)))))
    (if (= (length  data) 3)
      (alert (strcat "Text: " (last data) "\nHeight: " (rtos (cadr data) 2 2) "\nColor: ByLayer \nLayer: " (car data)))
      (alert (strcat "Text: " (last data) "\nHeight: " (rtos (caddr data) 2 2) 
        (cond
          ((= (cadr data) 1) "\nColor: RED")
          ((= (cadr data) 2) "\nColor: YELLOW")
          ((= (cadr data) 3) "\nColor: GREEN")
          ((= (cadr data) 4) "\nColor: CYAN")
          ((= (cadr data) 5) "\nColor: BLUE")
          ((= (cadr data) 6) "\nColor: MAGENTA")
          ((= (cadr data) 7) "\nColor: WHITE")
          (t (strcat "\nColor: " (itoa (cadr data)))) ;their are over 256 colors so if it isn't the first 7 display number
        )
        "\nLayer: " (car data)))
    )
  )
  (princ)
)

 

Edited by mhupp
  • Thanks 1
Link to comment
Share on other sites

55 minutes ago, mhupp said:

Coming along way @AeJay for only 22 posts.

 

to simplify things

(setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
(if (= textobj nil)
>>
(if (setq textobj (ssname (ssget "_+.:E:S" (list (cons 0 "TEXT,MTEXT"))) 0))
or
(if textobj

with two or more string side by side you can just join them into one
...(rtos textheight 2 1) "\nColor: " "Bylayer" "\nLayer: " textlayer))
...(rtos textheight 2 1) "\nColor: Bylayer \nLayer: " textlayer))

 

I think your code would error or not display if selecting text that its color isn't 1-7

 

again from above  join strings into one.

((= nColor 1)(strcat "\nColor: " "RED"))
can just be
((= nColor 1) "\nColor: RED")

 

My code keeps everything in a list. so their is only the selection set and the data variable.

 

Entget

((-1 . <Entity name: 3eed7ec0>) (0 . "TEXT") (5 . "71") (330 . <Entity name: 3e488ae0>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (370 . -1) (100 . "AcDbText") (10 5.59944594793636 4.30743710947954 0.0) (40 . 0.2) (1 . "asdfasdfsdaf") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . "AcDbText") (73 . 0))

 

Becomes 

(8 . "0") (62 . 1) (40 . 0.2) (1 . "asdfasdfsdaf")

 

Then values are put into list data

'("0" 1 0.2 "asdfasdfsdaf")

'(Layer color height textstring)

 

finally

image.png.9eb8198d29c6b628c959a1ac71c7eb8b.png

 

(defun c:ttp (/ ss data)
  (while (setq ss (ssget "_+.:E:S" '((0 . "TEXT,MTEXT")))) ;while to allow you to keep selecting in the same command.
    (setq data (mapcar 'cdr (vl-remove-if-not '(lambda (x) (or (= (car x) 1) (= (car x) 40) (= (car x) 62) (= (car x) 8))) (entget (ssname ss 0)))))
    (if (= (length  data) 3)
      (alert (strcat "Text: " (last data) "\nHeight: " (rtos (cadr data) 2 2) "\nColor: ByLayer \nLayer: " (car data)))
      (alert (strcat "Text: " (last data) "\nHeight: " (rtos (caddr data) 2 2) 
        (cond
          ((= (cadr data) 1) "\nColor: RED")
          ((= (cadr data) 2) "\nColor: YELLOW")
          ((= (cadr data) 3) "\nColor: GREEN")
          ((= (cadr data) 4) "\nColor: CYAN")
          ((= (cadr data) 5) "\nColor: BLUE")
          ((= (cadr data) 6) "\nColor: MAGENTA")
          ((= (cadr data) 7) "\nColor: WHITE")
          (t (strcat "\nColor: " (itoa (cadr data)))) ;their are over 256 colors so if it isn't the first 7 display number
        )
        "\nLayer: " (car data)))
    )
  )
  (princ)
)

 

Such a detailed answer, thank you so much!

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