|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
, F8 u" O# g+ s/ O% J0 h/ q
/ U! _ U; z# TSub LianX()
8 N' U: \$ z( n& w0 o8 wOn Error GoTo xx1 J% S2 @" o, D% s1 {. k5 u1 G: x
Dim ssetObj As AcadSelectionSet
. o4 }( C7 t! Q, w a Set ssetObj = CreateSelectionSet("uniteSS" ' E3 B+ A4 q& V3 j8 G+ B+ a
Dim fType, fData
0 C5 z9 V6 `2 m( D+ s BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
- O7 H7 s+ m8 q3 }" j- D0 ] '屏选直线或多段线$ I: S7 Q/ }7 A
ssetObj.SelectOnScreen fType, fData
2 Y ~' g |" l) D Dim i As Integer
1 ]' Q% v- p$ n# u( @5 T# r5 O# R; `/ } If ssetObj.Count <= 1 Then
+ z3 R' ~. K: r( b: V( H- A, Z( | ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"
( F) P8 S9 D5 \7 Z0 d Exit Sub
! |( H- [/ z( |# ~% } B End If+ j" r4 }+ j' M# x7 G- U" `5 A# g+ g {
% P. L2 _. ?! [2 n& h; L
Dim line1 As Object
2 @& q2 O4 c& p' X- w" a Dim line2 As Object( F: d* b6 o/ O2 b3 \7 z$ O7 K. c
. Z. ~2 [0 m: V
Set line1 = ssetObj(0) r: t& R/ |7 B* D! Q/ f5 e: I2 j
Dim pd As Boolean! o8 Y5 n5 N& |) M- Z* z, G- [
For i = 1 To ssetObj.Count
2 s. j! {7 ^3 @4 \* T0 {) i Set line2 = ssetObj(i)/ ^$ P9 V t U' k% Y ] E
'连接线
! u' N5 d% m8 A pd = unite2Line(line1, line2)
" s& `0 y4 ?; x( k. {: B' O+ V2 A( O. E '如果连接不成功,则退出命令。
1 ?9 }( l' x! N6 B( F If Not pd Then ssetObj.Delete: Exit Sub& _$ J! W0 y" o1 Q
Next
?; r/ S; z% wxx:, S' S- J6 S* \5 W
Select Case line1.ObjectName
6 `- x' ?- A6 T1 S- E! A7 k. p Case "AcDbLine"& D* k9 n! @- b3 B
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."
, \; i4 b3 c" T% D' s. M3 w0 x Case "AcDbPolyline". p0 c0 `8 F* j8 ]# ?- j
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."
- A, C, l8 E/ N. t4 Q7 E End Select
# n# X/ M, Q; M7 i ssetObj.Delete
- m( g. r% A, c7 ?; g1 G) `( S# s2 zEnd Sub# s0 o5 i: \4 c; Q# v% I/ T
- i6 v3 Y+ ?# sSub uniteline()2 o, u" J% v! k8 f
On Error Resume Next4 L# C' z, `# D4 g, T$ r
'取得线
. Q% t/ C6 v6 ^9 X3 k Dim line1 As Object& W Q3 a6 z* [* @- ^: q
Dim line2 As Object% l- K' P) A& W4 V5 B) p. K) R
Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity
' p! v$ V8 w, J" L# j Dim lpt1, lpt2 As Variant
. `& _! q2 W5 S+ Q: ]% F
: j) x' R# S# ] gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline": s+ B E) J: |2 f+ y
If line1 Is Nothing Then1 D# }# z) C0 w% ^9 \$ c+ s% L
ThisDrawing.Utility.Prompt "用户取消,退出命令。"+ ?9 l% r( {1 h1 V+ ~
Exit Sub m- c/ D# J. @4 i* x* g
End If i) A" V0 g: R& |9 H
/ c g4 X& D1 N0 h( \
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"
$ ~, K/ b, l- w5 J& [' x1 t" v If line2 Is Nothing Then
, E! e* ~ Z) i" W ThisDrawing.Utility.Prompt "用户取消,退出命令。"
7 }0 e* z* S# t6 e9 f3 J" R Exit Sub! B. c2 _ R! U3 Y5 x! R+ e
End If4 ]; r S4 s( P, U l
'连接线
2 ^ S W9 z0 Y$ j" | unite2Line line1, line2
% s1 {3 c! {4 X' Z S7 N$ t. i# fEnd Sub
& k, y& \: Z# ~; v8 j- A3 A/ d5 H
# c& G9 x9 _2 j! C: |; ?0 D5 C, U" |% h/ \
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean2 Z- W0 p) A! @- ?, }
'连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false
) F1 a% h, b3 G) c' y s& T' E0 YOn Error Resume Next
. H) E5 J; i$ ]8 _; c+ N! W unite2Line = False
& @( r3 I, |' A: ~ R5 L0 w
9 F( ^% k" T: n M If line1.Handle = line2.Handle Then; G9 a, Z. Q0 C
ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"
) |- u* i% U1 l7 [: h. n0 Y( \ Exit Function
* f+ O! ?+ u2 h* M End If- `3 O+ s% q, B$ B% H6 R6 |
+ Y: V* j% L1 t. |: v1 |( J getLinePoint line1, pt1, pt2
+ ~% T! L8 E1 T9 P0 Q getLinePoint line2, pt3, pt49 g/ M7 k# l6 B H
: n- s, e% S5 e1 z Dim A1, A2, A3 As Double/ q0 W' c4 y" Y% S+ M8 I5 f
Dim maxdi As Double/ _" ~2 `0 z7 }# ^( w; I1 G* j6 G
A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
, ]6 W5 ?3 }- c: q% e. v# m A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
z9 n. r y' j& v0 ], O A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)/ M' R8 B/ p4 w( w# |, @7 z+ [
'判断四点是否共线* J e0 _/ D) V1 P+ y1 v& F( _
If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then
, \8 X# i3 b" f% X" A+ Y( T8 e6 s( y9 o '取得距离最远的两个点。
% Z7 C6 k& O, q8 e! z maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _0 L8 x! B q% z6 V. i& a. T% {
GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))0 k5 o9 V# J/ W" Q! ^
If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2# [. Z6 q7 x- ^$ q2 J, H: `8 R
If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3# m$ o( W( G0 }' L8 r+ z) a
If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4
/ E/ l3 T& K8 ^" h. H If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3- ?! \1 Z2 S. B3 X) N# _
If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4
: {" S6 |4 U9 [4 G4 y If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4
3 D: c! i7 Q) K( z4 P '画直线* ?* ]0 Z8 @0 q% F+ y
Select Case line1.ObjectName; ^% \0 u+ R6 |- G
Case "AcDbLine"
: F5 a7 J' B5 v( j line1.StartPoint = lpt1
( h5 \0 a7 W& A' t5 v line1.EndPoint = lpt2
+ w' n* F( g% ?1 @% g/ k+ c line2.Delete
; z. Q' j! b' [$ e ]1 @! ]" i: } unite2Line = True9 Z, `' m O- w5 V( W! Y
Case "AcDbPolyline"9 h$ c. D" |- i/ w) ^# H0 a
Dim newPline As AcadLWPolyline
( T7 }: z+ F% u2 J2 J5 Z! F Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)3 Q' B# J; e% t0 M5 D9 A* R2 p& H
newPline.Layer = line1.Layer
- e7 ~' y2 I. y; E% \" @ newPline.color = line1.color
' f" d& ^5 x# d newPline.Linetype = line1.Linetype
) n' B2 ?4 T8 n" L line1.Delete: t$ o* o3 D8 i* J4 o
line2.Delete
: H1 r* R6 l8 F2 E+ a* ^ Set line1 = newPline
. F H( O0 y& U% R0 T/ ~ unite2Line = True
5 Y! k' e% u2 R# h. l% ]& N End Select
- g* a. D' i+ Z0 W \ Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令.". ?: [; f K1 \2 K! Q
End If- j. {5 D7 ]1 `- F% l9 B: P* v
End Function: W, B/ P. H6 Z# k7 E
0 P. d% Q9 j9 t) Z/ ]% v9 i p6 m& N* K$ |& W. {
3 \: G; x4 k* _7 c/ O'以下是上述代码调用的函数?9 [# u* T) a' i$ ?3 ?1 r& X7 V0 u
9 y. m( C3 t+ i. |. k3 k' y( m! n: g) ]& x1 F8 |; D/ P1 Z
'创建轻量多段线(只有两个顶点的直线多段线)
: W( X( E4 a' j7 k! @' OPublic Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline' _1 f! t7 }5 M
Dim objPline As AcadLWPolyline
, O) h8 k2 J [7 f6 a$ k Dim ptArr(0 To 3) As Double
0 t; F' }5 A8 t " W; ?: i \& O- l: x
ptArr(0) = ptSt(0)+ U! i1 t) g* s. m0 ]
ptArr(1) = ptSt(1)
6 A) e) Z+ V" a* E1 ` ptArr(2) = ptEn(0)
7 T! e7 w- I+ ?) r! O7 {3 o0 |5 s ptArr(3) = ptEn(1)
# l6 _$ B* w O& B! F ( T$ K4 T0 G% m L
Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)
* R/ S2 R/ d" h: U) F! x6 Q) Y7 E objPline.ConstantWidth = width
8 R' y+ {0 Q2 ?0 _' s5 Y objPline.Update
# D- x3 i, }. x3 i; o, c$ b1 Z0 M Set AddLWPlineSeg = objPline2 e1 \6 O8 N M/ u
End Function. S! [; l X# P" C* [9 M" `
Public Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)$ E4 V6 g8 o @2 o
'本函数得到线的端点,其中point1为Y坐标较小的点
! @7 j' p7 }, @+ d/ V Dim p1(2) As Double, B6 \4 R8 j8 ^
Dim p2(2) As Double
6 ?; y* j2 j* v# B' y8 m* y Dim k As Integer
2 r0 I/ g/ i- V3 j& H5 t On Error Resume Next
( e* @: {0 s! r1 B( W% Z, ^) b4 D+ b Select Case ent.ObjectName
& O* P) J( C. H. A- | Case "AcDbLine"
) Y# s; j8 P' @4 R4 E- Y4 j% u/ f Point1 = ent.StartPoint
8 x( Z8 o, l) x, k0 M1 ^# \ Point2 = ent.EndPoint
3 \& q+ h" x; [4 Q( [8 f) T) T' O+ f( s If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then; N; C+ S' F; |6 Y# Z% Y
Point1 = ent.EndPoint
5 {# ?. V" a* l$ P% j4 | Point2 = ent.StartPoint1 B" [( G: P. i% V( j0 p
End If9 c+ Z' T- w& q4 d& _2 ~, O* C
Case "AcDbPolyline"
8 t5 p& P9 g& f; f, @# q0 B6 C6 Q Dim entCo As Variant
7 O/ o7 O! }7 [+ W entCo = ent.Coordinates
/ p7 K, ~. r Q( p0 S7 y% y4 p k = UBound(entCo)
2 L* p E9 F8 ^0 v If k >= 3 Then
+ ?- Y5 U8 f9 l7 _2 S1 E- V8 m' W p1(0) = entCo(0): p1(1) = entCo(1)
* a0 N. j T( t) f7 Y% V' H8 E p2(0) = entCo(k - 1): p2(1) = entCo(k)
$ _; ]1 ~1 C* _2 v8 g; [ If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then8 Y# M$ x0 E# X
p2(0) = entCo(0): p2(1) = entCo(1)! ]. R& q) }3 ~& C. [
p1(0) = entCo(k - 1): p1(1) = entCo(k)0 S; H+ G5 @3 n- p8 `) m
End If/ e$ r; H5 e9 q# h! ^
Point1 = p1: Point2 = p2
8 s7 T, }% Z# S% l End If) ^9 a. s: M Y- I
End Select
, i/ B" H" j2 A; |End Function
+ d9 T& a! J" ^# c8 Q/ jPublic Function PI() As Double
9 Y T5 }0 b/ f3 l PI = Atn(1) * 40 l T+ t6 b c" _* V4 w7 V1 `
End Function1 N! _$ r" L2 D9 D" S4 Q. B
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
2 f& ]; Y* X& H4 t '选择实体,直到用户取消操作
" Z; n! k k- C On Error Resume Next+ m7 a* N9 @. B6 e3 T( E
StartLoop:& i1 I1 }" A( @: F' U
ThisDrawing.Utility.GetEntity ent, pt, Prompt& j6 D$ G6 j. j( d* Y
If Err Then
. E3 r" V8 u& e+ \) T* [* h If ThisDrawing.GetVariable("errno") = 7 Then
! w" s% ?; ~- g+ O# i' |4 U Err.Clear
: {: D! h4 O4 |! X GoTo StartLoop
' p _4 b- G! g; G Else
3 D. A1 N5 {* z% S- q/ U Err.Raise vbObjectError + 5, , "用户取消操作"
& b# G0 l8 k" J h$ a' {, ~7 A6 p End If
: B3 o' j, T# a' [5 u( J End If
/ I u. p3 K \5 H+ |$ Y2 o4 bEnd Sub' O8 U3 m+ T6 i8 k
Public Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType()). g1 p* b* U+ Z3 [; o! z `' T, X% j
'选择某一类型的实体,如果选择错误则继续,按ESC退出
& \2 r3 e- `" P$ Z* U/ w5 o7 t. l'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等
6 G' b8 u7 |* ODim i As Integer. c/ J* D1 r* G4 B. o4 k3 K
Dim pd As Boolean7 X& f1 ^* [5 @+ m1 j7 {" X1 r
pd = False
2 |1 l. `7 e% Y0 T% F; }0 qDo
6 Y1 E( G# ?! Z. U' J, g: k GetEntityEx ent, pickedPoint, Prompt
: D( Y' ?- ?5 Q/ w3 ^% Q" g F/ F' B" k* L% c* C
If ent Is Nothing Then# D/ F- K2 G6 c6 S* g& q
Exit Do5 O. t# u, Y; W" K
ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
* j v, e: E: K, [; i3 F) J) E Exit Do# h! [. f8 ^' ~7 j+ {
Else
3 h8 k+ G* `4 m I% W( _( [ For i = LBound(gType) To UBound(gType)% |5 l8 z( f R5 W8 V6 R m
If UCase(ent.ObjectName) Like UCase(gType(i)) Then
; I) p: K* U: u }- X: s Exit Do
4 c: F( p7 j" D1 C/ c Else
( e9 |6 H2 J! B+ z. { pd = True' ?& u. H- E( p3 [: Y f
End If" I0 t/ c% a3 E Q4 {
Next i
* o4 Z# {& L2 i+ A7 N8 Q1 O' H If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."8 z" m2 k$ f: [: B, q, G0 c
End If; I# q7 O4 w7 {! h6 I, q
Loop. r, n$ J, ?) S9 x) @
$ t; H1 s" X1 O( U
End Sub
; G% ]! B! ]+ P- S! d4 l'计算两点之间距离( ]0 x7 L' ~4 c ?- ]3 L
Public Function GetDistance(sp As Variant, ep As Variant) As Double
- \% e: _) [& M" U5 ?1 ~6 ` Dim X As Double+ p" n) T! V G% s' ]
Dim y As Double/ h( s0 w! }8 k6 J0 j% ?
Dim z As Double
: v0 n) |$ f5 @ 6 N) u5 B% m, }. n1 w
X = sp(0) - ep(0)
9 I% f0 \: L3 e! P' ^2 ^ y = sp(1) - ep(1)
3 O# K/ m( @. e( w' Q z = sp(2) - ep(2)
8 u U0 f+ ?$ N
# Y m/ ]* s+ g# { GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))6 E/ t H6 T8 t1 r: h$ t L$ \
End Function
8 j; b7 E& p9 m* B o) w0 J'返回两个Double类型变量的最大值# |0 R& u g" ~* H
Public Function MaxDouble(ByVal a As Double, ParamArray b()) As Double& w/ N! w% |" R" P: `1 E1 g
MaxDouble = a
; H% j( }* y# Z& ~$ {- O Dim i As Integer/ z3 l1 @2 s) s& m( z! W* E* J; B4 X
For i = LBound(b) To UBound(b)
: Y; \+ n0 b* c8 N/ _ If b(i) > MaxDouble Then MaxDouble = b(i)
1 N# b$ l" j0 l- l6 z8 l Next i
' h* g0 j+ ^: k1 N, o% B9 \" mEnd Function
% K9 U% ~( P; Y6 z9 j+ O; oPublic Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet
. e. l. t$ Z: p; a+ E '返回一个空白选择集+ h7 q" v5 B' U" m
1 j6 A" E/ Q7 |. I Dim ss As AcadSelectionSet
' s/ E, }, ]7 g" b" |; T) o
$ b. d- ^; w. g" n6 b# ? On Error Resume Next- w7 v4 t" g3 U4 T" c7 c$ @& N
Set ss = ThisDrawing.SelectionSets(ssName)3 x; Y8 B* R/ F. `9 X
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)
3 n/ j% c% m: W; { l: M& J- X ss.Clear
; `$ N0 X- e1 M# Z5 I7 f! }, r' @ Set CreateSelectionSet = ss
1 }* S4 B+ ?8 K- c: _7 CEnd Function7 y3 y) I( m5 s4 O; D+ T
Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())
, n; A& o$ Z- w' Q. A '用数组方式填充一对变量以用作为选择集过滤器使用
/ B. p7 A: {/ }. M Dim fType() As Integer, fData()* C' f7 g4 C F ?4 c! B4 k" ?
Dim index As Long, i As Long
, h$ }7 C' L# w1 W$ Q% e
% g' t7 M/ J( B, e- L$ W, t index = LBound(gCodes) - 1
0 Y9 {2 R& E4 u' r1 l8 u/ c
7 Y) }1 h/ u' t7 \. ?7 W3 J. w For i = LBound(gCodes) To UBound(gCodes) Step 2+ I+ h! m! Q& b4 X' m7 w) Q G
index = index + 1
9 _" q9 n% l# Q* k$ Y6 v ReDim Preserve fType(0 To index)
0 U9 {1 f7 k5 n9 V `3 s ReDim Preserve fData(0 To index)7 `" m% M- I( D) t
fType(index) = CInt(gCodes(i))
" k! W" O9 T, h6 l9 Y( k fData(index) = gCodes(i + 1)9 c/ n& {* n* @- I8 m) J1 j2 e) W
Next7 g' z# n9 d) @; g
typeArray = fType: dataArray = fData
7 \3 b9 w; T% \( W% U, dEnd Sub, M. z" k8 J7 S
9 E0 @( ~6 I" D+ Q+ g5 O$ D( R[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|