|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人! - I8 }* h! L! S# l% B
2 P" Y: z9 f3 H. ^' R6 Q5 k/ i2 mSub LianX()
$ V9 s3 @( X- r: M- S3 S" QOn Error GoTo xx8 k7 K0 u, O. Z% ?. e
Dim ssetObj As AcadSelectionSet0 e% t+ a e9 U7 X
Set ssetObj = CreateSelectionSet("uniteSS"
" ]) H6 V, p. _" k5 x Dim fType, fData
4 \* C. Y& S- y0 [ \1 @2 ^ BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
1 k& _$ k- {: h0 P7 c/ J '屏选直线或多段线
; i" E/ R/ B3 `, `: u ssetObj.SelectOnScreen fType, fData$ j1 M& N* `9 t8 ]( S' s
Dim i As Integer
% ]/ _7 l( f. X) w! R( m# t( K, k If ssetObj.Count <= 1 Then
' k1 U6 u- j) }5 ?3 R ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"
6 l, V4 c& k \% e/ X" c Exit Sub' w, L; {2 v. b+ V5 U
End If# B9 E B( @8 `- \0 S
; M- K( Z! h" p4 o! j: o' i Dim line1 As Object- j/ ^( ~- V; H( |
Dim line2 As Object
# m3 d! B# x2 k4 ~# u2 G/ r) Y
& n, O- v1 e- b* Z Set line1 = ssetObj(0)
/ Q% M8 i! M6 C+ D. ^+ r3 ~1 @0 d Dim pd As Boolean
+ u) x i$ E A For i = 1 To ssetObj.Count
; }! Z2 c5 w; L! e Set line2 = ssetObj(i)) q: f% a- G. `. _
'连接线
* m4 S8 \, }, K/ s% b m pd = unite2Line(line1, line2)6 m! [5 L! C( m" N0 p4 Y5 l( D
'如果连接不成功,则退出命令。2 b% l& L2 g8 }* a/ r4 C: E- | |2 N1 s+ P
If Not pd Then ssetObj.Delete: Exit Sub
Z) f9 Q- X, X, h) n4 l# H$ | Next3 l7 Q _; Y: q3 A. T& h$ Y$ n; g
xx:
1 o& c' c! @8 g& M" ^ Select Case line1.ObjectName1 ~* Q' }4 a% o: o: |
Case "AcDbLine"" c1 d! K, V5 w4 y0 a, h( W, o( _/ ]
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."
6 h/ ?9 a& i4 L u3 y Case "AcDbPolyline"
% }4 X$ F+ Q- }( L: T ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."1 b) R; T0 G8 T Z' y
End Select6 d* m2 K: r! V: o K% y( ]8 D' V
ssetObj.Delete
' h: N5 Z4 S" \) z, M# FEnd Sub0 N; C2 Y( {+ _* E3 h# k5 p+ X7 _7 o
" X( m; i6 k& a: T8 BSub uniteline()
; Y# x+ |6 ~( A! g' }8 L" Q On Error Resume Next
3 `' N8 {# x: q- Q0 \5 P+ j '取得线
7 i4 X6 y* g- m: z+ O7 @ Dim line1 As Object
/ R" `/ X3 G3 P9 j# u$ Q- q/ p Dim line2 As Object& u9 k6 n. X! C* I/ `
Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity
; a. Z" N" s/ G; H" R8 d Dim lpt1, lpt2 As Variant
% Q/ h" @6 b( u
$ i6 r! w7 a+ t2 j gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"; E' J7 |% [: n4 b4 @, q
If line1 Is Nothing Then
& g9 Z& z; ~& V ThisDrawing.Utility.Prompt "用户取消,退出命令。"
1 D1 {- H8 [- w; x6 j, r Exit Sub( h0 y1 p- P) H" `7 O. h4 { o, b: Y
End If) k# ~. s, e( `! t/ M5 n, q) l
; V \+ [" ], \( e2 }3 I( a
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline": a' i! B* R: I) ]' Q
If line2 Is Nothing Then Z- t. ?* r4 m* H* t8 o
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
" p/ k- r4 |6 d/ E Exit Sub
8 U7 o% Z5 O8 T | End If
2 a" Q4 \* J& ?% G- U4 t '连接线6 J* L! P* v, J2 A1 K! \: J
unite2Line line1, line2% Q$ M6 i) F( X0 H1 M2 m( }
End Sub
7 s) @. Q$ Y' _+ n8 L4 a& n4 ?" f7 {& a. K/ l& b: H2 I
4 `! w6 V/ K$ w$ P5 ^& y
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean
& L& e/ Y0 h$ u" x '连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false
1 ?* h3 H9 [% b6 EOn Error Resume Next
3 Q2 w2 t; p! q9 o! e' K& F unite2Line = False
0 E1 u _( [3 m- P& ?
" V' Z4 _" y @: V5 w If line1.Handle = line2.Handle Then3 h5 f/ z, ], x9 K+ \$ A9 g
ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"% ]) T& R R: l
Exit Function5 e+ C( K" O7 B
End If% c% V" C7 O9 C1 d7 x! J' F
& X. l# G- T$ c5 y) G9 z# F8 G
getLinePoint line1, pt1, pt2" x( U; J% `$ l4 X, j+ ^
getLinePoint line2, pt3, pt40 [) P* O- B% s) a0 h
\$ u: n R7 D. r6 i( C6 [ Dim A1, A2, A3 As Double
$ o, d* c' ~- K1 H2 V3 t Dim maxdi As Double6 \/ D* }" O: k9 K
A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
; Y' g3 _4 ^) V' c, o- x9 F8 U/ j5 B A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
* g6 A% e) v0 `" K3 r& m( l. j A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
. u) D2 m7 M- h1 Z '判断四点是否共线' A# X* P: T8 w& U7 \1 _
If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then. x! l7 a2 ~. S8 c
'取得距离最远的两个点。5 z E! `; m8 s) ^
maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _
. a5 B0 b" W$ F3 s8 W/ w' C( t. B GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4)). L5 H# f1 X% `2 e. e3 g ?
If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2
" j$ ]4 T3 T D! u* u If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3
w0 L; \3 z8 @ If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4
+ G4 d& `: \, i5 O! y If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3; r+ U; Y1 o) {+ I3 Z
If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4
$ `/ q/ f; A6 v# h, I" \ If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4! J; Z n ?0 P0 k. Q5 y) \
'画直线 c. e+ Y+ E( i! Y( I
Select Case line1.ObjectName
$ f3 d) d3 `! W, m Case "AcDbLine"
0 f1 x7 o$ A7 R6 m0 l line1.StartPoint = lpt1
5 g# x0 G5 P# r: Y line1.EndPoint = lpt2) {' M8 {9 k; [+ k8 J7 M7 \$ y4 j
line2.Delete" U/ Z" V! C( a0 X# p7 X8 r
unite2Line = True- _' f! V2 M' `
Case "AcDbPolyline"
. q3 o5 x/ d) n/ X. i Dim newPline As AcadLWPolyline* M: z9 O6 }! d9 J: I, N
Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)
9 D9 b: b8 f# E% X; T& m0 L newPline.Layer = line1.Layer0 X0 Q" Y8 e& G* ^' P
newPline.color = line1.color6 o, V" a6 H. n0 Z1 U6 v2 e/ b
newPline.Linetype = line1.Linetype
0 f+ j0 e* X( V& A% Z0 Y4 n1 R1 { line1.Delete3 p8 y& `$ ~6 B9 s1 j
line2.Delete
( I4 {2 ~4 w) ? Set line1 = newPline
1 d, O& \# {1 W& i unite2Line = True$ _ j. d5 J9 t% H
End Select
% j: X/ o6 Z1 r3 A; E9 D Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."
3 { u5 U3 r& u" F- B: a End If; Y# {6 ^9 n: H( t! f' H/ [3 M
End Function
& M5 S% H) S1 X5 m' ^6 ^5 g* s
% \* J2 B. h% ~8 ^/ ?4 {1 l. w" O, ?+ x
! a' \2 Q/ P7 p; d) L* y7 q& Z1 b+ w- p$ o
'以下是上述代码调用的函数?
( p2 w9 l- y* y& b6 G# K8 V/ E) y# o, z' A% m8 U
$ c0 S. e1 w( P2 i6 E'创建轻量多段线(只有两个顶点的直线多段线)8 N! b( B" o# x, S
Public Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline
# O: h3 Q$ T9 C! B9 q( x Dim objPline As AcadLWPolyline4 b8 Q% n# E& q" f+ [. b
Dim ptArr(0 To 3) As Double
2 W' R, S9 I0 b3 J/ A
' J$ u7 `+ t6 r- \* o4 D% x* j ptArr(0) = ptSt(0)$ I( O+ T( }2 v9 q
ptArr(1) = ptSt(1)
9 R' |) L9 b& O ptArr(2) = ptEn(0)7 r" X" n' c8 {1 L3 ?
ptArr(3) = ptEn(1)2 S+ ?; h; R, b" b. T3 Z% H
1 o" g' n2 S! Z( ~$ U Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)/ x! j- z: }5 y# B7 g' X0 c
objPline.ConstantWidth = width
3 d! L; ^( F j) [+ z" c% i4 C% k objPline.Update! l9 J" h$ V- p! Q% J
Set AddLWPlineSeg = objPline+ N* h) R# ~+ m4 u" n. y, M$ k$ c
End Function
& [# a8 v& K- ^: }2 k& F& ?: i' wPublic Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)& t; }: e" S7 D' x. O; f- W% F
'本函数得到线的端点,其中point1为Y坐标较小的点 e( Z" ]" Y& ]* W
Dim p1(2) As Double$ R# R% G8 }8 f4 r
Dim p2(2) As Double
( E8 k+ P/ C& L6 ]7 c, E Dim k As Integer0 `! q- l+ Z: ^7 G/ f
On Error Resume Next
- o% f7 F+ P7 M- S& U" E Select Case ent.ObjectName
! T0 j% x; Q) W: }4 }. U: s) I Case "AcDbLine"
; K k/ V3 c" Q }2 q; R. l Point1 = ent.StartPoint+ M2 G: r5 @( U7 C3 ?4 A) h: k
Point2 = ent.EndPoint
3 O- L' a! H8 n. r2 ]" v If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then, O$ Q; c2 N$ Q2 R" b/ O
Point1 = ent.EndPoint
& `% v, V$ q0 ~$ Y$ b Point2 = ent.StartPoint
; v: m1 q* q) s: z( {+ L End If
, p( C, L- C6 \8 n% [; X Case "AcDbPolyline"" ^& O s. Z" E* E2 v& t1 U
Dim entCo As Variant
4 |$ h& }, k$ t% z entCo = ent.Coordinates& A. w2 W4 d# F/ @7 K2 ?
k = UBound(entCo)2 d* {( S/ M+ E2 {! k% U
If k >= 3 Then
, m2 }* ?4 x6 h z# l p1(0) = entCo(0): p1(1) = entCo(1)
/ N/ e8 g3 o5 I8 Q# D k% R p2(0) = entCo(k - 1): p2(1) = entCo(k)
0 |& ?, O! `4 Y/ N' { If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then9 |& p* Z' O! h' q/ o
p2(0) = entCo(0): p2(1) = entCo(1)
. u' S' @$ Y0 o1 C9 t3 R p1(0) = entCo(k - 1): p1(1) = entCo(k)
3 ^" Q& r7 V; B- p" d" [1 I7 C End If; b- ?: y5 Y- x- q2 r4 l) q
Point1 = p1: Point2 = p2$ g2 C, M3 \; E' u/ a: P
End If8 g( D) K1 b2 o8 ?' b! r
End Select9 q; ?4 K) U4 o( c e; U) r
End Function
1 ?+ A' F4 P. o( c0 h# G, hPublic Function PI() As Double
& f6 L9 z; Z4 n+ n2 ?0 W PI = Atn(1) * 43 Z% m- b, M. e. R/ G: k
End Function# d+ ^& D# @# L- k, Y
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
. S4 L# x& K* p- d& G '选择实体,直到用户取消操作
$ M) w2 V) N, B0 ~7 Y8 q On Error Resume Next: \: e/ i4 z: H0 i/ G
StartLoop:0 L% R( `, E. ^5 M2 D4 E
ThisDrawing.Utility.GetEntity ent, pt, Prompt
0 j8 y% h- ]. A* |- Y If Err Then
+ @- }) E6 T) r5 d+ o9 E- d/ C If ThisDrawing.GetVariable("errno") = 7 Then: N4 q* d8 k" k
Err.Clear
& c1 C- n% S8 }" K. B GoTo StartLoop
9 y& g1 r8 M/ c Else1 ~+ y5 e. B, R) x
Err.Raise vbObjectError + 5, , "用户取消操作"9 s7 E* u+ s, m& m
End If. r5 B) B7 Y1 N- O( Y
End If
6 E* t' ]) V |) H# }& O) o L2 Y) YEnd Sub
5 B6 J7 Z1 O+ r. }+ F. J8 ~Public Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())
% O) A' w4 D* H* \: z'选择某一类型的实体,如果选择错误则继续,按ESC退出2 N; u9 c/ T% [1 E
'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等, G$ J0 z5 L# d }: x: |
Dim i As Integer
" P5 {9 J" c8 ^/ X. e7 T7 y+ y1 uDim pd As Boolean
, p0 F* }) _! |, |; ]6 r# L( h" Qpd = False
6 Y- o, F& T7 O ]Do @/ K3 G! M5 F. f% Z* u
GetEntityEx ent, pickedPoint, Prompt
& n" @* ?' j6 u$ Q& E 4 M3 k% d, ]* g
If ent Is Nothing Then
8 T' a& x. {( E; B# l+ w/ g0 w% ^ Exit Do
3 U7 y6 W* ^& r! M# Y6 v+ M' H- t ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
( h5 n+ E8 |# w! J; ? Exit Do! p1 `8 F; U" M
Else* [$ @# A- u1 E& C( G% w
For i = LBound(gType) To UBound(gType)* I2 | U4 f3 [
If UCase(ent.ObjectName) Like UCase(gType(i)) Then+ w' v! \( @3 U
Exit Do
! A; l% }$ o$ k, y. ` Else
9 L* y% j& s- N2 Z: U0 F3 i pd = True
. P" w9 e/ \6 d. n# W& X1 r End If
) B0 g' T: _( X! C V Next i" }! {. w* x7 ^. V: E
If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
' V0 o6 p! s* M8 a4 S6 ^" l, x End If
9 s" C$ r! f% JLoop
3 ~6 F( ?; B+ j. Y3 f+ m
; i% m4 k/ h7 {; c; ? k7 t) L3 VEnd Sub" g. o3 W8 L' ]
'计算两点之间距离" k' @: Q5 Q! M s3 S! m
Public Function GetDistance(sp As Variant, ep As Variant) As Double
& \4 j8 x& z% Y+ k Dim X As Double+ c% R/ s8 K3 f9 ~9 h4 H+ h
Dim y As Double
- x P* M: U% c; _! z/ x Dim z As Double
( O6 }/ S1 [# \$ h8 x
8 N# a: T- U4 t0 ` X = sp(0) - ep(0)3 ?% K/ e# i# I. [8 _& g+ w$ E
y = sp(1) - ep(1)
: S- C3 q' J% [ z = sp(2) - ep(2)6 l' r" l7 Y1 U" R
! q% r2 z& Z k4 O8 r4 D. g8 p0 v
GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))
7 B4 V% M- o% }7 Q8 T$ `" KEnd Function
5 i- J: G: W) v( j'返回两个Double类型变量的最大值
. S4 X8 L9 u3 ^; N, ?/ P2 xPublic Function MaxDouble(ByVal a As Double, ParamArray b()) As Double
4 L9 l5 u! e4 h9 H! u MaxDouble = a5 y) V6 I( x' a1 w+ K" E9 E3 `
Dim i As Integer- L& `6 B3 d" y% z$ ~4 x4 D! k
For i = LBound(b) To UBound(b)
( Z# O: p4 F7 Z' j7 @* E If b(i) > MaxDouble Then MaxDouble = b(i)
: }8 L4 Q* P' D) D/ f3 s Next i6 T- k; \) d" A5 s7 R; S6 P
End Function
' ~) L, B% a* f& f. t8 [Public Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet6 L" ^7 s# b5 O8 w3 V
'返回一个空白选择集3 f/ g! ~- @6 o) d$ w- O# b
" j3 G) J5 f) f
Dim ss As AcadSelectionSet
# \; r3 ~' x/ e1 _& m% f1 J: M
8 N1 M* m8 ~. o& h On Error Resume Next" P/ T+ h9 g1 m! v {( @: K, Q3 k
Set ss = ThisDrawing.SelectionSets(ssName)7 h) `& ?3 P0 a- z5 A
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)$ H) h' O5 m. |6 }* ^
ss.Clear7 z( b. F2 S" i8 A2 V
Set CreateSelectionSet = ss! y7 w2 Z8 D( P) S
End Function& \" l1 O: u; z3 W V9 |- S5 S
Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())
; h" L8 z L6 N$ z0 G# a; j' G0 J '用数组方式填充一对变量以用作为选择集过滤器使用
( _+ Y' Y. d2 i Dim fType() As Integer, fData()
P6 J. G0 M; C2 i9 S" E Dim index As Long, i As Long
+ K0 I( U& K6 u4 p# ~# f* Q0 ?
* Y4 p. k1 ]* y$ h1 M i8 [4 _ index = LBound(gCodes) - 1# N" y4 [- y: [, b
" n- }6 x5 V7 s4 p ^1 h
For i = LBound(gCodes) To UBound(gCodes) Step 2, N* f+ X8 `+ o' w: w
index = index + 1
4 q4 e5 Y2 Z9 [ ReDim Preserve fType(0 To index)% e& u4 H/ I+ n" X/ B. M1 H
ReDim Preserve fData(0 To index)
0 J0 K! I+ k1 h6 K, z! D fType(index) = CInt(gCodes(i))
: z0 A+ Y' \2 n5 y fData(index) = gCodes(i + 1)% B) d/ i7 K# d. k5 r4 L
Next$ B3 Q9 {* |( s% k3 B) o
typeArray = fType: dataArray = fData
* n3 C% n; x. `8 XEnd Sub
% M! S/ N& ]) t& V( O- r- {$ e" N' `
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|