天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 71|回复: 1

Lisp程序设计错误处理的技巧

[复制链接]
  • TA的每日心情
    开心
    前天 09:51
  • 签到天数: 80 天

    [LV.6]常住居民II

    1564

    主题

    202

    回帖

    214748万

    积分

    管理员

    积分
    2147483647
    发表于 2024-4-6 16:40:32 | 显示全部楼层 |阅读模式
    1. ;|
    2.   Gxl-ErrStaSys  -> Gxl-ErrEnd ;只针对系统变量的恢复
    3.   Gxl-ErrSta     -> Gxl-ErrEnd ;系统变量+函数+编组
    4.   Gxl-ErrStaNrm  -> Gxl-ErrEndNrm ;只针对自定义常量的恢复
    5. |;

    6. Lisp程序设计错误处理的技巧@Gu_xl,由Kucha梳理 (源自博客:http://guxl.mjtd.com/?p=14)

    7.   任何程序在运行中都可能不完全会按照程序设计者预想的方式去运行,程序运行中会出现各种意想不到的情况,
    8.   AutoLisp提供的标准错误处理函数*error*,仅能告诉你程序运行有了错误,但不能对错误进行善后处理。
    9.   这对于一个优秀的程序来说,是不能忍受的,为此,我们应当用自定义的错误处理函数来改善这种情况,使程序在出现任何错误情况下都能正确处理!

    10. //一、在程序内设置局部自定义错误处理函数
    11.   AutoLisp提供内部提供了一个标准的自定义错误处理函数:(*error* string)
    12.   当AutoLisp程序运行出错时, *error* 函数值不为空
    13.   AutoCAD会传递给 *error* 函数的参数 string 一个错误信息字符串值,并自动执行 *error* 函数。
    14.   根据这个错误处理运行机制,我们可以根据自己的需要,对错误处理函数 *error* 进行自定义。
    15.   ;;;例1:自定义如下错误处理函数:
    16.   (defun *error* (Msg)
    17.     (princ "error:")
    18.     (princ Msg);打印错误信息
    19.     (princ)
    20.   )

    21.   当Lisp程序运行出错时,系统会自动调用 *error* 函数,打印出错误处理信息。
    22.   但是这个错误处理函数几乎没有什么用,该错误处理函数仅仅是对错误信息进行了输出,没有对可能出现的错误进行任何处理
    23.   这可不是我们想要的程序,我们需要对 *error* 函数内容根据程序处理的需要进行定制!
    24.   ;;;例2:下面是一个绘制三角形的例子,程序目的是在图上选取三点,自动绘制三角形,。
    25.   (defun C:TT (/ Old_CMD Old_OSM p1 p2 P3)
    26.     (setq Old_CMD (getvar "cmdecho"));保存系统变量cmdecho值
    27.     (setvar "cmdecho" 0);关闭命令行的回显提示
    28.     (setq Old_OSM (getvar "osmode"));保存系统变量osmode值
    29.     (setvar "osmode" 0);关闭捕捉模式

    30.     (setq p1 (getpoint "\n输入第一点: ")
    31.           P2 (getpoint "\n输入第二点: ")
    32.           P3 (getpoint "\n输入第三点: ")
    33.     )
    34.     (vl-cmdf "_.pline" p1 p2 p3 "c")

    35.     (setvar "cmdecho" Old_CMD);恢复cmdecho系统变量
    36.     (setvar "osmode" Old_OSM);恢复osmode系统变量
    37.     (princ)
    38.   )

    39.   在程序正常运行的情况下,程序会在绘制完三角形后自动恢复系统变量"osmode"、" Old_CMD",
    40.   但是在图面选取点时,按下ESC键,或某个点输入为空,会导致程序出错
    41.   后面的恢复系统变量值的代码则不会执行,程序关闭了捕捉模式,我们不得不手动来重新设置捕捉方式。
    42.   为此,我们在程序的开始自定义一个错误处理函数 *error* ,在 *error* 函数内添加恢复系统变量"osmode"、" Old_CMD"的代码
    43.   在程序运行出错时自动调用 *error* 函数, *error* 函数内恢复系统变量"osmode"、" Old_CMD"的代码自动运行
    44.   这便达到了我们对程序错误处理的要求!示例代码如下:
    45.   (defun C:TT (/ *error* Old_OSM Old_CMD p1 p2 P3)
    46.     (defun *error* (Msg)
    47.         (setvar "cmdecho" Old_CMD);恢复cmdecho系统变量
    48.         (setvar "osmode" Old_OSM);恢复osmode系统变量
    49.         (princ "error: ")
    50.         (princ Msg);打印错误信息
    51.         (princ)
    52.     )
    53.     ;;以下为主程序内容
    54.     (setq Old_CMD (getvar "cmdecho"));保存系统变量cmdecho值
    55.     (setvar "cmdecho" 0);关闭命令行的回显提示
    56.     (setq Old_OSM (getvar "osmode"));保存系统变量osmode值
    57.     (setvar "osmode" 0);关闭捕捉模式

    58.     (setq p1 (getpoint "\n输入第一点: ")
    59.           P2 (getpoint "\n输入第二点: ")
    60.           P3 (getpoint "\n输入第三点: ")
    61.     )
    62.     (vl-cmdf "_.pline" p1 p2 p3 "c")
    63.     (setvar "cmdecho" Old_CMD);恢复cmdecho系统变量
    64.     (setvar "osmode" Old_OSM);恢复osmode系统变量
    65.     (princ)
    66.   )

    67. //二、通用错误处理函数的处理技巧
    68.   请注意,在上面例2的程序中,我们是将 *error* 函数声明为局部变量,则该错误处理仅在test函数范围内有效!
    69.   这样我们就需要在每个程序里都要添加类似的错误处理代码,其实大部分程序的错误处理代码都类似
    70.   如果在每个程序里都添加相同的代码,是一件很讨厌的事儿,会导致代码越来越长
    71.   为此,我们可以做一个通用错误处理函数,以后仅需要调用该函数即可,无需再写出长长的一串代码!
    72.   ;;;例3:自定义通用错误处理初始化函数
    73.   (defun Gxl-ErrStaSys (SysLst / SysNam SysVar)
    74.     ;|(Gxl-ErrStaSys SysLst) 初始化*error*
    75.       功能: 保存 SysLst 给定的系统变量值,并按表给定的系统变量值设置系统变量
    76.       参数:
    77.           SysLst 系统变量及其设置值列表 例如: '("osmode" 0 "cmdecho" 0  "cecolor" "1")
    78.     |;·
    79.     (setq *OldEr* *error*);储存*error*函数
    80.    
    81.     (defun *error* (Msg / SysNam SysVar)
    82.         (if *Old_SysVar* ;储存的系统变量值列表
    83.             (while
    84.                 (and (setq SysNam (car *Old_SysVar*))
    85.                     (setq SysVar (cadr *Old_SysVar*))
    86.                 )
    87.                 (setq *Old_SysVar* (cddr *Old_SysVar*))
    88.                 (setvar SysNam SysVar)
    89.             )
    90.         );恢复
    91.         (setq *error* *OldEr*)
    92.         (or (wcmatch (strcase Msg) "*BREAK,*CANCEL*,*EXIT*")
    93.             (princ (strcat "\n** Error: " Msg " **"))
    94.         )
    95.     );自定义出错函数 *error*
    96.     (if (= 8 (logand (getvar "undoctl") 8))
    97.         (command "_undo" "_e")
    98.     );如果有活动编组,先结束编组
    99.    
    100.     (command "_undo" "_be")
    101.     (if SysLst
    102.         (while
    103.             (and (setq SysNam (car SysLst))
    104.                  (setq SysVar (cadr SysLst))
    105.             )
    106.             (setq *Old_SysVar* (append *Old_SysVar* (list SysNam (getvar SysNam))));储存系统变量
    107.             (setq SysLst (cddr SysLst))
    108.             (setvar SysNam SysVar);设置系统变量
    109.         )
    110.     )
    111.     (princ)
    112.   )
    113.   ;;;例4:自定义通用错误处理恢复函数
    114.   (defun Gxl-ErrEnd ();恢复参数
    115.     (if (= 8 (logand (getvar "undoctl") 8))
    116.       (command "_undo" "_e")
    117.     );如果有活动编组,先结束编组
    118.     (if *OldEr*
    119.         (setq *error* *OldEr*
    120.               *OldEr* nil
    121.         );恢复参数函数
    122.     )
    123.     (if *Old_SysVar* ;恢复储存的系统变量
    124.         (while
    125.           (and (setq SysNam (car *Old_SysVar*))
    126.                (setq SysVar (cadr *Old_SysVar*))
    127.           )
    128.           (setq *Old_SysVar* (cddr *Old_SysVar*))
    129.           (setvar SysNam SysVar)
    130.         )
    131.     )
    132.     (setq *DoFun* nil
    133.           *UnMde* nil
    134.     )
    135.     (princ)
    136.   )

    137.   ;;;实际运用示例:
    138.   (defun C:TT ()
    139.     (Gxl-ErrStaSys '("osmode" 0 "cmdecho" 0 "cecolor" "1"));记录参数
    140.     ;;主程序内容
    141.     .
    142.     .
    143.     (Gxl-ErrEnd);恢复参数
    144.     (princ)
    145.   )

    146.   (Gxl-ErrStaSys SysLst)错误处理函数,当程序运行出错时只可以对保存的系统变量进行恢复
    147.   但这在复杂的程序面前,并不能满足我们的需要,因为各种各样的程序在运行出错后可能还要进行其他各种各样不同的处理
    148.   为此,我们要对 Gxl-ErrStaSys 函数进行进一步改进,使得 Gxl-ErrStaSys 函数可以应对各种可能出现的各种问题。
    149.   ;;;例5:改进后的自定义通用错误处理初始化函数
    150.   (defun Gxl-ErrSta (SysLst DoFun UnMde / SysNam SysVar)
    151.     ;|(Gxl-ErrSta SysLst DoFun UnMde)
    152.       功能: 多功能错误处理函数
    153.       参数:
    154.         SysLst = 系统变量表
    155.         DoFun  = 要执行的函数 ,无动作则为nil
    156.         UnMde  = Undo处理模式 0 = 不编组 1 = 仅仅编组 2 = 回到出错前
    157.     |;
    158.     (setq *OldEr* *error*
    159.           *DoFun* DoFun
    160.           *UnMde* UnMde
    161.     )
    162.     (defun *error* (Msg / SysNam SysVar)
    163.       (if (= 2 *UnMde*)
    164.           (progn
    165.               (if (= 8 (logand (getvar "undoctl") 8))
    166.                   (command "_undo" "_e")
    167.               );如果有活动编组,先结束编组
    168.               (command "_U")
    169.           )
    170.           (progn
    171.             (if *Old_SysVar*
    172.               (while
    173.                   (and (setq SysNam (car *Old_SysVar*))
    174.                       (setq SysVar (cadr *Old_SysVar*))
    175.                   )
    176.                   (setq *Old_SysVar* (cddr *Old_SysVar*))
    177.                   (setvar SysNam SysVar)
    178.               )
    179.             )
    180.             (if *DoFun* (vl-catch-all-apply *DoFun*));执行函数
    181.             (if (= *UnMde* 1)
    182.               (if (= 8 (logand (getvar "undoctl") 8))
    183.                   (command "_undo" "_e")
    184.               );如果有活动编组,先结束编组
    185.             )
    186.           )
    187.       )
    188.       (setq *error* *OldEr*
    189.             *OldEr* nil
    190.             *DoFun* nil
    191.             *UnMde* nil
    192.       )
    193.       (or (wcmatch (strcase Msg) "*BREAK,*CANCEL*,*EXIT*")
    194.           (princ (strcat "\n** Error: " Msg " **"))
    195.       )
    196.     )

    197.     (if (or (= *UnMde* 1) (= *UnMde* 2))
    198.         (progn
    199.             (if (= 8 (logand (getvar "undoctl") 8))
    200.               (command "_undo" "_e")
    201.             );如果有活动编组,先结束编组
    202.             (command "_undo" "_BE");编组开始
    203.         )
    204.     )
    205.     (if SysLst
    206.       (while
    207.         (and (setq SysNam (car SysLst))
    208.              (setq SysVar (cadr SysLst))
    209.         )
    210.         (setq *Old_SysVar* (append *Old_SysVar* (list SysNam (getvar SysNam))))
    211.         (setq SysLst (cddr SysLst))
    212.         (setvar SysNam SysVar)
    213.       )
    214.     )
    215.     (princ)
    216.   )

    217.   ;;;错误处理应用范例:
    218.   (defun C:TT (/ ErrFun p1 p2 p3)
    219.     ;初始化*error* 参数UnMde根据需要可设置为 0 1 2
    220.     (Gxl-ErrSta (list 'blipmode 0 'cmdecho 0 'osmode 0) 'ErrFun 2);出错只编组
    221.     (defun ErrFun () ;出错后*error*要执行的动作
    222.       (alert "出错啦!")
    223.     )
    224.     (setq p1 (getpoint "\n第一点: "))
    225.     (setq p2 (getpoint "\n第二点: "))
    226.     (setq p3 (getpoint "\n第三点: "))
    227.     (vl-cmdf "line" p1 p2 p3 "c")
    228.     ;将UnMde分别设置为 0 1 2,运行到以下任意位置按下ESC试试效果
    229.     (setq p1 (getpoint "\n第一点: "))
    230.     (setq p2 (getpoint "\n第二点: "))
    231.     (setq p3 (getpoint "\n第三点: "))
    232.     (vl-cmdf "line" p1 p2 p3 "c")
    233.     (setq p1 (getpoint "\n第一点: "))
    234.     (setq p2 (getpoint "\n第二点: "))
    235.     (setq p3 (getpoint "\n第三点: "))
    236.     (vl-cmdf "line" p1 p2 p3 "c")
    237.     (setq p1 (getpoint "\n第一点: "))
    238.     (setq p2 (getpoint "\n第二点: "))
    239.     (setq p3 (getpoint "\n第三点: "))
    240.     (vl-cmdf "line" p1 p2 p3 "c")
    241.     (Gxl-ErrEnd)
    242.     (princ)
    243.   )

    244.   可能有些读者觉得对于这样的出错处理函数中,对于系统变量表参数,要写一长串变量,也很麻烦
    245.   因为在程序中,我们经常要设置和使用的一些系统变量都数量有限。为此,我们提供另外一种错误处理的方法和思路
    246.   在初始化错误函数中保存一些常用的系统变量初始值,储存在全局变量中,然后初始化一些常用系统变量的值
    247.   程序中可以对这些已经保存的系统变量任意修改,在程序结束时用错误恢复函数自动恢复系统变量值,程序出错时由错误处理函数来恢复系统变量值。
    248.   我们将一些有关经常使用的系统变量名储存表,设为常量 *SNLst* :

    249.   (setq *SNLst* (list 'AUNITS 'AUPREC 'ATTDIA 'ATTREQ 'BLIPMODE 'DIMZIN 'CECOLOR
    250.                         'CELTYPE 'CLAYER 'CMDECHO 'TRIMMODE 'EXPERT 'HIGHLIGHT 'LUNITS
    251.                         'LUPREC 'EDGEMODE 'OSMODE 'ORTHOMODE 'TEXTSTYLE 'PLINEWID 'PLINEGEN
    252.                         'FILEDIA 'PICKBOX 'QAFLAGS 'UCSAXISANG 'CELTSCALE 'NOMUTT
    253.                         'PEDITACCEPT 'Mirrtext 'limcheck
    254.                   )
    255.   );*SNLst* 常用系统变量表

    256.   ;;;例6、自定义通用错误处理函数Gxl-ErrSta02:
    257.   (defun Gxl-ErrStaNrm (DoFun UnMde)
    258.     ;|自定义错误处理函数 Gxl-ErrStaNrm
    259.       参数:
    260.         DoFun = 要执行的函数,无动作则为nil
    261.         UnMde = Undo处理模式 0 = 不编组 1 = 仅仅编组 2 = 回到出错前
    262.     |;
    263.     (defun *error* (Msg / SysNam SysVar)
    264.       (if (= 2 *UnMde*)
    265.         (progn
    266.             (if (= 8 (logand (getvar "undoctl") 8))
    267.               (command "_undo" "_e")
    268.             );如果有活动编组,先结束编组
    269.             (command "_U")
    270.         )
    271.         (progn
    272.           (if *DoFun* (vl-catch-all-apply *DoFun*));执行函数
    273.           (if (= *UnMde* 1)
    274.               (if (= 8 (logand (getvar "undoctl") 8))
    275.                   (command "_undo" "_e")
    276.               );如果有活动编组,先结束编组
    277.           )
    278.         )
    279.       )
    280.       (if (and *SVLst* *SNLst*)
    281.           (mapcar
    282.             '(lambda (a b)
    283.               (vl-catch-all-apply 'setvar (list a b))
    284.             )
    285.             *SNLst*
    286.             *SVLst*
    287.           )
    288.       );回收变量值
    289.       (setq *error* *OldEr*
    290.             *OldEr* nil
    291.             *DoFun* nil
    292.             *UnMde* nil
    293.             *SVLst* nil
    294.       )
    295.       (or (wcmatch (strcase Msg) "*BREAK,*CANCEL*,*EXIT*")
    296.           (princ (strcat "\n** Error: " Msg " **"))
    297.       )
    298.     );定义出错函数

    299.     ;程序开始
    300.     (setq *SVLst* nil);*SVLst* 用于储存系统变量表 *SNLst* 中系统变量对应的值
    301.     (setq *SVLst* (mapcar '(lambda (x) (getvar x)) *SNLst*))
    302.     ;对一些程序中必须要初始化为0的系统变量初始化为0
    303.     (foreach XX '("ATTDIA" "ATTREQ" "BLIPMODE" "CMDECHO" "DIMZIN" "OSMODE" "ORTHOMODE" "MIRRTEXT")
    304.         (setvar XX 0)
    305.     )
    306.     (setq *OldEr* *error*
    307.           *DoFun* DoFun
    308.           *UnMde* UnMde
    309.     )
    310.   
    311.     (if (or (= *UnMde* 1) (= *UnMde* 2))
    312.       (progn
    313.         (if (= 8 (logand (getvar "undoctl") 8))
    314.           (command "_undo" "_e")
    315.         );如果有活动编组,先结束编组
    316.         (command "_undo" "_BE")
    317.       )
    318.     );是否开始编组
    319.    ;| EXPERT = 5 禁止显示提示
    320.       "块已经存在。重新定义?"
    321.       使用DIMSTYLE 命令的"保存"选项时,如果输入的标注样式名已经存在,系统将显示该提示。
    322.       如果 EXPERT 禁止显示一个提示,相应操作会认为用户已输入 y 确认提示。
    323.       EXPERT 的设置会影响脚本、菜单宏、AutoLISP 及其命令函数。
    324.     |;
    325.     (setvar "EXPERT" 5)
    326.     (setvar "CECOLOR" "BYLAYER");设置颜色随层
    327.     (setvar "celtype" "BYLAYER");设置线型随层
    328.     (setvar "LWDISPLAY" 1);设置显示线宽
    329.     (setvar "CELTSCALE" 1);设置当前线形比例为1
    330.     (setvar "PLINEGEN" 1);设置围绕多段线顶点生成连续线型
    331.   )

    332.   ;;;例7:Gxl-ErrSta02对应的自定义通用错误处理恢复函数
    333.   (defun Gxl-ErrEndNrm ()
    334.     (if (or (= *UnMde* 1) (= *UnMde* 2))
    335.       (if (= 8 (logand (getvar "undoctl") 8))
    336.         (command "_undo" "_e")
    337.       );如果有活动编组,先结束编组
    338.     )
    339.     (if *OldEr*
    340.         (setq *error* *OldEr*
    341.               *OldEr* nil
    342.         );恢复参数函数
    343.     )
    344.     (if (and *SVLst* *SNLst*)
    345.         (mapcar
    346.           '(lambda (a b)
    347.             (vl-catch-all-apply 'setvar (list a b))
    348.           )
    349.           *SNLst*
    350.           *SVLst*
    351.         )
    352.     )
    353.     (setq *DoFun* nil
    354.           *UnMde* nil
    355.           *SVLst* nil
    356.     )
    357.   )(princ)

    358.   ;;;错误处理应用示例:
    359.   (defun C:TT (/ ErrFun p1 p2 p3)
    360.     ;;初始化*error* 参数UnMde根据需要可设置为 0 1 2
    361.     (Gxl-ErrStaNrm 'ErrFun 2);出错只编组,这里省去了系统变量设置
    362.     (defun ErrFun ();出错后*error*要执行的动作
    363.       (alert "出错啦!")
    364.     )
    365.     (setq p1 (getpoint "\n第一点: "))
    366.     (setq p2 (getpoint "\n第二点: "))
    367.     (setq p3 (getpoint "\n第三点: "))
    368.     (vl-cmdf "line" p1 p2 p3 "c")
    369.     ;;将 UnMde分别设置为 0 1 2,运行到以下任意位置按下ESC试试效果
    370.     (setq p1 (getpoint "\n第一点: "))
    371.     (setq p2 (getpoint "\n第二点: "))
    372.     (setq p3 (getpoint "\n第三点: "))
    373.     (vl-cmdf "line" p1 p2 p3 "c")
    374.     (setq p1 (getpoint "\n第一点: "))
    375.     (setq p2 (getpoint "\n第二点: "))
    376.     (setq p3 (getpoint "\n第三点: "))
    377.     (vl-cmdf "line" p1 p2 p3 "c")
    378.     (setq p1 (getpoint "\n第一点: "))
    379.     (setq p2 (getpoint "\n第二点: "))
    380.     (setq p3 (getpoint "\n第三点: "))
    381.     (vl-cmdf "line" p1 p2 p3 "c")
    382.     (Gxl-ErrEndNrm)
    383.     (princ)
    384.   )

    385. //三、Vl-Catch-All-Apply函数捕捉错误的应用技巧
    386.   上面部分讨论的是传统的*error*方法,这种方法是对整个程序设置的统一的处理功能
    387.   无论程序中什么地方出错,都集中在这里处理!这种情况在程序比较简单,要处理的情况不多时,比较容易应付,因为这时程序需要处理的情况比较少!
    388.   当程序的规模比较大,要处理的情况比较复杂时,就很难满足我们对程序错误处理的要求,特别是当出现同样的错误代码需要在程序的不同部分做出不同处理的时候。
    389.   幸运的是,AutoLisp另外还提供了三个错误处理函数。
    390.   Vl-Catch-All-Apply函数能够捕捉指定函数的错误
    391.   Vl-Catch-All-Apply-Error-Message函数可以读取相关错误信息
    392.   Vl-Catch-All-Error-P函数可以测试Vl-Catch-All-Apply函数返回结果是否异常。
    393.   ;;;例如:下面这个函数是根据图上选取直角三角形的一条直角边,然后输入斜边长度,根据勾股定理计算另一直角边,并绘制三角形的例子:
    394.   (defun C:TT (/ p1 p2 d1 dd Ang)
    395.     ;初始化错误处理,出错后回到初始状态
    396.     (Gxl-ErrSta (list "cmdecho" 0 "osmode" 0) nil 2)
    397.     (setq p1 (getpoint "\n输入直角三角形直角边第一点: "))
    398.     (setq p2 (getpoint p1 "\n输入直角三角形直角边第二点: "))
    399.     (setq d1 (distance p1 p2))
    400.     (vl-cmdf "_line" p1 p2 "")
    401.     (setq dd (getdist p1 "\n请输入斜边长度: "))
    402.     ;;根据勾股定理计算另一条直角边长度
    403.     (setq d2 (vl-catch-all-apply ;捕捉 sqrt 函数的错误
    404.                                 'sqrt
    405.                                 (list
    406.                                   (- (* dd dd) (* d1 d1))
    407.                                 )
    408.             )
    409.     )
    410.     (if (vl-catch-all-error-p d2);当输入的斜边长度小于直角边长度时 sqrt 函数会出错
    411.         (progn ;sqrt 函数结果异常
    412.               (alert (vl-catch-all-error-message d2));提示错误信息
    413.               (abcdefg);自己的错误退出程序
    414.         )
    415.         (progn
    416.             (setq Ang (+ (angle p1 p2) (* 0.5 pi)))
    417.             (command "_line" p2 (polar p2 angd2) p1 "")
    418.         );绘制三角形
    419.     )
    420.     (Gxl-ErrEnd);恢复错误处理
    421.     (princ)
    422.   )

    423.   这样,自定义函数test就可以返回正确的结果或出错信息这两种结果,这是一种新的函数定义模式
    424.   其使用方法简而言之就是使用Vl-Catch-All-Apply对函数进行包装,然后使用Vl-Catch-All-Error-P判断包装函数返回值是否异常
    425.   若有异常,可使用Vl-Catch-All-Apply-Error-Message函数输出错误信息,并再此对错误进行处理。
    复制代码

     

     

     

     

    Lisp程序设计错误处理的技巧
    中国膜结构网打造全中国最好的膜结构综合平台 ,统一协调膜结构设计,膜结构施工,膜材采购,膜材定制,膜结构预算全方位服务。 中国空间膜结构协会合作单位。
  • TA的每日心情
    开心
    前天 09:51
  • 签到天数: 80 天

    [LV.6]常住居民II

    1564

    主题

    202

    回帖

    214748万

    积分

    管理员

    积分
    2147483647
     楼主| 发表于 2024-4-6 16:40:58 | 显示全部楼层
    1. Gxl-ErrStaSys  -> Gxl-ErrEnd ;只针对系统变量的恢复
    2.   Gxl-ErrSta     -> Gxl-ErrEnd ;系统变量+函数+编组
    3.   Gxl-ErrStaNrm  -> Gxl-ErrEndNrm ;只针对自定义常量的恢复



    4. (if (null vlax-dump-object) (vl-load-com));将Visual LISP扩展功能加载到 AutoLISP
    5. (defun C:TT (/ *error* CurDoc *Old_SysVar*)
    6.   (setq CurDoc (vla-get-activedocument (vlax-get-acad-object)))
    7.   (defun *error* (x)  ;出错函数
    8.     ;其它需要恢复的内容
    9.     (if *Old_SysVar* (foreach xx *Old_SysVar* (apply 'setvar xx)));参数恢复
    10.     (vla-endundomark CurDoc) ;错误时结束编组
    11.   )

    12.   (while (eq 8 (logand 8 (getvar 'undoctl)))
    13.     (vla-endundomark CurDoc)
    14.   ) ;关闭以前的编组
    15.   (vla-startundomark CurDoc) ;记录编组
    16.     (progn ;记录系统变量
    17.       (setq *Old_SysVar* '());清空变量,避免出错
    18.       (setq *Old_SysVar*
    19.           (mapcar
    20.             '(lambda (a / b)
    21.               (if (setq b (getvar (car a)))
    22.                   (progn
    23.                     (vl-catch-all-apply 'setvar a)
    24.                     (list (car a) b)
    25.                   )
    26.               )
    27.             )
    28.             (list
    29.               (list "DIMZIN" 0);保留前导和后续的零
    30.               (list "CMDECHO" 0) ;关闭回显
    31.             )
    32.           )
    33.       );记录参数
    34.     )
    35.    
    36.     ;你的程序
    37.    
    38.     (command "redraw");清空一行
    39.     (if *Old_SysVar* (foreach xx *Old_SysVar* (apply 'setvar xx)));参数恢复
    40.   (vla-endundomark CurDoc) ;结束编组
    41.   (princ)
    42. )
    复制代码

     

     

     

     

    Lisp程序设计错误处理的技巧
    中国膜结构网打造全中国最好的膜结构综合平台 ,统一协调膜结构设计,膜结构施工,膜材采购,膜材定制,膜结构预算全方位服务。 中国空间膜结构协会合作单位。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-5-15 14:20 , Processed in 0.058792 second(s), 21 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表