text to line lisp required

text to line lisp required

ash19854
Contributor Contributor
472 Views
17 Replies
Message 1 of 18

text to line lisp required

ash19854
Contributor
Contributor

Dear Experts, Thank you for helping me whenever i am in trouble,

I need a lisp which can draw line from the x,y values from the selected text (not mtext). In my case X value starts with E & Y value starts with N as preceding text

Example : E406755, N2746409

Thank you.

0 Likes
Accepted solutions (3)
473 Views
17 Replies
Replies (17)
Message 2 of 18

Kent1Cooper
Consultant
Consultant

@ash19854 wrote:

.... from the x,y values from the selected text .... Example : E406755, N2746409


Are they in one Text object together, always with the comma and space between, and always with E first?

Kent Cooper, AIA
0 Likes
Message 3 of 18

ash19854
Contributor
Contributor

2 separate text entities and no comma

0 Likes
Message 4 of 18

Kent1Cooper
Consultant
Consultant
Accepted solution

Something like this, perhaps?  Minimally tested:

(defun C:TEST (/ ss Etxt Ntxt)
  (if
    ;; picked 2 Text objects, one of which starts with E & at least
    ;; one number, and the other with N & at least one number?
    (and
      (setq ss (ssget '((0 . "TEXT") (1 . "E#*,N#*"))))
      (= (sslength ss) 2)
      (setq Etxt (ssname (ssget "_P" '((1 . "E*"))) 0))
      (setq Ntxt (ssname (ssdel Etxt ss) 0))
      (wcmatch (getpropertyvalue Ntxt "TextString") "N*")
    ); and
    (command "_.line" ; then
      "_non"
      (strcat
        (substr (getpropertyvalue Etxt "TextString") 2)
        ","
        (substr (getpropertyvalue Ntxt "TextString") 2)
      ); strcat
    ); command [leaves you in it to finish]
    (prompt "\nDid not select correct combination of two Text objects."); else
  ); if
  (prin1)
)

It doesn't matter how you pick the two, nor if picked individually, in which order you pick them.

It leaves you in the Line command that it started from those coordinates, to go where you want with it, to any number of segments.

It requires capital E and N, but could be made to allow lower-case.

It assumes the numerical parts of the Text content will be in a format that AutoCAD can take as X,Y input -- for example no thousands comma separator, but decimals or even fractions [formatted correctly] are OK.

Kent Cooper, AIA
0 Likes
Message 5 of 18

ash19854
Contributor
Contributor

Thank you 😍

0 Likes
Message 6 of 18

Kent1Cooper
Consultant
Consultant

@ash19854 wrote:

Thank you 😍


You're welcome, and thank you -- you just put me over the edge to 4000 accepted solutions!  One every other day, approximately, and every 7th post on average, over the last 22 years or so of participating here.

Kent Cooper, AIA
Message 7 of 18

pbejse
Mentor
Mentor
4,000 accepted solutions unlocked! You are a community legend.
Congratulations 🔥
0 Likes
Message 8 of 18

Sea-Haven
Mentor
Mentor

Congratulations that is a significant number of "Accepted Solutions" let alone how many post that would be. 20,000 + ?

 

Just a suggestion (1 . "E#*,E #*,N#*,N #*") often the text has a space.  For another person looking for similar solution. The "e 1234 & n 5678" worked fine with ssget. Where I am in AUS we don't tend to label the E & N.

 

0 Likes
Message 9 of 18

Kent1Cooper
Consultant
Consultant

@Sea-Haven wrote:

.... how many post that would be. 20,000 + ?

.... (1 . "E#*,E #*,N#*,N #*") often the text has a space.  ....


It's worse than that:  28,000+.  [Hover over anyone's user name to see how many messages they've posted, how many solutions, etc.]

Yes, I thought of the possibility of a space.  I just went with the OP's example content [after they answered my other questions about it].  And if there could be a space, could there be two?  Etc.

Kent Cooper, AIA
0 Likes
Message 10 of 18

ash19854
Contributor
Contributor

In Some drawings XY Value texts are given with space for example E 123 456 & N 1 234 567 as separate text entities, is it possible to modify the same lisp so that it works with / without space please?. The program should ignore the spaces and should consider only numerical values mentioned therin. Thank you

0 Likes
Message 11 of 18

Kent1Cooper
Consultant
Consultant
Accepted solution

@ash19854 wrote:

In Some drawings XY Value texts are given with space for example E 123 456 & N 1 234 567....


It would have been better to have known that initially.

Try this [also minimally tested]:

(defun C:TEST (/ stripspaces ss Etxt Ntxt Estr Nstr)
  (defun stripspaces (str)
    (while (wcmatch str "* *"); still contains space(s)
      (setq str (vl-string-subst "" " " str)); replace with nothing
    ); while
    str ; feed out to function
  ); defun
  (if
    ;; picked 2 Text objects, one of which starts with E & at least
    ;; one number, and the other with N & at least one number,
    ;; either or both with or without space(s)?
    (and
      (setq ss (ssget '((0 . "TEXT") (1 . "E#*,E #*,N#*,N #*"))))
      (= (sslength ss) 2)
      (setq Etxt (ssname (ssget "_P" '((1 . "E*"))) 0))
      (setq Ntxt (ssname (ssdel Etxt ss) 0))
      (wcmatch (getpropertyvalue Ntxt "TextString") "N*,N #*")
    ); and
    (progn ; then
      (setq
        Estr (getpropertyvalue Etxt "TextString")
        Nstr (getpropertyvalue Ntxt "TextString")
        Estr (stripspaces Estr) 
        Nstr (stripspaces Nstr)
      ); setq
      (command "_.line"
        "_non"
        (strcat
          (substr Estr 2)
          ","
          (substr Nstr 2)
        ); strcat
      ); command [leaves you in it to finish]
    ); progn
    (prompt "\nDid not select correct combination of two Text objects."); else
  ); if
  (prin1)
)

It won't work if there are more than one space between the letter and the first numerical character, but there can be multiple spaces further in, between numerical substrings.

Kent Cooper, AIA
0 Likes
Message 12 of 18

ash19854
Contributor
Contributor

Thank you a lot, you are a great mentor. It was indeed a big help and may god bless you with lot of success .

0 Likes
Message 13 of 18

Sea-Haven
Mentor
Mentor

@Kent1Cooper For the task of getting number in a string like this I use Lee-mac lisp, https://www.lee-mac.com/parsenumbers.html  . It also removes the "E & N" and any spaces, then a simple join back foreach into a real number. 

(setq nums (LM:parsenumbers "E 1 234 956.789"))
(1 234 956.789)

(setq str "")
(foreach val nums
  (setq str (strcat str (rtos val 2 3)))
)
(setq num (atof str))

 

 

Message 14 of 18

Kent1Cooper
Consultant
Consultant

@Sea-Haven wrote:

.... For the task of getting number in a string .... back ... into a real number. 


[... and then back to a string with (strcat) & (rtos).]  But since they start out as text strings and are ultimately used as combined strings, to me it seems overkill to convert to numbers and then back to strings.  It's more direct to just keep the strings, and adjust those into viable coordinate input format [remove the E or N and the space(s)].

Kent Cooper, AIA
0 Likes
Message 15 of 18

komondormrex
Mentor
Mentor
Accepted solution

@ash19854 

hey there,

check the following

(defun c:draw_line_from_en (/ text en_selected ne_selected e_text n_text)
  (if (and
	(while (not en_selected)
	  (setq text (car (entsel "\nPick E/N text: ")))
	  (if (and text
		   (equal '(0 . "TEXT") (assoc 0 (entget text)))
		   (or
			(not (setq e_text text))
		        (vl-string-position (ascii "E") (cdr (assoc 1 (entget text))))
			(setq e_text nil)
			(not (setq n_text text))
			(vl-string-position (ascii "N") (cdr (assoc 1 (entget text))))
			(setq n_text nil)
		   )
	      )
	      (setq en_selected t)
	  )
	)
	(while (not ne_selected)
	  (setq text (car (entsel (if e_text "\nPick N text: " "\nPick E text: "))))
	  (if (and text
		   (equal '(0 . "TEXT") (assoc 0 (entget text)))
		   (vl-string-position (if e_text (ascii "N") (ascii "E")) (cdr (assoc 1 (entget text))))
	      )
	      (progn
		(if e_text (setq n_text text) (setq e_text text))  
	        (setq ne_selected t)
	      )
	  )
	)
       )
       (command "_line" "_non"
			(strcat (vl-list->string (vl-remove-if '(lambda (el) (member el (list 32 69 78))) (vl-string->list (cdr (assoc 1 (entget e_text))))))
				","
				(vl-list->string (vl-remove-if '(lambda (el) (member el (list 32 69 78))) (vl-string->list (cdr (assoc 1 (entget n_text))))))
			)
       )
   )
)

 

Message 16 of 18

Sea-Haven
Mentor
Mentor

Yes @Kent1Cooper you are right, woke up in middle of night and thought about it more, so a simpler method.

 

(defun str2num ( txt / len pos ascchar str)
(setq len (strlen txt))
(setq pos 1 str "")
(repeat len
  (setq char (substr txt pos 1))
  (setq ascchar (ascii char))
  (if (or (= ascchar 46)(and (> ascchar 47)(< ascchar 58)))
    (setq str (strcat str char))
  )
  (setq pos (1+ pos))
)
(setq num (atof str))
(princ)
)

(setq txt "E 123 456.789")
(str2num txt)
123456.789

 

0 Likes
Message 17 of 18

Kent1Cooper
Consultant
Consultant

How about this?

....
(repeat len
  (setq char (substr txt pos 1))
  (if (wcmatch char "#,`.") (setq str (strcat str char)))
  (setq pos (1+ pos))
)
....
Kent Cooper, AIA
0 Likes
Message 18 of 18

Sea-Haven
Mentor
Mentor

@Kent1Cooper even better as it uses the wcmatch to identify a number, a comma or a period etc.

0 Likes