Newsgroup: it.comp.software.cad
Titolo: Problema con un [LISP+C]

Ecco un lispino che ho scritto un po' di tempo fa.
Serve per generare una sequenza di numeri, partendo da un valore indicato,
toccando ad uno ad uno testi già presenti nel disegno. In pratica  scrivo un
testo, es. "1", lo copio n volte nella posizione in qui mi serve, poi con la
funzione del lisp li cambio generando una sequenza crescente di numeri
interi di
intervallo costante +1.
Il lisp così com'è funziona già però ......
----------------------------------------------------------------------------
--
;SEQUENZA DI NUMERI
(defun NN (/ ss e  N TT)   ; definizioni
 (princ "Selezionare IL TESTO DA NUMERARE..\n") ; scelta testo
 (setq E (car (entsel "DIGITARE ")))  ;  "      "
 (if (= E nil) (nn))    ; ripete la 'chiama' in caso di errore
 (SETQ N (GETVAR "USERR4"))   ; setta N uguale alla variabile USERR4
 (SETQ N (+ N 1))    ; aggiunge 1 alla variabile
 (COMMAND "USERR4" N \R )   ; setta la variabile USERR4 = N +1
 (SETQ TT (RTOS N 2 0))    ; setta TT = testo senza decimali
 (command "._CHANGE" e "" "" "" "" "" "" TT) ; cambia il testo selezionato
 (NN)      ; fa ripartire la routine
)
(defun C:num (/ ss e  n TT)   ; sette N al numero voluto per la partenza
  (SETQ N (GETREAL "numero di inizio :")) ; chiede il numero da cui partire
  (SETQ N (- N 1))    ; toglie 1 perchè la routine ne aggiunge 1
      ; ogni volta, anche la prima
  (COMMAND "USERR4" n \R    ; setta USERR4
 )
 (nn)      ; lancia la routine
)
(princ "\nProgramma SEZUENZA NUMERI ............caricato .....Usare NUM")
;commento
----------------------------------------------------------------------------
Come si fa a far terminare la funzione senza dover premere necessariamente
ESC, ma premendo Invio o meglio tasto DX del mouse?
E' già inserita una riga di controllo " (if (= E nil) (nn))" per evitare che
quando si sbaglia premendo a vuoto  non si generi un errore o peggio non
sballi la sequenza. Ma se per sbaglio seleziono una linea e non un testo
inevitabilmente, così com'è il lispino adesso sono costretto a ripartire
perchè viene modificata la sequenza. Come si fa a mettere un filtro di
selezione solo sui testi?
Grazie a chi mi risponderà.
--------------
Massimo Ghio

Ciao Massimo, io ho messo il tutto in un ciclo while per comodità.
Guarda se ti può essere utile:
(ho fatto una modifica senza provarla, se non funziona avvertimi che la
sistemo) 
Ciao Mario Scavroni 
(defun c:text_ord1 ( / txt v_iniz pass p1 txtold txtnew txt txt1 datent
tipent )
(setvar "cmdecho" 0)
	(if (not #v_iniz)(setq #v_iniz 1)) 
	(setq txt (itoa #v_iniz ))
	(initget 6 )
	(setq v_iniz (getint (strcat "\nValore iniziale <" txt ">: ")))
	(if (not v_iniz)(setq v_iniz #v_iniz))
	(setq #v_iniz v_iniz)
	(if (not #pass)(setq #pass 1)) 
	(setq txt (itoa #pass ))
	(initget 6 )
	(setq pass (getint (strcat "\nIncremento della progressione <" txt ">:
")))
	(if (not pass)(setq pass #pass))
	(setq #pass pass)
	(setq datent T)
	(while datent
		(progn	
		(prompt (strcat "\nImmissione numero " (itoa v_iniz)))
		(while (not ent)
		(setq datent (entget (car 
		(entsel "\nSelezionare un testo da cambiare:"))))
		)
       		(setq tipent (cdr (assoc 0 datent )))
		(if (= tipent "TEXT")						; controllo testo
		(progn	
			(setq txtold (assoc 1 datent))
			(setq txtnew (strcat (itoa v_iniz) "-" (itoa (1+ v_iniz))))
			(setq txt1 (cons (car txtold) txtnew ))
			(setq txt (subst txt1 txtold datent))
			(entmod txt)
	       		(setq v_iniz (+ v_iniz pass))
		))
		)
	)
(princ)
)

 selezione solo sui testi?
Eccoti un piccolo manualetto sull'uso del "ssget"
 -----------------------------------------------------
(ssget "_:E")      ; varie selezioni di un singlo oggetto alla volta
(ssget "_:S")      ; unica selezione di uno o piu' oggetti alla volta
(ssget "_:E:S")  ; unica selezione di un singolo ogetto
(ssget '((0 . "TEXT"))) ; scarta dalle varie selezioni cio' che non e' text
-----------------------------------------------------
io userei un "ssget"  nella forma di un unica selezione
di un singolo oggetto e che sia text, altrimenti restituisce nil:
-----------------------------------------------------
(setq stxt (ssget "_:E:S" '((0 . "TEXT"))))
(setq ntxt (if stxt (ssname stxt 1) nil))
-----------------------------------------------------
Cosi' facendo sei certo che stai passando
alla tua procedura un testo oppure un nil,
in tal caso puoi fermarti senza modificare la
sequenza.
Fossi in te mi butterei su quanto impostato da Mario e
lascerei perdere la "USERR4", Mario e' bravissimo
a gestire i valori di default; in quel modo hai una procedura duttile
che ti consente se vuoi di continuare la numerazione
o in alternativa di ricominciarla.
Forse pero' ti interessava ritrovarti il valore
nella nuova sessione di lavoro:
-----------------------------------------------------
(setq stxt (ssget "_X" '((0 . "TEXT"))))
-----------------------------------------------------
ti restituira' tutti i testi presenti nel file,
li processi ad uno ad uno e vedi qual'e' il numero piu' alto.
puoi cosi' settare quello come valore di default.
Vado di fretta scusa, non entro nel dettaglio.
Per curiosita', mi spieghi:
-----------------------------------------------------
ok -> (SETQ N (GETVAR "USERR4"))
ok -> (SETQ N (+ N 1))
?? -> (COMMAND "USERR4" N \R )
-----------------------------------------------------
cos'e' "\R"?
-----------------------------------------------------
-----------------------------------------------------
Cio' detto potrebbe essare bella pure una versione
che non sovrascriva ma aggiunga il numero davanti:
ho piu testi nel disegno:
pippo, pappa, peppe, altro
click pippo --> 1) pippo
click pappa --> 2) pappa
click peppe --> 3) peppe
click altro  --> 4) altro
----
Cio' detto potrebbe essare bella pure una versione
che quota e numera dei punti:
ho varie linee o altro nel disegno
voglio indicarne le coordinate degli estremi
ad esempio:
PT1= (1,1,1)
PT2 =(2,2,2)
click PT1 (getpoint) [con snap a endpoint] --> scrivo "1) (1,1,1)"
click PT2 (getpoint) [con snap a endpoint] --> scrivo "2) (2,2,2)"
----
idee che mi frullano in testa.
--
Ciao Giovanni

Ciao Massimo, scusa ma nella fretta di modificare il programma per postarlo
ho dimenticato una piccola modifica, riposto il programma funzionante
(spero).
Ciao Mario Scavroni 
(defun c:text_ord1 ( / txt v_iniz pass p1 txtold txtnew txt txt1 datent
tipent )
(setvar "cmdecho" 0)
	(if (not #v_iniz)(setq #v_iniz 1)) 
	(setq txt (itoa #v_iniz ))
	(initget 6 )
	(setq v_iniz (getint (strcat "\nValore iniziale <" txt ">: ")))
	(if (not v_iniz)(setq v_iniz #v_iniz))
	(setq #v_iniz v_iniz)
	(if (not #pass)(setq #pass 1)) 
	(setq txt (itoa #pass ))
	(initget 6 )
	(setq pass (getint (strcat "\nIncremento della progressione <" txt ">:
")))
	(if (not pass)(setq pass #pass))
	(setq #pass pass)
	(setq datent T)
	(while datent
		(progn	
		(prompt (strcat "\nImmissione numero " (itoa v_iniz)))
;;;-------------------
		(while (not datent)
			(setq datent (entget (car 
			(entsel "\nSelezionare un testo da cambiare:"))))
		)
		;;; Giovanni mi ha fatto notare che il proogramma non funzionava, è
perche ho aggiunto un "pezzo"
		;;; di codice per evitare che si selezioni a vuoto e vada in errore (il
ciclo while sopra riportato)
		;;; ora dovrebbe funzionare (spero, non dovrei postare varianti senza
provarle) 
;;;-------------------


 ha scritto nel messaggio
news:01ba84e4$95b3abe0$8d1ab7c2@gqgrmhba...


 cos'e' "\R"?
Non lo so perchè l'ho messo. /r Manda semplicemente a capo.
Grazie Giovanni
--------
Massimo Ghio