ysq101 发表于 2014-4-13 00:38:59

处女作:关于错误处理----其实可以不写

本帖最后由 ysq101 于 2014-4-13 00:44 编辑

处女作:
关于错误处理,BBS上有很多这类型的主题
下面来点新手的见解:
众所周知,大程序需要做得更人性化,就必须加入错误处理
但是小程序呢.其实可以不写,这里面有点小技巧   也许大师们早发现了
我比较迟钝,现在才发现,现如今分享出来,希望对大家有一点点用

先来说说小程序
例子:
(defun c:tt ()
;用户输入
(setq ss (ssget))
(setq pt (getpoint))
(setq a (getreal))

   ;更改系统变量
   (setvar "cmdecho" 0)
(setvar "********" **)
;程序代码
   ("command" "undo" "be")
.......
.......
.......
   ("command" "undo" "e")

;还原系统变量

(setvar "cmdecho" 1)
)


发现规律了吗??

ssget getpoint getreal等等需要用户输入的代码都放最前面
然后再改变系统变量   (关捕捉等....)
再写    处理图元代码
再    还原系统变量

先来模拟一下用户的操作:

第一步:选择对像   -----哎,选错了ESC强退程序重新选                        程序中断,后面的代码没被执行
第二步:指定一个点 -----咦,点错了ESC强退程序重来                        程序中断,后面的代码没被执行
第三步:输入一个数 -----哎,输入的数值错得太多,懒得删, ESC强退程序 程序中断,后面的代码没被执行第四步:程序自动完成 (小程序速度太快)   用户没有机会按ESC强退程序



用户也只能在第三步前人为的终止程序
后来用户即使发现之前输入错误时也没办法了,,,只能是让程序执行完再UNDO了


嘻嘻,这样是不是就不用写错误处理了??
以上只是新手见解
望高手指点

大程序就让大师们来补充了

题外话:
之前就是用别人的程序没写误处理
系统变量被改得面目前非而且还不知道他改了些什么系统变量
尤其是UDNO 经常没有END 没法回退
所以要自己学LISP



Free-Lancer 发表于 2014-4-13 02:03:21

本帖最后由 Free-Lancer 于 2014-4-13 02:05 编辑

综合到一起给大家一个完整版的 *error* 处理机制,这些函数大都来源于网络,只是稍加整理通用化了,可以作为 A/Vlisp 程序的错误处理机制的终极版本

;; *error*
(defun fy:error      (msg)
(if (and msg (/= msg "Function cancelled"))
    (prompt (strcat "Error: " msg))
    (princ)
)
(fy:end)
(princ)
)
;;start progam
(defun fy:begin      ()
(setq      olderr      *error*
      *error*      fy:error
)
(fy:Clearcset)
(fy:startundo)
t
)
;;progame end
(defun fy:end ()
(fy:unsetv)
(setq      *error*      olderr
      *sysvars* nil
)
(if *FyGlobleSym*
    (progn
      (if (vl-symbolp (car *FyGlobleSym*))
      (foreach x *FyGlobleSym* (set x nil))
      (foreach x *FyGlobleSym* (set (read x) nil))
      )
      (setq *FyGlobleSym* nil)
    )
)
(fy:endundo)
(princ)
)
;;push sysvar
(defun fy:setv (name value / oldval)
(setq oldval (getvar name))
(if (not (assoc name *sysvars*))
    (setq *sysvars* (append *sysvars* (list (cons name oldval))))
)
(setvar name value)
oldval
)
;;Restore sysvar
(defun fy:unsetv ()
(foreach v *sysvars* (setvar (car v) (cdr v)))
)
;;ActiveDocument
(defun Fy:acDoc      nil
(eval      (list 'defun
            'FY:acdoc
            'nil
            (vla-get-activedocument (vlax-get-acad-object))
      )
)
(fy:acdoc)
)
;;StartUndo Mark
(defun fy:StartUndo ()
(vla-startundomark (fy:acdoc))
)
;;EndUndo Mark
(defun fy:EndUndo ()
(vla-endundomark (fy:acdoc))
)
;;ActiveSelectionSets
(defun fy:acsets nil
(eval      (list 'defun
            'fy:acsets
            'nil
            (vla-get-Selectionsets (fy:acdoc))
      )
)
(fy:acsets)
)
;; From eachy
(defun fy:Clearcset (/ cset)
(if (not (vl-catch-all-error-p
             (setq cset
                  (vl-catch-all-apply
                      'vla-item
                      (list
                        (fy:acsets)
                        "CURRENT"
                      )
                  )
             )
         )
      )
    (vla-delete cset)
)
(princ)
)

使用方法

程序起始
(fy:begin);_完成初始化,标记 Undo
...
(fy:setv "cmdecho" 0);_程序中用这个函数替代 setvar,功能是仅保存系统变量的初始状态,后面可以根据需要再次对同一系统变量进行设置,但以后的设置仅仅是 setvar , 不会再保存该系统变量,类似 xdrx_sysvar_push ,堆栈概念;同时完成 ActiveX 中的 ActiveSelectionSet 的初始化
...
(fy:end);_程序结束,恢复保存的系统变量至程序运行前状态,程序运行编组结束

以上代码就是 app.fas 中的部分,编译版可以在下方签名链接下载

st788796 发表于 2014-4-13 02:12:49

简单程序可以用 vl-catch-all-apply 进行包裹,不写 *error* 部分

kwok 发表于 2014-4-13 10:23:13

这个要支持一下,方法不错.

/db_自贡黄明儒_ 发表于 2014-4-13 10:36:15

st788796 发表于 2014-4-13 02:12
简单程序可以用 vl-catch-all-apply 进行包裹,不写 *error* 部分

还是你的这个办法好,赞!

ysq101 发表于 2014-4-13 12:54:55

kwok 发表于 2014-4-13 10:23
这个要支持一下,方法不错.

谢谢支持~~~~

ysq101 发表于 2014-4-13 12:55:40

Free-Lancer 发表于 2014-4-13 02:03
综合到一起给大家一个完整版的 *error* 处理机制,这些函数大都来源于网络,只是稍加整理通用化了,可以作 ...

我的宗旨是偷懒不用写哈

ysq101 发表于 2014-4-13 12:56:54

st788796 发表于 2014-4-13 02:12
简单程序可以用 vl-catch-all-apply 进行包裹,不写 *error* 部分

谢谢指点....回去试试

chen7560152 发表于 2022-12-18 17:32:23

感谢大佬分享,学习了

happyending 发表于 2025-12-18 08:01:39

学习一下错误处理。感谢分享。
页: [1]
查看完整版本: 处女作:关于错误处理----其实可以不写