TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: jlogan02 on December 06, 2018, 07:22:01 PM

Title: Set a default and ask the user for input
Post by: jlogan02 on December 06, 2018, 07:22:01 PM
I'm trying to make this work but can't seem to get it done.

I want to ask the user for a ltscale for the zigzag line to be drawn on [.25/.5]
with a default .5

I get that the code sets a default but it doesn't deal with a real number and
that I need to use getreal. But I can't make it work.

Code - Auto/Visual Lisp: [Select]
  1. (if (null global:int)
  2.     (setq global:int 1)
  3. )
  4. (if (setq tmp (getint (strcat "\nEnter a positive non-zero integer <" (itoa global:int) ">: ")))
  5.     (setq global:int tmp)
  6. )



Code - Auto/Visual Lisp: [Select]
  1. (defun c:ZigZag (/ clt clts lts clayr a)
  2.   (setq oldosmode (getvar 'osmode))
  3.   (setq clt (getvar 'celtype))
  4.   (setq clts (getvar 'celtscale))
  5.   (setq lts (getvar 'ltscale))
  6.   (setq clayr (getvar 'clayer))
  7.   (setvar 'osmode 1)     
  8.   (setq a "zigzag")
  9.  
  10. (getreal "\Enter LTSCALE [.25/.5] :")
  11.  
  12. (if (= (tblsearch "ltype" a) nil)
  13.     (command "-linetype" "l" a "acad.lin" "")
  14.   )
  15.  
  16.   (command "._layer" "make" "CLOUD" "Color" "RED" "CLOUD" "")
  17.   (command "-linetype" "_s" a "")
  18.   (command "pline")
  19.  
  20.   (while (> (getvar 'cmdactive) 0)
  21.   (command pause))
  22.  
  23.   (setvar 'celtype clt)
  24.   (setvar 'celtscale clts)
  25.   (setvar 'clayer clayr)
  26.   (setvar 'ltscale lts)
  27.   (setvar 'osmode oldosmode)    
  28.   (princ)
  29. )

J. Logan
ACAD 2018
Title: Re: Set a default and ask the user for input
Post by: Grrr1337 on December 06, 2018, 07:45:32 PM
Like this ? :

Code - Auto/Visual Lisp: [Select]
  1. (setvar 'LTSCALE
  2.   (read
  3.     (progn
  4.       (initget "0.25 0.5")
  5.       (cond ((getkword "\nEnter LTSCALE [0.25/0.5] <0.5>: "))("0.5"))
  6.     )
  7.   )
  8. )
Title: Re: Set a default and ask the user for input
Post by: CAB on December 07, 2018, 07:48:45 AM
Another Option:
Code - Auto/Visual Lisp: [Select]
  1. ;;  CAB 12.26.2009
  2. ;;  example Get number within a Numeric Range
  3. ;;    Arguments
  4. ;;  If nil, Ignore MinNum or MaxNum or DefNum
  5. ;;  msg and ErrMsg may be nil as well
  6. (defun GetNumInRange(MinNum MaxNum DefNum msg ErrMsg / num)
  7.   (or msg (setq msg "\nEnter number: "))
  8.   (or ErrMsg (setq ErrMsg "\nEntry is out of range. Try Again."))
  9.   (while
  10.     (cond
  11.       ((null (setq num (getdist msg)))
  12.        (if DefNum
  13.          (null (setq num DefNum))
  14.          (princ ErrMsg)
  15.        )
  16.       )
  17.       ((and MinNum (< num MinNum))
  18.        (princ ErrMsg))
  19.       ((and MaxNum (> num MaxNum))
  20.        (princ ErrMsg))
  21.     )
  22.   )
  23.   num
  24. )
  25.  
  26. (defun c:test()
  27.   (print
  28.   (GetNumInRange 10 50 39 "\nEnter number [10 =< Num >= 50]."
  29.                      "\nError - entry is out of range. Try Again.")
  30.     )
  31.   (princ)
  32.      
  33. )[\code]
  34.  
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 07, 2018, 12:01:21 PM
Great work on both parts Grrr1337 and CAB. Thanks. I have questions.

Grrr1337. Please just confirm for me. I'd like to search and destroy for myself.

As it stands now this only allows for 0.25 and 0.5. I know some users like to forego enter the "0" and just use .25 or .5.
Is there a way to insure either input is accepted.

Code - Auto/Visual Lisp: [Select]
  1. (setvar 'LTSCALE
  2.   (read
  3.     (progn
  4.       (initget "0.25 0.5")
  5.       (cond ((getkword "\nEnter LTSCALE [0.25/0.5] <0.5>: "))("0.5"))
  6.     )
  7.   )
  8. )

CAB
I placed the GetNumInRange Defun code right after my routines defun and placed

Code - Auto/Visual Lisp: [Select]
  1.   (GetNumInRange 0.25 1.0 39 "\nEnter number [0.25 =< Num >= 1]."
  2.                      "\nError - entry is out of range. Try Again.")
  3.     )

Just below my if statement.

Code - Auto/Visual Lisp: [Select]
  1. ...(if (= (tblsearch "ltype" a) nil)
  2.     (command "-linetype" "l" a "acad.lin" "")
  3.   )
  4. (GetNumInRange 0.25 1.0 39 "\nEnter number [0.25 =< Num >= 1]."
  5.                      "\nError - entry is out of range. Try Again.")
  6.     )
  7.    
  8.   (command "._layer" "make" "CLOUD" "Color" "RED" "CLOUD" "")
  9.   (command "-linetype" "_s" a "")
  10.   (command "pline")
  11.  
  12.   (while (> (getvar 'cmdactive) 0)
  13.   (command pause))
  14.  
  15.   (setvar 'celtype clt)
  16.   (setvar 'celtscale clts)
  17.   (setvar 'clayer clayr)
  18.   (setvar 'ltscale lts)
  19.   (setvar 'osmode oldosmode)    
  20.   (princ)
  21. )
  22.  

It prints the message to the command line and I can enter  a number. However, the ZigZag line result is always Ltscale of 1.0 no matter what I enter. 
Title: Re: Set a default and ask the user for input
Post by: ronjonp on December 07, 2018, 12:22:24 PM
If you set DYNMODE to 1, Grrr's code should popup the options on the screen.
Title: Re: Set a default and ask the user for input
Post by: Lee Mac on December 07, 2018, 12:28:31 PM
Here's another option:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / scl )
  2.     (while
  3.         (progn
  4.             (initget 6)
  5.             (not (member (setq scl (cond ((getreal "\nEnter LTSCALE [.25/.5] <.5>: ")) (0.5))) '(0.25 0.5)))
  6.         )
  7.         (princ "\nPlease choose between 0.25 & 0.5.")
  8.     )
  9.     (setvar 'ltscale scl)
  10. )

This will accept user input of 0.25/.25/0.5/.5.
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 07, 2018, 01:01:08 PM
I beat you to the punch on that one RonJonp but thanks for the message

If you set DYNMODE to 1, Grrr's code should popup the options on the screen.

Grrr1337...Works like a charm now.

Lee...

What is the

Code - Auto/Visual Lisp: [Select]
  1. (not (member...

doing? I like having that option to enter either way. It's what would be expected from an AutoCAD command.

J. Logan
Acad 2018

Edit: Don't answer that last question Lee. I never realized I could just click on any of the blue text and be taken to a definition page for that word. Life just got easier, me thinks. I know...what was I thinking?

Title: Re: Set a default and ask the user for input
Post by: Lee Mac on December 07, 2018, 01:16:24 PM
I never realized I could just click on any of the blue text and be taken to a definition page for that word. Life just got easier, me thinks. I know...what was I thinking?

You have John Kaul (Se7en) to thank for that cool feature of this site  :wink:
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 07, 2018, 01:39:57 PM
Well then, Thank you John Kaul (Se7en) for that handy feature. Well played sir!

J. Logan
ACAD 2018
Title: Re: Set a default and ask the user for input
Post by: ronjonp on December 07, 2018, 02:04:22 PM
I beat you to the punch on that one RonJonp but thanks for the message
Glad you got it sorted .. FWIW here's a little constructive criticism. Happy coding! :)
Code - Auto/Visual Lisp: [Select]
  1. (defun c:zigzag (/ *error* a oldosmode)
  2.   ;; Error handler to reset osmode if you hit a snag
  3.   (defun *error* (msg)
  4.     (and oldosmode (setvar 'osmode oldosmode))
  5.     (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\n** Error: " msg " **")))
  6.     (princ)
  7.   )
  8.   (setq oldosmode (getvar 'osmode))
  9.   ;; No need to gather all these variable since you're not changing them below
  10. ;;;  (setq clt (getvar 'celtype))
  11. ;;;  (setq clts (getvar 'celtscale))
  12. ;;;  (setq lts (getvar 'ltscale))
  13. ;;;  (setq clayr (getvar 'clayer))
  14.   (setvar 'osmode 1)
  15.   ;; Use one of the sugestions here
  16.   (initget 6)
  17.   (getreal "\Enter LTSCALE [.25/.5] :")
  18.   ;; this could be
  19. ;;;  (if (= (tblsearch "ltype" a) nil)
  20. ;;;    (command "-linetype" "l" a "acad.lin" "")
  21. ;;;  )
  22.   ;; this
  23.   (or (tblsearch "ltype" (setq a "zigzag")) (command "-linetype" "l" a "acad.lin" ""))
  24.   (command "._layer" "make" "CLOUD" "Color" "RED" "CLOUD" "")
  25.   (command "-linetype" "_s" a "")
  26.   (command "pline")
  27.   (while (> (getvar 'cmdactive) 0) (command pause))
  28.   ;; No need to set all these variable since they never changed
  29. ;;;  (setvar 'celtype clt)
  30. ;;;  (setvar 'celtscale clts)
  31. ;;;  (setvar 'clayer clayr)
  32. ;;;  (setvar 'ltscale lts)
  33.   (setvar 'osmode oldosmode)
  34.   (princ)
  35. )
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 07, 2018, 02:48:03 PM
Thanks for that RonJonp. I don't mind at all when someone points things out to me.

Have a good weekend.

J. Logan
ACAD 2018
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 07, 2018, 04:52:57 PM
Turns out I have to revisit this. I forgot about adjusting for drawings with different Dimscale settings

Code - Auto/Visual Lisp: [Select]
  1.     (progn
  2.       (initget 6)
  3.         (not (member (setq scl (cond ((getreal "\nSet LTSCALE [.25 Text/.5 Lines] <.5>: ")) (0.5))) '(0.25 0.5)))
  4.     )
  5.      (Alert "\nYou Must Choose 0.25 or 0.5")
  6.   )
  7.   (setvar 'ltscale scl)

Am I correct in saying the above is setting the ltscale based on the result the user picks?

Code - Auto/Visual Lisp: [Select]
  1. (setq scl (cond...
  2. (setvar 'ltscale scl)

If so, it seems to me I need to add the use of the dimscale variable in the (cond statement. Not sure though.

J. Logan
ACAD 2018
Title: Re: Set a default and ask the user for input
Post by: kdub_nz on December 07, 2018, 06:54:37 PM
How about something like

Code - Auto/Visual Lisp: [Select]
  1. (setvar 'ltscale (* scl (getvar "DIMSCALE")))

Because it's a scalar value your users will understsand that either option will be multiplied by Dimscale
... or add a note to the prompt to that effect.
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 08, 2018, 01:45:42 PM
Thanks kdub.

So this is how I tried it before asking this forum.
Same thing but alot more typing???

Code - Auto/Visual Lisp: [Select]
  1. (setq dim (getvar 'dimscale)
  2. (setvar 'ltscale (* scl dim))

Well that and it didn't seem to work the first time. Just tried it again as a test and it worked.
Maybe it was a simple as me not changing the dimscale to something other than (1) when I tested the first time.
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 08, 2018, 02:27:27 PM
Something isn't right with this code.

It does everything I want, but I'm finding that the linetype scale doesn't seem to be
correct. When I check the properties of a zigzag line I've drawn, it shows the ltscale as 1.00. When I clearly chose .25 or .5.
It will not let me physically change the ltscale property in the properties dialog unless I use the calculator. When I do, it changes the zigzag linetype scale and size to what I assume is the correct scale.

Am I truly drawing the zigzag line at my chosen ltscale?


Code - Auto/Visual Lisp: [Select]
  1. (defun c:ZigZag (/ *error* a oldosmode)
  2.   ;; Error handler to reset osmode if you hit a snag
  3.   (defun *error* (msg)
  4.     (and oldosmode (setvar 'osmode oldosmode))
  5.     (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
  6.         (princ (strcat "\n** Error: " msg " **"))
  7.     )
  8.     (princ)
  9.   )
  10.   (setq cosmode (getvar 'osmode))
  11.   (setq clt (getvar 'celtype))
  12.   (setq clayr (getvar 'clayer))
  13.   (setvar 'osmode 1)
  14.   (setq a "zigzag")
  15.  
  16.   (while
  17.     (progn
  18.       (initget 6)
  19.         (not (member (setq scl (cond ((getreal "\nSet LTSCALE [.25 Text/.5 Lines] <.5>: ")) (0.5))) '(0.25 0.5)))
  20.     )
  21.      (Alert "\nYou Must Choose 0.25 or 0.5")
  22.   )
  23.  
  24.   (setvar 'ltscale (* scl (getvar 'dimscale)))
  25.  
  26.   (if (= (tblsearch "ltype" a) nil)
  27.     (command "-linetype" "l" a "acad.lin" "")
  28.   )
  29.  
  30.   (command "._layer" "make" "CLOUD" "Color" "RED" "CLOUD" "")
  31.   (command "-linetype" "_s" a "")
  32.   (command "pline")
  33.  
  34.   (while (> (getvar 'cmdactive) 0)
  35.     (command pause)
  36.   )
  37.  
  38.   (setvar 'osmode cosmode)
  39.   (setvar 'celtype clt)
  40.   (setvar 'clayer clayr)
  41.  
  42.   (princ)
  43. )

Title: Re: Set a default and ask the user for input
Post by: Lee Mac on December 08, 2018, 03:48:12 PM
Here are some suggestions for your code:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:zigzag ( / *error* lay ltp scl val var )
  2.     ;; Define function and declare local variables
  3.  
  4.     ;; Define a local error handler to reset system variables in the event of an error
  5.     (defun *error* ( msg )
  6.         (mapcar 'setvar var val) ;; Reset system variables
  7.         (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")) ;; Suppress cancellation messages
  8.             (princ (strcat "\nError: " msg)) ;; Print critical errors
  9.         ) ;; end IF
  10.         (princ) ;; Suppress the value returned by the last evaluated expression
  11.     ) ;; end DEFUN
  12.  
  13.     (setq var '(cmdecho clayer celtype celtscale osmode) ;; List of system variables whose values will be modified
  14.           val  (mapcar 'getvar var) ;; Retrieve current values
  15.           ltp  "ZIGZAG" ;; Linetype to be set
  16.           lay  "CLOUD"  ;; Layer for polyline
  17.     ) ;; end SETQ
  18.    
  19.     (while ;; While the following expression returns a non-nil value
  20.         (progn ;; Evaluate the following expressions and return the value returned by the last expression
  21.             (initget 6) ;; Disallow zero or negative values
  22.             ;; Whilst the supplied value is not a member of this list:
  23.             (not (member (setq scl (cond ((getreal "\nSet LTSCALE [.25 Text/.5 Lines] <.5>: ")) (0.5))) '(0.25 0.5)))
  24.         ) ;; end PROGN
  25.         (princ "\nYou must choose 0.25 or 0.5.") ;; Notify the user to provide another value
  26.     ) ;; end WHILE
  27.    
  28.     (setvar 'cmdecho 0) ;; Suppress command-line echo
  29.     (if (not (tblsearch "ltype" ltp)) ;; If the linetype isn't defined in this drawing
  30.         (command "_.-linetype" "_l" ltp "acad.lin" "") ;; Load it
  31.     ) ;; end IF
  32.    
  33.     ;; Create/modify the target layer and make it current
  34.     (command "_.-layer" "_M" lay "_C" "Red" lay "")
  35.     (setvar 'celtype ltp) ;; Make the linetype current
  36.     (setvar 'celtscale (* scl (getvar 'dimscale))) ;; Set the linetype scale appropriately
  37.     (setvar 'osmode  1) ;; Set Object Snap to Endpoint
  38.     (setvar 'cmdecho 1) ;; Now we want command-line echo
  39.     (command "_.pline") ;; Initiate the PLINE command
  40.    
  41.     (while (< 0 (getvar 'cmdactive)) ;; While the command is active, pause
  42.         (command "\\") ;; Pause for user input
  43.     ) ;; end WHILE
  44.    
  45.     (mapcar 'setvar var val) ;; Reset the system variable values
  46.     (princ) ;; Suppress the value returned by the last evaluated expression
  47. ) ;; end DEFUN
Title: Re: Set a default and ask the user for input
Post by: kdub_nz on December 08, 2018, 05:27:58 PM
A more universal selector for the LineTypeFile may be something like :


Code - Auto/Visual Lisp: [Select]
  1.  
  2.  (if (zerop (getvar "measurement") )
  3.    (setq LineTypeFile (findfile "acad.lin"))
  4.    (setq LineTypeFile (findfile "acadiso.lin")) ;; for metric system
  5.  )
  6.  
Title: Re: Set a default and ask the user for input
Post by: Marc'Antonio Alessi on December 10, 2018, 04:15:15 AM
A more universal selector for the LineTypeFile may be something like :


Code - Auto/Visual Lisp: [Select]
  1.  
  2.  (if (zerop (getvar "measurement") )
  3.    (setq LineTypeFile (findfile "acad.lin"))
  4.    (setq LineTypeFile (findfile "acadiso.lin")) ;; for metric system
  5.  )
  6.  
My version:

Code: [Select]
; Function: ALE_Layer_LoadLinetype
;
; Version 1.00 - 16/11/2006
;
; Arguments:
;   VlaDoc: IAcadDocument: An AutoCAD drawing or IAxDbDocument: Interface
;   LTpCol: LineType Collection
;   LtpNam: Linetype name [STR]
;
; Return Values: [VLA-OBJECT] or nil if vla-load fails
;
; Example:
;   (or *AcadApp* (setq *AcadApp* (vlax-get-Acad-Object)            ))
;   (or *AcAcDwg* (setq *AcAcDwg* (vla-get-ActiveDocument *AcadApp*)))
;   (or *AcLnTps* (setq *AcLnTps* (vla-get-Linetypes      *AcAcDwg*)))
;
;   (ALE_Layer_LoadLinetype *AcAcDwg* *AcLnTps* "Divide")
;
(defun ALE_Layer_LoadLinetype (VlaDoc LTpCol LtpNam / VrtVal)
  (cond
    ( (ALE_Utl_GetItem LTpCol LtpNam) )
    ( (vl-catch-all-error-p
        (vl-catch-all-apply
          'vla-load
          (list
            LTpCol
            LtpNam
            (cond
              ( (vl-catch-all-error-p (setq VrtVal (vl-catch-all-apply 'vla-getvariable (list VlaDoc "MEASUREINIT"))))
                "acadiso.lin"  ; load linetype from metric  linetype file if VlaDoc is a IAxDbDocument: Interface
              )                ; because getvariable it is not a property of a ODbx Document
              ( (zerop (vlax-variant-value VrtVal));English or metric
                 "acad.lin"    ; load linetype from english linetype file
              )
              ( "acadiso.lin" ); load linetype from metric  linetype file
            )
          )
        )
      )
;_i__ (alert (strcat "Asso message:\nTipolinea '" LtpNam "' non trovato in Acadxxx.lin"))
;|e|; (alert (strcat "Asso message:\nLinetype '"  LtpNam "' not found in Acadxxx.lin"  ))
    )
    ( (ALE_Utl_GetItem LTpCol LtpNam) )
  )
)

; Function: ALE_Utl_GetItem
;
; Arguments:
;   VlaCol = Collection Object > ex. (vla-get-Layers *AcAcDwg*)
;   KeyNam = String            > "0"
;
; Return Values:
;   VLA-OBJECT or nil if (vla-item) fails
;
; Note:
;   the Item method is case-sensitive when used with the SelectionSets
;   collection it is not case-sensitive for other collections.
;
; Example:
;  (ALE_Utl_GetItem
;    (vla-get-Layers (vla-get-ActiveDocument (vlax-get-Acad-Object)))
;    "0"
;  )
;
(defun ALE_Utl_GetItem (VlaCol KeyNam / VlaObj)
  (vl-catch-all-apply
   '(lambda ( )
      (setq VlaObj (vla-item VlaCol KeyNam))
    )
  )
  VlaObj
)
 
Title: Re: Set a default and ask the user for input
Post by: jlogan02 on December 10, 2018, 05:12:25 PM
Thanks guys for all the suggestions.

Lee, I like...

Code - Auto/Visual Lisp: [Select]
  1. (setq var '(cmdecho clayer celtype celtscale osmode) ;; List of system variables whose values will be modified
  2.           val  (mapcar 'getvar var) ;; Retrieve current values

With my limited exposure I hadn't really considered this. Makes sense though. Thanks for the line by line comments to. Big help.

kdub,

Although I didn't use your suggestion, I filed it away in my "starter code" folder.

Marc' Antonio,

Sadly I'm not familiar with this approach. Baby steps, I say. Baby steps.
Title: Re: Set a default and ask the user for input
Post by: Lee Mac on December 10, 2018, 05:55:15 PM
You're most welcome - feel free to ask if any of the comments are unclear  :-)