Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Exiting a while loop

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Anonymous
5207 Views, 6 Replies

Exiting a while loop

Hello

I have got this problem while i use the while clause, I wanted to exit the while loop if i 'obj' is nil that is if I do not select anything.

 

....

(setq obj 0)  ;initializing the variable 'obj'

(while (not (= obj nil))

(setq str1 (cdr (assoc 1 (entget (car (setq obj (nentsel "Select the first construction BOX \n")))))))

 

the problem is when i am not selecting any object it exits the program with th following error message. "Error: bad argument type: lentityp nil"

Any Help Please

6 REPLIES 6
Message 2 of 7
dbroad
in reply to: Anonymous

First you should setq obj.  Then test it at the top of the while loop.  In the while loop you keep asking the question until answered.  After the answer, then access the data.

 

(while (not (setq obj (entsel....)))

;;empty while body

)

;;at this point, obj is set, continue

(setq str1 (cdr (assoc 1 (entget (car obj)))))

....

Architect, Registered NC, VA, SC, & GA.
Message 3 of 7
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

.... I wanted to exit the while loop if i 'obj' is nil that is if I do not select anything.

.... the problem is when i am not selecting any object it exits the program ....


I might suggest a rather different solution, depending on which of two ways you are referring to when you say "I do not select anything."  One way to not select any object is to miss when trying to select one, which I think may be what you mean, and @Anonymous suggested a way to get around that.  But that requires hitting Escape to end the routine.  Another way, when you want to finish the routine, by not selecting anything, is to build in the possibility of hitting Enter/space to end it, and offering <exit> as a default.  I can't spell it out right now, but if you Search for threads involving object selection and the "errno" System Variable, you should find examples of code that will ask you again if you just miss, but will offer <exit> as a default so you can hit Enter to get out of it.

Kent Cooper, AIA
Message 4 of 7
Anonymous
in reply to: dbroad

Thank you so much dbroad, it is a perfect suggestion. I dint know I could assign a value to a variable in side the while clause. It is working great now. The only thing I did  is i omitted the "not" from your solution. 

so I wrote the code as 

...(while  (setq obj (entsel....))

 

Message 5 of 7
Anonymous
in reply to: Kent1Cooper

 

 

Thank you for your great suggestion Kent, I didnt see that there are two conditions to exit the while loop, "one intentional and an other by missing or hiting the wrong object. so I wanted to modify the code based on your suggestion. The code I am writing now extracts numbers from block attributes, adds them and copy the result to a clip board, so I will paste it on a table. I wanted to select as many blocks and exist the loop. what @dbroad suggested me works great in this case. But for the other case which is "missing or hiting the wrong object", It exits not only the loop but also the program. I would rather prefer if the loop continues when such mistakes happen by giving me a message "wrong object, select only blocks with this name".  Here is the whole code.

 

;; I have a text in an attribute which is:

 

"DIR. BORE (284') 2-1.25" HDPE"   the number '284' varies, the other characters are the same always, I wanted the number between the first parenthesis and the ' character in this case 284

 

(defun C:RF()

 

(setq addnumber 0)                                                                          ;;initializing the variable 'firstnumber'

(setq total 0)                                                                                     ;;initializing the variable 'total'

 

  (

                while (setq obj (nentsel "Select construction BOX \n"))     

                (setq str (cdr (assoc 1 (entget (car obj)))))                          ;;extracting the attribute

 

                (setq a (vl-string-search "\(" str))                                      ;;the position of the character before the number

                (setq b (vl-string-search "'" str))                                       ;;the position of the character after the number

 

                (setq addnumber (atoi (substr str (+ a 2) (- b (+ a 1)))))    ;; extracting the number using the substring function

                (setq total (+ total addnumber))                                      ;; adding the number and exit or continue the loop

  )

 

(setq total (itoa total))                                                                     ;;copy the number to a clip board

(vlax-invoke

                (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData)

                'setData

                "TEXT"

                total

)

)

Message 6 of 7
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

 

Thank you for your great suggestion Kent, I didnt see that there are two conditions to exit the while loop, "one intentional and an other by missing or hiting the wrong object. so I wanted to modify the code based on your suggestion. .... I wanted to select as many blocks and exist the loop. what @Anonymous suggested me works great in this case. But for the other case which is "missing or hiting the wrong object", It exits not only the loop but also the program. I would rather prefer if the loop continues when such mistakes happen by giving me a message "wrong object, select only blocks with this name". ....


An example of a routine that does that is OffsetAndErase.lsp, available here.  Of course you would check different things about the selected objects and do different things with the appropriate ones after the (while) loop for selection, but it's one way to have it ask again if you either miss or pick the wrong kind of thing, and end the selection when you hit Enter/space, offering <exit> as the default [which you might reword -- <done> or something?], after which a routine can [though this one doesn't] move on to the processing part.

Kent Cooper, AIA
Message 7 of 7
dbroad
in reply to: Anonymous

You're most welcome.  It's nice to help those who are really trying to learn AutoLISP.  Entsel and nentsel are primarily useful if you want to select a single object (or nested object) by pick.  Ssget is better to use if you want to select multiple objects (deliberate miss on first pick).  Then you can check for the existence of a selection set rather than what happens on a single point pick.  Selection set filters can be used to select according to specific criteria.

 

;;Initial prompt for selection

(while (not (setq ss (ssget.....)))

;;followup prompt for selection

)

;;do stuff with selection set.

 

There are also other ways to trap an escape to allow for branching.  VL-CATCH-ALL-APPLY can be used to trap an error and to allow for branching.

Architect, Registered NC, VA, SC, & GA.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


AutoCAD Beta