While won't loop

While won't loop

Anonymous
Not applicable
526 Views
6 Replies
Message 1 of 7

While won't loop

Anonymous
Not applicable

Hi everyone,

 

I'm new to the AutoLISP programming and have a problem with my routine. This code should auto-nummerate some objects. I work with the AutoCAD MEP 2014

In this routine the While-Function doesn't loop (code is in German... if anyone has a problem i will translate the code):

 

(defun c:autonum ()
	(setq p1 (getpoint "\nBitte Bereich auswählen (Links oben beginnen): "))
	(setq p3 (getpoint "\nBitte Ecke unten Rechts angeben: "))
	(setq p2 (list (car p1)(cadr p3)))
	(setq p4 (list (car p3)(cadr p1)))
	
	(setq sym (entget (car (entsel))))
	(setq symname (cdr(assoc 2 sym)))
	
	
	(setq sel1 (ssadd)) ; Auswahlsatz sel1 erstellen
	(setq entdata (ssget "X" (list (cons 0 "INSERT")))) ; Alle Objekte des Typs "INSERT" werden ausgewählt
	(setq i (sslength entdata)) ; Anzahl Objekte die sich im Auswahlsatz entdata befinden werden ausgezählt
	(setq i (1- i))
	
	(while (not(< i 0)) ; Erstelle Schleife und suche jedes Objekt nach symname ab
		(setq ausw (ssname entdata i))
		(setq auswerw (entget ausw))
		(setq symnamecheck (cdr(assoc 2 auswerw)))
		(if (eq (strcase symnamecheck) (strcase symname)) ; Wenn symnamecheck gleich ist wie symname dann wird Objekt zu Auswahlsatz sel1 hinzugefügt.
			(progn
				(ssadd ausw sel1)
			)
		)
		(setq i (1- i))
)
	
	(setq sel2 (ssadd))
	(setq i (sslength sel1))
	(setq i (1- i))
	(setq posarray (list)) ; Erzeuge Array um von jedem Symbol die Position zu merken (Wird beim Nummerierungsschritt benötigt
  
	(while (not(< i 0)) ; Bei dieser Schleife werden alle Objekte ermittelt, die sich im Auswahlrahmen befinden
		(setq ausw (ssname sel1 i))
		(setq auswerw (entget ausw))
		(setq p1y (cadr p1))
		(setq p2x (car p2))
		(setq p3y (cadr p3))
		(setq p4x (car p4))
		(setq posx (cadr(assoc 10 auswerw)))
		(setq posy (caddr(assoc 10 auswerw)))
	  	
		
		(if (>= p1y posy) ; Hier wird geprüft ob sich das Objekt im Auswahlrahmen befindet
			(progn
				(if (<= p2x posx)
					(progn
						(if (<= p3y posy)
							(progn
								(if (>= p4x posx)
									(progn
										(ssadd ausw sel2) ; Wenn ja dann füge es zum Auswahlsatz sel2 hinzu
									  	(setq posarray (append posarray (list posx) (list posy))) ; Füge die Position des Objektes in das Array ein
									)
								)
							)
						)
					)
				)
			)
		)
		(setq i (1- i))
	 
	)
	(sssetfirst nil sel2)
	(setq z (sslength sel2))
	(setq z (1- z))
	       
    	(setq num (getstring "\nBeschriftung auf [X]-Achse oder auf [Y]-Achse: ")) ; Wie soll die Beschriftung erfolgen? Von Links nach Rechts (X-Achse) oder von Oben nach Unten (Y-Achse)
	(cond ((or(= num "x")(= num "X")) ; Beschriftung auf X-Achse
	       
		(setq prfix (getstring "\nWird ein Präfix benötigt? Wenn ja, bitte eingeben: ")) ; Präfix der Nummerierung bspw. Geschoss-Buchstaben (A...
		(setq zahl (getreal "\nBitte erste Nummer eingeben (nur ein Komma erlaubt!): ")) ; Erste Nummer eingeben
		(setq sffix (getstring "\nWird ein Suffix benötigt? Wenn ja, bitte eingeben: ")) ; Suffix der Nummerierung bspw. Geschoss-Buchstaben (A....)
	   	(setq schritt (getstring "\nBitte Nummerierungsschritt eingeben (z.B. +0.1): "))
		(setq feld (getstring "\nWie heisst das Feld des Symbols das beschriftet werden soll (z.B. BEZ1): ")).
							
			(while (not (< z 0)) ; This is the loop which won't loop
				(setq q 0)
				(setq number (rtos zahl))
				(setq beschriftung (strcat prfix number sffix))
							  	
				(setq n (entnext (ssname sel2 z)))
				(setq e (entget n))
							  
					(while (not (eq q 1))
						(if (eq (cdr (assoc 2 e)) feld)
							(progn
								(entmod (subst (cons 1 beschriftung) (assoc 1 e) e))
								(entupd n)
								(setq q 1)
							)
						)
					(setq n (entnext n))
					(setq e (entget n))
					)
			  
 				(setq number (atof schritt))
				(setq number (+ zahl number))
				(setq z (1- z))
			) ; 
	      )
	      )
  )

The first object will be edited and the other won't...

Can anyone help me? I'm really frustrated...

 

Thanks!

0 Likes
527 Views
6 Replies
Replies (6)
Message 2 of 7

ВeekeeCZ
Consultant
Consultant

Please post a sample drawing where we can clearly see the initial state and then state of what you want to have.
And yes. Simple translation would make it easier for us a lot!

 

Btw. In following cut is progn function nowhere necessary! (ok, except the last one) 

Why won't you use the and function?

 

Spoiler
(if (>= p1y posy)			; Hier wird geprüft ob sich das Objekt im Auswahlrahmen befindet
  (progn
    (if	(<= p2x posx)
      (progn
	(if (<= p3y posy)
	  (progn
	    (if	(>= p4x posx)
	      (progn
		(ssadd ausw sel2)	; Wenn ja dann füge es zum Auswahlsatz sel2 hinzu
		(setq posarray (append posarray (list posx) (list posy))
		)			; Füge die Position des Objektes in das Array ein
	      )
	    )
	  )
	)
      )
    )
  )
)

 

 

 

 

0 Likes
Message 3 of 7

Anonymous
Not applicable

Hi BeekeeCZ,

 

Thanks for your answer. I uploaded a test.dwg. And this is the english version (i hope you understand it ^^) of my code:

(defun c:autonum ()
    (setq p1 (getpoint "\nPlase select first corner: "))
    (setq p3 (getpoint "\nNow the second: "))
    (setq p2 (list (car p1)(cadr p3)))
    (setq p4 (list (car p3)(cadr p1)))
    
    (setq sym (entget (car (entsel))))
    (setq symname (cdr(assoc 2 sym)))
    
    
    (setq sel1 (ssadd)) ; create selection set sel1
    (setq entdata (ssget "X" (list (cons 0 "INSERT")))) ; All objects with the type "INSERT" will be selected
    (setq i (sslength entdata)) ; How many objects are in this selection set
    (setq i (1- i))
    
    (while (not(< i 0)) ; Create loop
        (setq ausw (ssname entdata i))
        (setq auswerw (entget ausw))
        (setq symnamecheck (cdr(assoc 2 auswerw)))
        (if (eq (strcase symnamecheck) (strcase symname))
            (progn
                (ssadd ausw sel1)
            )
        )
        (setq i (1- i))
)
    
    (setq sel2 (ssadd))
    (setq i (sslength sel1))
    (setq i (1- i))
    (setq posarray (list)) ; Create list to put all positions in it
 
    (while (not(< i 0)) ; In this loop all objects will be selected which are in the selection (p1, p2, p3 etc..)
        (setq ausw (ssname sel1 i))
        (setq auswerw (entget ausw))
        (setq p1y (cadr p1))
        (setq p2x (car p2))
        (setq p3y (cadr p3))
        (setq p4x (car p4))
        (setq posx (cadr(assoc 10 auswerw)))
        (setq posy (caddr(assoc 10 auswerw)))
          
        
          (if (and
              (>= p1y posy)
              (<= p2x posx)
              (<= p3y posy)
              (>= p4x posx)
            )
        (setq i (1- i))
    
    )
    (sssetfirst nil sel2)
    (setq z (sslength sel2))
    (setq z (1- z))
           
        (setq num (getstring "\nHow do you want to numerate the objects [X]-Axis or [Y]-Axis : "))
    (cond ((or(= num "x")(= num "X"))
           
        (setq prfix (getstring "\nPrefix: "))
        (setq zahl (getreal "\nFirst Number: "))
        (setq sffix (getstring "\nSuffix: "))
           (setq schritt (getstring "\nIncrement: "))
        (setq feld (getstring "\nWhich Attribute do you want to edit (f.e. BEZ1): ")).
                            
            (while (not (< z 0))
                (setq q 0)
                (setq number (rtos zahl))
                (setq beschriftung (strcat prfix number sffix))
                                  
                (setq n (entnext (ssname sel2 z)))
                (setq e (entget n))
                              
                    (while (not (eq q 1))
                        (if (eq (cdr (assoc 2 e)) feld)
                            (progn
                                (entmod (subst (cons 1 beschriftung) (assoc 1 e) e))
                                (entupd n)
                                (setq q 1)
                            )
                        )
                    (setq n (entnext n))
                    (setq e (entget n))
                    )
              
                 (setq number (atof schritt))
                (setq number (+ zahl number))
                (setq z (1- z))
            )
          )
          )
  )

Ok thanks for your tip i'll change it to and!

 

/EDIT:

Sorry forgot the second dwg

 

/EDIT2:

I've changed the If expressions to and

0 Likes
Message 4 of 7

ВeekeeCZ
Consultant
Consultant

Hi duebi,

 

I tried your code and I coudn't get through all of it.

 

Your implementation of and function is wrong... you missed this part: (ssadd ausw sel2) (setq posarray (append posarray (list posx) (list posy)))

 

Even I tried your previous code then at line (sssetfirst nil sel2) I can't get any sel2 - it's always empty. So I gave up... but main reason why is that your code is unnecessarily complicated! Try to learn about (ssget) function and its filters! HERE

 

So I decided to rewrite it all from a basement. Using (ssget) function is HUGE help that with couple of lines I can replace a whole page of yours...

Some parts are downloaded from web.

 

Spoiler
(defun c:autonum ( / *error* LM:getattributes LM:getattributes _SortSSByXYValue
		     doc ssp enp ss atts attst att ax pre start inc suf i n e)

  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg)))
    (vla-endundomark doc)
    (princ))

  
  ;; Get Attributes  -  Lee Mac
  (defun LM:getattributes ( blk / enx )
    (if (= "ATTRIB" (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk)))))))
        (cons (cons (cdr (assoc 2 enx))
		    (cdr (assoc 1 enx)))
	      (LM:getattributes blk))))

  ;; Get Attributes  -  Lee Mac
  (defun LM:getattributes ( blk / enx lst )
    (while (= "ATTRIB" (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk)))))))
      (setq lst (cons (cons (cdr (assoc 2 enx))
			    (cdr (assoc 1 enx)))
		      lst)))
    (reverse lst))

  ;alanjt http://forums.augi.com/showthread.php?137837-Sort-Selectionset-by-X-coord&p=1164075&viewfull=1#post1164075
  (defun _SortSSByXYValue (ss ax / lst i e add)
    (if (eq (type ss) 'PICKSET)
      (progn
	(repeat (setq i (sslength ss))
	  (setq lst (cons (cons (setq e (ssname ss (setq i (1- i))))
				(if (= ax "X")
				  (cadr (assoc 10 (entget e)))
				  (caddr (assoc 10 (entget e)))))
			  lst)))
	(setq add (ssadd))
	(foreach e (vl-sort lst (function (lambda (a b) (< (cdr a) (cdr b))))) (ssadd (car e) add))
	(if (> (sslength add) 0) add))))

  
  ;------- MAIN ROUTINE -------------------------------------------------------------------------------------------
  ;----------------------------------------------------------------------------------------------------------------
  
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))

  (if (and (princ "\nSingle block as pattern is needed,")
	   (setq ssp (ssget "_+.:E:S" '((0 . "INSERT"))))
	   (setq enp (ssname ssp 0))
	   (princ "\nSelect blocks to be numbered,")
	   (setq ss (ssget "_:L" (list '(0 . "INSERT")
				       '(66 . 1)
				       (assoc 2 (entget enp)))))
	   (setq atts (LM:getattributes enp))
	   (setq attst ""
		 attst (vl-string-right-trim "," (foreach e atts (setq attst (strcat attst (car e) ",")))))
	   (if (eq "" (setq att (strcase (getstring (strcat "\nSelect edited attribute /" attst "/ <" (caar atts)">: ")))))
	     (setq att (caar atts))
	     T)
	   (not (initget "X Y"))
	   (setq ax (cond ((getkword "\nNumerate by [X-axis/Y-axis] <X>: "))
			  (T "X")))
	   (setq ss (_SortSSByXYValue ss ax))
	   (setq pre (getstring "\nPrefix: "))
	   (setq start (cond ((getreal "\nStart number <1>: "))
			     (T 1)))
	   (setq inc (cond ((getreal "\nIncrement <1>: "))
			     (T 1)))
	   (setq suf (getstring "\nSuffix: ")))
    (repeat (setq i (sslength ss))
      (setq n (entnext (ssname ss (setq i (1- i)))))
      (while (not (eq "SEQEND" (cdr (assoc 0 (setq e (entget n))))))
	(if (eq (cdr (assoc 2 e)) att)
	  (progn
	    (entmod (subst (cons 1 (strcat pre (rtos (+ start (* i inc))) suf))
			   (assoc 1 e)
			   e))
	    (entupd n)))
	(setq n (entnext n)))))

  (vla-endundomark doc)
  (princ)
)

 

I hope it helps you to learn some of lisp 🙂

Message 5 of 7

ВeekeeCZ
Consultant
Consultant

I just realized that I have a Mac Lee's double. And since I can't edit it any more...

 

Spoiler
(defun c:autonum ( / *error* LM:getattributes LM:getattributes _SortSSByXYValue
		     doc ssp enp ss atts attst att ax pre start inc suf i n e)

  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg)))
    (vla-endundomark doc)
    (princ))

  ;; Get Attributes  -  Lee Mac
  (defun LM:getattributes ( blk / enx lst )
    (while (= "ATTRIB" (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk)))))))
      (setq lst (cons (cons (cdr (assoc 2 enx))
			    (cdr (assoc 1 enx)))
		      lst)))
    (reverse lst))

  ;alanjt http://forums.augi.com/showthread.php?137837-Sort-Selectionset-by-X-coord&p=1164075&viewfull=1#post1164075
  (defun _SortSSByXYValue (ss ax / lst i e add)
    (if (eq (type ss) 'PICKSET)
      (progn
	(repeat (setq i (sslength ss))
	  (setq lst (cons (cons (setq e (ssname ss (setq i (1- i))))
				(if (= ax "X")
				  (cadr (assoc 10 (entget e)))
				  (caddr (assoc 10 (entget e)))))
			  lst)))
	(setq add (ssadd))
	(foreach e (vl-sort lst (function (lambda (a b) (< (cdr a) (cdr b))))) (ssadd (car e) add))
	(if (> (sslength add) 0) add))))

  
  ;------- MAIN ROUTINE -------------------------------------------------------------------------------------------
  ;----------------------------------------------------------------------------------------------------------------
  
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))

  (if (and (princ "\nSingle block as pattern is needed,")
	   (setq ssp (ssget "_+.:E:S" '((0 . "INSERT"))))
	   (setq enp (ssname ssp 0))
	   (princ "\nSelect blocks to be numbered,")
	   (setq ss (ssget "_:L" (list '(0 . "INSERT")
				       '(66 . 1)
				       (assoc 2 (entget enp)))))
	   (setq atts (LM:getattributes enp))
	   (setq attst ""
		 attst (vl-string-right-trim "," (foreach e atts (setq attst (strcat attst (car e) ",")))))
	   (if (eq "" (setq att (strcase (getstring (strcat "\nSelect edited attribute /" attst "/ <" (caar atts)">: ")))))
	     (setq att (caar atts))
	     T)
	   (not (initget "X Y"))
	   (setq ax (cond ((getkword "\nNumerate by [X-axis/Y-axis] <X>: "))
			  (T "X")))
	   (setq ss (_SortSSByXYValue ss ax))
	   (setq pre (getstring "\nPrefix: "))
	   (setq start (cond ((getreal "\nStart number <1>: "))
			     (T 1)))
	   (setq inc (cond ((getreal "\nIncrement <1>: "))
			     (T 1)))
	   (setq suf (getstring "\nSuffix: ")))
    (repeat (setq i (sslength ss))
      (setq n (entnext (ssname ss (setq i (1- i)))))
      (while (not (eq "SEQEND" (cdr (assoc 0 (setq e (entget n))))))
	(if (eq (cdr (assoc 2 e)) att)
	  (progn
	    (entmod (subst (cons 1 (strcat pre (rtos (+ start (* i inc))) suf))
			   (assoc 1 e)
			   e))
	    (entupd n)))
	(setq n (entnext n)))))

  (vla-endundomark doc)
  (princ)
)
Message 6 of 7

Anonymous
Not applicable

Hi BeekeeCZ,

 

Thank you very much for your answer!

That's strange because on my PC it works until the loop...

 

If I find some time today I will check your code and try to understand it.

 

Have a nice day!

0 Likes
Message 7 of 7

ВeekeeCZ
Consultant
Consultant

@duebi_gr wrote:

Hi everyone,

 

...

In this routine the While-Function doesn't loop (code is in German... if anyone has a problem i will translate the code):

 

...	(setq sffix (getstring "\nWird ein Suffix benötigt? Wenn ja, bitte eingeben: ")) ; Suffix der Nummerierung bspw. Geschoss-Buchstaben (A....)
	(setq schritt (getstring "\nBitte Nummerierungsschritt eingeben (z.B. +0.1): "))
	(setq feld (getstring "\nWie heisst das Feld des Symbols das beschriftet werden soll (z.B. BEZ1): ")).
							
		(while (not (< z 0)) ; This is the loop which won't loop
			(setq q 0)
...

I marked your problem.

0 Likes