土木在线论坛 \ 建筑设计 \ CAD下载及教程 \ 在程序中实现图层的检查及新建

在程序中实现图层的检查及新建

发布于:2004-11-12 18:35:12 来自:建筑设计/CAD下载及教程 [复制转发]
在程序中实现图层的检查及新建

有些编程者编程时没有考虑到用户环境的不同,经常所编制的程序能运行在自制的模板图形上,而不能在用户的图形中运行,这种情况也是我经常碰到的。
最容易碰到的是图层。程序中,经常会使用特定的图层来放置程序所生成的对象,比如说你将图层设置为“3”层,写出的程序如下:

(setq oldLayer ( getvar "clayer")) ;将当前图层保存起来,以便以后的恢复
(setvar "clayer" "3") ;将图层“3”转换为当前图层

这时,如果用户当前图形中在存在“3”图层,程序就会出错并中断。为此,你首先应判断“3”图层是否存在,采用以下的聚光灯中判断图层的存在:

(tblobjname "layer" "3")

这时,如果图层“3”确实不存在时,则可用以下函数内容建立该名称的图层:

(entmake (list
’(0 . "LAYER")
’(100 . "AcDbSymbolTableRecord")
’(100 . "AcDbLayerTableRecord")
’(6 . "CONTINUOUS")
’(62 . 3)
’(70 . 0)
’(2. "3")
)
)

这样就可以建立新图层,完整的程序如下:

(setq old_lay (getvar "clayer"))
(if (=(tblobjname "LAYER" "3") nil)
(progn
(entmake (list
’(0 . "LAYER")
’(100 . "AcDbSymbolTableRecord")
’(100 . "AcDbLayerTableRecord")
’(6 . "CONTINUOUS")
’(62 . 3)
’(70 . 0)
(cons 2 "3")
)
)
)
)
(setvar "clayer" "3")

可能有人会说,使用command转换及新建图层不是更加简单吗?但我总认为其它函数能完成的动作,最好不要使用“command”函数,因为可能下一个版本中,command所引用的命令内容会有变化(如功能的加强),使用程序出错。就象R12、R13、R14版中的清理命令[Purge]就各不相同。
<回到顶部>

 

将一个大程序分成多个小程序以简化编写过程

初学者常常会将所有的功能都编入到一个程序(或函数)中。这不仅会使程序冗长难读,也会给修改和重用带来麻烦。AutoLISP是一种函数式的语言,因此,将一个单独的功能编制成一个函数可以使程序简明易读。对于重复调用次数较多的程序,应编制一个通用函数并在初始化时加载到环境中,以便于调用。

<回到顶部>

将自己编制的程序或函数的调用放在菜单系统中

不要让自己编制的程序只能够从命令行调用,要将它们安排在菜单中以方便用户的调用。

<回到顶部>

不要将自己编制的程序全都放入ACAD.LSP文件中

一些程序只喜欢将自己编写的程序或函数放在ACAD.LSP文件中,因为该文件可以在AutoCAD启动时装载到环境中。这样做的确可以方便自己编制函数的调用。不过,如果ACAD.LSP文件太大,则调入每个绘图的时间将变长,因为内存减小了。

事实上,ACAD.LSP是用来存放通用函数的,只有频率很高的函数才应放入到ACAD.LSP中。例如:用户库函数通常都放在ACAD.LSP中,或在ACAD.LSP中加载。

<回到顶部>

加载文件前应判别程序是否已被加载

在调用用户自己定义的函数之前,应将与之相关的应用程序加载到AutoCAD环境中,否则AutoCAD会报告不存在该函数。当一个函数会被多次调用时,如果每次调用之前都加载一次文件,则会浪费很多时间,因为一个文件只需加载一闪即可。这时,判别一下某文件是否已经装入是非常必要的,这种用法在菜单文件的语句中很常见,例如:

...

[技术要求](if(not jsyq)(load"jsyq"));(jsyq);

...

这里我们假定jsyq是文件jsyq.lsp中的一个函数(不是一个变量),在调用函数(jsyq)之前,(if not...)语句首先判断一下该函数是否已经存在。如果不存在,就加载相关文件jsyq.lsp;否则说明步过加载语句。

<回到顶部>

为自己的应用程序建立一个单独的目录

不要将自己的应用程序放在AutoCAD软件包所在的目录下,这样不仅会扰乱软件包中文件的排列,也不便于管理。通常开发者会建立一个单独的目录来旋转自己的应用程序。此建立目录的名字应尽量避免可能会因安装 AutoCAD或其它第三方软件包而产生的冲突。

全部回复(2 )

只看楼主 我来说两句抢地板
  • pcy520
    pcy520 沙发


    1.不要和计算机较劲

    请记住,计算机是不知疲惫的,可你不行。如果感到累了,可以暂时放下工作去花园散散步或干脆去看场电影,等你精神转好了再重新投入工作中去。

    2.计算机是非常公正的

    计算机的眼睛是雪亮的,它绝不会让任何错误的数据蒙混过关。加外,计算机几乎不会犯错误,因此,请多找一找自身的原因吧!

    3.在计算机中,相是的激励应该得到相同的结果

    有时,你的程序可能会在相同的输入下得到不尽相同的结果,这时你要提醒自己:一定有什么条件被改变了,虽然它还未暴露出来。

    在调试程序时更要注意这一点,不要因之而影响你的判断力。

    4.两种常见的错误类型

    语法错误和逻辑错误是程序中两种常见的错误类型。语法错误是较容易发现的,因为其中存在错误的命令,例如:

    (setq a (ang1 p1 p2))

    此处函数(ang1)拼写错了,正确的名字是(angle),系统会提示发现空函数而终止。

    逻辑错误是不容易发现的,例如:

    (angle pnt1 pnt2)

    这条语句看上去似乎是正确的,但如果pnt2的值为空,程序同样运行不下去。

    5.通过“断点”检查与变量有关的错误

    如果希望在程序运行到某处时检查变量a的当前值,可在程序中的该处加入如下语句:

    (princ a )

    (setq bp(getstring))

    这样,到印出a的值之后,函数(getstring)可使程序暂停,就好象遇到了一个断点一样,观察完a的值之后,可按任意键使程序继续。

    6.变量作用哉的定义

    在刚开始编程时,应将函数中用到的变量定义成全局性的。在AutoLISP中,函数中的变量只要不在函数定义defun命令的函数名之后的()中用斜杠说明,该变量就是全局的,例如:

    (defun drawline()

    ...

    )

    假设(drawline)用到了两个点pnt1和pnt2,则这两个将成为全局性的.用户可在命令秆用!字符检查它们的值.

    一旦将程序调试完毕确认无错之后,便可将变量定义成局部的,例如:

    (defun drawline(/ pnt1 pnt2)

    ...

    )

    这样,函数运行过程中pnt1和pnt2有效,运行完毕之后它们将消失,这样可以节省出一点内存空间来。

    7.注意不要混淆度和弧度

    当使用到角度时,最常见的错误是混淆了度和弧度两种单位,请记住,AutoLISP函数使用弧度为单位,AutoCAD命令使用度为单位。

    8.对相关的系统变量进行检查

    程序运行得正常与否与系统变量也有着直接的关系。例如:将对象捕捉系统变量OSMODE设置为终点捕捉模式(1)或交战捕捉模式(32),同一个程序在运行效果上可能就会产生很大的差别。

    9.从屏幕上的细微变化观察程序运行

    在AutoLISP程序运行时,屏幕上常会产生一些微小的变化,如:若出现一个表示点的小叉丝然后又消失,这有可能是在执行insert或与插入点有关的命令。若屏幕上的对象变成虚线表示,这有可能是在执行(ssget)函数并选中了这些对象,总之,仔细观察屏幕上的细微变化将有助于了解程序运行的进程,这对于程序的调试是有益的。

    10.调试通则

    程序出错通常是由多个错误引发的,而许多错误会导致同一种现象,因此,在分析错误时,应将它们分享出来进行检查,不要企图一次性将所有的错误都改正过来。

    <回到顶部>

    使命令暂停以等待用户输入

    在AutoLISP函数(command)中,您可以加入pause项使命令在执行到该处时暂时停下来以等待用户输入,例如:

    (command "circle" pnt1 pause)

    该命令将pnt1指定为圆心之后暂停,等待用户输入圆的半径值。

    <回到顶部>

    AutoCAD原始命令的取消与恢复

    UNDEFINE和REDEFINE是AutoCAD的两条命令。UNDEFINE用来取消AutoCAD的原始命令。例如:如果你在命令行上键入INDEFINE FILLET,AutoCAD会禁止FILLET命令的使用,这样你使可以使用自己定义的FILLET命令。如果你想再使用AutoCAD的FILLET命令,这时应使用.FILLET命令,当然,你也可以干脆使用REDEFINE来恢复原先的状态。

    <回到顶部>

    (findfile)——查找文件

    (findfile)函数用来在磁盘上查找指定的文件,若只给出了文件名,则它会在当前路径、DOS的PATH环境变量所指定的路径和ACAD环境变量所指定的路径中查找该文件(找到第一个便停止)。例如:若要查找TYL.INI文件,则使用:

    (findfile "tyl.ini)

    它将返回:

    "c:\\program files\\acad2000\\tyl.ini"

    <回到顶部>

    (getenv)——取系统的环境变量

    库函数允许用户在AutoCAD环境中取系统的环境变量。例如:

    (getenv "acad")

    它将返回:

    "C:\\program files\\acad2000\\support;C:\\program files\\a
    2004-11-12 18:28:12

    回复 举报
    赞同0
  • pcy520
    pcy520 板凳


    <回到顶部>

    尽量减小应用程序的文件数

    AutoLISP程序通常都很短小,因为一个功能一般只需几十条语句就可以完成,这也是AutoLISP语言的效率所在。不过,如果将每一个编制的功能都生成一个单独的文件,不仅会使程序的数量繁多,而且使用时也要一次次加载,十分不方便。因此,应尽量将相关甚至相关性不太强的文件合并为一。这样,您可以将多个文件合为一个,使用时只要装载一次而无需多次装载。如本站提供的图栏程序和流程程序就是这样,图栏程序将六个相关的功能组合在一起,而流程程序将四个相关的功能组合在一起。

    <回到顶部>

    用缩进方法使程序便于阅读

    和其它软件开发程序一样,AutoLISP程序也可以使用缩进的方法进行编写以便于阅读,缩进后程序的调用并不多占用内存。

    <回到顶部>

    为变量取名应便于理解但不要太长

    在为变量取名时,应力求简洁且含义清晰。例如:ABC、QQX会被认为是无意义的,它不便于理解和记忆变量cornerpoint1虽然很便于理解,但它太冗长,会多占用内存。另外,变量名p1或pt1要比point1更为合适。

    <回到顶部>

    修改系统变量时应注意对原有变量的保存以便恢复

    AutoCAD启动之后,会为每个系统变量都初始化一个缺省值。在应用程序运行时,可能需要暂时将某系统产生的值修改一下。不过应注意在修改之前应将其原始值加以保存,使用完毕后再将其恢复回原始值。

    例如:在进行对象捕捉时,我们希望它使用终点捕捉方式,这时只要将系统变量OSMODE的值设为1即可。不过,在修改OSMODE的值之前,应将其原始值保存起来:

    (setq oldosmode(getvar "osmode"))

    然后再进行修改:

    (setvar"osmode" 1)

    这样再进行对象捕捉时,将使用终点方式。当捕捉结束之后,应将其恢复为原始的值:

    (setvar"osmode" oldosmode)

    此处oldosmode是一个用以保存OSMODE原始值的中间变量。

    <回到顶部>

    第三方开发的ACAD.LSP的引用

    很多第三方软件开发商在开发AutoCAD时会改写ACAD.LSP文件甚至将其加密。如果用户要在此基础上再开发自己的程序,则需要建立自己的ACAD.LSP文件。

    首先,将原来的ACAD.LSP文件为ACADOLD.LSP,然后建立一个自己的ACAD.LSP文件并在最后将原先的ACAD.LSP文件装载:

    (load "acadold")

    这样,AutoCAD启动时会自己装载ACAD.LSP文件,同时也装入ACADOLD.LSP文件,但有一点请注意,如果原先的ACAD.LSP文件中带有(S::STARTUP)函数,则按上述方法装入之后,该函数不会被自动执行,这时,你还应该在装载原先的ACAD.LSP文件之后运行如下语句:

    (S::STARTUP)

    <回到顶部>

    抑制函数运行之后返回的nil显示

    在一个AutoLISP运行结束之后,它常会在命令行上返回一个nil,我们可以在函数的最后一个右括号之前加上一条(princ)语句抑制nil的出现。

    注意:如果函数是用来返回一个值,则不能使用上述的方法。

    <回到顶部>

    为用户选择提供缺省值

    在AutoLISP应用程序中,当需要用户输入时,应为用户提供一个缺省的值。用户想输入的值刚好就是缺省的值时,只需按回车键或空格键即可,这样可以给用户带来方便。

    通常,缺省值跟在输入提示串之后并用尖括号(<...>)括起来,下面的例子中将最后一次用户输入的字符串存放在一个变量defvar中,当提示用户输入时,它将前一次用户输入的字符串做为缺省的值。

    (defun c:testpgm(/a)

    (if (= defvar nil)(setq defvar ""))

    (pormpt "\n输入名称:<")(princ defvar)(princ ">:")

    (setq a (getstring))

    (if (= a "")(setq a defvar))

    (setq defvar a)

    )

    注意:上面这段程序中,变量defvar是做为全局变量使用的,它将存在于AutoCAD环境中,运行testpgm之后,用户可以通过!字符检查defvar的当前值。

    <回到顶部>

    为命令行的选项提供右键快捷菜单

    在AutoCAD2000中,命令行中的可选项可以使用鼠标的右键显示,提高了用户的操作速度,但这种方法必须按照一定的格式书写程序,一般,选项内容是用中括号[...]括起来,每个选项之间使用"/"分隔。例如:

    (initget "Single Horizonal Vertical")
    (setq sele(getkword "\n部装明细序号填写方式[水平多项(H)/垂直多项(V)/单一序号(S)]<单一序号>:"))

    这样,在程序运行到当前提示时,用户可点击鼠标右键弹出快捷菜单显示各选项的内容选取。

    <回到顶部>

    关于程序调试的一些建议

    一个程
    2004-11-12 18:28:12

    回复 举报
    赞同0
这个家伙什么也没有留下。。。

CAD下载及教程

返回版块

52.08 万条内容 · 658 人订阅

猜你喜欢

阅读下一篇

在程序中实现图层的检查及新建

在程序中实现图层的检查及新建 有些编程者编程时没有考虑到用户环境的不同,经常所编制的程序能运行在自制的模板图形上,而不能在用户的图形中运行,这种情况也是我经常碰到的。最容易碰到的是图层。程序中,经常会使用特定的图层来放置程序所生成的对象,比如说你将图层设置为“3”层,写出的程序如下:(setq oldLayer ( getvar "clayer")) ;将当前图层保存起来,以便以后的恢复

回帖成功

经验值 +10