. : : ClassiClub ForuM : : .

会员中心 论坛帮助 日历事件 标记论坛已读
返回   精品技术论坛 » 技术论坛 » 『软件使用』

『软件使用』: 电脑软件推荐, 电脑软件使用, 经验分享



发表新主题 关闭主题
 
主题工具
lee1892
 
lee1892 的头像
荣誉版主
 
资 料:
注册日期: Sep 2001
帖子: 1,572 声望值: 14
精华: 4,解答: 10
#1 旧 2012-11-14, 12:43:19 默认 【原创】如何使用VBA获取AutoCAD文件中的表格信息
lee1892 当前离线  

最近在工作中碰到需要提取大量AutoCAD图纸中表格内容的事情,于是花了些时间学习了一下,有了下面的笔记。

在早期的AutoCAD的版本中没有Table这个图形对象,所以零件表通常是以线和文字构成的。即使现在,众多的建模软件在生成DWG文件时,仍然延续了这一做法。这样的表格信息是比较难以提取的。但仍然可以利用这些文字的特定信息,诸如:颜色、图层、字体、位置等和其它文件中的文字予以区分,并通过对位置的排序而获得完整的表格。

VBA获得当前AuotCAD程序的代码片断,及逐个打开文件以进行处理
PHP 代码:
Dim acadApp As ObjectacadDocs As ObjectacadNewDoc As Object
Set acadApp 
GetObject(, "AutoCAD.Application")
Set acadDocs acadApp.Documents
'关闭所有已经打开的文件'
For 1 To acadDocs.Count
    acadDocs
.Item(0).Close False '关闭文件,不存储'
Next
'逐个打开文件,处理后关闭,不保存'
For 0 To UBound(arrFilesPath)
    
Set acadNewDoc acadDocs.Open(arrFilesPath(i), True'以只读方式打开数组中的文件'
    
acadNewDoc.Close False
Next
Set acadNewDoc 
Nothing
Set acadDocs 
Nothing
Set acadApp 
Nothing 
发现在VBA环境下,用CAD文件内的所有图形对象逐个筛选的办法效率无法忍受,所以一开始采用的办法是:
先编写一个vLisp程序来处理单个文件,并将查询得到的结果储存在一个文本文件中,然后在AutoCAD中将这个vLisp程序设定为启动加载,最后再处理结果文本文件。
整个过程虽然实现了自动化,但需要分步进行,相当繁琐。

在认真学习了AutoCAD的对象树之后,发现Lisp内的选择集函数(ssget "X" ...)在VBA中有对应的对象,即SelectionSet对象。
DWG文件作为一个优秀的图形数据库是非常强大且高效的,而充分利用好SelectionSet对象是能够高效得检索这个数据库的前提,其作用方式类似于传统数据库中的关键字检索,而且几乎所有图形信息都可以作为关键字进行检索。
有必要简单说一下DWG文件中图形信息的组织方式,其数据是以所谓的数据对表构成的,即每个数据都是由组码和值成对的出现的。例如一个文字对象,其数据可能如下:
((-1 . <图元名: 7eb7e0f8>) (0 . "TEXT") (330 . <图元名: 7efc0ca8>) (5 . "117AF") (100 . "AcDbEntity") (67 . 1) (410 . "Layout1") (8 . "ReportHeader") (62 . 3) (6 . "Continuous") (100 . "AcDbText") (10 745.649 535.124 0.0) (40 . 1.8) (1 . "1200-PLF-0049-A061") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "Arial") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . "AcDbText") (73 . 0))
其中,每个括号内就是一个数据对表,前面的数字就是组码,后面的是值。每个组码代表的是不同的信息类别,比如上面这个文字对象中,组码 0 对应的 TEXT 值表示该对象是一个文字图元,而组码 1 对应的 "1200-PLF-0049-A061" 则表示该文字图元的内容。使用SelectionSet对象时,就是要告诉程序需要检索的组码和其对应的值。
上述数据可以通过在AutuoCAD命令行中键入:
(entget (car (entsel)))
然后通过鼠标选择一个图元,按F2键即可查看到该图元的全部数据信息。


下面是使用SelectionSet对象进行检索的代码片断:
PHP 代码:
Dim acadSSet As Object
Dim arrGroupCode
() As IntegerarrDataValue() As Variant
On Error Resume Next
Set acadSSet 
acadNewDoc.SelectionSets.Add("SS_Temp")
If 
Err 0 Then
    Set acadSSet 
acadNewDoc.SelectionSets.Item("SS_Temp")
    
acadSSet.Clear
    Err
.Clear
End 
If
On Error Goto 0
ReDim arrGroupCode
(7): ReDim arrDataValue(7)
arrGroupCode(0) = -4arrDataValue(0) = "<AND" '组码-4,用于 和、或 组合'
arrGroupCode(1) = 0:  arrDataValue(1) = "TEXT" '组码0,图元种类'
arrGroupCode(2) = -4arrDataValue(2) = "<OR"
arrGroupCode(3) = 8:  arrDataValue(3) = "0" '组码8,图层名'
arrGroupCode(4) = 8:  arrDataValue(4) = "Table"
arrGroupCode(5) = -4arrDataValue(5) = "OR>"
arrGroupCode(6) = 62arrDataValue(6) = '组码62,颜色'
arrGroupCode(7) = -4arrDataValue(7) = "AND>"
acadSSet.Select Mode:=5FilterType:=arrGroupCodeFilterData:=arrDataValue
'Mode种类:'
'acSelectionSetWindow = 0'
'acSelectionSetCrossing = 1'
'acSelectionSetPrevious = 3'
'acSelectionSetLast = 4'
'acSelectionSetAll = 5'
For 0 To acadSSet.Count 1
    Debug
.Print acadSSet.Item(i).TextString
Next
acadSSet
.Delete
Set acadSSet 
Nothing 
至于如何进一步筛选出表格中的文字,不外乎通过统一的特殊文字或文字片断获得表头位置和表结尾位置,从而进一步确定表的上下左右边界位置,然后通过文字图元的位置进行筛选和排序。本文就不展开代码了。

关于AutoCAD对象模型树可参考 "AutoCAD 帮助:开发人员文档" 中的 "ActiveX and VBA Reference"。
关于AutoCAD组码可参考 "AutoCAD 帮助:开发人员文档" 中的 "DXF 参考手册"。
该文档在AutoCAD菜单:帮助->其他资源->开发人员帮助。


以上代码测试环境:Excel 2003,AutoCAD 2007,Windows XP Pro。

欢迎讨论...

以上
Lee1892 于 2012-11-14

此帖于 2012-11-14 13:04:24 被 lee1892 编辑. .


行行复行行...人生路漫长...
发表新主题 关闭主题

主题工具

论坛规则  发帖规则
不可以发表主题
不可以回复帖子
不可以上传附件
不可以编辑自己的帖子
论坛启用 vB 代码
版面启用 表情符号
版面启用 [IMG] 代码
版面禁用 HTML 代码


所有时间均为北京时间, 现在的时间是 17:56:01.

本论坛带宽由迅通网络提供
SSL证书由TrustAsia提供

Copyright © 2000 - 2019 ClassiClub Forum All Rights Reserved.
粤ICP备09123456号