TunzaGibbo Posted April 14, 2018 Share Posted April 14, 2018 Hi All #(setq Cloud (getstring("\nEnter an Option P or O )))# Can you tell me why this line is producing an error? This is the error: .Cannot invoke (command) from *error* without prior call to (*push-error-using-command*). Converting (command) calls to (command-s) is recommended. However this line works if I substitute it for the one above but obviously it doesn't give me a choice #(setq Cloud O)# Quote Link to comment Share on other sites More sharing options...
Grrr Posted April 14, 2018 Share Posted April 14, 2018 (setq Cloud (progn (initget "P O") (getkword "\nEnter an Option [P/O]: " ))) Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 14, 2018 Share Posted April 14, 2018 Tunzagibbo pick the # not type it or [ c o d e] and [ / c o d e] if you want to type it. Quote Link to comment Share on other sites More sharing options...
TunzaGibbo Posted April 15, 2018 Author Share Posted April 15, 2018 Hi Grrr Thanks for your code I'm still having a bit of a problem here. Can you please help me with this code? I know that by just running the "revcloud" command in Autocad I can make a selection of either P or O, but my Lisp is only part of the bigger picture. If I cut and paste the 2 DEFUNS ("objectcloud" & "polygoncloud") into the Autocad command line they both run fine on their own. It's when I try to combine them into a lisp program that I get the error. It seems to fail when I enter either P or O (defun c: mycloud () (setq Cloud (progn (initget "P O") (getkword "\nEnter an Option [P/O]: " ))) (if (= Cloud O) (objectcloud)) (if (= Cloud P) (polygoncloud)) (defun polygoncloud () (setvar "orthmode" 1) (command-s"._revcloud" "_P") ) (defun objectcloud () (command "._revcloud" "_O" pause "No") ) Quote Link to comment Share on other sites More sharing options...
FranknBeans Posted April 15, 2018 Share Posted April 15, 2018 Because you are storing a string in the variable 'cloud' its value will be either "P" or "O" not P or O (defun c:mycloud ( / Cloud )[color=royalblue] ; localise cloud variable[/color] (initget 1 "P O") (setq Cloud (getkword "\nEnter an Option [P/O]: " )) (if (= Cloud "P") (polygoncloud)[color=royalblue] ; if "P"[/color] (objectcloud)[color=royalblue] ; else "O"[/color] ) ) Quote Link to comment Share on other sites More sharing options...
TunzaGibbo Posted April 15, 2018 Author Share Posted April 15, 2018 This the actual code I am trying to run But still having trouble. (defun c:bbb (/ Cloud) (initget 1 "P O p o") (setq Cloud (getkword "\nEnter an Option [P/O] " )) (if (= Cloud "O") (objectcloud) (polygoncloud)) (defun polygoncloud () (setvar "orthmode" 1) (command-s"._revcloud" "_P") ) (defun objectcloud () (command-s "._revcloud" "_O" pause "No") ) ) Quote Link to comment Share on other sites More sharing options...
FranknBeans Posted April 15, 2018 Share Posted April 15, 2018 (edited) hmm.. it works if you declare the subfunctions first, I didn't know this was an issue, have always just put them at the top by habit. Good idea allowing for upper & lower case, adding strcase will make sure the variable is always capital. (defun c:bbb (/ polygoncloud objectcloud Cloud) (defun polygoncloud () (setvar "orth[color=red]o[/color]mode" 1) (command "._revcloud" "_P") ) (defun objectcloud () (command "._revcloud" "_O" pause "No") ) (initget 1 "P O") (setq Cloud (strcase (getkword "\nEnter an Option [P/O]: "))) (if (= Cloud "O") (objectcloud) (polygoncloud)) (princ) ) Edited April 15, 2018 by FranknBeans formatting Quote Link to comment Share on other sites More sharing options...
TunzaGibbo Posted April 15, 2018 Author Share Posted April 15, 2018 Thanks for your help Frank. All works good now Regards Tony Quote Link to comment Share on other sites More sharing options...
Grrr Posted April 15, 2018 Share Posted April 15, 2018 hmm.. it works if you declare the subfunctions first, I didn't know this was an issue, have always just put them at the top by habit. In this case they appear to be local for the main function, and its important to be declared first - Everything that you put inside in a function (main or sub) is being evaluated from top to bottom order. Exceptions from the default 'top2bottom' order are calling from functions that have been evaluated already. Top to bottom evaluation order applies when apploading the .lsp file aswell, it evaluates all the declared function one by one starting to the top till the bottom is reached. Then once all the main(s) and subfunction(s) are declared/evaluated, you can run the main without any worries for undefined (sub)functions. Notice that when the interpreter evaluates a function, it just checks it content - where potentially you could recieve 'extra left/right paren on input' error, but it DOESN'T run the function (which means running/checking all the evaluations inside): _$ (defun test ( / ) [color="darkgreen"]; <- The function /main/[/color] [color="darkgreen"]; These things will be evaluated from top to bottom order, starting from this row ; <code> ... bla bla[/color] (MyUndefinedFunction [color="darkgreen"]; <- a subfunction we use inside of our main, but we didn't define it anywhere (so the main will try to run it, but will crash because it was never evaluated)[/color] ) [color="darkgreen"]; <- our main should crash at this evaluation, and will stop going thru the next bottom lines [/color] [color="darkgreen"] ; <code> ... bla bla ; we could define/evaluate the subfoo here, but since we already attempted to run it before defining it, we will recieve an error ; (defun MyUndefinedFunction ( / ) <code> .. bla bla)[/color] )[color="darkgreen"]; defun test[/color] TEST [color="darkgreen"]; <- This means our main function evaluated successfuly (no syntax errors)[/color] _$ (test) [color="darkgreen"]; <- Now we run it, it will step through all the evaluations inside (TOP to BOTTOM order)[/color] Error: [color="red"]no function definition[/color]: MYUNDEFINEDFUNCTION [color="darkgreen"]; <- it doesn't recognise it, because we never define it (or we tried to define it after we ran it)[/color] _1$ _$ test [color="darkgreen"]; <- lets check if our main is defined/evaluated[/color] #<USUBR @000000b646f7c570 TEST>[color="darkgreen"] ; <- yes it is[/color] _$ MyUndefinedFunction [color="darkgreen"]; <- lets check if our subfunction is defined/evaluated[/color] nil [color="darkgreen"]; <- no its not[/color] Overall related things in this thread. IMO Anyway in this case its not required, and probably better to avoid defining subfoos. Good idea allowing for upper & lower case, adding strcase will make sure the variable is always capital. Although in my example its not strictly required to check for lower/upper case, I agree that its a good overall practice to perform 'just in case' techniques. ...(initget [color=red]1[/color] "P O")... I wouldn't advise to force user's input, because if he decides to exits you leave no other option than making him to trigger an error. [Time ago Lee pointed that out in my code, when I used (while T ...)] Even here you can trace this bad example from the adsk techs, by calling: (command "._revcloud" "_O") That said, it would be better to pass your own arguments and decide whether to call the "REVCLOUD" command, rather than calling it first and regretting it (instantly) : (defun C:MyCloud nil (eval (cdr (assoc (progn (initget "P O X") (cond ((getkword "\nEnter an Option [P/O/eXit] <O>: " ))("O"))) '( ("O" '( ( / e ) (and (setq e (entsel "\nPick object: ")) (not (vl-catch-all-error-p (vl-catch-all-apply 'vlax-curve-getEndParam (list (car e))))) (command "._REVCLOUD" "_O" e "No" ) ) ) ) ("P" '( (x / v) (setq v (getvar x)) (initcommandversion) (command "._REVCLOUD" "_P") (while (= 1 (logand 1 (getvar 'CMDACTIVE))) (setvar x 1) (command pause)) (setvar x v) ) 'orthomode ) ) ) ) ) (princ) ); defun C:MyCloud (vl-load-com) (princ) I know that the structure of my code would be more readable/simple for someones, if cond function was used rather than assoc, but I just think this was the plain conception when LISP was designed (to use/manipulate/evaluate lists). Quote Link to comment Share on other sites More sharing options...
TunzaGibbo Posted April 15, 2018 Author Share Posted April 15, 2018 Thank you to all involved here I really appreciate your help Regards Tony Quote Link to comment Share on other sites More sharing options...
FranknBeans Posted April 15, 2018 Share Posted April 15, 2018 Thanks Grrr, all useful info to keep in mind Quote Link to comment Share on other sites More sharing options...
TunzaGibbo Posted April 16, 2018 Author Share Posted April 16, 2018 If I could reopen this for a small change I am using this line and it works well but if I wanted to still have the "O" as an option bur have the "P" by hitting the enter key I tried a few things but no luck (setq Cloud (getkword "\nEnter an Option [P/O] " )) (setq Cloud (getkword "\nType O or Default <"P"> " )) Thanks Quote Link to comment Share on other sites More sharing options...
ronjonp Posted April 16, 2018 Share Posted April 16, 2018 If I could reopen this for a small changeI am using this line and it works well but if I wanted to still have the "O" as an option bur have the "P" by hitting the enter key I tried a few things but no luck (setq Cloud (getkword "\nEnter an Option [P/O] " )) (setq Cloud (getkword "\nType O or Default <"P"> " )) Thanks Try something like this: (or (setq cloud (getenv "MyCloud")) (setq cloud "P")) (initget 0 "P O") (setq cloud (setenv "MyCloud" (cond ((getkword (strcat "\nEnter an Option [P/O] <" cloud ">: "))) (cloud) ) ) ) Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 17, 2018 Share Posted April 17, 2018 My $0.05 then I check is it P or O if not do again and change the message second time to reflect incorrect input. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.