QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

楼主: koutx
收起左侧

[已解决] CAD二次开发对二维图某些数据的统计(请我爱谁家版主再指导)

[复制链接]
发表于 2009-3-3 18:46:33 | 显示全部楼层 来自: 中国

回复 25# koutx 的帖子

分别在两台电脑上运行附件中的文件,方法一在我的电脑上完全没有问题;在另一台老旧的电脑(1G+128M,XP+sp2,office2003,acad2008)上不稳定,有几次CAD程序运行不起来,应该是硬件的缘故。
 楼主| 发表于 2009-3-3 23:12:48 | 显示全部楼层 来自: 中国北京
原帖由 woaishuijia 于 2009-3-3 18:46 发表 http://www.3dportal.cn/discuz/images/common/back.gif
+ C0 w: a) G7 b% d) I5 x& W分别在两台电脑上运行附件中的文件,方法一在我的电脑上完全没有问题;在另一台老旧的电脑(1G+128M,XP+sp2,office2003,acad2008)上不稳定,有几次CAD程序运行不起来,应该是硬件的缘故。
. `' ]4 G9 O) B* Y  t$ W6 O' i6 E

2 x! W0 [; c+ w( Y我的电脑为60G+512M,XP+sp2,office2003,acad2004),请问版主到底为什么不行呢?谢谢
发表于 2009-3-4 08:12:21 | 显示全部楼层 来自: 中国

回复 27# koutx 的帖子

首先,在运行AccessVBA前应该把ACAD关掉。因为按现在AccessVBA的代码是要创建一个新的CAD进程,如果不关闭原先打开的CAD程序,电脑中就会运行两个或更多CAD进程,配置较低的电脑会承受不了的。
) y7 ]7 V% J$ m; J; j6 \. }4 d% _实际上,在代码中调用CAD(其它程序也一样)不一定要创建一个新的进程,我在7楼的帖子中已经说到了这个问题。
  1. 4 }; W; H7 e& h' ?9 o. V: \
  2.     Dim CAD As AcadApplication
    + F/ J0 I3 ^0 d( J5 j# z
  3.     On Error Resume Next7 G. F3 d! f1 Z- x, C
  4.     '引用已运行的CAD进程: g/ X! y; g: z* B3 T' Q7 ?
  5.     '如果此时电脑中没有正在运行的CAD进程则会返回一个错误3 q: {$ s# p) s; K+ m
  6.     Set CAD = GetObject(, "AutoCAD.Application")5 Y! r0 U/ S1 _% x: y1 |
  7.     '如果出错则创建一个新的CAD进程
    + P5 d5 H# h, n1 q. G! r; o) }9 a
  8.     If Err Then
    6 b0 y  e7 q, r( x! ?# {7 H
  9.         Set CAD = CreateObject("AutoCAD.Application")$ P# T+ g* b0 `' z
  10.         Err.Clear
    . j4 h( O* J: Y" b$ g# e5 `
  11.     End If  v  B4 M! {# b+ Z( u# z. T" |
  12.     CAD.Visible = True
    3 n1 ?3 `6 v& g& X$ Q# o# V
复制代码
这段代码比以前的代码
  1. Dim CAD As New AcadApplication
    ( V# f( W& t- u7 C0 [+ r
  2. CAD.Visible = True
复制代码
复杂,但也更完整,通常在VBA中互相调用应用程序时都是这样写的。如果代码仅供自己使用,则还是直接声明并创建一个新的进程更方便,只是要明白自己在使用时应该注意什么。  m$ v3 }6 p6 }
' j. F$ ~% y* L* c
再回到你的问题上来,当程序运行完
  1. CAD.Visible = True
复制代码
这一行后,Windows任务栏中应该显示CAD程序,桌面也应该显示CAD窗口。
9 K, @- E+ {) w4 e! R8 G运行完
  1. CAD.Documents.Open "D:\CAD二次开发\例子.dwg"
复制代码
,在CAD窗口应该打开这个文档, P2 C4 `4 M5 k- x- d2 a; g
运行完
  1. CAD.LoadDVB "D:\CAD二次开发\Project.dvb"
复制代码
,在CAD命令行应该出现“命令:正在初始化VBA系统...”
) u) Z# f2 ^5 t1 w/ m下面接着运行
  1. CAD.RunMacro "D:\CAD二次开发\Project.dvb!模块1.A"
复制代码
应该就在这时你的电脑出现问题了,CAD的宏迟迟运行不起来,然后你强行关闭了CAD,于是AccessVBA报错“无法运行VBA宏”。当你选择“调试”时,这一行代码被用黄色高亮显示,说明这一行没能正常完成。鼠标移到“CAD.Visible = True”这一行时,显示“CAD.Visible=<远程服务器不存在或不可用>”的提示--因为这时被调用的CAD进程已经被关掉了,“CAD”变量找不到对象了 ! ^6 ~* ]. G3 y' T+ }7 |+ K
不知道分析得对不对。如果是这样的话,还是考虑一下如何减轻系统负担吧。关掉与此不相关的程序,VBA中不要使用无关的“引用”(比如,在AccessVBA的“引用”对话框中,我看到你除“AutoCAD2004类型库”外还有两个与CAD有关的引用,不知是什么用意,从代码上看不到用处),或者关机重启后运行一下试试。3 ^, \% T! [) h( D; S' M
我暂时也想不出其它可能的原因。
 楼主| 发表于 2009-3-4 09:49:19 | 显示全部楼层 来自: 中国北京
谢谢详尽的讲解,我换了一张新的.dwg图 例子.rar (38.28 KB, 下载次数: 3)
发表于 2009-3-4 20:56:49 | 显示全部楼层 来自: 中国

回复 29# koutx 的帖子

如果在宏代码中能修改AutoCAD宏安全等级,那AutoCAD宏安全不是形同虚设了吗,呵呵 ( f3 z4 D1 t# J$ S" s; W; |2 r
还是在CAD的“宏”对话框中点“选项”,在“选项”对话框中设置吧。
 楼主| 发表于 2009-3-4 23:04:24 | 显示全部楼层 来自: 中国北京
好的,我试试取消宏安全提问后怎么样。6 s) r( X( [/ A+ a' X1 l" D4 c
不过Access的宏安全级别可通过修改注册表键值来实现,不知AutoCAD怎么样。
 楼主| 发表于 2009-3-5 12:09:35 | 显示全部楼层 来自: 中国北京
取消宏安全警告后,还是不能自动运行宏A,真不知是什么原因。只好手工输入VBArun了。
发表于 2009-3-5 20:56:01 | 显示全部楼层 来自: 中国
你在AccessVBA中并没有调用加载的.dvb工程啊 。而是调用了AccessVBA中的一个过程--尽管这个过程的代码与.dvb工程中一样--AutocadVBA的代码不能直接复制粘贴到AccessVBA中使用的。
 楼主| 发表于 2009-3-6 09:00:08 | 显示全部楼层 来自: 中国北京
可我在25楼上传的例子中的Access代码是:. B2 |$ Z" h* g$ S
Private Sub Command5_Click()
+ C& Z  @* k# F'方法一(这是照版主教的作的)
  F" y5 R% n6 Q7 R8 U    If Dir("D:\CAD二次开发\Project.dvb") = "" Then
4 D* ^0 V/ [5 |; }" H               Exit Sub
$ L  o" o# I; L4 N$ E6 E! v    Else
% K5 g* ]! R3 S               Dim CAD As New AcadApplication
9 k% K8 ^, X9 r( I3 D8 |              CAD.Visible = True
# N+ s- A4 E: G; W) Y6 A              CAD.Documents.Open "D:\CAD二次开发\例子.dwg"
2 |" ^7 E! U8 z! A! s# v              CAD.LoadDVB "D:\CAD二次开发\Project.dvb"                    '调用工程! `9 X' p' \* N/ H) M+ e1 w: i; P
              CAD.RunMacro "D:\CAD二次开发\Project.dvb!模块1.A"    '运行宏
( M9 `( i! I+ Y) u    End If& A! N, @# N* {( \0 ~
End Sub
. ~- D6 _5 W; K从代码上看调用的不是Access的一个过程啊?还请版主明示。
发表于 2009-3-7 08:52:21 | 显示全部楼层 来自: 中国辽宁营口

回复 34# koutx 的帖子

这段代码没有问题。你所遇到的问题一定是出于代码以外的原因。
7 u" C% ^1 @( Z$ d+ }可是你在29楼上传的附件中的代码可不是这样的,你把“运行宏”这一行注释掉了,代之以“call A”。。。也就是说,这段代码只是在CAD中加载了DVB工程,并没有运行宏。而在调用“A”宏时,由于“A”宏只是简单地从DVB工程中复制粘贴过来,对于Access环境来说,“Thisdrawing”是它不可理解的词语,所以“A”宏事实上什么也没有做就结束了。
: J* R3 h9 k2 e* l! _& w也许这是你在尝试中的一种方法吧?0 i0 U& k" Y3 |7 ?! h) i
把DVB工程代码移植到Access中应该这样做。% E% x* H3 S# K" ?* w0 a( g" |
下面代码中黑色部分是“方法一”按钮单击事件过程中原先就有的;绿色部分来自于“A”宏;红色部分是我添加或修改的。+ }3 W% C& u9 s  \! v! g
这段代码需要在AccessVBA中引用CAD和EXCEL类库4 E1 K) G# |! M0 _$ K

$ i. S7 Z) O; `- r9 `8 q) f3 |Private Sub Command5_Click()
4 n3 R) p. ]8 w# W3 S% G    Dim CAD As AcadApplication, DWG As AcadDocument
6 P3 s# W* ~; t( t8 [/ |- m    '声明一个选择集及过滤器
5 h( ^4 k: p7 B, ?8 e# P    Dim SS As AcadSelectionSet, FT(0) As Integer, FD(0) As Variant
3 t9 X+ W, v( n4 T9 \    '声明一个直线临时变量
# g- B- w) y% j7 i4 [$ D    '声明两个直线动态数组,分别用于存放水平直线和垂直直线
1 }* L8 ^& a, M+ [    Dim L As AcadLine, L1() As AcadLine, L2() As AcadLine
8 L  e8 @3 F2 g& S& T/ |4 I  l    '声明一个双精度变量,用于存放计算精度。精度的用途见后面输入框中的文字
; n, [  U: A( Q% z* T5 K  V; Q    Dim 精度 As Double9 Y; H% j( |3 \* N1 f
    '声明循环变量) P5 Y4 M7 \6 |% U
    Dim I As Long, J As Long, K As Long. j# o. i2 V, f4 a; T. w/ M& Q
    '声明四个变体变量,用于存放两相邻水平直线与两相邻垂直直线间的四个交点& i6 v! W& q, a: m# q& U
    '通过检查交点是否存在,鉴别该四条直线是否能围成矩形
# o% F6 I9 t6 X    Dim P1 As Variant, P2 As Variant, P3 As Variant, P4 As Variant
% H9 D( f, K9 Z5 U( X+ ]    '声明一个动态数组,用于存放查询矩形规格数量的结果( U- k8 C6 N3 b, P* @+ [  k8 ?& C
    Dim 矩形() As Double; R9 Z, @7 u3 N, n
    '声明一个逻辑变量,用于条件判断0 @. K9 M. Q* k6 R6 S/ v4 R6 r
    Dim B As Boolean

& r: y3 R1 w0 l$ H7 }* R   
$ {$ e4 z' E( J4 X$ {) y' ?    On Error Resume Next
) S; `: o- e+ g! t6 s9 }" G/ w% d    Set CAD = GetObject(, "AutoCAD.Application" )6 U! d5 ^5 k3 q1 ^* c. O+ e* C
    If Err Then3 n! K! \5 V, p: w! l
        Set CAD = CreateObject("AutoCAD.Application" )
+ p. G# [2 j4 x, O9 l  T% I. Z6 @        Err.Clear
+ G. F' ~8 ^  `    End If- k- B5 [5 L+ v  D* X
    CAD.Visible = True
) z) C0 {0 g* m- K+ \    Set DWG = CAD.Documents.Open("D:\CAD二次开发\例子.dwg" )" q, b& v! K7 e  k8 u
    With DWG

- J- H: K, o' M& z; ~2 f        '输入精度
: @3 P% Y* `. W% P5 x        '精度 = Val(InputBox("输入精度" & vbLf & "鉴别直线是否水平(垂直)时,如果直线与极轴的夹角(弧度)的绝对值小于该精度值,即认为该直线水平(垂直)" _( J) ]. l1 M& o" X' C: F
            & vbLf & "鉴别矩形大小是否一致时,如果被比较的矩形的长(宽)与原始矩形的(长)宽之差的绝对值小于该精度值,即认为两矩形一样大小", "AutoCAD", 0.000001))
! a# F9 [/ ?) E  {1 M% j        精度 = 0.000001
4 b9 u( I& t8 l& E/ h- S- s        '定义选择的对象为直线对象,创建选择集并由用户在屏幕上选择
  x: c" k! C8 ~  O1 c& L2 c+ s' Z        FT(0) = 0* n) o5 n+ ^( o6 `
        FD(0) = "line"0 K- d: s8 X' \; l
        0 m6 q1 Z; C0 R; H2 W0 D$ o: o
        Set SS = .SelectionSets.Add("SS" )
! U6 [9 Q$ e; Y2 A% g. H        SS.SelectOnScreen FT, FD! v+ s0 h' ~' o3 O1 h! d! L
        '遍历选择集,鉴别其中的水平和垂直直线并分别存入动态数组3 C# @! p. h& F& t& O
        
: b$ g/ K. N) Y  M, H+ ?5 V        3 z  D) J& n& [  Q" G
        For Each L In SS( u) G# a8 Z  ?9 O1 a
       ' MsgBox UBound(L1)1 y, \4 C6 I. c' s6 U# P  D# }$ n
            If L.Angle < 精度 Or L.Angle > .Utility.AngleToReal(180, acDegrees) * 2 - 精度 Or Abs(L.Angle - .Utility.AngleToReal(180, acDegrees)) < 精度 Then
- }( f0 x; @" S4 u+ V; `: B                If UBound(L1) = -1 Then, F3 H0 g2 J! S9 c! n5 B
                    ReDim L1(0)
  L6 c; t- M4 ~                Else
6 H  g$ d8 Z+ S" q0 c' a5 p                    ReDim Preserve L1(UBound(L1) + 1)
% z; f/ M1 V. q! I6 E6 q                End If# ~/ q& f$ _* c, ^' I  A
                Set L1(UBound(L1)) = L+ o- |7 C2 U9 G
            ElseIf Abs(L.Angle - .Utility.AngleToReal(90, acDegrees)) < 精度 Or Abs(L.Angle - .Utility.AngleToReal(270, acDegrees)) < 精度 Then
2 z, W- w" m7 _& |, z9 m& x5 P# n                If UBound(L2) = -1 Then
6 a' c3 d9 \5 ^( |& t" ?  ~, X                    ReDim L2(0)3 [0 u* _8 \1 v1 z
                Else; r0 o: Y4 S! d0 ]
                    ReDim Preserve L2(UBound(L2) + 1)0 X9 b6 x9 f2 S- B3 Y% p  O
                End If* D1 _( @- ^/ ?4 Z' v  E1 k
                Set L2(UBound(L2)) = L
7 S- j5 j, a, ?& R$ Q0 H, S( r! j            End If! `; ]9 I; R+ L6 F, P# k" G6 h
       Next6 n. {& P) C4 M9 K- _7 D! n, }
        1 [0 g" }+ m% h/ k
        0 d1 v7 C5 Q/ ?
        '删除选择集
+ j; j  W8 Q# s: l. d        SS.Delete
1 o& D& v' A7 }        '当水平直线和垂直直线数量均不小于2时,执行下面的代码,查询矩形规格和数量并保存! \" @2 ]1 M- }& h
        
" O4 m! |8 `& r) [        If UBound(L1) < 1 And UBound(L2) < 1 Then
: m0 L- l* p8 I& g. J        Else
8 o) W* H. v% ]1 @+ O" ^8 u  M/ ~      
# Y9 Z, h9 n4 i1 Q            '水平直线数组中的直线,按起点纵坐标由小到大重新排序5 ^& j8 |  P3 i; q/ N# |7 `. ]
            For I = 0 To UBound(L1) - 1
+ k7 {! D, A! {0 k                For J = I + 1 To UBound(L1). ~% t/ S+ D0 b4 _) a7 `& o
                    If L1(J).StartPoint(1) < L1(I).StartPoint(1) Then) Q0 h6 Y9 ?: o/ ]2 R# n
                        Set L = L1(I)
7 Y# e: \- e6 V                        Set L1(I) = L1(J), m2 Y$ q/ [2 U0 O) M
                        Set L1(J) = L
1 c  j8 S9 [5 U& ^. q                    End If
8 T( `' S& `2 J! l                Next( p: a1 I8 s2 Z2 d. c2 h
            Next- K# A' }5 @" ?
            '垂直直线数组中的直线,按起点横坐标由小到大重新排序
+ v- v& R; Q0 ~+ u1 ~7 c; A- p            For I = 0 To UBound(L2) - 1
  }, n8 C1 P, Q. O) D                For J = I + 1 To UBound(L2)* R9 ~4 y# K. K1 F
                    If L2(J).StartPoint(0) < L2(I).StartPoint(0) Then$ z" S  J: T1 Q8 N. Y% C; X
                        Set L = L2(I)
* Y/ Z& \$ X0 E                        Set L2(I) = L2(J)  `% K! L- o+ |. v3 q  l# \
                        Set L2(J) = L
& m7 N9 y, ~; }: D$ p% z* ^# }                    End If
8 S+ `% p% o, p# ]8 f+ D) N                Next* y. K4 R$ |; U5 L8 ]
            Next
) \2 V0 h. N" [) }* x& d2 p            '检查相邻直线是否相交围成矩形并做进一步处理  ^  k8 g' R# F) B& x: x
            For I = 0 To UBound(L1) - 1
* p9 l5 o: I2 X) @9 E! X                For J = 0 To UBound(L2) - 1+ u: b: h, }. H9 l; q4 F+ m
                    '获得相邻直线的交点2 X: ^. q" A) G- }6 [' q
                    P1 = L1(I).IntersectWith(L2(J), acExtendNone)
' m( d. `: b8 E- Z+ o( L  u                    P2 = L1(I).IntersectWith(L2(J + 1), acExtendNone)
- |, h( G+ A5 Z3 m                    P3 = L1(I + 1).IntersectWith(L2(J + 1), acExtendNone)
/ s6 M; u" r0 R1 ?' G. D' Y3 i9 k                    P4 = L1(I + 1).IntersectWith(L2(J), acExtendNone)
! g1 c. H( v4 Z& b- q+ n- m8 ?0 ~7 D                    '当四个交点都存在时,执行下面的代码3 n" R' B% m; e
                    If UBound(P1) = -1 Or UBound(P2) = -1 Or UBound(P3) = -1 Or UBound(P4) = -1 Then1 w5 |& ^1 K! z; M0 I
                    Else$ ~1 t* Y, z+ F) |! L6 E
                        If UBound(矩形, 2) < 0 Then '第一个矩形直接存入数组
3 ]9 C; \8 s8 q2 A$ O+ h4 W                            ReDim 矩形(2, 0)
- s, E3 G8 t+ _) n) z                            矩形(0, 0) = P2(0) - P1(0)+ \6 [$ H! r$ Z" _" {
                            矩形(1, 0) = P3(1) - P2(1)
; p' ]  `) Y" c                            矩形(2, 0) = 1
2 Z; `+ s7 l" n7 M3 M                        Else '其它矩形% X7 i, g/ t: J% s9 v; G0 q" D
                            '检查前面存入数组的矩形中是否有相同规格3 Y- H4 U6 }# \8 q
                            '如果存在,则在数组中的数量上加1,并改写逻辑变量(标记)
! g) g6 z" u4 [                            B = False
4 h4 o8 X- J7 E8 y) A6 w0 o- W                            For K = 0 To UBound(矩形, 2)( c: o( _3 F6 l% u2 s& C' [( s8 \
                                If Abs(矩形(0, K) - (P2(0) - P1(0))) < 精度 And Abs(矩形(1, K) - (P3(1) - P2(1))) < 精度 Then
5 x, x! q2 I' }8 D                                    矩形(2, K) = 矩形(2, K) + 12 k6 d8 [$ b' T: v" Y& `
                                    B = True
# C: W( v. ]; F% ^/ j( r/ ?                                    Exit For
, N5 p( z( v/ E& |' |6 {                                End If0 M2 `5 P8 B8 e0 d+ F7 P
                            Next5 n. p  @' R! a0 c9 J  V7 W
                            '如果数组中没有相同规格的矩形,则重定义数组,并写入新的规格、数量为1
4 R$ d- k* G! ]8 T; A+ d2 b                            If Not (B) Then- p0 E" \# x& I5 V& I7 ]) ~: b
                                ReDim Preserve 矩形(2, UBound(矩形, 2) + 1)
/ o' p% c$ d9 R( s7 l6 U# v                                矩形(0, UBound(矩形, 2)) = P2(0) - P1(0)
/ t' G5 @: e* t) q* z                                矩形(1, UBound(矩形, 2)) = P3(1) - P2(1)
$ c% j5 D6 e7 o                                矩形(2, UBound(矩形, 2)) = 1
! G8 i6 {+ o; C1 |: o( ~                            End If
3 }! l( y9 Z8 x  j                        End If
2 q6 m$ ~+ M0 m/ B0 R                    End If3 W1 l9 _0 Y8 ?. X; V
                Next
4 B) E  A; k8 h0 ?/ v) r            Next: N% N- h" z( \  v) C8 l
            '如果存在矩形,把数组中的规格、数量写入Excel文档9 x0 O* s1 S- ]/ o: v4 q! @0 B' M
            If UBound(矩形, 2) < 0 Then
. }4 z8 l  p5 ~% v5 ?- h0 U& ^2 S! x0 Q            Else' A4 ]6 @9 N" O' A3 C4 Z: ?/ X- P
                '声明并启动Excel程序
; L% ]7 A: V5 X7 l  ^) Y; P                '声明工作簿: K4 `7 j5 \4 [# _/ ?& S8 B, {
                Dim E As New Excel.Application, Book As Workbook
" K, C- W3 h8 a7 s0 k. Y7 t  ~2 u% a                '创建工作簿4 y" R2 z# ^, Z: y2 V: y( l5 t. z6 ?
                Set Book = E.Workbooks.Add
9 v- l/ ^5 S8 n7 M9 i; ^                '写入字段名称
, q' Y) a- ^2 p/ k- i                Book.ActiveSheet.Cells(1, 1) = "长"
8 M1 _: }0 I2 j                Book.ActiveSheet.Cells(1, 2) = "宽"" f4 U2 r4 n: \& [7 o
                Book.ActiveSheet.Cells(1, 3) = "块数"
; N. j) g' I5 v8 R9 p9 e% y) F' P                '写入矩形规格和数量$ V, v8 G6 G- a6 P. [. z
                For I = 0 To UBound(矩形, 2)
. j' W9 u4 P5 W" q# }                    For J = 0 To 2
' u. m6 j$ V' }                        Book.ActiveSheet.Cells(I + 2, J + 1) = 矩形(J, I)6 y8 j/ t: F+ j
                    Next* F) `) b1 j! S" X2 B: k
                Next: G- s3 \) u) W' g. t: Z. h* Z
                '保存文档并退出Excel
( a0 E9 D8 G# f+ u3 [7 c& Y                Book.SaveAs "D:\CAD二次开发\biao.xls"
9 b# n+ q. O% m: m                Book.Close/ n* {1 U4 V; a0 f9 d
                E.Quit
% X5 c% T5 H( `5 K  f* v* g' j            End If  [4 X. g! g7 N* k" K; ?
        End If% Z) r% x, T, Z  k
    End With
' e5 B7 Y# G' o1 x4 ^: U
End Sub
' R" ?  j8 e* V( B) j6 a3 s( B( n6 F# @. h
[ 本帖最后由 woaishuijia 于 2009-3-7 09:17 编辑 ]
 楼主| 发表于 2009-3-7 11:04:58 | 显示全部楼层 来自: 中国北京
谢谢,我再按版主的思路试一试,学一学。) s( b3 r1 H1 e" a5 q
再请问一下版主:我在本站下载了j04150209上传的一个小的程序如附件。其能对线段进行多选,计算其总长度。1 V2 x  E  @& R6 E! M
使用方法:只需CAD加载该程序,再输入qxcd命令,选取对象即可。不知是用什么语言开发的。
/ r4 t7 A- X9 Y: o 计算线长度的小程序.rar (1.65 KB, 下载次数: 2)
发表于 2009-3-7 11:29:00 | 显示全部楼层 来自: 中国辽宁营口

回复 36# koutx 的帖子

是用Visual LISP开发的。
 楼主| 发表于 2009-3-8 23:16:20 | 显示全部楼层 来自: 中国北京
没办法,我对Lisp是一窍不通。敢问版主:如版主在35楼中提供的CAD过程代码,如不在AutoCAD中编写Project过程,而是在.NET中用VB编写为.dll或.exe文件,而从AutoCAD中调用能实现吗?
发表于 2009-3-9 07:12:24 | 显示全部楼层 来自: 中国

回复 38# koutx 的帖子

不能,AutoCAD没有提供这样的工具。
 楼主| 发表于 2009-3-9 08:48:11 | 显示全部楼层 来自: 中国北京
知道了。那AutoCAD VBA能否将类似版主的代码生成非Project过程的外接程序?
发表于 2009-3-9 12:15:54 | 显示全部楼层 来自: 中国辽宁营口

回复 40# koutx 的帖子

不能自动生成,要适当地进行修改,就像我在35#楼做的一样。  c2 i* H1 a" [" P; h
. Q3 P" Z2 Q3 J2 n8 q. F
下面的内容摘自ACAD帮助文件《ActiveX 和 VBA 开发人员手册》> ActiveX Automation 基础知识 > 使用其他编程语言 > 将 VBA 代码转换为 VB5 C9 j9 ]+ _% q3 V* O
& P5 J' ^. W( V9 n& g. \, ~
要更新代码样例以在 VB 中使用,必须先引用 AutoCAD 类型库。要在 VB 中完成此操作,请从“工程”菜单中选择“引用”选项,启动“引用”对话框。在“引用”对话框中,选择 AutoCAD 类型库,然后单击“确定”。0 r4 |! ~* w) B1 m$ {7 z
然后在代码样例中,将所有对 ThisDrawing 的引用替换为引用活动文档、用户指定的变量。要完成这项操作,请为 AutoCAD 应用程序 (acadApp) 和当前的文档 (acadDoc) 定义变量。然后,将应用程序变量设置为当前的 AutoCAD 应用程序。) T4 F0 D( W# B# Z. o6 y
如果 AutoCAD 正在运行,指定 AutoCAD 版本号时,VB GetObject 函数将检索 AutoCAD Application 对象。如果 AutoCAD 没有运行,发生的错误(本例中)会被捕获然后清除。CreateObject 函数接着会试图创建一个 AutoCAD Application 对象。如果创建成功,会启动 AutoCAD;如果失败,则会显示一个消息框,说明发生的错误。) W$ N8 i0 Q# v0 J% o
同时运行多个 AutoCAD 任务时,GetObject 函数会返回 Windows 运行对象表中的第一个 AutoCAD 实例。关于验证 GetObject 所返回任务的详细信息,请参见 Microsoft VBA 文档中的运行对象表 (ROT) 和 GetObject 函数。9 E( K, ^" A1 u2 G/ i/ A$ \  w: ~
要显示 AutoCAD 图形窗口,必须将 AutoCAD 应用程序的 Visible 特性设置为 TRUE。3 O. S: G, `  U1 [, A, m* I
如果 GetObject 创建了一个新的 AutoCAD 实例(即调用 GetObject 时 AutoCAD 没有运行),没有将 Visible 设置为 TRUE 会导致 AutoCAD 应用程序不可见,甚至 AutoCAD 不在 Windows 任务栏上显示。
# _. a5 a, I4 C& v* c注意 使用依赖于版本的 ProgID。如果 CreateObject 或 GetObject 函数使用的是独立于版本的 ProgID,则将函数更改为使用依赖于版本的 ProgID。例如,如果使用的是 CreateObject,请将 CreateObject ("AutoCAD.Application" ) 更改为 CreateObject ("AutoCAD.Application.17" )。此外,如果 GetInterfaceObject 方法使用的是独立于版本的 ProgID,则必须将该方法更改成使用依赖于版本的 ProgID。
 楼主| 发表于 2009-3-10 21:55:24 | 显示全部楼层 来自: 中国北京
多谢版主指导,已测试通过了。还有一个问题总是搞不明白:加载并执行过程成功后,选择并生成Excel文件后,再次选择就不允许了。我只知道是关闭了选择集的原因,能否再次启动选择集?
发表于 2009-3-11 18:25:23 | 显示全部楼层 来自: 中国河北石家庄
我爱谁家老师既认真又热情,真是让人感动。
发表于 2009-3-13 06:51:30 | 显示全部楼层 来自: 中国

回复 42# koutx 的帖子

你是不是说,想在选择并生成ECXEL文件后,再次选择并生成文件。。。?
1 n( C, r/ }6 j+ d9 C& z可以加上一个DO循环,反复运行从创建选择集到生成文件并结束的这部分代码,根据适当的条件退出循环。以3楼的代码为例
' F" T$ h3 Z* L& h* ?! i% U( z: ?# ~# O. r- K2 H, M+ [
    '声明部分略    " K. J. h3 f( J! A
    On Error Resume Next
+ A9 ?5 Z2 K) ~. O$ H8 |2 }    With ThisDrawing& I9 `' N0 S. `$ R3 r
        '输入精度
% I) x, t) W; O5 Q4 @4 z        精度 = Val(InputBox("输入精度" & vbLf & "鉴别直线是否水平(垂直)时,如果直线与极轴的夹角(弧度)的绝对值小于该精度值,即认为该直线水平(垂直)" _
9 u) F% b% L4 \7 \( v  p% Q            & vbLf & "鉴别矩形大小是否一致时,如果被比较的矩形的长(宽)与原始矩形的(长)宽之差的绝对值小于该精度值,即认为两矩形一样大小", "AutoCAD", 0.00000001))6 o# ^8 j3 c' N& _: P
        Do1 v, o2 x% @' E' c' F" G  i& D. d
            '定义选择的对象为直线对象,创建选择集并由用户在屏幕上选择
2 _6 B9 ]% c& K" l" b+ I            FT(0) = 06 N, }# b8 [$ f* C$ z  J
            FD(0) = "line"5 \% z0 W# \0 G7 e
            Set SS = .SelectionSets.Add("SS" )
6 x# Q/ p, [# v1 Y: ^0 ^) i, b            SS.SelectOnScreen FT, FD- i* d' L6 T( v" t
            If SS.Count = 0 Then7 R& W6 s, R5 v0 b7 j
                SS.Delete+ B$ `, Z0 t! p/ y3 a: M* s# h- ?% w
                Exit Do$ C0 `. T) Y  t& _0 H% j
            End If# C+ @/ G2 h) F& N/ \0 A9 K
0 ^& K! g  Y$ X. o& ]
            '中间部分略
* d& G9 S2 X$ N$ `$ R, M( Z! b% g  L- v) J
        Loop
! `- J9 @5 T; i
    End With
* i3 ]5 T- w# o" {$ f8 w, Y% |& {$ H/ U% S6 O9 M
这段代码运行时,会在生成一个文件后再次要求用户选择对象,如果选择对象,就再生成一个文件。。。如果没有选择对象(选择集为空)就退出循环结束
' |9 u$ H8 l( h7 W: y: f; Y- D; Q3 t1 H$ |( O8 n9 J
[ 本帖最后由 woaishuijia 于 2009-3-13 06:55 编辑 ]
 楼主| 发表于 2009-3-13 15:41:16 | 显示全部楼层 来自: 中国北京
谢谢版主,我马上就试。再次谢谢。
 楼主| 发表于 2009-3-13 18:04:52 | 显示全部楼层 来自: 中国北京
试了多少次,Do--------Loop循环中好象并不是删除选择集SS后再新建选择集,因此第二次选择直线时,选择集中会存在重复选择的直线。& p/ {6 f& ^; R: V5 X
请问版主能不能实现如下的效果:
% P! W) N, j5 g5 W' q5 K9 I; @一、首次选择某些直线,导出Excel时,判断biao.xls存在与否,如不存在则创建其并导出相应尺寸;如biao.xls存在则追加相应尺寸。同时清空ss选择集中的内容,以备第二次选择。( Z6 {0 Q6 z# A3 ?
二、第二次选择某些直线时,将新选择的直线生成的相应尺寸也追加到biao.xls。一直到不选择任何内容回车时跳出循环并终止过程。% v5 O$ B; q5 D+ x
麻烦版主指导,谢谢。
  T' n" ^% @8 p9 k1 ~% R6 l
0 L5 q5 P4 u- @, K, k[ 本帖最后由 koutx 于 2009-3-13 18:10 编辑 ]
发表于 2009-3-14 07:03:51 | 显示全部楼层 来自: 中国
Do--------Loop循环中好象并不是删除选择集SS后再新建选择集,因此第二次选择直线时,选择集中会存在重复选择的直线。

( y; _$ L4 ]. T0 M( y我想这是由于你的DO循环中没有删除用过的选择集的原因。你可以在VBAIDE界面按F8键逐语句运行宏,查找一下问题出在什么地方。+ ]. g" [  r! \2 z! k& V
导出Excel时,判断biao.xls存在与否,如不存在则创建其并导出相应尺寸;如biao.xls存在则追加相应尺寸. f, W. p7 W( l
第二次选择某些直线时,将新选择的直线生成的相应尺寸也追加到biao.xls。

& C* K' ]3 i; h" v6 a把创建ECXEL工作簿(workbook)的代码改写一下,先尝试打开原有的biao.xls文件,如没有这个文件则新建一个。
3 Y% O5 B# U) ^. k具体点说就是先把错误代码清空(err.clear),用workbooks的open方法打开文件,用if err then检查一下,如果错误存在则说明没有打开文件,就用workbooks的add方法新建一个文档,并且做好一个标记用于在保存文件时使用saveas方法;如果没有错误则说明文件已经打开,跳过去直接操作当前工作表。$ `8 m& n, `! S: |
操作工作表(sheet)的基本方法在以前的代码中就有,无非就是单元格(cell)、行、列、值(value)。
% b0 O0 |+ I0 m7 j7 ?- j6 h工作表改写完,就可以保存文件。如果是打开的旧文件,就用save方法;新创建的文件用saveas
4 L6 F: ?9 Y& U, q2 c/ G1 t+ T
同时清空ss选择集中的内容,以备第二次选择

- }- s/ ~8 w+ s2 F) Z: c只要每次循环都是创建一个选择集并确保在本次循环中能够删除它就可以了。如果你实在找不到问题出在哪里,可以在创建选择集时用一个随机数(RND()函数)做选择集的名字,以避免重复。
 楼主| 发表于 2009-3-14 15:31:06 | 显示全部楼层 来自: 中国北京
谢谢版主多天来的详尽指导,按版主于楼上的方法,已测试通过。5 t# |+ g- L+ ?! x  c
有一个困惑百思不解,还得麻烦版主:在CAD制图中当进行图案填充(bhatch)命令时,即可点击矩形中任一点而选取该矩形,并可多选(见下图)。可我将+ |: @1 }0 l$ [3 J& |( ^/ k0 s9 k
FT(0) = 0
/ A. o/ m8 f: o2 f( wFD(0) = "line"      此两句改为:
3 e$ S4 i; ?+ L3 D) t$ l3 y8 m2 Q, [
FT(0) = 0# j) m7 }) q! u' C. {& D' V) C  I
FD(0) = "rectangle"  后为什么并不能选取呢?所谓的孤岛选取又是怎么回事?如何调用呢。
7 {4 V& t, a8 T& q  c# N0 s  g3 L请问能否将类似这种选取方法来代替用选取直线的方法呢?多谢了。' f* d- q" L1 F' _* g( @9 }
Snap2.jpg ( R2 i" \+ }9 |- m' Y8 I, b

  ?% {' n0 q/ [1 G; q8 d) }2 Q[ 本帖最后由 koutx 于 2009-3-14 15:38 编辑 ]
发表于 2009-3-14 19:37:00 | 显示全部楼层 来自: 中国
"rectangle"不是组码。“矩形”是优化多段线的一种,组码是"lwpolyline"。至于该多段线是否是矩形,还要用其它方法检查。
. }  c+ a2 X' l+ s图形对象的组码在《AutoLISP&DCL基础篇》的附录C中有比较详细的介绍,此书本版区就有电子版,可以自己搜一下。, F9 G% p! o  X4 t0 I4 D$ _
ACAD的VBA并没有提供“孤岛检测”的方法,不过可以调用图形界面的“边界”命令实现它。

  1. * H% ]- S5 ~7 X7 ?
  2.     Dim I As Integer, SS As AcadSelectionSet, FT(0) As Integer, FD(0) As Variant, P As Variant, LP As AcadLWPolyline; [- i6 d& ^/ \' j4 |3 X0 U1 T
  3.     With ThisDrawing
    7 x/ s- v6 C5 h5 u6 i; {' Y1 a$ t( S
  4.         On Error Resume Next7 |6 q9 U: [6 t' k1 X, ^
  5.         Set SS = .SelectionSets.Add("SS" ) '新建选择集
    2 S" O# V2 G% Q4 x0 w
  6.         FD(0) = "lwpolyline" '定义选择集过滤器为选择优化多段线' G: i' W; a9 D. ]% J- `
  7.         Do, s- i- _% [- i- L. [2 @- y: ~" f
  8.             P = .Utility.GetPoint(, vbCrLf & "拾取内部点:") '由用户指定拾取矩形的内部点! T: H4 g* u, ]. F  N0 k& h- S
  9.             If Err Then Exit Do '如果用户没有指定点(按下回车、空格、右键或Esc)退出循环结束选择5 R# j7 l' j+ g
  10.             .SendCommand "-boundary " & P(0) & "," & P(1) & "  " '向命令行发送字符串,调用图形界面的“边界”命令进行孤岛检测并生成闭合的优化多段线(如果可能的话)。字符串中包含用户指定的二维点。注意字符串中的空格7 ^5 v$ N; D$ g9 f2 |1 _& b
  11.             SS.Select acSelectionSetLast, , , FT, FD '把最后创建的图形对象(而且必须是优化多段线)添加进选择集,如果不重复的话
    3 {' K6 H. k/ Y& [0 _
  12.             If SS.Count = I Then '如果选择集没有增加新元素,即“边界”命令没能创建新多段线。用于检查的变量 I 在后面累加, x0 a' K  p8 A' f2 K! n
  13.                 .SendCommand "n " '向命令行发送字符串,阻止“边界”命令在无法创建多段线时转而创建面域: p, P& t- |! w6 n& G# p
  14.                 Exit Do '退出循环,结束选择% @. O; u; Z- v" o% Y: D
  15.             Else, }( T; f: R3 R
  16.                 SS.Item(I).Highlight (True) '选择集的最后一个元素即新创建的多段线用高亮显示* j* e# F$ C, p! m
  17.                 I = I + 1 '变量 I 累加用于检查选择集的元素数量是否递增
    0 C6 N; G6 }" U) j9 Y+ k8 {, H( ~5 y
  18.             End If% E5 I& z; [# z- o2 u  _* {# K" F" d
  19.         Loop& w( ?  V. `! |, C0 v8 [
  20.         For Each LP In SS '遍历选择集,检查多段线是否是矩形并统计结果! r. _' ?- r; M9 p
  21.             LP.Highlight (False) '被高亮显示的多段线取消高亮  T+ Z8 h: w0 n/ z
  22.             '中间检查、统计部分省略
    3 m7 b5 \/ M$ A6 a
  23.         Next
    + Y/ O* c& z8 J* H9 I+ ?! ~
  24.         SS.Erase '删除选择集中图形对象,即删除用过的多段线(不是必要的)
    ) A7 w3 K  t. D8 {4 X9 u6 w1 l
  25.         SS.Delete '删除用过的选择集. N. p: B2 k  }
  26.         '输出文件部分省略
    5 R0 c: W- o; J! o4 o( n+ b+ s  S
  27.     End With
    4 Q( @" r/ V+ `
复制代码
 楼主| 发表于 2009-3-14 23:42:27 | 显示全部楼层 来自: 中国北京
非常感谢,又够学几天了。有弄不了的再来请教您。多谢了。
发表回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则


Licensed Copyright © 2016-2020 http://www.3dportal.cn/ All Rights Reserved 京 ICP备13008828号

小黑屋|手机版|Archiver|三维网 ( 京ICP备2023026364号-1 )

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