设置和重置系统变量 - AutoCAD LISP

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (19)

我试图在AutoCAD中使绘图接线图非常容易,除了我预先编程的按钮之外没有按钮按下。

其中一个涉及LISP,它不能很好地设置系统变量,然后将它们重置为之前的状态。该程序似乎执行预期的功能,但不是预期的结果。

一旦我的PLINE命令开始,变量得到重置。我需要PLINE启动,完成,然后变量重置。

我已经尝试在LISP中的命令中设置OrthoMode和SnapMode,以及通过(setvar (getvar ...))命令。

(defun varget ()
    (setq lis '("orthomode" "snapmode"))
    (setq var (mapcar 'getvar lis))
    (setq var1 '(1 1))
    (setq no 0)
    (repeat (length lis)
        (setvar (nth no lis) (nth no var1))
        (setq no (1+ no))
    )
    (princ)
 )

(defun varset ()
    (setq no 0)
    (repeat (length lis)
        (setvar (nth no lis) (nth no var))
        (setq no (1+ no))
    )
(princ)
)

(princ)

(defun C:wire ()
(progn
(varget)
(setq prevlayer (getvar "clayer"))
(setq P (getstring "Audio(A)/Video(V)/Comm(CO)/Coax(R)/Control(C)/(N)etwork/(P)ower:"))
(IF (= P "V")(command "-LAYER" "M" "VIDEO" "C" "150" "" "" "PLINE" PAUSE))
(IF (= P "A")(command "-LAYER" "M" "AUDIO" "C" "94" "" "" "PLINE" PAUSE))
(IF (= P "CO")(command "-LAYER" "M" "COMM" "C" "206" "" "" "PLINE" PAUSE))
(IF (= P "R")(command "-LAYER" "M" "COAX" "C" "44" "" "" "PLINE" PAUSE))
(IF (= P "C")(command "-LAYER" "M" "CONTROL" "C" "10" "" "" "PLINE" PAUSE))
(IF (= P "N")(command "-LAYER" "M" "NETWORK" "C" "210" "" "" "PLINE" PAUSE))
(IF (= P "P")(command "-LAYER" "M" "POWER" "C" "7" "" "" "PLINE" PAUSE))
(setvar "clayer" prevlayer)
(varset)
(princ)
);Progn
);defun

没有错误消息。

我希望执行PLINE命令重置变量。

提问于
用户回答回答于

您的代码的问题在于,您只是在尝试重置系统变量并完成程序评估之前暂停单个用户输入。

相反,在继续进行程序评估之前,您需要使用循环来持续暂停用户输入。

例如:

;; Define function, declare local symbols
(defun c:wire ( / col lay opt val var )

    ;; System variables to be modified within the program
    (setq var '(clayer orthomode snapmode cmdecho)
    ;; Retrieve current sys var values
          val  (mapcar 'getvar var)                
    ) ;; end setq

    ;; Predefine the getkword options
    (initget "Audio Video COmm R Control Network Power")
    ;; Prompt the user for input, default to "Audio" on null input
    (setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))

    ;; Define the layer & colour based on the option returned
    (cond
        (   (= opt "Audio")   (setq lay "AUDIO"    col  94))
        (   (= opt "Video")   (setq lay "VIDEO"    col 150))
        (   (= opt "COmm")    (setq lay "COMM"     col 206))
        (   (= opt "R")       (setq lay "COAX"     col  44))
        (   (= opt "Control") (setq lay "CONTROL"  col  10))
        (   (= opt "Network") (setq lay "NETWORK"  col 210))
        (   (= opt "Power")   (setq lay "POWER"    col   7))
    ) ;; end cond

    ;; Suppress command-line output for the -LAYER command
    (setvar 'cmdecho 0)
    ;; Create & set the layer & layer colour
    (command "_.-layer" "_M" lay "_C" col "" "")

    ;; Set everything except the first sys var
    (mapcar 'setvar (cdr var) '(1 1 1))
    ;; Initiate the PLINE command
    (command "_.pline")
    ;; Continuously pause for user input
    (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))

    ;; Reset system variables
    (mapcar 'setvar var val)

    ;; Suppress the value returned by the last evaluated expression
    (princ) 
) ;; end defun

需要注意的几点:

  • 始终声明局部变量以避免与文档命名空间中具有相同名称的变量发生冲突。见我的教程这里的更多信息,如何和为什么这样做。
  • 使用getkword到位的getstring控制和验证用户的输入。
  • 用于"\\"代替pause符号,因为pause符号是一个不受保护的全局变量,很容易在程序之外无意中重新定义,导致程序中断。由于pause符号评估,"\\"您也可以使用文字反斜杠。

作为扩展,您可能还需要考虑实现一个本地错误处理程序来处理用户Esc在评估程序期间不可避免地按下的时间(系统变量在这种情况下不会被重置)。我在这里的教程中描述了如何做到这一点

这是一个演示包含本地错误处理程序的基本示例:

;; Define function, declare local symbols
(defun c:wire ( / *error* col lay opt val var )

    ;; Define local error handler
    (defun *error* ( msg )
        ;; Reset system variables
        (mapcar 'setvar var val)
        ;; Suppress the output of standard cancellation messages
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            ;; Print critical errors
            (princ (strcat "\nError: " msg))
        ) ;; end if
        (princ) ;; Suppress the value returned by the last evaluated expression
    ) ;; end defun

    ;; System variables to be modified within the program
    (setq var '(clayer orthomode snapmode cmdecho)
    ;; Retrieve current sys var values
          val  (mapcar 'getvar var)                
    ) ;; end setq

    ;; Predefine the getkword options
    (initget "Audio Video COmm R Control Network Power")
    ;; Prompt the user for input, default to "Audio" on null input
    (setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))

    ;; Define the layer & colour based on the option returned
    (cond
        (   (= opt "Audio")   (setq lay "AUDIO"    col  94))
        (   (= opt "Video")   (setq lay "VIDEO"    col 150))
        (   (= opt "COmm")    (setq lay "COMM"     col 206))
        (   (= opt "R")       (setq lay "COAX"     col  44))
        (   (= opt "Control") (setq lay "CONTROL"  col  10))
        (   (= opt "Network") (setq lay "NETWORK"  col 210))
        (   (= opt "Power")   (setq lay "POWER"    col   7))
    ) ;; end cond

    ;; Suppress command-line output for the -LAYER command
    (setvar 'cmdecho 0)
    ;; Create & set the layer & layer colour
    (command "_.-layer" "_M" lay "_C" col "" "")

    ;; Set everything except the first sys var
    (mapcar 'setvar (cdr var) '(1 1 1))
    ;; Initiate the PLINE command
    (command "_.pline")
    ;; Continuously pause for user input
    (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))

    ;; Reset system variables
    (mapcar 'setvar var val)

    ;; Suppress the value returned by the last evaluated expression
    (princ) 
) ;; end defun

扫码关注云+社区

领取腾讯云代金券