明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5698|回复: 10

vba/vb取得autocad对象的组码对应值

[复制链接]
发表于 2015-4-26 00:57:12 | 显示全部楼层 |阅读模式
本帖最后由 zzyong00 于 2015-4-26 01:02 编辑

众所周知,vba/vb6二次开发AutoCAD插件,都是基于autocad的对象模型,对象模型中给出大部分autocad的对象类型,但并不是全部,比如,有个对象是AcDbWipeoutVariables,vba中没有给出对应的对象,而它的70组码控制着wipeout的边框是否显示,在autocad2013以后的版本,有一个系统变量WIPEOUTFRAME控制着wipeout的边框是否显示,但在autocad2013以前的版本,却没有这个变量。用vba编程时,很难知道当前图的wipeout边框是否显示!但用lisp却很容易知道,详见:http://bbs.xdcad.net/thread-4040-1-1.html,造成这个问题的关键原因是,vba不能直接获取对象的组码值。用vba编写autocad插件,一般很少用到组码,只有选择实体时能用到,还有就是getxdata和setxdata函数,可以获取和设置1000以上组码值。而对于选择,autocad只能选择实体,像AcDbWipeoutVariables,属于词典类型(但不能把赋值给dictionary类型的变量),无法选择!也就是说,无法通过选择来判断组码的值!用vba/vb做这事儿,真是无能为力(我认为)!好在,有vlax.cls类,使得vba/vb可以调用lisp,这使得vba/vb取得autocad对象的组码对应值成为可能!经过我多次测试,把代码写出来,看起来也非常简单:

  1. '工程中加载vlax.cls,如没有可从明经通道可以下载到
  2. ''By zzyong00
  3. ''2015.04.26
  4. Public Function GetEntDxf(ByVal handle As String, ByVal DxfCode As Long)
  5.     Dim objVLAX As VLAX
  6.     Set objVLAX = New VLAX
  7.     Dim retval
  8.     With objVLAX
  9.         '.EvalLispExpression "(setq retval (cdr (assoc '" & DxfCode & " (entget (handent " & Chr(34) & handle & Chr(34) & ")))))"
  10.         .SetLispSymbol "handle", handle
  11.         .EvalLispExpression "(setq retval (cdr (assoc '" & DxfCode & " (entget (handent handle)))))"
  12.         retval = .GetLispSymbol("retval")
  13.         .NullifySymbol "handle", "retval"
  14.     End With
  15.     GetEntDxf = retval
  16. End Function

调用以上GetEntDxf,获取wipeout的边框是否显示:
  1. Dim d As AcadObject
  2. Dim obj As AcadObject
  3.     For Each d In ThisDrawing.Dictionaries
  4.         If d.ObjectName = "AcDbWipeoutVariables" Then
  5.             Set obj = d
  6. '            Debug.Print obj.handle
  7.             Exit For
  8.         End If
  9.     Next
  10.     If obj Is Nothing Then Exit Sub
  11.     Dim ret1 As Long
  12.     ret1 = CLng(GetEntDxf(obj.handle, 70))‘取得组码为70对应的值
  13.     MsgBox ret1

GetEntDxf只能用于组码对应值为一个简单值的情况,如组码对应值为关联表,哪就不行。而在我实际测试过程中,发现vlax.cls也无法对返回值为关联表的函数正确执行,找了很多资料,都没能解决!如下面代码,是设置AcDbWipeoutVariables的70组码值为1的,用到subst 和entmod,都返回关联表的,用vlax.cls始终无法正确执行!好在这里不需要返回值,于是就用sendcommand了
  1. Dim d As AcadObject
  2. Dim obj As AcadObject
  3.     For Each d In ThisDrawing.Dictionaries
  4.         If d.ObjectName = "AcDbWipeoutVariables" Then
  5.             Set obj = d
  6. '            Debug.Print obj.handle
  7.             Exit For
  8.         End If
  9.     Next
  10.     If obj Is Nothing Then Exit Sub
  11.     ThisDrawing.SendCommand "(entmod (subst '(" & "70" & " . " & "1" & ") (assoc " & "70" & " (entget (handent " & Chr(34) & obj.handle & Chr(34) & "))) (entget (handent " & Chr(34) & obj.handle & Chr(34) & ")))) "
  12.     ThisDrawing.Regen acAllViewports




本人写个帖子,是由于这个同学的启示而写的:http://bbs.mjtd.com/thread-113374-1-1.html

希望能对他也有点帮助!
 楼主| 发表于 2015-4-26 01:23:43 | 显示全部楼层
另外,本论坛的efan2000给出了用LastPrompt系统变量取组码的方法!
http://bbs.mjtd.com/forum.php?mo ... 9897&pid=101902
发表于 2015-4-29 13:39:12 | 显示全部楼层
发表于 2015-4-29 14:17:55 | 显示全部楼层
本帖最后由 lennie 于 2015-4-29 14:32 编辑

程序精简了一下:
  1. Public Function WipeOutFrame() As Boolean     '返回wipout边界是否打开的状态,打开返回True
  2.     Dim obj As Object
  3.     For Each obj In ThisDrawing.Dictionaries
  4.         If obj.ObjectName = "AcDbWipeoutVariables" Then
  5.             WipeOutFrame = CBool(GetDXFCodeValue(obj, 70))
  6.         End If
  7.     Next
  8. End Function
这里用到一个修改后的函数 GetDXFCodeValue
  1. Public Function GetDXFCodeValue(Ent As Object, gCode As Integer) As Variant
  2.     Dim retval
  3.     Dim obj As New CL
  4.         retval = obj.EvalLispExpression("(cdr (assoc " & gCode & " (entget (handent " & Chr(34) & Ent.Handle & Chr(34) & "))))")
  5.         GetDXFCodeValue = retval
  6.         Set obj = Nothing
  7. End Function
另外,用SendCommand的方法命令窗口会跳出一堆文字,毕竟不美观。以下是我来获取天正对象坐标(组码10)的函数:
  1. Function GetDxfPoint(Ent As Object, gCode As Integer) As Variant
  2.     Select Case TypeName(Ent)
  3.         Case "IComSymbElev", "IComLineText", "IComSpace"
  4.             Dim retval
  5.             Dim aPoint(2) As Double
  6.             Dim obj As New CL
  7.             retval = obj.EvalLispExpression("(car(cdr (assoc " & gCode & " (entget (handent " & Chr(34) & Ent.Handle & Chr(34) & ")))))")
  8.             aPoint(0) = retval
  9.             retval = obj.EvalLispExpression("(car (cdr (cdr (assoc " & gCode & " (entget (handent " & Chr(34) & Ent.Handle & Chr(34) & "))))))")
  10.             aPoint(1) = retval
  11.             retval = obj.EvalLispExpression("(car (cdr (cdr (cdr (assoc " & gCode & " (entget (handent " & Chr(34) & Ent.Handle & Chr(34) & ")))))))")
  12.             aPoint(2) = retval
  13.             GetDxfPoint = aPoint
  14.             Set obj = Nothing
  15.         Case "IAcadText", "IAcadMText"
  16.             GetDxfPoint = Ent.InsertionPoint
  17.     End Select
  18. End Function

点评

赞一下,我也同意哪个SendCommand的方法有点不专业!  发表于 2015-4-29 14:39
发表于 2015-4-29 14:38:06 | 显示全部楼层

找到这个字典以后,监视窗口里对象居然是空白的。

VB局限性太大了,而且64位CAD的话原来做的Dll文件都不能用了。好处是采用后绑定的方法可以通吃多个CAD版本。这里要鄙视微软,鄙视自动桌子。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

点评

64位cad,是可能用32位的activex dll的,一般都没问题  发表于 2015-4-29 15:00
监测窗口里有什么,关键是你定义成什么类型,autocad对象基本都继承自acadobject,你把obj定义成AcadObject试试,但autodesk的确没内置所有的类型  发表于 2015-4-29 14:54
 楼主| 发表于 2015-4-29 14:41:57 | 显示全部楼层
本帖最后由 zzyong00 于 2015-4-29 14:49 编辑

现在用vlax.cls,可以读取实体的组码了,但是,修改实体组码时,还是会有一些问题,如以下lsp
"(entmod (subst '(" & "70" & " . " & "1" & ") (assoc " & "70" & " (entget (handent " & Chr(34) & obj.handle & Chr(34) & "))) (entget (handent " & Chr(34) & obj.handle & Chr(34) & ")))) "
就无法用vlax.cls执行,不得以只好用SendCommand
发表于 2015-4-29 15:33:37 | 显示全部楼层
lennie 发表于 2015-4-29 14:38
找到这个字典以后,监视窗口里对象居然是空白的。

VB局限性太大了,而且64位CAD的话原来做的Dll文件都 ...

dll里面涉及object对象作为参数传递 基本上都有问题。

点评

这个真没问题!  发表于 2015-4-29 15:39
 楼主| 发表于 2015-4-29 15:42:10 | 显示全部楼层
http://bbs.mjtd.com/thread-111871-1-1.html
你看看我哪个帖子里的dll,就是传对象进去,一点问题没有
 楼主| 发表于 2015-4-29 15:43:07 | 显示全部楼层
发表于 2015-12-11 22:11:44 | 显示全部楼层
'工程中加载vlax.cls,如没有可从明经通道可以下载到
''By zzyong00
''2015.04.26

方便给出vlax.cls的下载链接吗?没搜索

点评

玩那个,没什么 意义,白费力气  发表于 2015-12-11 22:46
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 14:38 , Processed in 0.186302 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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