添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
如果开发者对AutoLISP的开发技术有所了解,则对AutoLISP中的Command函数会有较深的印象。在AutoLISP开发中,Command函数事用得最多的一个函数。
在VBA开发时,许多用户都希望能有这样一个与Command函数相同功能的方法,以方便VBA的开发。
在AutoCAD的对象模型中提供了SendCommand方法,从字面上可理解为与Command函数一样的功能,但从实际使用时却无法达到满意的效果。可以说,SendCommand方法只是一个摆设,它不能完成复杂的编程工作。
先来说说它的缺点:
通过SendCommand方法发送的命令无法让它不在命令行中显示。这对于一个专业的程序来说,杂乱的命令行显示显的不够专业。
无法控制程序的执行顺序,SendCommand方法只是单方面地向命令行发送命令,该命令发送完成后就直接执行后续的程序,而不管发送的命令执行是否完成,这样就有可能会使程序的执行顺序发生变化而导致程序出错。
SendCommand方法发送的命令只能以字母串的方式发送,不能传递点坐标、双元表、图元对象及其它数据格式。 这样就无法完成一些复杂的命令过程。
总之,AutoLISP中的Command函数中的那些优点在SendCommand方法中都找不到。但是,由于AutoCAD提供的对象模型到目前版本(AutoCAD 2007版)都还不完善,许多功能都不能通过对象模型来完成编程,所以这里还需要花点精力来挖掘SendCommand方法的一些功能。
在以前的编程中,很少使用SendCommand方法来解决问题,主要是考虑到此方法本身的一些局限性,列如不能传递参数,导致宏执行顺序的错乱等。目前,经过大家的努力,已经通过和AutoLISP的结合解决乐这些问题。
在VBA中,可以通过SendCommand方法来发送命令给AutoCAD以对AutoCAD直接进行操作,就像LISP中的Command函数一样,但它却没有Command函数那么方便。因为Command函数可以直接接受LISP命令以及LISP提供的点坐标形式以及双元表等,所以它能够通过程序对图元进行修剪、截断、延伸等操作。但SendCommand方法却不能接受VBA提供的点坐标,也不能接受VBA中的其它方法,列如点坐标形式,而且也不能使出双元表这样的特殊格式,它只能像在命令行一样的输入在命令行中能识别的点形式及双元表。
所以这个问题也难道乐许多的专家,一段时间以来,这个问题都被认为使一个不能解决的问题。虽然有些专家也试图通过其它方式来解决,但毕竟要使用一些控件,而且些出来的语句也难以看懂。
通过对SendCommand方法的研究,不难发现它可以接受与命令输入一模一样的语句;也就是说,它也能够接受AutoLISP的函数以及相同格式的点坐标。这样,我们就可以通过VBA来制造这样的点坐标,也可以通过VBA来生产一些供SendCommand方法使用的组合起来的AutoLISP语句来表达的一个双元表。
1) 切换到ThisDrawing模块的代码窗口,添加一个函数axPoint2lspPoint,用与将VBA中的点转换成AutoLISP中可以使用的点参数。
Function AxPoint2lspPoint(ByVal Pnt As Variant) As String
AxPoint2lspPoint = Pnt(0) & "," & Pnt(1) & "," & Pnt(2)
End Function
2) 添加一个函数axEnt2lspEnt,用与将VBA中的实体转换成AutoLISP中可以使用的参数。其中handent是一个AutoLISP中的函数,根据制定的句柄返回实体名称。
'转换图元函数
Public Function axEnt2lspEnt(EntObj As AcadEntity) As String
Dim entHandle As String
entHandle = EntObj.Handle
axEnt2lspEnt = "(handent " & Chr(34) & entHandle & Chr(34) & ")"
End Function
3) 添加一个函数GetDoubleEntTable,用于将VBA中GetEntity方法返回的参数转换成可在AutoLISP中使用的形式。
'转换双元表的函数
Public Function GetDoubleEntTable(entObj1 As AcadEntity, Pnt As Variant) As String
Dim entHandle As String
entHandle = entObj1.Handle
GetDoubleEntTable = "(list(handent " & Chr(34) & entHandle & Chr(34) & _
")(list " & Str(Pnt(0)) & Str(Pnt(1)) & Str(Pnt(2)) & "))"
End Function
此函数根据VBA中GetEntity方法的返回值构建双元表用于AutoLISP中。双元表是AutoLISP中的一个概念。
“双元表”是AutoLISP特有的表数据类型之一,是一种针对AutoCAD数据库所特有的检索指针,就像是EntSel函数的返回值那样的数据结构。实际上也可以用List函数,按这种格式组成自定义的双元表。这种特有的数据结构,是在程序中使用CAGD技术的关键之一。
对于一些编辑命令,在指目标时,所指点位与处理的结果有关,就要在AutoLISP中应用双元表来“精确响应”要目标的提示,这也时AutoLISP特有的、相当有实用价值的技巧。这类命令有:DIM、EXIEND、TRIM、FILLET、CHAMFER、DIVIDE、MEASURE等等。
4) 添加一个函数axSSet2lspEnts,用于将VBA选择集中的实体转换成可在AutoLISP中使用的形式。
5) 创建一个宏Break,用于模拟AutoCAD中的Bread命令
在命令行的提示中加上vbCrLf关键字,可以让跟在此关键字后面的内容换行显示(与vbNewLine关键字的作业相同),这在SendCommand和Prompt方法中均是有效的。
6) 创建一个宏Trim,用于模拟AutoCAD中的Trim命令
1) 在AutoCAD中,使用Circle命令创建一个圆。在VBA集成开发环境中,执行Break宏,按照命令提示,首先在图形窗口中选择实体(兼做第一个打段点),然后制定第二个打断点,完成操作后,就能对圆执行打断的操作。
2) 重新创建一个圆和两条直线
3) 在VBA集成开发环境中,执行Trim宏,首先选择两条直线作为修剪的边界,然后单击圆位于两条直线之间的部分
使用SendCommand方法简单直接,能在AutoCAD命令行中完成的操作,用SendCommand方法基本都能完成,但是SendCommand方法是将命令传给AutoCAD,而不会等其是否执行完毕就直接运行后续的语句,所以经常会导致程序运行次序的混乱。
尽量不要使用SendCommand方法,如果用的话,最好也吧它放在最后。再不行的话,把一个过程分成两段,第一段把SendCommand方法写在最后,接下再执行第二段。而第二段可以再第一段最后直接用程序调用。
再SendCommand方法中,可以使用空格或者vbCr标示按下Enter键,列如“line”和“line&vbCr”是等效的,但是在一些特殊的情况下空格键是无效的,因此建议在所以的情况下使用vbCr来表示按下Enter键。