Layout Switch Lisp - Erroring out

Discussion in 'AutoCAD' started by Jenna, Dec 7, 2004.

  1. Jenna

    Jenna Guest

    I just got this great little lisp routine at AU and I've been trying to
    modify it to work with our office's settings. However, I keep getting an
    error with a specific part of the routine, which I added.

    Here's the routine...it's not finished so I'm sure there are other things
    wrong with it, but the part I'm concerned with here are the lines beginning
    with "command". Everything appears to be working fine, but when it gets to
    the "command" lines it errors out with "error: invalid AutoCAD command:
    nil". Each of those "command" lines work fine when entered individually or
    even if I paste the entire progn statement in, but they fail every time I
    try to run the entire routine (by switching tabs).

    (vl-load-com)

    (defun DoThisAfterLayoutSwitch (Caller CmdSet)
    (prompt (strcat "\nLayout tab switched to: " (getvar "ctab")))

    (if (= (getvar "ctab") "Model")
    (progn
    (setvar "ltscale" (/ USERDSCALE 3.0))
    (setvar "textsize" (* 0.078125 USERDSCALE))
    (command "-dimstyle" "r" USERDSTYLE)
    )
    (progn
    (setq USERDSCALE (getvar "dimscale"))
    (setq USERDSTYLE (getvar "dimstyle"))
    (setvar "ltscale" 0.33333333)
    (setvar "textsize" 0.078125)
    (command "-insert" "*madim" "0,0" "" "")
    (command "-rename" "d" "MADIM" "001-DIM")
    (command "-rename" "d" "MADIM$0" (strcat "001-DIM" "$0"))
    (command "-dimstyle" "r" "001-DIM")
    )
    )
    (princ)
    )


    (setq MAReactor1
    (vlr-miscellaneous-reactor
    nil
    '(:)vlr-layoutSwitched . DoThisAfterLayoutSwitch)
    )
    )
    )
     
    Jenna, Dec 7, 2004
    #1
  2. Jenna

    OLD-CADaver Guest

    Have you set USERDSCALE and USERDSTYLE somewhere else??? This routine doesn't save them initially until ctab is not equal to "Model".
     
    OLD-CADaver, Dec 7, 2004
    #2
  3. Jenna,

    Just to make clear what Luis stated: Reactors *cannot* use the (command)
    function.

    Also, as you currently have it written (I know you are not done) the reactor
    will insert block after block after block every time you switch to model
    space. Your renames will fail after the first switch because the new names
    will already exist.

    --
    R. Robert Bell


    "Jenna" <stilesj AT nospam DOT com> wrote in message
    I just got this great little lisp routine at AU and I've been trying to
    modify it to work with our office's settings. However, I keep getting an
    error with a specific part of the routine, which I added.

    Here's the routine...it's not finished so I'm sure there are other things
    wrong with it, but the part I'm concerned with here are the lines beginning
    with "command". Everything appears to be working fine, but when it gets to
    the "command" lines it errors out with "error: invalid AutoCAD command:
    nil". Each of those "command" lines work fine when entered individually or
    even if I paste the entire progn statement in, but they fail every time I
    try to run the entire routine (by switching tabs).

    (vl-load-com)

    (defun DoThisAfterLayoutSwitch (Caller CmdSet)
    (prompt (strcat "\nLayout tab switched to: " (getvar "ctab")))

    (if (= (getvar "ctab") "Model")
    (progn
    (setvar "ltscale" (/ USERDSCALE 3.0))
    (setvar "textsize" (* 0.078125 USERDSCALE))
    (command "-dimstyle" "r" USERDSTYLE)
    )
    (progn
    (setq USERDSCALE (getvar "dimscale"))
    (setq USERDSTYLE (getvar "dimstyle"))
    (setvar "ltscale" 0.33333333)
    (setvar "textsize" 0.078125)
    (command "-insert" "*madim" "0,0" "" "")
    (command "-rename" "d" "MADIM" "001-DIM")
    (command "-rename" "d" "MADIM$0" (strcat "001-DIM" "$0"))
    (command "-dimstyle" "r" "001-DIM")
    )
    )
    (princ)
    )


    (setq MAReactor1
    (vlr-miscellaneous-reactor
    nil
    '(:)vlr-layoutSwitched . DoThisAfterLayoutSwitch)
    )
    )
    )
     
    R. Robert Bell, Dec 7, 2004
    #3
  4. Jenna

    Jenna Guest

    That's fine...I don't need them until ctab is not equal to Model.
     
    Jenna, Dec 7, 2004
    #4
  5. Jenna

    Jenna Guest

    This sounds like the problem...along with R. Robert Bell's reponse...I
    didn't know I couldn't use command in this.
    I couldn't find vla-sendcommand in the help files...can you give a little
    more information on how I would run commands from within this routine?

     
    Jenna, Dec 7, 2004
    #5
  6. Jenna

    Doug Broad Guest

    Jenna,
    Was this routine given to you be a friend or was it part of a class?

    OLD has a point. If you open the drawing with a layout active
    and switch to model, USERDSCALE will not be set and will cause
    an error. Luis and Robert are correct also.

    The whole program is probably best trashed unfortunately. Start with
    goals.

    Regards,
    Doug
     
    Doug Broad, Dec 7, 2004
    #6
  7. Jenna

    Josh Guest

    As far as setting a dimstyle current without using (command... you can use this from a recent post ("SET DIMSTYLE PROGRAMATICALLY" 11-12-04)


    (setq *thisdrawing* (vla-get-activedocument(vlax-get-acad-object)))

    ;;SetDimstyle - Doug Broad 9/02
    (defun SetDimstyle (name)
    (vl-catch-all-apply
    '(lambda (doc name)
    (vla-put-activedimstyle
    doc
    (vla-item
    (vla-get-dimstyles doc)
    name)))
    (list *thisdrawing* name)))

    Josh
     
    Josh, Dec 7, 2004
    #7
  8. Jenna

    RDI Guest

    What specifically is it that you're trying to do? What's the block for?

    It LOOKS like you're inserting it so that the dimstyles will be imported
    from the block. Is that the case? If so, why does it need to be done for
    each layout? Why not just when you open the file?
     
    RDI, Dec 7, 2004
    #8
  9. Jenna

    Jenna Guest

    The reactor information was provided in the class, mostly as a concept to be
    able to have something happen when a user changes tabs. In the code I was
    given, though, it was only setting variables, not runnning any sort of
    commands...that was the stuff I was trying to add.
    As far as the error starting in paper and going to model, I don't know that
    it really matters in my case, as long as it doesn't harm anything. Or maybe
    I could use an if statement to have it bypass the routine if the variables
    are nil? We have a routine that people run to set all their variables for
    the scale factor in which they are working, so they would run that to begin
    working in model anyway.
    Here is the issue I'm really trying to solve with this routine:
    We have this routine that sets all the necessary variables based on user
    input of the scale factor. In order to plot/work correctly in paper space,
    they are supposed to set that scale factor to 1, but often people forget and
    wonder why their linetypes don't look right in their plot. So, the idea was
    that if I could use this reactor that runs a routine when the layout tab is
    switched, it would automatically switch the scale factor to 1 for them and
    eliminate that step and any wasted paper from printing incorrectly.
    Per your response, though, this routine doesn't even come close?
     
    Jenna, Dec 7, 2004
    #9
  10. Jenna

    Jenna Guest

    We have a lisp routine that people use all the time to set their scale
    factor. It takes the user input, i.e. 48, and import and sets up a dimstyle
    with dimscale of 48 named 048-DIM, creates our standard text style, sets the
    textsize, and sets the ltscale. The block is a standard base dimstyle which
    then gets modified and renamed for each scale factor used in the drawing.
    Since I can't run a lisp from within another lisp, I thought I'd just
    extract a portion of it to create the 001-DIM dimstyle when the user
    switches to model space. I know that that part may not be right yet, but
    the first stumbling block I wanted to deal with is how to even run the
    commands within the routine since they were failing in my tests.
     
    Jenna, Dec 7, 2004
    #10
  11. Jenna

    OLD-CADaver Guest

    <<That's fine...I don't need them until ctab is not equal to Model. >>

    ummm.... yes you do, if ctab is equal to Model, you're trying to divide USERDSCALE by 3

    (setvar "ltscale" (/ USERDSCALE 3.0))

    If USERDSCALE doesn't exist, you'll have an error.

    As the others have pointed out "COMMAND" is a problem, but SETVAR is not.

    (setvar "ltscale" (/ (getvar "dimscale") 3.0))

    or

    (setvar "ltscale" 0.3333)

    ~~~~~~~~~~~~~

    The other command sequences are a problem as well. Why would you want to insert MADIM every time you switch layouts? Same goes for the rename portions. Doesn't seem necessary EVERY time you switch layouts.
     
    OLD-CADaver, Dec 7, 2004
    #11
  12. Jenna

    Jenna Guest

    The class was given by Robert Green. He only got to the reactor concepts
    portion with the sample code at the very end, so there wasn't much time
    spent on it. I also edited his sample...mostly I just kept the reactor
    stuff as it was and the main structure, but changed the more detailed
    settings.
    I am a novice to visual lisp, so I'm just going off what he gave and my own
    limited lisp knowledge in trying to edit this to suit my needs.
     
    Jenna, Dec 7, 2004
    #12
  13. Jenna

    Jenna Guest

    Yes, I see about the USERDSCALE, etc. (see my response to Doug Broad)
    Also, I understand that there are still issues with the rest of the
    routine...but one issue at a time, please...right now, I just want to know
    how I can even run commands in this routine...if I can figure that out, I
    can just copy the material from my other lisp routine to set all these
    variables as I would like, because I know that routine works. The insert
    stuff, etc., is just an excerpt from my other routine, not the whole thing.
     
    Jenna, Dec 7, 2004
    #13
  14. Jenna

    Doug Broad Guest

    Jenna,
    Thanks for the info. Setvar statements are OK but the use of vla-setvariable
    is better in some versions of ACAD. In the past, I have triggered some elock
    violations with setvar.

    Command statements are definitely out. Vla-sendcommand is sometimes OK
    but you need to be careful within some reactors you don't create an infinite loops
    where one command triggers a reactor which sends another command which
    triggers another reactor...

    I have also used VBA statements within reactors if my memory serves.

    In general, you should substitute ActiveX methods and properties for commands
    within reactors.

    The layoutchanged reactor is OK for what you want to do but it won't solve all
    your problems. I also have a plot reactor which activates when the drawing is
    plotted. After all, What if someone (myself included) started messing with the
    variable settings and messed them up without changing the layout and then plotted?

    Suggestions: 1) use templates for dimension settings. 2) Use dimscale to control
    the overall size of dimensions. 3) allow overrides versus adding numerous dimstyles
    that vary only by overall size. 4) When in a layout, use psltscale=1 and dimscale = 0.
    5)Save your model space scale in a dictionary or in the userr variables 6) Where possible,
    draw one scale per file and assemble differently scaled drawings on a sheet by xreffing.
    7)
    If you use multiple scales per drawing (I do this sometimes), then add a reactor to manage
    not just your dimensions but text sizes and annotation scale block insertions. You can't
    do this with a layoutchanged reactor alone.

    Hope that helps.

    Regards,
    Doug
     
    Doug Broad, Dec 7, 2004
    #14
  15. Jenna

    RDI Guest

    <<Since I can't run a lisp from within another lisp>>
    You CAN run lisp from within another lisp. What you CAN'T do is run lisp
    routine and when it prompts you for info, try and run ANOTHER lisp
    routine/function.

    For example the following will NOT work:

    command: (getpoint "Pick a point on screen: ")

    That will result in the following
    Pick a point on screen:

    If you then try to type (getvar "anyvariable"), you'll get a message that
    lisp can't be restarted.

    However the following WILL work: Type runit at the command line and you'll
    see "I passed the test".

    (defun thisIsMyTest()
    (princ "I passed the test")
    )

    (defun c:runit()
    (thisIsMyTest)
    )

    Of course all this does nothing for using the command within your reactor,
    but I thought it sounded like you had the wrong impression of lisp and
    wnated to make it clear. Also there is a GREAT tutorial site available over
    at www.afralisp.com. I don't know if you'll find this specific issue
    covered but there's a lot there you can learn and use. I don't know HOW
    you're going to get around the issue of inserting the block, but for the
    renaiming issues, I'd suggest looking at ENTMOD and DXF codes.

    Here's a little function that I wrote because I always had trouble
    remembering the syntax of the entmod function.

    ; Arguments:
    ; bit - what portion of the element to change
    ; entity - the entity NAME (entget (car(entsel))
    ; val - the NEW value
    (defun EMod (bit entity val)
    (setq newel(subst(cons bit val) (assoc bit entity) entity))
    (entmod newel)
    )
     
    RDI, Dec 7, 2004
    #15
  16. Jenna

    RDI Guest

    Jenna,

    Having seen this reply, it sounds almost like you just need to set the
    variables. And the block really only needs to be inserted once. If that's
    the set it up so that the block is inserted when you open the file (check
    first to see if it's already been inserted). Then your reactor can change
    the variables and do any renaming that you need done.
     
    RDI, Dec 7, 2004
    #16
  17. Jenna

    Jenna Guest

    Well, this is disappointing...I seem to be in over my head here with what I
    thought would be a simple solution.
    Unfortunately, your suggestions, while the may be good for some, go just
    about opposite the way we have our stuff set up (which has worked very well
    for use thus far).
    We do use a unique name for each dim style, finding this easier when we do
    have multiple scales within a drawing. While multiple scales may not be
    ideal, it really is what works best for our drawings, where we might have a
    floor plan at 1/8" scale with a blowup area at 1/4", or a group of details
    with some at 1" and some at 1/2". Even when xreffing separate scales
    together into one sheet, I find it easier to distinguish what's going on if
    the dimstyles are actually named appropriate to the scale rather than all
    having the same name. Overrides I have never found to be very easy to work
    with and often you get people changing other things that they shouldn't.
    Inserting the standard style each time someone changes their scale factor
    keeps our dimensions pretty standard.
    We do use psltscale set to 1, but what advantage does setting dimscale to 0
    have in paper space?
    In the original reactor routine I got from the class, it was using the
    userr1 variable to store the model space...that was my own change, probably
    unnecessarily and incorrectly.
    For the multiple scales per drawing, our current lisp routine does set, in
    addition to dimstyle/scale, the text size, ltscale, and annotation scale
    block insertions (controlled by the dimscale).
    I don't know whether the way we're set up is the "best" way, but I know that
    there are many ways to do things and as this works well for us, I'm not
    eager to revise the whole process for this reactor. Maybe I'll have to put
    this concept on the back burner for the moment and rethink what I'd like it
    to do...like you said, start with goals.
    Thanks!
     
    Jenna, Dec 7, 2004
    #17
  18. Jenna

    Jenna Guest

    I wonder if I could get away with just setting the ltscale??
    Or is that just a cop-out?
    That's really the only problem variable that makes things look wrong when
    people don't switch their scale factor to 1 before plotting. If they need
    to work in paperspace, they know to run the routine that sets everything
    else (ltscale, textsize, dimstyle, dimscale, etc.) to scale factor 1.
    What am I missing? Would I totally screw people up if I invisibly change
    their ltscale to 1 when they switch to paper and back to their original
    scale when they switch back to model?
     
    Jenna, Dec 7, 2004
    #18
  19. Jenna

    Doug Broad Guest

    Jenna,
    AutoCAD is big enough for many different practices. If you need the different
    dimscales, then use (vla-put-activedimstyle doc "yourdimstylename")
    to switch dimstyles. If the dimstyle doesn't exist yet, then use the add method
    of the dimstyles collection to create a new dimstyle and then use the copyfrom
    method to copy the settings from one dimstyle to another.

    (vla-setvariable doc "ltscale" yourvalue)
    (vla-setvariable doc "dimsclale" yourvalue)

    can be used.

    Dimscale set to 0 allows you to dimension in any viewport and have the dimensions
    appear the same size. With 2004/2005 you can also dimension transpatially in
    paper space and avoid the complexities of adding annotation in multiple scaled viewports.

    Don't lose heart. Just avoid the command function statements in reactors. Also check for
    the existence of named objects before renaming objects.

    Regards,
    Doug
     
    Doug Broad, Dec 7, 2004
    #19
  20. Jenna

    RDI Guest

    It seems like if they've been TOLD that will happen, it shouldn't be too big
    a problem (once they got used to it).
     
    RDI, Dec 7, 2004
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.