nil in lisp routine not working
I have a group lisp routines that needs to just input nil if nothing is found. It doesn't seem to be working. Could someone help me get this to work in Bricscad?
(DEFUN C:SSWD () (SETQ FIL(SSGET "X" (LIST (CONS 8 "DOOR-WINDOW*"))))
(If (Not (= FIL nil))(command "DRAWORDER" FIL "" "BACK")(Setq FIL nil))(princ))
Comments
-
nm I figured out a solution. Just ^C exit the command if nothing is found
(DEFUN C:SSWD () (SETQ FIL(SSGET "X" (LIST (CONS 8 "DOOR-WINDOW*"))))
(If (Not (= ^C))(command "DRAWORDER" FIL "" "BACK")(Setq FIL nil))(princ))0 -
better format would be:
(DEFUN C:SSWD ( / FIL)
(SETQ FIL (SSGET "X" (LIST (CONS 8 "DOOR-WINDOW*"))))
(If FIL (command "DRAWORDER" FIL "" "BACK"))
(princ))The (If (Not (= ^C)) makes no sense, you did not compare ^C to anything, so don't do that.
Putting FIL after / like ( / FIL) is how you "localize" a var in lisp. No need to set to nil in code.0 -
Ahh ok. I just wasn't sure. The ^C was ugly but worked so now I can make it correct and coherent . So it will only run the command if FIL has data correct?
Thank you,
Russell0 -
@betazero
Yes. I can tell you are new to lisp, and glad you are trying.
One thing to know, you can copy a chunk of code to the command line and see the return.
if you do (setq ss (ssget)) and select nothing, you see nil.
The IF format for lisp only allows two statements after. the first is if true, then false.
If you want to run multiple things for say, true, your group them with a (PROGN....) like:
(PROGN
...do this and that...
)that makes lisp treat it like one statement.
thx0 -
I have tons of lisp routines but have not gotten into the small programs as much with IF statements etc. Where would you put the false after the IF? In another set of ()?
Thanks,
Russell0 -
Yes, like
(if (set ss (ssget))
(progn
(princ (strcat "\nCount was " (itoa (sslength ss))))
(princ "another line...")
)
(princ "\nNothing Selected")
)If you wanted to do multiple if's like in C# where you do if, else if, else if, else...
You can use COND for that, as it exits once a true condition is found, just like the elses.one critical thing with lisp - use eitehr the VLIDE in acad or bcad, as it allows easy paren matching.
You double click before or after a paren, and it highlights to the opening or closing paren.
Other text editors do similar, but not as well IMO.
I'd be happy to do an online meeting to demo that. Let me know if you do. Im in california so needs to be when I am awake.0 -
Changed to below but there is nothing on Format layer and the lisp fails then trys to run BACK as a command...
(DEFUN C:SSFORMAT (/ FIL)
(SETQ FIL(SSGET "X" (LIST (CONS 8 "FORMAT"))))
(If FIL (command "DRAWORDER" FIL "" "BACK"))
(princ))0 -
Hello,
try
(DEFUN C:SSFORMAT (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "FORMAT")))) (print FIL) (If FIL (command "DRAWORDER" FIL "" "BACK")) (princ) )
to print what FIL is ...
seems, the (ssget "X" ...) did find some objects on layer "FORMAT" ?
But if such object(s) are on locked layer "FORMAT", then the DRAWORDER command will remove those entities on any locked layer, which might result in an empty selectionset ... then, the end-of-selection by "" will finish the DRAWORDER command (as nothing selected), and results in an out-of-sync "BACK" command ...hope this helps a bit ?
0 -
good call Torsten. I guess I am assuming we are operating in a clean situation.
If not, heck, someone could redefine the draworder command and really git yah!
There is a way to handle that (the locked layer issue) though. We run into this with plotting and a few other things.
You can check the CMDACTIVE var, like
(If FIL
(progn
(command "DRAWORDER" FIL ""))
(IF (= (GETVAR "CMDACTIVE") 1)
(command "back")
)
)
)
darn forum program, should look like this:0 -
No I don't use locked layers. Maybe like 10 years ago but nope not anymore. The lisp fails when it doesn't find anything on a certain layer and instead of exiting it just keeps running down the lines of the code which then bombs because back isn't a command. You have to try this as a command in a .lsp file. It seems to run fine when you copy paste code to the command line. I will try the new one you sent to see if it works differently.
0 -
@betazero
Post your current lisp please. You can walk through the lines by copy and paste style and they should shake things out.
It sounds like you are running old code or something on accident.0 -
-
@Torsten Moses
I tried that formatting with limited success in the past. Is that something actively being worked on, or limited to what the forum provider offers as standard?0 -
Dear James,
actually that "Code" formatting seems to work (even with coloring) ... primarily we use a a forum system from a provider
(but I seems to remember that there are plans to reqork it ... ).
many greetings !0 -
Ok I changed to the code Torsten posted and it works. Not sure if maybe I had something messed up with what you posted James. I do like how Torstens displays a NIL when nothing was found.
Thank you both for your help. This is a very important part of my layer display order.
0 -
This is killing me....It fails again around the 5th one. SS1 is the main lisp which runs thru the others. Is there something I am doing wrong?
(DEFUN C:SS1 () (C:SSWD)(C:SSWE)(C:SSWEL)(C:SSC)(C:SSWES)(C:SSDOORI)(C:SSWE)(C:SSWI)(C:SSCOF)(C:SSSOFFIT)(C:SSST)(C:SSCA)(C:SSAP)(C:SSSTEP)(C:SSCURB)(C:SSWH)(C:SSWP)(C:SSPOOL)(C:SSWNEW)
(DEFUN C:SSWD (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "DOOR-WINDOW"))))
(print FIL)(If FIL (command "DRAWORDER" FIL "" "BACK"))(princ))
(DEFUN C:SSWE (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "WALL-EXTERIOR"))))
(print FIL)(If FIL (command "DRAWORDER" FIL "" "BACK"))(princ))
(DEFUN C:SSWEL (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "WALL-EXTERIOR-LOW"))))
(print FIL)(If FIL (command "DRAWORDER" FIL "" "BACK"))(princ))
(DEFUN C:SSC (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "COLUMN*"))))
(print FIL)(If FIL (command "DRAWORDER" FIL "" "BACK"))(princ))fails on this one for some reason.... The WEL also does not find anything and outputs NIL. If I put something on the column layer it gets further again then fails....
- DRAWORDER
Select entities to change draw order [selection options (?)]:
8 found.
Entities in set: 8
Select entities to change draw order [selection options (?)]:
Change draw order [Above/Under/Clear all orders/bring to Front/send to Back] :BACK - DRAWORDER
Select entities to change draw order [selection options (?)]:
6 found.
Entities in set: 6
Select entities to change draw order [selection options (?)]:
Change draw order [Above/Under/Clear all orders/bring to Front/send to Back] :BACK
NIL - DRAWORDER
Select entities to change draw order [selection options (?)]:
12 entities are not in the current space.
12 found.
Select entities to change draw order [selection options (?)]: - BACK
Unable to recognize command "BACK". This error can occur when the command is not supported for the active license.BLANKTXT: Function cancelled
0 - DRAWORDER
-
@betazero
You are getting caught in the trap of not knowing lisp well enough to troubleshoot.
Please stick with it, as this is how you get out, and hopefully then grow as far as you want.
The thinking to troubleshoot needs to go like this:
1) I am getting a sel set by filter. Is that working?
To test on a given filter that seems to have issues, try on command line.
(SETQ FIL(SSGET "X" (LIST (CONS 8 "WALL-EXTERIOR-LOW"))))
BTW, you should have a space between FIL and (SSGET...
What does that spit out on command line? You need to tell us, but likely you won't need to once you get the hang of this.2) if you get something other than nil for step 1, did you get the number of entities expected?
to answer that, use this code on command line:
(princ (strcat "\n SS count is:" (itoa (sslength FIL))))
the itoa command converts an integer to string, as princ wants strings.
strcat is the "add these strings together" function3) is there a problem with modifying those entities?
try an erase command on them, say P for previous, or !FIL
did that erase what you expected? undo of course.by the time you get to that, you should have a feel for the issue.
You need to learn a few functions that give feedback during the command, that reveal what is going on.I sometimes take that much further, where I get the bounding box of each entity and draw it, or report what was selected on command line.
All that needs skills to access the data, typically using ENTGET on each item, and formatting it as a string for command line.That is all slow debugging though. Once you learn to set a breakpoint using the BLADE (VLIDE in acad), you can fix stuff 20x faster without a bunch of debug code cluttering your function. I deal with thousands of lines of code for certain things and can run right down rabbit holes and out with the debugger. Its not that hard but best if someone demonstrates it on screen.
0 -
Hello, betazero,
this message indicates the problem :
"DRAWORDER
Select entities to change draw order [selection options (?)]:
12 entities are not in the current space.
12 found."to understand, that (ssget "X" filter) as you use it will scan the entire database, and collect entities from specified layer(s) ...
therefore, it can also collect entities located on such layers, being located on other layouts (!) - and those are filtered-out by DRAWORDER command, which might result in an empty selection, hence DRAWORDER finishes - leaving "BACK" as a pending command then.Solution would need 2 things :
a)
add the "actual layout" to your filter - (LIST (CONS 8 "WALL-EXTERIOR") (cons 410 (getvar "CTAB"))) )
b)
additionally check that selectionset is not empty :
(If (and FIL (> (sslength FIL) 0)) (command "DRAWORDER" FIL "" "BACK"))(princ))for extreme safety, you could put the foreground/background/xxx option into a separate (command) statement, like this way
(command "DRAWORDER" FIL "")
(if (> (getvar "CMDACTIVE") 0) (command "_BACK"))this means, if DRAWORDER finishes prematurely (as no valid entities found in the non-empty selectionset), then (getvar "CMDACTIVE") will be 0;
otherwise, DRAWORDER is still active, expecting the next option ...hope this will help you a bit ?
many greetings !0 -
@Torsten Moses
but of course, good catch.
Yes, the "X" searches the whole universe, including your inner thoughts!
filter that baby with group 410.
BTW, those troubleshooting steps would catch this. When you erased or moved the items from selection set, you would see nothing move.
Lisp is this way. Very slow to learn on your own, but fast with someone, and once you get to a certain level.0 -
James I don't need to be told I am new to Lisp. Yes I am new to Bricscad Lisp quirks and the more advanced stuff I am not as familiar. But I have been using Lisp forever (over 15+ years?...god I'm old...)... One of the main reasons Bricscad is so appealing. These routines have worked for over 10+ years so I have not needed to do anything with them. Never ever did they fail in Autocad so I am just trying to get them to work here.
How do I just ignore paper space? I really just need it to do its thing in model space. I think I will try option b to see if that works and add the safety thing in there.
0 -
I did just the safety thing and instead of trying to run Back it just breaks the LISP. It does not go to the next lisp. I will try option "b" now.
(DEFUN C:SSWD (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "DOOR-WINDOW*"))))
(print FIL)(If FIL (command "DRAWORDER" FIL ""))(if(>(getvar "CMDACTIVE")0)(command "_BACK"))(princ))- DRAWORDER
Select entities to change draw order [selection options (?)]:
8 entities are not in the current space.
8 found.
Select entities to change draw order [selection options (?)]: BLANKTXT: Function cancelled
0 - DRAWORDER
-
With option "b" and safety thing and it still doesn't work once it hits an entity on paperspace.
(DEFUN C:SSWD (/ FIL) (SETQ FIL(SSGET "X" (LIST (CONS 8 "DOOR-WINDOW*"))))
(print FIL)(If(and FIL(> (sslength FIL)0))(command "DRAWORDER" FIL ""))(if(>(getvar "CMDACTIVE")0)(command "_BACK"))(princ))I think I just need to ignore paper space . How can I do that? I guess that's option "a" ?
0 -
Ok geez got it
(DEFUN C:SSWD (/ FIL) (SETQ FIL(SSGET "_X"(LIST (CONS 8 "DOOR-WINDOW*")(CONS 410 "MODEL"))))
(print FIL)(If(and FIL(> (sslength FIL)0))(command "DRAWORDER" FIL ""))(if(>(getvar "CMDACTIVE")0)(command "_BACK"))(princ))Now it just totally ignores paperspace. I guess I can remove the extra stuff in there now. One great thing is that it works a lot faster now!
Thank you , Torsten, James and Google.
Ok final cleaned up and working perfect now
(DEFUN C:SSWD (/ FIL) (SETQ FIL(SSGET "_X"(LIST (CONS 8 "DOOR-WINDOW*")(CONS 410 "MODEL"))))
(If FIL (command "DRAWORDER" FIL "" "BACK"))(princ))0 -
Hi betazero,
best to keep that filtering by (CONS 410 "MODEL") in mind :-)
There are most likely more "core commands" (like DRAWORDER) which filter-out entities from non-active layout ...
And, it is not about "modelspace" or "paperspace" - but about the active layout (each entity has that dxf 410 group, defining to which layout is belongs).If a command only uses the entities from active layout, it can indeed happen that the internally-final selectionset is empty - and some commands then assume "all done" ...
meanins,
a) using dxf 410 filtering
and
b) (If (and FIL (> (sslength FIL) 0)) (command "DRAWORDER" FIL "" "BACK"))(princ))seems most safe :-)
many greetings !0 -
@Torsten Moses
I don't think the (SSLENGTH FIL) helps though, as the nil test covered that, and its the "other space" issue at hand.
I know you know that, just saying for the OP.
In this draworder case, the space filter is king and again, great catch on that.0 -
Yea the safety test really didn't solve the problem. It wasn't until I excluded paperspace or limited it to the current layout that it worked flawlessly. Autocad must handle this automatically or something which is why it worked in Autocad but not here.
Thanks again. I literally use these draw order commands 10-20 times a day. I have a mental breakdown if a hatch pattern is over a line
0 -
James...James...waz up...
0 -
@RudyT
??? The Tovar???
Shall we meet for pizza again and inspire another 20 years of software ideas?
You recall, you convinced me the "find perp intersection of pt to line and arc" was possible (for me) conversation?
That allowed me to make a parallel system to old Land Desktop and that grew to replace most of Civil3D for us.
Now I'm doing triangle manipulation for cleaning up surfaces from drone point clouds, all on both Acad/Bricscad. Its one code base.0 -
Dear James,
I don't think the (SSLENGTH FIL) helps though, as the nil test covered that,
yes, "normally" an empty selectionset should be NIL :-) But who knows, whether i.e. external BRX code returns an empty selection sometimes, with OK status ? So that extra check for 0 length is just a safety measure, for the exotic & unexpected cases :-)
Dear betazero
Autocad must handle this automatically or something which is why it worked in Autocad but not here.
due to my knowledge, the (ssget "X" ...) also + always scans the entire dwg database ... and I remember cases where the 410 layout filter was necessary in AutoCAD as well.
many greetings !
0 -
@Torsten Moses
Good points. I think this thread was about solving a minor issue that was causing a big issue, and how the OP is not up the learning curve enough to troubleshoot that. All these comments on checking for 0 length ss and so on are very useful for many routines and I hope the OP is encouraged enough by replies here to pursue LISP a bit more, especially with the marshall law lockdowns going on these days.0