处女作:关于错误处理----其实可以不写
本帖最后由 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: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 中的部分,编译版可以在下方签名链接下载 简单程序可以用 vl-catch-all-apply 进行包裹,不写 *error* 部分 这个要支持一下,方法不错. st788796 发表于 2014-4-13 02:12
简单程序可以用 vl-catch-all-apply 进行包裹,不写 *error* 部分
还是你的这个办法好,赞! kwok 发表于 2014-4-13 10:23
这个要支持一下,方法不错.
谢谢支持~~~~
Free-Lancer 发表于 2014-4-13 02:03
综合到一起给大家一个完整版的 *error* 处理机制,这些函数大都来源于网络,只是稍加整理通用化了,可以作 ...
我的宗旨是偷懒不用写哈
st788796 发表于 2014-4-13 02:12
简单程序可以用 vl-catch-all-apply 进行包裹,不写 *error* 部分
谢谢指点....回去试试
感谢大佬分享,学习了 学习一下错误处理。感谢分享。
页:
[1]