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

If statement?

51 REPLIES 51
Reply
Message 1 of 52
Anonymous
582 Views, 51 Replies

If statement?

I have written the following lisp, but am unsure how to go about adding a
section to it. If no object is selected show "\nNo entities selected" on
the command line and then repeat the entsel process. I think I should be
using an if statement. Any hints are appreciated
;one click break
(defun c:bb ()
(command ".break" (ENTSEL "\nSelect object to break") "F" (GETPOINT
"\nSelect point to break at" "@"))
(princ)
)

Thank you,
Beau Turner
51 REPLIES 51
Message 21 of 52
Anonymous
in reply to: Anonymous

Hey Jason, the advantage with the ERRNO method is that you are able to
differentiate between a user mispick and the user hitting an enter.
--
Bobby C. Jones
Dots & Parens living in harmony...
http://www.acadx.com
Message 22 of 52
Anonymous
in reply to: Anonymous

> Nice tutorial Bobby.

thanks for the compliment Doug. I consider yours a big one coming from
someone in the education field 🙂

> Can't get the final routine to work however. No matter what I
> pick for the break, it doesn't exit the object select loop. Am running
AC2000 with Arch
> Desktop 2.
> Errno should work but doesn't on my system. Anyone else experience the
problem?

There was an error in my 'final' version. Please see my reply to Beau.

> And don't forget another possibility
>
> E) User selected an object not supported by the command.
> In this case blocks, text....
>
> That's where filtering the selection is important.
>
> (while (null (setq ss (ssget ":s" (list (cons 0
> "line,arc,circle,trace,lwpolyline,spline,"))))))
> could be better, filtering out incorrect object selection of insert, xref,
text....)
>

looks like (ssget ":s") and ERRNO could be a killer combination 🙂
--
Bobby C. Jones
Dots & Parens living in harmony...
http://www.AcadX.com
Message 23 of 52
Anonymous
in reply to: Anonymous

It works with no problems on my system. NT 4 ADT 3.3

It is amazing how far such a seemingly simple idea goes for the interest of
good & proper coding.....

Beau


Doug Broad wrote in message
news:2F74E5F686EACD0F88C83B977C7AEA0C@in.WebX.maYIadrTaRb...
> Nice tutorial Bobby.
>
> Can't get the final routine to work however. No matter what I
> pick for the break, it doesn't exit the object select loop. Am running
AC2000 with Arch
> Desktop 2.
> Errno should work but doesn't on my system. Anyone else experience the
problem?
>
> And don't forget another possibility
>
> E) User selected an object not supported by the command.
> In this case blocks, text....
>
> That's where filtering the selection is important.
>
> (while (null (setq ss (ssget ":s" (list (cons 0
> "line,arc,circle,trace,lwpolyline,spline,"))))))
> could be better, filtering out incorrect object selection of insert, xref,
text....)
>
> Or entget could be used to get entity info from entsel ename and filter an
incorrect
> entity
> type prior to feeding to command.
>
> Doug
>
>
>
> "Bobby Jones" wrote in message
> news:40894B0A7B5E96C308F318FA7D85D1F5@in.WebX.maYIadrTaRb...
> > Several things can happen when you are asking the user to select an
object
> > with ENTGET.
> >
> > A) they will successfully select an object
> > B) they will mis-pick and select empty space in the drawing
> > C) they will hit enter to exit out of the selection process
> > D) they will hit escape to exit out of the entire routine
> >
> > Your routine should be smart enough to catch all of those events and
handle
> > them. The sign of a good lisp routine is one that emulates how acad
> > commands function so that the user has a consistent interface. So start
the
> > break command and see what it does in each of the four situations above.
If
> > the user selects an object, the routine runs with that object. If the
user
> > mis-picks, it asks him to select again. If they hit enter or escape the
> > command simply exits, with the exception that hitting escape prints
*Cancel*
> > to the command line. I think what you're really asking is how to do
that.
> > Let's re-write your routine and see just how to accomplish this.
> >
> > While ENTSEL honors keywords set up with the INITGET function, it does
not
> > honor the no null bit, so we will need to set up a while loop.
Basically we
> > are saying, "While the user hasn't selected anything, keep asking."
> > (while (not ent)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> >
> > Then you can ask for a break point on the line with GETPOINT. GETPOINT
does
> > honor the no null bit of INITGET, so use it.
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> >
> > Finally feed all this collected info to the break command.
> > (command "_.break" ent "f" pnt pnt)
> >
> > Also, since we are collecting all needed information prior to calling
the
> > COMMAND function, we will want to suppress any output to the command
line
> > from the actuall break command. Do this by setting the CMDECHO sysvar
to 0,
> > and then setting it back at the end of the routine. A nice clean exit
with
> > PRINC is always a nice touch.
> >
> > The complete function:
> > ((defun c:bb (/ ent pnt cmd)
> > (setq cmd (getvar "cmdecho"))
> > (setvar "cmdecho" 0)
> > (while (not ent)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> > (command "_.break" ent "f" pnt pnt)
> > (setvar cmdecho cmd)
> > (princ)
> > )
> >
> > Wow. That little function has really grown. Give it a try. How does
it
> > handle all the possible events listed above? It works beautifully when
the
> > user selects the line...Yea. It asks for a re-pick when they mis-pick
the
> > line...Yea. What? It won't exit the selection process when they hit
enter?
> > And WHAT!!!???!!! It leaves the CMDECHO sysvar set to 0 when they hit
> > escape??!!?? That's totally unacceptable. Let's fix it. First lets
fix
> > that escape key bug. Yes, it's a bug in your routine. To fix the bug
you
> > will need to implement a custom *error* handler. There has been much
> > discussion on this topic in the recent past, so I'm just going to put
one in
> > and let you either do the research yourself or come back and ask
specific
> > questions:
> >
> > The routine with the custom *error* handler:
> > (defun c:bb (/ ent pnt cmd *error*)
> >
> > (defun *error* (msg)
> > (if (not (member Msg '(nil "console break" "Function cancelled"
"quit /
> > exit abort")))
> > (princ (strcat "\nError: " Msg))
> > )
> > (setvar "cmdecho" cmd)
> > (princ)
> > )
> >
> > (setq cmd (getvar "cmdecho"))
> > (setvar "cmdecho" 0)
> > (while (not ent)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> > (command "_.break" ent "f" pnt pnt)
> > (*error* nil)
> > )
> >
> > Wow. Now our little function can't really be called a "little" function
> > anymore. Okay, so is it ready for prime time now? Well, give it a test
run
> > and see. How'd it do? You mean it still doesn't exit when the user
hits
> > enter while selecting an object? Well that's not so bad, is it? For
many
> > that's good enough, but I can tell that you're a perfectionist and that
you
> > want this thing perfect. So let's fix this one more time. Currently
our
> > function doesn't distinguish between a user mispick on the screen and
the
> > user hitting the enter key, or spacebar. All it knows is that nothing
was
> > selected and it wants something. The answer for how to determine the
> > difference between a mispick and an enter key lies in the ERRNO sysvar.
> > When ENTSEL fails with a user mispick, ERRNO is set to 7. Looking up
ERRNO
> > in the help files reveals a chart that lists error #7 as, "Object
selection:
> > pick failed". But when ENTSEL fails with a user hitting enter, ERRNO is
set
> > to 52, "Entity selection: null response". We can now use that in our
while
> > loop to determine why ENTSEL failed. Instead of looping until our
variable
> > 'ent' contains something, we can loop as long as the user mis-picks,
while
> > ERRNO = 7, and stop our loop only when they pick an object or if they
hit
> > enter, ERRNO = 52. Then we'll need to test our 'ent' variable to see if
the
> > user did indeed select an object or just hit enter. If they simply hit
> > enter, then we'll want to skip the code that asks for the break point
and
> > runs the break command.
> >
> > Final routine:
> > (defun c:bb (/ ent pnt cmd *error*)
> >
> > (defun *error* (msg)
> > (if (not (member Msg '(nil "console break" "Function cancelled"
"quit /
> > exit abort")))
> > (princ (strcat "\nError: # " (itoa (getvar "errno")) Msg))
> > )
> > (setvar "errno" 0)
> > (setvar "cmdecho" cmd)
> > (princ)
> > )
> >
> > (setq cmd (getvar "cmdecho"))
> > (setvar "cmdecho" 0)
> > (setvar "errno" 7)
> > (while (= (getvar "errno") 7)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> > (if ent
> > (progn
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> > (command "_.break" ent "f" pnt pnt)
> > )
> > )
> > (*error* nil)
> > )
> >
> > Now that wasn't so hard, was it?
> > --
> > Bobby C. Jones
> > Dots & Parens living in harmony...
> >
> >
> >
>
>
Message 24 of 52
Anonymous
in reply to: Anonymous

Ya, Now it vurks!

The approach is novel and has great applications. For this little problem, however,
I think I'll keep my simpleminded approach:

(defun c:bb()(command "break" pause "f" pause)(princ))

Other way's too much typing for me. Ouch.

Thanks again.

Doug

"Bobby C. Jones" wrote in message news:A1961FC10F9A2AC1FEFEAB71E9A42AE7@in.WebX.maYIadrTaRb...
> > Nice tutorial Bobby.
>
> thanks for the compliment Doug. I consider yours a big one coming from
> someone in the education field 🙂
>
> > Can't get the final routine to work however. No matter what I
> > pick for the break, it doesn't exit the object select loop. Am running
> AC2000 with Arch
> > Desktop 2.
> > Errno should work but doesn't on my system. Anyone else experience the
> problem?
>
> There was an error in my 'final' version. Please see my reply to Beau.
>
> > And don't forget another possibility
> >
> > E) User selected an object not supported by the command.
> > In this case blocks, text....
> >
> > That's where filtering the selection is important.
> >
> > (while (null (setq ss (ssget ":s" (list (cons 0
> > "line,arc,circle,trace,lwpolyline,spline,"))))))
> > could be better, filtering out incorrect object selection of insert, xref,
> text....)
> >
>
> looks like (ssget ":s") and ERRNO could be a killer combination 🙂
> --
> Bobby C. Jones
> Dots & Parens living in harmony...
> http://www.AcadX.com
>
>
Message 25 of 52
Anonymous
in reply to: Anonymous

----------------------------------------------------------------------------
-
One other thought, what about when the user selects something that can't be
broken, such as a block. Hmm...seems as though our work is never done.
Anyone else care to give this scenario a shot?
--
Bobby C. Jones
Dots & Parens living in harmony...
----------------------------------------------------------------------------

Can't figure out how to do this with errno involved.
How about a little hint.




--
Ken Alexander
Acad2000
Win2000prof.

------------------------------------------
"Bobby Jones" wrote in message
news:8EFA6A96A816D72763A52D4821FA4098@in.WebX.maYIadrTaRb...
> Before everyone rushes out to buy any books from me, please note that
> there's an error in my 'final' code 🙂 To ensure that our ERRNO sysvar
is
> always reset to zero, we must include (setvar "ERRNO" 0) as the first line
> of code in our loop. Here is the corrected final routine:
> (defun c:bb (/ ent pnt cmd *error*)
>
> (defun *error* (msg)
> (if (not (member Msg '(nil "console break" "Function cancelled" "quit
/
> exit abort")))
> (princ (strcat "\nError: # " (itoa (getvar "errno")) Msg))
> )
> (setvar "errno" 0)
> (setvar "cmdecho" cmd)
> (princ)
> )
>
> (setq cmd (getvar "cmdecho"))
> (setvar "cmdecho" 0)
> (setvar "errno" 7)
> (while (= (getvar "errno") 7)
> (setvar "errno" 0)
> (setq ent (entsel "\nSelect object to break: "))
> )
> (if ent
> (progn
> (initget 1)
> (setq pnt (getpoint "\nSelect break point: "))
> (command "_.break" ent "f" pnt pnt)
> )
> )
> (*error* nil)
> )
>
> One other thought, what about when the user selects something that can't
be
> broken, such as a block. Hmm...seems as though our work is never done.
> Anyone else care to give this scenario a shot?
> --
> Bobby C. Jones
> Dots & Parens living in harmony...
>
>
>
Message 26 of 52
Anonymous
in reply to: Anonymous

> simple idea goes for the interest of good & proper coding.....

That is just the tip of the iceberg.

-Jsson


"Beau Turner" wrote in message
news:22EB93B3BFF74A2DF5D0CE9AD642CCA7@in.WebX.maYIadrTaRb...
> It works with no problems on my system. NT 4 ADT 3.3
>
> It is amazing how far such a seemingly simple idea goes for the interest
of
> good & proper coding.....
>
> Beau
>
>
> Doug Broad wrote in message
> news:2F74E5F686EACD0F88C83B977C7AEA0C@in.WebX.maYIadrTaRb...
> > Nice tutorial Bobby.
> >
> > Can't get the final routine to work however. No matter what I
> > pick for the break, it doesn't exit the object select loop. Am running
> AC2000 with Arch
> > Desktop 2.
> > Errno should work but doesn't on my system. Anyone else experience the
> problem?
> >
> > And don't forget another possibility
> >
> > E) User selected an object not supported by the command.
> > In this case blocks, text....
> >
> > That's where filtering the selection is important.
> >
> > (while (null (setq ss (ssget ":s" (list (cons 0
> > "line,arc,circle,trace,lwpolyline,spline,"))))))
> > could be better, filtering out incorrect object selection of insert,
xref,
> text....)
> >
> > Or entget could be used to get entity info from entsel ename and filter
an
> incorrect
> > entity
> > type prior to feeding to command.
> >
> > Doug
> >
> >
> >
> > "Bobby Jones" wrote in message
> > news:40894B0A7B5E96C308F318FA7D85D1F5@in.WebX.maYIadrTaRb...
> > > Several things can happen when you are asking the user to select an
> object
> > > with ENTGET.
> > >
> > > A) they will successfully select an object
> > > B) they will mis-pick and select empty space in the drawing
> > > C) they will hit enter to exit out of the selection process
> > > D) they will hit escape to exit out of the entire routine
> > >
> > > Your routine should be smart enough to catch all of those events and
> handle
> > > them. The sign of a good lisp routine is one that emulates how acad
> > > commands function so that the user has a consistent interface. So
start
> the
> > > break command and see what it does in each of the four situations
above.
> If
> > > the user selects an object, the routine runs with that object. If the
> user
> > > mis-picks, it asks him to select again. If they hit enter or escape
the
> > > command simply exits, with the exception that hitting escape prints
> *Cancel*
> > > to the command line. I think what you're really asking is how to do
> that.
> > > Let's re-write your routine and see just how to accomplish this.
> > >
> > > While ENTSEL honors keywords set up with the INITGET function, it does
> not
> > > honor the no null bit, so we will need to set up a while loop.
> Basically we
> > > are saying, "While the user hasn't selected anything, keep asking."
> > > (while (not ent)
> > > (setq ent (entsel "\nSelect object to break: "))
> > > )
> > >
> > > Then you can ask for a break point on the line with GETPOINT.
GETPOINT
> does
> > > honor the no null bit of INITGET, so use it.
> > > (initget 1)
> > > (setq pnt (getpoint "\nSelect break point: "))
> > >
> > > Finally feed all this collected info to the break command.
> > > (command "_.break" ent "f" pnt pnt)
> > >
> > > Also, since we are collecting all needed information prior to calling
> the
> > > COMMAND function, we will want to suppress any output to the command
> line
> > > from the actuall break command. Do this by setting the CMDECHO sysvar
> to 0,
> > > and then setting it back at the end of the routine. A nice clean exit
> with
> > > PRINC is always a nice touch.
> > >
> > > The complete function:
> > > ((defun c:bb (/ ent pnt cmd)
> > > (setq cmd (getvar "cmdecho"))
> > > (setvar "cmdecho" 0)
> > > (while (not ent)
> > > (setq ent (entsel "\nSelect object to break: "))
> > > )
> > > (initget 1)
> > > (setq pnt (getpoint "\nSelect break point: "))
> > > (command "_.break" ent "f" pnt pnt)
> > > (setvar cmdecho cmd)
> > > (princ)
> > > )
> > >
> > > Wow. That little function has really grown. Give it a try. How does
> it
> > > handle all the possible events listed above? It works beautifully
when
> the
> > > user selects the line...Yea. It asks for a re-pick when they mis-pick
> the
> > > line...Yea. What? It won't exit the selection process when they hit
> enter?
> > > And WHAT!!!???!!! It leaves the CMDECHO sysvar set to 0 when they hit
> > > escape??!!?? That's totally unacceptable. Let's fix it. First lets
> fix
> > > that escape key bug. Yes, it's a bug in your routine. To fix the bug
> you
> > > will need to implement a custom *error* handler. There has been much
> > > discussion on this topic in the recent past, so I'm just going to put
> one in
> > > and let you either do the research yourself or come back and ask
> specific
> > > questions:
> > >
> > > The routine with the custom *error* handler:
> > > (defun c:bb (/ ent pnt cmd *error*)
> > >
> > > (defun *error* (msg)
> > > (if (not (member Msg '(nil "console break" "Function cancelled"
> "quit /
> > > exit abort")))
> > > (princ (strcat "\nError: " Msg))
> > > )
> > > (setvar "cmdecho" cmd)
> > > (princ)
> > > )
> > >
> > > (setq cmd (getvar "cmdecho"))
> > > (setvar "cmdecho" 0)
> > > (while (not ent)
> > > (setq ent (entsel "\nSelect object to break: "))
> > > )
> > > (initget 1)
> > > (setq pnt (getpoint "\nSelect break point: "))
> > > (command "_.break" ent "f" pnt pnt)
> > > (*error* nil)
> > > )
> > >
> > > Wow. Now our little function can't really be called a "little"
function
> > > anymore. Okay, so is it ready for prime time now? Well, give it a
test
> run
> > > and see. How'd it do? You mean it still doesn't exit when the user
> hits
> > > enter while selecting an object? Well that's not so bad, is it? For
> many
> > > that's good enough, but I can tell that you're a perfectionist and
that
> you
> > > want this thing perfect. So let's fix this one more time. Currently
> our
> > > function doesn't distinguish between a user mispick on the screen and
> the
> > > user hitting the enter key, or spacebar. All it knows is that nothing
> was
> > > selected and it wants something. The answer for how to determine the
> > > difference between a mispick and an enter key lies in the ERRNO
sysvar.
> > > When ENTSEL fails with a user mispick, ERRNO is set to 7. Looking up
> ERRNO
> > > in the help files reveals a chart that lists error #7 as, "Object
> selection:
> > > pick failed". But when ENTSEL fails with a user hitting enter, ERRNO
is
> set
> > > to 52, "Entity selection: null response". We can now use that in our
> while
> > > loop to determine why ENTSEL failed. Instead of looping until our
> variable
> > > 'ent' contains something, we can loop as long as the user mis-picks,
> while
> > > ERRNO = 7, and stop our loop only when they pick an object or if they
> hit
> > > enter, ERRNO = 52. Then we'll need to test our 'ent' variable to see
if
> the
> > > user did indeed select an object or just hit enter. If they simply
hit
> > > enter, then we'll want to skip the code that asks for the break point
> and
> > > runs the break command.
> > >
> > > Final routine:
> > > (defun c:bb (/ ent pnt cmd *error*)
> > >
> > > (defun *error* (msg)
> > > (if (not (member Msg '(nil "console break" "Function cancelled"
> "quit /
> > > exit abort")))
> > > (princ (strcat "\nError: # " (itoa (getvar "errno")) Msg))
> > > )
> > > (setvar "errno" 0)
> > > (setvar "cmdecho" cmd)
> > > (princ)
> > > )
> > >
> > > (setq cmd (getvar "cmdecho"))
> > > (setvar "cmdecho" 0)
> > > (setvar "errno" 7)
> > > (while (= (getvar "errno") 7)
> > > (setq ent (entsel "\nSelect object to break: "))
> > > )
> > > (if ent
> > > (progn
> > > (initget 1)
> > > (setq pnt (getpoint "\nSelect break point: "))
> > > (command "_.break" ent "f" pnt pnt)
> > > )
> > > )
> > > (*error* nil)
> > > )
> > >
> > > Now that wasn't so hard, was it?
> > > --
> > > Bobby C. Jones
> > > Dots & Parens living in harmony...
> > >
> > >
> > >
> >
> >
>
>
Message 27 of 52
Anonymous
in reply to: Anonymous

Bullet-proofing the custom break command requires more than mentioned:

1. You can't break a circle at the same point because arcs can't be a full
360 degrees
2. OSMODE - The user may have overridden with "Non" but the (command ...)
will honor running osnaps.
3. There are custom objects that the break command can be used on, eg.
AECC_CONTOURs.
4. Checking for locked layers.

All in all, I wonder if the simple menu macro was good enough.
But, here's some of the fixits, based on the theory that most things that
can be broken can be offset (or vice versa). Anyone is free to add more
conditions to the object_ok function.

(defun c:ba (/ ent etype pnt cmd *error* os object_ok)
(defun *error* (msg)
(if (not (member Msg '(nil "console break" "Function cancelled" "quit /
exit abort")))
(princ (strcat "\nError: # " (itoa (getvar "errno")) Msg))
)
(setvar "errno" 0)
(setvar "cmdecho" cmd)
(setvar "osmode" os)
(princ)
)
(defun object_ok (e / ent etype flag layer locked)
(setq ent (entget e)
etype (cdr (assoc 0 ent))
layer (cdr (assoc 8 ent))
flag (cdr (assoc 70 ent))
locked (= (logand (cdr (assoc 70 (tblsearch "layer" layer))) 4) 4)
bad (cond
((= etype "CIRCLE") T)
((= etype "TRACE") nil)
((and (= etype "POLYLINE")(/= (logand flag 16) 16)) nil) ;
3DMesh
((not (vlax-method-applicable-p (vlax-ename->vla-object e)
"Offset")) T)
)
)
(cond
(bad (prompt " Object can't be broken."))
(locked (prompt (strcat " Layer \"" layer "\" is locked.")))
(1 T)
)
)
(setq cmd (getvar "cmdecho")
os (getvar "osmode")
)
(setvar "cmdecho" 0)
(setvar "errno" 0)
(while (/= (getvar "errno") 52)
(if (setq ent (entsel "\nSelect object to break: "))
(if (object_ok (car ent))
(if (setq pnt (getpoint "\nSelect break point: "))
(progn
(setvar "osmode" 0)
(command "_.break" ent "_f" pnt pnt)
(setvar "osmode" os)
(setvar "errno" 52)
)
)
)
)
)
(*error* nil)
)


--
John Uhden, Cadlantic/formerly CADvantage
--> mailto:juhden@cadlantic.com
--> http://www.cadlantic.com
2 Village Road
Sea Girt, NJ 08750
Tel. 732-974-1711
FAX 732-528-1332

"Bobby C. Jones" wrote in message
news:A1961FC10F9A2AC1FEFEAB71E9A42AE7@in.WebX.maYIadrTaRb...
> > Nice tutorial Bobby.
>
> thanks for the compliment Doug. I consider yours a big one coming from
> someone in the education field 🙂
>
> > Can't get the final routine to work however. No matter what I
> > pick for the break, it doesn't exit the object select loop. Am running
> AC2000 with Arch
> > Desktop 2.
> > Errno should work but doesn't on my system. Anyone else experience the
> problem?
>
> There was an error in my 'final' version. Please see my reply to Beau.
>
> > And don't forget another possibility
> >
> > E) User selected an object not supported by the command.
> > In this case blocks, text....
> >
> > That's where filtering the selection is important.
> >
> > (while (null (setq ss (ssget ":s" (list (cons 0
> > "line,arc,circle,trace,lwpolyline,spline,"))))))
> > could be better, filtering out incorrect object selection of insert,
xref,
> text....)
> >
>
> looks like (ssget ":s") and ERRNO could be a killer combination 🙂
> --
> Bobby C. Jones
> Dots & Parens living in harmony...
> http://www.AcadX.com
>
>
Message 28 of 52
Anonymous
in reply to: Anonymous

Wow! Back to the old 90-10 / 10-90 rule:


It takes 10 percent of the effort to get 90 percent of the results and
90 percent of the effort to get that last 10 percent working.


Bobby and John, thanks for the effort and thoughts!

As an aside,

A single "and" function can be preferable to a nested "if" structure
when there are no "elses" and the return value is not an issue.
Consider:

if structure :
(if (setq ent (entsel "\nSelect object to break: "))
(if (object_ok (car ent))
(if (setq pnt (getpoint "\nSelect break point: "))
(progn
(setvar "osmode" 0)
(command "_.break" ent "_f" pnt pnt)
(setvar "osmode" os)
(setvar "errno" 52)
)
)
)


and structure
(and
(setq ent (entsel "\nSelect object to break: ")) ;each condition must evaluate to
true to proceed.
(object_ok (car ent))
(setq pnt (getpoint "\nSelect break point: "))
(progn
(setvar "osmode" 0)
(command "_.break" ent "_f" pnt pnt)
(setvar "osmode" os)
(setvar "errno" 52)
))

What do ya think?

Doug


"John Uhden" wrote in message
news:391C889F0A21F857B5C6C7F49EA12ACD@in.WebX.maYIadrTaRb...
> Bullet-proofing the custom break command requires more than mentioned:
......
Message 29 of 52
Anonymous
in reply to: Anonymous

I think I like to use (and ...) a lot. But if I want the user to see
results specific to the necessary steps, then I nest (if)s so that each can
return a relevant message. As I look back on this one, I definitely could
have...

(if (and (setq ent (entsel "\nSelect object to break: "))(object_ok
(car ent))) ...

--
John Uhden, Cadlantic/formerly CADvantage
--> mailto:juhden@cadlantic.com
--> http://www.cadlantic.com
2 Village Road
Sea Girt, NJ 08750
Tel. 732-974-1711
FAX 732-528-1332

"Doug Broad" wrote in message
news:5524107C4D7281317D48937EC6FF513A@in.WebX.maYIadrTaRb...
> Wow! Back to the old 90-10 / 10-90 rule:
>
>
> It takes 10 percent of the effort to get 90 percent of the results and
> 90 percent of the effort to get that last 10 percent working.
>

>
> Bobby and John, thanks for the effort and thoughts!
>
> As an aside,
>
> A single "and" function can be preferable to a nested "if" structure
> when there are no "elses" and the return value is not an issue.
> Consider:
>
> if structure :
> (if (setq ent (entsel "\nSelect object to break: "))
> (if (object_ok (car ent))
> (if (setq pnt (getpoint "\nSelect break point: "))
> (progn
> (setvar "osmode" 0)
> (command "_.break" ent "_f" pnt pnt)
> (setvar "osmode" os)
> (setvar "errno" 52)
> )
> )
> )
>
>
> and structure
> (and
> (setq ent (entsel "\nSelect object to break: ")) ;each condition must
evaluate to
> true to proceed.
> (object_ok (car ent))
> (setq pnt (getpoint "\nSelect break point: "))
> (progn
> (setvar "osmode" 0)
> (command "_.break" ent "_f" pnt pnt)
> (setvar "osmode" os)
> (setvar "errno" 52)
> ))
>
> What do ya think?
>
> Doug
Message 30 of 52
Anonymous
in reply to: Anonymous

Sorry for the delay in getting back to you all. I was out of pocket for
most of the day. I hope that all of you have enjoyed this thread as much as
I have. It brings up a tremendous amount of questions and I've seen several
really good ideas to solving this problem. The best of which may be that
the simple one line macro may have been good enough 🙂 While I don't
totally agree with that, I do think that this particular piece of code, in
most situations, should stop with the basic checks and a simple out for
those custom objects that the break command doesn't work with. This code
below is probably further than I would normally have taken it, but in the
interest of education & to satisfy my own curiosities...

;;;----------------------------------------------
;;;Define function and basic error handler
;;;----------------------------------------------
(defun c:bb (/ ent pnt cmd elist *error*)

(defun *error* (msg)
(if (not (member Msg '(nil "console break" "Function cancelled" "quit /
exit abort")))
(princ (strcat "\nError #" (itoa (getvar "errno")) ": " Msg))
)
(setvar "errno" 0)
(setvar "cmdecho" cmd)
(princ)
)

;;;----------------------------------------------
;;;save & set sysvars
;;;----------------------------------------------
(setq cmd (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setvar "errno" 7)

;;;----------------------------------------------
;;;Start entity selection loop
;;;----------------------------------------------
(while (= (getvar "errno") 7)
(setvar "errno" 0)
(setq ent (entsel "\nSelect object to break: "))

;;;----------------------------------------------
;;;conditional test to determine if an entity
;;;was selected and if so, can it can be broken.
;;;add other items to scan for as desired.
;;;----------------------------------------------
(cond
;;mispick
((= (getvar "errno") 7))
;;user hit enter
((= (getvar "errno") 52))
((= (logand (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 (setq
elist (entget (car ent)))))))) 4) 4)
(prompt "The object is on a locked layer.")
(setvar "errno" 7)
)
((equal (cdr (assoc 0 elist)) "INSERT")
(prompt "Cannot break a block.")
(setvar "errno" 7)
)
((equal (cdr (assoc 0 elist)) "CIRCLE")
(prompt "Arc cannot be full 360 degrees.")
(setvar "errno" 7)
)
((equal (cdr (assoc 0 elist)) "ELLIPSE")
(prompt "Cannot break a closed, periodic curve at only one point.")
(setvar "errno" 7)
)
;;closed spline
((and
(equal (cdr (assoc 0 elist)) "SPLINE")
(/= (logand (cdr (assoc 70 elist)) 1) 0)
)
(prompt "Cannot break a closed, periodic curve at only one point.")
(setvar "errno" 7)
)
)
)

;;;----------------------------------------------
;;;if an entity was selected, break it.
;;;if the break command doesn't
;;;terminate, then it failed. On failure
;;;terminate the break command
;;;and report to the user.
;;;----------------------------------------------
(if ent
(progn
(initget 1)
(setq pnt (getpoint "\nSelect break point: "))
(command "_.break" ent "_f" "_non" pnt "_non" pnt)
(if (> (getvar "cmdactive") 0)
(progn
(command)
(prompt "\nCannot break object.")
)
)
)
)

;;;----------------------------------------------
;;;reset system & exit cleanly
;;;----------------------------------------------
(*error* nil)
)

Sheesh, was that Jason that said we only saw the tip of iceberg earlier 🙂
--
Bobby C. Jones
Dots & Parens living in harmony...
http://www.acadx.com
Message 31 of 52
Anonymous
in reply to: Anonymous

Bobby,
Eric S. actually answered the original question I was trying to ask, however
you turned this into something that all can learn from. Thank you again for
taking the time to explain how and why each part does what it does. I am
currently reading up on posts to understand error handlers.

Knowing that there is always one more thing not thought about til you notice
it, what about ways to handle the pick not being on the entity?

Thanks again for your guidance,
Beau


Bobby C. Jones wrote in message
news:CE627CEEFEC791A03B9B2609E8F3E23A@in.WebX.maYIadrTaRb...
> Sorry for the delay in getting back to you all. I was out of pocket for
> most of the day. I hope that all of you have enjoyed this thread as much
as
> I have. It brings up a tremendous amount of questions and I've seen
several
> really good ideas to solving this problem. The best of which may be that
> the simple one line macro may have been good enough 🙂 While I don't
> totally agree with that, I do think that this particular piece of code, in
> most situations, should stop with the basic checks and a simple out for
> those custom objects that the break command doesn't work with. This code
> below is probably further than I would normally have taken it, but in the
> interest of education & to satisfy my own curiosities...
>
> ;;;----------------------------------------------
> ;;;Define function and basic error handler
> ;;;----------------------------------------------
> (defun c:bb (/ ent pnt cmd elist *error*)
>
> (defun *error* (msg)
> (if (not (member Msg '(nil "console break" "Function cancelled" "quit
/
> exit abort")))
> (princ (strcat "\nError #" (itoa (getvar "errno")) ": " Msg))
> )
> (setvar "errno" 0)
> (setvar "cmdecho" cmd)
> (princ)
> )
>
> ;;;----------------------------------------------
> ;;;save & set sysvars
> ;;;----------------------------------------------
> (setq cmd (getvar "cmdecho"))
> (setvar "cmdecho" 0)
> (setvar "errno" 7)
>
> ;;;----------------------------------------------
> ;;;Start entity selection loop
> ;;;----------------------------------------------
> (while (= (getvar "errno") 7)
> (setvar "errno" 0)
> (setq ent (entsel "\nSelect object to break: "))
>
> ;;;----------------------------------------------
> ;;;conditional test to determine if an entity
> ;;;was selected and if so, can it can be broken.
> ;;;add other items to scan for as desired.
> ;;;----------------------------------------------
> (cond
> ;;mispick
> ((= (getvar "errno") 7))
> ;;user hit enter
> ((= (getvar "errno") 52))
> ((= (logand (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 (setq
> elist (entget (car ent)))))))) 4) 4)
> (prompt "The object is on a locked layer.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "INSERT")
> (prompt "Cannot break a block.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "CIRCLE")
> (prompt "Arc cannot be full 360 degrees.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "ELLIPSE")
> (prompt "Cannot break a closed, periodic curve at only one
point.")
> (setvar "errno" 7)
> )
> ;;closed spline
> ((and
> (equal (cdr (assoc 0 elist)) "SPLINE")
> (/= (logand (cdr (assoc 70 elist)) 1) 0)
> )
> (prompt "Cannot break a closed, periodic curve at only one
point.")
> (setvar "errno" 7)
> )
> )
> )
>
> ;;;----------------------------------------------
> ;;;if an entity was selected, break it.
> ;;;if the break command doesn't
> ;;;terminate, then it failed. On failure
> ;;;terminate the break command
> ;;;and report to the user.
> ;;;----------------------------------------------
> (if ent
> (progn
> (initget 1)
> (setq pnt (getpoint "\nSelect break point: "))
> (command "_.break" ent "_f" "_non" pnt "_non" pnt)
> (if (> (getvar "cmdactive") 0)
> (progn
> (command)
> (prompt "\nCannot break object.")
> )
> )
> )
> )
>
> ;;;----------------------------------------------
> ;;;reset system & exit cleanly
> ;;;----------------------------------------------
> (*error* nil)
> )
>
> Sheesh, was that Jason that said we only saw the tip of iceberg earlier
:-)
> --
> Bobby C. Jones
> Dots & Parens living in harmony...
> http://www.acadx.com
>
>
>
Message 32 of 52
Anonymous
in reply to: Anonymous

Beau,
This 'little' routine uses the same basic method for checking for a mispick
that Eric suggested. When ENTSEL detects a pick and an entity is not in the
pick box, the ERRNO sysvar is set to 7. Our WHILE loop actually loops until
the ERRNO sysvar is no longer set to 7. In essence we've told our code that
asks to select an entity to loop until the user actually selects one. For
entities that we want to discard like circles and entities on locked layers,
we fake a mispick by manually setting the ERRNO sysvar to 7. Look carefully
at the loop below. Then try out the full routine. Try out some of the
things that we test for in the loop and see what happens. Try a mispick,
pick a circle or an ellipse, select anything on a locked layer. All of
these things will cause the loop to repeat and ask the user to select
another entity. Then start the command and hit enter or the escape key when
it's asking for an entity. Both of those will cause the command to
terminate, just like the acad BREAK command.

;;;----------------------------------------------
;;;Set up while loop
;;;----------------------------------------------
(setvar "errno" 7)

;;;----------------------------------------------
;;;Start entity selection loop
;;;----------------------------------------------
(while (= (getvar "errno") 7)
(setvar "errno" 0)
(setq ent (entsel "\nSelect object to break: "))

;;;----------------------------------------------
;;;conditional test to determine if an entity
;;;was selected and if so, can it can be broken.
;;;add other items to scan for as desired.
;;;----------------------------------------------
(cond
;;mispick
((= (getvar "errno") 7))
;;user hit enter
((= (getvar "errno") 52))
((= (logand (cdr (assoc 70 (tblsearch "layer"
(cdr (assoc 8 (setq elist (entget (car ent)))))))) 4)
4)
(prompt "The object is on a locked layer.")
(setvar "errno" 7)
)
((equal (cdr (assoc 0 elist)) "INSERT")
(prompt "Cannot break a block.")
(setvar "errno" 7)
)
((equal (cdr (assoc 0 elist)) "CIRCLE")
(prompt "Arc cannot be full 360 degrees.")
(setvar "errno" 7)
)
((equal (cdr (assoc 0 elist)) "ELLIPSE")
(prompt "Cannot break a closed, periodic curve at only one point.")
(setvar "errno" 7)
)
;;closed spline
((and
(equal (cdr (assoc 0 elist)) "SPLINE")
(/= (logand (cdr (assoc 70 elist)) 1) 0)
)
(prompt "Cannot break a closed, periodic curve at only one point.")
(setvar "errno" 7)
)
)
)
--
Bobby C. Jones
Working for you...from home 🙂
http://www.acadx.com
Message 33 of 52
Anonymous
in reply to: Anonymous

Sorry, I should have clarified a bit more on what I meant by my pick. The
pick I was referring too was the break point pick. It is not necessarily
for my application here, but was wondering how to handle a picked break
point not being on the entity you selected. What would need to be used to
repeat if the picked break point is not on the entity until it is on the
entity? Do you see this as even being necessary?

Again many thanks,
Beau

Bobby C. Jones wrote in message
news:BCDFBAA8D1EA9E589F38B27F88346B3D@in.WebX.maYIadrTaRb...
> Beau,
> This 'little' routine uses the same basic method for checking for a
mispick
> that Eric suggested. When ENTSEL detects a pick and an entity is not in
the
> pick box, the ERRNO sysvar is set to 7. Our WHILE loop actually loops
until
> the ERRNO sysvar is no longer set to 7. In essence we've told our code
that
> asks to select an entity to loop until the user actually selects one. For
> entities that we want to discard like circles and entities on locked
layers,
> we fake a mispick by manually setting the ERRNO sysvar to 7. Look
carefully
> at the loop below. Then try out the full routine. Try out some of the
> things that we test for in the loop and see what happens. Try a mispick,
> pick a circle or an ellipse, select anything on a locked layer. All of
> these things will cause the loop to repeat and ask the user to select
> another entity. Then start the command and hit enter or the escape key
when
> it's asking for an entity. Both of those will cause the command to
> terminate, just like the acad BREAK command.
>
> ;;;----------------------------------------------
> ;;;Set up while loop
> ;;;----------------------------------------------
> (setvar "errno" 7)
>
> ;;;----------------------------------------------
> ;;;Start entity selection loop
> ;;;----------------------------------------------
> (while (= (getvar "errno") 7)
> (setvar "errno" 0)
> (setq ent (entsel "\nSelect object to break: "))
>
> ;;;----------------------------------------------
> ;;;conditional test to determine if an entity
> ;;;was selected and if so, can it can be broken.
> ;;;add other items to scan for as desired.
> ;;;----------------------------------------------
> (cond
> ;;mispick
> ((= (getvar "errno") 7))
> ;;user hit enter
> ((= (getvar "errno") 52))
> ((= (logand (cdr (assoc 70 (tblsearch "layer"
> (cdr (assoc 8 (setq elist (entget (car ent)))))))) 4)
> 4)
> (prompt "The object is on a locked layer.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "INSERT")
> (prompt "Cannot break a block.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "CIRCLE")
> (prompt "Arc cannot be full 360 degrees.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "ELLIPSE")
> (prompt "Cannot break a closed, periodic curve at only one
point.")
> (setvar "errno" 7)
> )
> ;;closed spline
> ((and
> (equal (cdr (assoc 0 elist)) "SPLINE")
> (/= (logand (cdr (assoc 70 elist)) 1) 0)
> )
> (prompt "Cannot break a closed, periodic curve at only one
point.")
> (setvar "errno" 7)
> )
> )
> )
> --
> Bobby C. Jones
> Working for you...from home 🙂
> http://www.acadx.com
>
>
>
Message 34 of 52
Anonymous
in reply to: Anonymous

As you stated, for this macro it is not needed. In fact since the BREAK
command doesn't require the user to select points on the entity, I think it
would be a bad idea. For future routines with other applications where you
want to verify if a selected point lies on a specific entity, you could
create a selection set of entities that pass through that point and see if
any of them match that particular entity. You can do this with SSGET. Have
a good one.
--
Bobby C. Jones
From home, yet again 🙂
http://www.acadx.com
Message 35 of 52
Anonymous
in reply to: Anonymous

Bobby,

Approaching genius level but will still fail(sometimes). 😞
(text, mtext, rtext.......who knows)

If you want to add something to your "customization wishlist", a big one that
would help solve problems this failure illustrates is:

A better command function that could issue commands and prompts and
stop without an error, returning an error code or error message to the
calling function that could be interpreted without recreating the entire checking
process of the Autocad command. For instance, if a text entity is fed to the "break"
command, the command function should politely return the same error message
to the calling function that it returns to the user and allow the process to continue,
perhaps suspended, without forcing the calling function to become as complex
as the AutoCAD command itself, prequalifying prompted information ad-infinitum.

The command function now chokes too easily and never returns any
useful information.

Prequalifying user supplied information could be a thing of the past with some
help from Autodesk.

Doug

"Bobby C. Jones" wrote in message
news:BCDFBAA8D1EA9E589F38B27F88346B3D@in.WebX.maYIadrTaRb...
> Beau,
> This 'little' routine uses the same basic method for checking for a mispick
> that Eric suggested. When ENTSEL detects a pick and an entity is not in the
> pick box, the ERRNO sysvar is set to 7. Our WHILE loop actually loops until
> the ERRNO sysvar is no longer set to 7. In essence we've told our code that
> asks to select an entity to loop until the user actually selects one. For
> entities that we want to discard like circles and entities on locked layers,
> we fake a mispick by manually setting the ERRNO sysvar to 7. Look carefully
> at the loop below. Then try out the full routine. Try out some of the
> things that we test for in the loop and see what happens. Try a mispick,
> pick a circle or an ellipse, select anything on a locked layer. All of
> these things will cause the loop to repeat and ask the user to select
> another entity. Then start the command and hit enter or the escape key when
> it's asking for an entity. Both of those will cause the command to
> terminate, just like the acad BREAK command.
>
> ;;;----------------------------------------------
> ;;;Set up while loop
> ;;;----------------------------------------------
> (setvar "errno" 7)
>
> ;;;----------------------------------------------
> ;;;Start entity selection loop
> ;;;----------------------------------------------
> (while (= (getvar "errno") 7)
> (setvar "errno" 0)
> (setq ent (entsel "\nSelect object to break: "))
>
> ;;;----------------------------------------------
> ;;;conditional test to determine if an entity
> ;;;was selected and if so, can it can be broken.
> ;;;add other items to scan for as desired.
> ;;;----------------------------------------------
> (cond
> ;;mispick
> ((= (getvar "errno") 7))
> ;;user hit enter
> ((= (getvar "errno") 52))
> ((= (logand (cdr (assoc 70 (tblsearch "layer"
> (cdr (assoc 8 (setq elist (entget (car ent)))))))) 4)
> 4)
> (prompt "The object is on a locked layer.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "INSERT")
> (prompt "Cannot break a block.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "CIRCLE")
> (prompt "Arc cannot be full 360 degrees.")
> (setvar "errno" 7)
> )
> ((equal (cdr (assoc 0 elist)) "ELLIPSE")
> (prompt "Cannot break a closed, periodic curve at only one point.")
> (setvar "errno" 7)
> )
> ;;closed spline
> ((and
> (equal (cdr (assoc 0 elist)) "SPLINE")
> (/= (logand (cdr (assoc 70 elist)) 1) 0)
> )
> (prompt "Cannot break a closed, periodic curve at only one point.")
> (setvar "errno" 7)
> )
> )
> )
> --
> Bobby C. Jones
> Working for you...from home 🙂
> http://www.acadx.com
>
>
>
Message 36 of 52
Anonymous
in reply to: Anonymous

VL-CMDF is a bit harder to choke, but still has a pretty much unusable
return.
--

Regards,
Eric S.
eschneider@jensenprecast.com
Message 37 of 52
Anonymous
in reply to: Anonymous

Could the VL-CATCHALL-ERROR be used with VL-CMDF to make
something like this easier or do we still have to rely on *ERROR*?

Doug

"Eric S." wrote in message news:FC7F37421E7C370B3CC6A4E79383AEBE@in.WebX.maYIadrTaRb...
> VL-CMDF is a bit harder to choke, but still has a pretty much unusable
> return.
> --
>
> Regards,
> Eric S.
> eschneider@jensenprecast.com
>
>
Message 38 of 52
Anonymous
in reply to: Anonymous

"John Uhden" wrote in message
news:2913FB0764F114F9F852CFBD4E619DF5@in.WebX.maYIadrTaRb...
| I think I like to use (and ...) a lot. But if I want the user to see
| results specific to the necessary steps, then I nest (if)s so that each
can
| return a relevant message. As I look back on this one, I definitely could
| have...
|
| (if (and (setq ent (entsel "\nSelect object to break: "))(object_ok
| (car ent))) ...
|

I like to use this approach:

(cond
((and
(setq ent ...)
(object_ok (car Ent))
(setq pnt ...)
)
;;; Normal code here.
)
;;; Test for errors in reverse order of (and) above.
((not pnt) (alert "Bad point"))
((not object_ok) (alert "Bad object"))
(alert "No object selected")
)


| > and structure
| > (and
| > (setq ent (entsel "\nSelect object to break: ")) ;each condition
must
| evaluate to
| > true to proceed.
| > (object_ok (car ent))
| > (setq pnt (getpoint "\nSelect break point: "))
| > (progn
| > (setvar "osmode" 0)
| > (command "_.break" ent "_f" pnt pnt)
| > (setvar "osmode" os)
| > (setvar "errno" 52)
| > ))
Message 39 of 52
Anonymous
in reply to: Anonymous

Unfortunately, no. VL-CMDF only returns T only if user input is required and
nothing on error or completion, error simply does not excecute. But it might
lend itself nicely to a loop somehow without having to examine CMDACTIVE.
Havn't tried, but looks interesting.
--

Regards,
Eric S.
eschneider@jensenprecast.com
Message 40 of 52
Anonymous
in reply to: Anonymous

Yes that seems like it would work well. I also really liked the way John
used the vlax-method-applicable-p function in his object_ok function
to eliminate all sorts of object types that couldn't be broken. I wonder
what inspired him to use that test?

Doug

"R. Robert Bell" wrote in message
news:15D7A02C5AAEB536C9E9F656E4CF63B7@in.WebX.maYIadrTaRb...
> "John Uhden" wrote in message
> news:2913FB0764F114F9F852CFBD4E619DF5@in.WebX.maYIadrTaRb...
> | I think I like to use (and ...) a lot. But if I want the user to see
> | results specific to the necessary steps, then I nest (if)s so that each
> can
> | return a relevant message. As I look back on this one, I definitely could
> | have...
> |
> | (if (and (setq ent (entsel "\nSelect object to break: "))(object_ok
> | (car ent))) ...
> |
>
> I like to use this approach:
>
> (cond
> ((and
> (setq ent ...)
> (object_ok (car Ent))
> (setq pnt ...)
> )
> ;;; Normal code here.
> )
> ;;; Test for errors in reverse order of (and) above.
> ((not pnt) (alert "Bad point"))
> ((not object_ok) (alert "Bad object"))
> (alert "No object selected")
> )
>
>
> | > and structure
> | > (and
> | > (setq ent (entsel "\nSelect object to break: ")) ;each condition
> must
> | evaluate to
> | > true to proceed.
> | > (object_ok (car ent))
> | > (setq pnt (getpoint "\nSelect break point: "))
> | > (progn
> | > (setvar "osmode" 0)
> | > (command "_.break" ent "_f" pnt pnt)
> | > (setvar "osmode" os)
> | > (setvar "errno" 52)
> | > ))
>
>
>

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

Post to forums  

Autodesk Design & Make Report

”Boost