Hi friend, I don't know LISP language, but I need a program urgently
A program that prompts:"select objects:"
then I can select some objects like as text, line, circle,...
after that program find all texts in selected items and swap text
swap means: xxx/yyy ===> yyy/xxx ; "/" is a divisor
swap function for one text is here:
(defun c:swap ( / pos ent el txt)
(vl-load-com)
(if(null #div#)(setq #div# "/"))
(setq #div#
(if(=(setq tmp(getstring(strcat "\nDivisor character: <"#div#"> ")))"")
#div# tmp
)
)
(while(setq ent(entsel "\nSelect text: "))
(if(=(cdr(assoc 0(setq el(entget(car ent)))))"TEXT")
(entmod(subst(cons 1
(if(setq pos(vl-string-search #div#(setq txt(cdr(assoc 1 el)))))
(strcat(substr txt(+ 2 pos))#div#(substr txt 1 pos))
txt
)
)
(assoc 1 el)el))
)
)
(princ)
)
-------------------------------------------------------------------------------------------
but I want a program to prompt me like this:
(prompt "Select objects:")(terpri)
(setq a (ssget '((0 . "TEXT"))))
and gets divisor char </>:
after that:
(setq n (sslength a))
(repeat n
....
)
repeats n times, n=number of texts in my selection
Please help me!
Solved! Go to Solution.
Solved by _Tharwat. Go to Solution.
(defun c:Test (/ ss i e st p) ;;; Tharwat 26. Oct. 2012 ;;; (if (setq ss (ssget "_:L" (List '(0 . "*TEXT") (cons 1 "*/*")))) (repeat (setq i (sslength ss)) (setq e (entget (ssname ss (setq i (1- i))))) (setq st (cdr (assoc 1 e))) (setq p (vl-string-search "/" st)) (entmod (subst (cons 1 (strcat (substr st (+ p 2) (strlen st)) "/" (substr st 1 p)) ) (assoc 1 e) e ) ) ) ) (princ) )
@_Tharwat wrote:.... (if (setq ss (ssget "_:L" (List '(0 . "*TEXT") (cons 1 "*/*")))) .... (strcat (substr st (+ p 2) (strlen st)) "/" (substr st 1 p)) ....
That's a good way to do it [you'll find various approaches to stepping through a selection set], though I notice two things about the above-quoted pieces that could be simplified slightly, if you're interested.
Wildcards in selection-set filtering can be used explicitly, that is, they are not considered to "require evaluation." That is already applied above with the "*TEXT" entry in an apostrophe-prefixed ["quoted," no-evaluation-needed] dotted-pair list, and the same can also be used with the "*/*" entry. That means you can make the filter list without the explicit (list) function or (cons), but rather using the ' shortcut of the (quote) function for the entire list instead of just part of it. So the first quoted line above can be reduced to:
(if (setq ss (ssget "_:L" '((0 . "*TEXT") (1 . "*/*"))))
And in (substr), the 'length' argument is optional, and if you don't give it a number of characters for that, it will just take it to the end of the string. So as in the OP's original, the second quoted line above can be done without that argument in the first (substr) function:
(strcat (substr st (+ p 2)) "/" (substr st 1 p))
Thank you so much. It works great!
however does not prompt for divisor char '/' , '|' , '-' , ....
but works fine for me.
Thanks
(defun c:swap2 (/ _delFinder #div# ss i e st str fs p) (vl-load-com) (defun _delFinder (str md / d l str) (while (setq d (vl-string-position md str nil T)) (setq l (cons (substr str (+ 2 d)) l) str (substr str 1 d) ) ) (cons str l) ) (if (null #div#) (setq #div# "/") ) (if (and (setq #div# (if (= (setq tmp (getstring (strcat "\nDivisor character: <" #div# "> ") ) ) "" ) #div# tmp ) ) (setq ss (ssget "_:L" (list '(0 . "*TEXT") (cons 1 (strcat "*" #div# "*"))) ) ) ) (repeat (setq i (sslength ss)) (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i))))) (setq st (_delfinder (setq str (vla-get-textstring e)) 32)) (setq fs (vl-some '(lambda (x) (if (vl-string-position (ascii #div#) x) x ) ) st ) ) (setq fsr (reverse (_delfinder fs (ascii #div#)))) (vla-put-textstring e (vl-string-subst (strcat (car fsr) #div# (cadr fsr)) fs str ) ) ) ) (princ) )
command: swap2
Divisor character: </> [enter]
Select objects: Specify opposite corner: 2 found
Select objects:
< objects selected >
"xxx/yyy"
"asdf xxx/yyy dfd"
result
"yyy/xxx"
"asdf yyy/xxx dfdf"
HTH