i can't find out my problem in this lisp

i can't find out my problem in this lisp

Anonymous
Not applicable
3,114 Views
21 Replies
Message 1 of 22

i can't find out my problem in this lisp

Anonymous
Not applicable

hi everyone

I want to reverse the text by the selected text, but it does not work properly.it's getting error "lentittyp". I tried so many times.kindly help me .its would be really appreciated for the help. kindly mentioned what i did mistake in this lisp

sample text "a" "b" "c" "123"  etc.....

i want to like this - "123" "c" "b" "a" etc.......

 

(defun c:lop ()
(setq ss (ssget '((0 . "text"))))
(setq ab (sslength ss))
(setq i 0)
(repeat ab

(setq ssn (ssname ss i ))
(setq ent (entget ssn))
(setq asso (cdr (assoc 0 ent)))
(setq rev (reverse (list asso)))
;(entmod rev)
(setq i (+ i 1))
)
)

0 Likes
Accepted solutions (1)
3,115 Views
21 Replies
Replies (21)
Message 2 of 22

SeeMSixty7
Advisor
Advisor

I'm not 100% sure if you are trying to reverse the values of the text or the text values themselves.

Based on your sample it looks like you just want to reverse the order of a list of string values pulled from a text selection set. To do that try the following.

(defun c:lop ()
	(setq ss (ssget '((0 . "text"))))
	(setq ab (sslength ss))
	(setq i 0)
	(setq mylist (list)) ; create a list to work with with nothing in it
	(repeat ab
		(setq ssn (ssname ss i ))
		(setq ent (entget ssn))
		(setq asso (cdr (assoc 1 ent))) ; used value if dxf 1 to get text value
		(setq mylist (append mylist (list asso))) ;append the text string to the list
		;(entmod rev)
		(setq i (+ i 1))
	)
	(setq revlist (reverse mylist)) ; reverse the list of text
)

If you want to actually reverse the value of a text string you will need to write a bit more code. The reverse function works on a list of values, not on a string.

 

Good luck

0 Likes
Message 3 of 22

Kent1Cooper
Consultant
Consultant

This:

(assoc 0 ent)

will get you the entity type of something [in this case all "TEXT"], not its text content.  For the text string content, you want:

(assoc 1 ent)

 

This:

(reverse (list asso))

doesn't do anything, since 'asso' is a single item [reversing a list with only one item is...].

 

If you want to put the strings into a list and reverse it, you will need a (cons) or maybe (append) function involved, somehow, to put each one into the list.  But it's not clear to me what you want -- to merely change the order of the strings in the list, or [suggested by your commented-out (entmod)] to change the contents of the strings themselves to be the contents of other strings?  If the latter, can you do it by just exchanging their positions instead of their content?

 

Also, the order of the Text objects in (ssget) could be anything, affected by pick order if you pick them separately, or by drawn order if you pick them by a window, or by the sequence along a Fence path if you pick them that way.  What should determine their order in the list?

Kent Cooper, AIA
0 Likes
Message 4 of 22

doaiena
Collaborator
Collaborator

A few lines of code if you want to reverse the text value:

(defun c:ReverseText ( / ss ctr ent ed text)
(if (setq ss (ssget '((0 . "TEXT"))))
(progn

(setq ctr 0)
(repeat (sslength ss)

(setq ent (ssname ss ctr))
(setq ed (entget ent))
(setq text (vl-list->string (reverse (vl-string->list (cdr (assoc 1 ed))))))
(setq ed (subst (cons 1 text) (assoc 1 ed) ed))
(entmod ed)

(setq ctr (1+ ctr))
)
))

(princ)
);defun
0 Likes
Message 5 of 22

Kent1Cooper
Consultant
Consultant

@SeeMSixty7 wrote:
....
		(setq mylist (append mylist (list asso))) ;append the text string to the list
....
(setq revlist (reverse mylist)) ; reverse the list of text ....

....


 

If that's what's wanted [and I agree, it's not clear], it can be done more simply.  Instead of using (append) to put each one on the back  end of the list, and after the list is finished, (reverse)ing it, just use (cons) to put each one on the front  end of the list, and it won't need reversing.

....
  (setq mylist (cons asso mylist))
....
Kent Cooper, AIA
0 Likes
Message 6 of 22

SeeMSixty7
Advisor
Advisor

@Kent1Cooper wrote:


If that's what's wanted [and I agree, it's not clear], it can be done more simply.  Instead of using (append) to put each one on the back  end of the list, and after the list is finished, (reverse)ing it, just use (cons) to put each one on the front  end of the list, and it won't need reversing.

....
  (setq mylist (cons asso mylist))
....

That is true, but the point was to show how to use the reverse function to reverse a list, and that it applies to a list not to a string.

0 Likes
Message 7 of 22

Anonymous
Not applicable

thanks, everyone for replying to my question.

i want to put text reverse order themselves which I attached the picture.

your code is just reverse the text only. anyway i appreciate so much. 

 

SAMPLE IMAGE.JPG

 

Message 8 of 22

Anonymous
Not applicable

thank you so much kent.

your explanation is very helping us those who learning the AutoLISP program. I am grateful to you.

by hussain

Message 9 of 22

Kent1Cooper
Consultant
Consultant

MIRROR [with the MIRRTEXT System Variable set to 0].

Kent Cooper, AIA
Message 10 of 22

CodeDing
Advisor
Advisor

@Anonymous ,

 

Kent normally has those good ideas. MIRROR will work assuming you have a MID reference point (which it appears you do). When you do not have a reference point, here's my simple take.

(defun c:LOP ( / iList ssItem e)
(setq iList '())
;get items
(while (setq ssItem (progn (prompt "\nSelect TEXT Item: ") (ssget "_+.:E:S" '((0 . "TEXT")))))
  (setq iList (cons (cons (setq e (ssname ssItem 0)) (getpropertyvalue e "TextString")) iList))
);while
;if more than 1 item, continue
(if (> (length iList) 1)
  (progn
    (foreach x (mapcar 'cons (mapcar 'car iList) (mapcar 'cdr (reverse iList)))
      (setpropertyvalue (car x) "TextString" (cdr x))
    );foreach
  );progn
;else
  (prompt "\n...One or fewer items were selected. No actions taken.")
);if
(prompt "\nLOP Complete.")
(princ)
);defun

Best,

~DD

Message 11 of 22

CodeDing
Advisor
Advisor

Due to the nature of my provided example, as an extra layer of "security" you could ask the user if they're ready to swap, instead of automatically committing them to it.. Here would be the updated section:

(setq iList '() g2g nil)
;get items
(while (not g2g) (while (setq ssItem (progn (prompt "\nSelect TEXT Item: ") (ssget "_+.:E:S" '((0 . "TEXT"))))) (setq iList (cons (cons (setq e (ssname ssItem 0)) (getpropertyvalue e "TextString")) iList)) );while (initget 1 "Yes No") (if (eq "Yes" (getkword "\nReady to Swap? [Yes/No]")) (setq g2g t)) );while ;if more than 1 item, continue

Best,

~DD

Message 12 of 22

ronjonp
Mentor
Mentor

Here's another 🙂

(defun c:foo (/ _daisy p s)
  ;; RJP » 2019-11-06
  (defun _daisy	(pt l / _d tmp r)
    (defun _d (p l)
      (vl-sort l (function (lambda (r j) (< (distance p (last r)) (distance p (last j))))))
    )
    (setq tmp (_d pt l))
    (while (setq tmp (_d (last (car tmp)) tmp)) (setq r (cons (car tmp) r)) (setq tmp (cdr tmp)))
    (reverse r)
  )
  (if (and (setq s (ssget ":L" '((0 . "text"))))
	   (setq p (getpoint "\nPick a point to sort from: "))
	   (setq
	     s (_daisy
		 p
		 (mapcar '(lambda (x) (list x (cdr (assoc 1 (entget x))) (cdr (assoc 10 (entget x)))))
			 (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
		 )
	       )
	   )
      )
    ;; Nice reverse @Codeding :)
    (foreach x (mapcar 'cons (mapcar 'car s) (mapcar 'cdr (reverse s)))
      (entmod (append (entget (car x)) (list (cons 1 (cadr x)))))
    )
  )
  (princ)
)

2019-11-06_10-54-12.gif

Message 13 of 22

Sea-Haven
Mentor
Mentor

Removed my idea

 

How do I delete a post ? 

 

0 Likes
Message 14 of 22

CodeDing
Advisor
Advisor

@Sea-Haven ,

 

I had the same initial reaction, but on looking further OP does not want to sort, but rather reverse the order of items. 

 

The solution provided by @ronjonp is actually quite elegant and, in my opinion, would be a great solution to this post.

 

Best,

~DD

0 Likes
Message 15 of 22

Sea-Haven
Mentor
Mentor

Thanks codeding updated my post just now thought about it a bit more ssget F may simplify code. 

 

This in Civil software is reorder strings. Generally with a new start number.

Message 16 of 22

CodeDing
Advisor
Advisor

Lol, I update my posts because of stuff like that all the time.

0 Likes
Message 17 of 22

Sea-Haven
Mentor
Mentor

Did not work in Briscad but ok in Autocad ?

0 Likes
Message 18 of 22

Anonymous
Not applicable

hi  R0NJ0NP

your code is really interesting. this is what I was expected from here. i am really grateful to you and everyone who replied to my query.

i have another question here. could i add here for block text?

(ssget ":L" '((0 . "text" "insert")))) "is this correct code for block"

thanks

hussain

0 Likes
Message 19 of 22

Sea-Haven
Mentor
Mentor

Very nice Ronjonp but look at image I made the numbers out of order, erased some made a new ones as the ssget uses the database its now out of order. so renumber is incorrect. Providing the numbers are done one after another they are ok. 

That's why I hinted some sort of string approach.

0 Likes
Message 20 of 22

Kent1Cooper
Consultant
Consultant

@Sea-Haven wrote:

.... I made the numbers out of order, erased some made a new ones as the ssget uses the database its now out of order. so renumber is incorrect. Providing the numbers are done one after another they are ok. 

That's why I hinted some sort of string approach.


That was exactly my concern at the end of Message 3 -- anything that depends on the order things occur in the selection set can give different results depending on exactly how the selection is made.  But I wonder about a "string approach," if by that you mean to sort into order by text-string content.  The values in the image at Message 7 happen to be in order from one end to the other, but @Anonymous , would that always the the case?

Kent Cooper, AIA
0 Likes