|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
, b# ^2 T: P/ R: m7 |( F1 h3 M) ^: L
: V1 q# G m5 `Sub LianX()
, C' T4 w, A F3 k, G7 |3 {On Error GoTo xx
9 l$ B1 i# t; P1 Y' a& ~, Z+ @ Dim ssetObj As AcadSelectionSet" m( v4 C/ l% c9 `/ W& K
Set ssetObj = CreateSelectionSet("uniteSS" # u9 k/ X( _6 m
Dim fType, fData
( }9 ]* c+ A# x- j$ \" G4 g BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
" ? @" O; h% m8 n% x '屏选直线或多段线7 Z) @) O# p0 k0 E
ssetObj.SelectOnScreen fType, fData/ x" A0 i2 e" [3 o) d3 s( d
Dim i As Integer
! j$ J) K; O7 t7 Y7 p: Q2 b If ssetObj.Count <= 1 Then
, p0 Z' |9 ^% k& X( ~. Q; b ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。" g/ I' m$ B. d! x. R5 k, v1 O1 N p) d
Exit Sub1 V @, o P; E. d6 J
End If* [% I; C% D2 H( H7 L
) b) j1 ]; \1 K4 \9 T, L Dim line1 As Object
9 r. r) F1 j: C Dim line2 As Object
4 H, p% ]$ F! @$ m
* y. b% o; H/ _# v( {4 t* k. G Set line1 = ssetObj(0)
2 C9 S8 {1 S% v3 q$ { Dim pd As Boolean m$ O$ p! B) X1 r; R
For i = 1 To ssetObj.Count. a7 X$ D* _1 e
Set line2 = ssetObj(i)
6 B1 t% R4 v+ o3 [ '连接线9 H1 b4 l, Y+ s( g" ~& I
pd = unite2Line(line1, line2)
+ ?- a% q8 ]! {- q '如果连接不成功,则退出命令。0 X3 A+ e. c' w4 e7 j2 ^5 i% A' H( Y
If Not pd Then ssetObj.Delete: Exit Sub
: B% k# M& y$ x: J% _( r Next
6 `* s/ C( {; q: \# pxx:
) S2 f) U: e+ @7 J$ I Select Case line1.ObjectName q9 P3 Y W# |1 ~' p
Case "AcDbLine"
; P* B' C0 L& f# Y8 q5 q. a ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."
& r8 e0 @$ E2 M2 y+ y' B Case "AcDbPolyline"
6 C1 z* Y$ ^! w* [8 @ ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线.", G; z% _# L ^) C7 _
End Select
8 U7 W8 |7 u/ K, Y' | ssetObj.Delete
. J% q" w7 x& y5 j4 c" W% z8 c- y$ b, NEnd Sub
- _6 ~+ k; M9 Z' f" u6 h8 v/ i
) B4 K4 k% q! w& W* _# iSub uniteline(), G# V8 S$ ~" |
On Error Resume Next
9 m; R) g. [1 y* \$ a '取得线2 Q$ s/ W' w2 x5 Y, t
Dim line1 As Object
/ T1 q5 r5 d; @: @( v Dim line2 As Object0 N: ~* `" n8 n' _. l s
Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity$ Y/ I1 Q0 G1 K
Dim lpt1, lpt2 As Variant
9 s! J$ C8 }# l- _2 R( v( C
/ ~7 Z! E+ M% }& u gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"
D @% p" M* h7 C" b% k* e, A3 G If line1 Is Nothing Then
0 ~7 {2 E7 d! C, @" y ThisDrawing.Utility.Prompt "用户取消,退出命令。"
6 I( g6 c; M& l+ b8 U. \ |/ P Exit Sub+ V% g9 `, k% R1 g+ T
End If* Q* L5 k# k+ r/ @ Y
/ J* p; {! A9 R s5 [; x4 k1 B7 X
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"4 C4 z2 S( e0 t+ o
If line2 Is Nothing Then! k4 [8 m. _" t; [
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
; v7 w; V" G' F% I' q Exit Sub
, }% ^8 }5 k- Y' n5 W* [ End If
" o' c3 C& x3 I' V6 E( K- F '连接线9 N" z; L& y! z0 G8 d; z7 t* k- r
unite2Line line1, line2
; Z+ v5 {$ h8 b. ~+ A MEnd Sub+ v4 ?8 p1 S5 e/ R
( N+ J! A# x+ }% \
* V8 z4 @6 f" L# H- ^9 D
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean2 } |% j& ?1 S: F& D; {
'连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false& P' j* m/ W2 r; M
On Error Resume Next/ r/ c. P' H" [0 h' l8 t+ N& o- F8 Y
unite2Line = False( m, M1 h% j8 z4 ]5 c
6 p3 J; s; G, t9 L If line1.Handle = line2.Handle Then* {6 ~7 o: _; i
ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。") J* L6 V1 ?5 p1 S! r, M5 I% ?7 @
Exit Function
; r3 d) y* U8 A/ [. L3 S0 Q: } End If' B. P! T1 ^, e
5 D9 U' T8 a3 A1 s! Q7 `, U$ y getLinePoint line1, pt1, pt2
6 }; w+ R' j. t# X getLinePoint line2, pt3, pt45 W1 r/ i. r/ j1 ?) O
& q8 ]7 i3 `4 _ Dim A1, A2, A3 As Double7 u5 e8 C0 f; f) K. M% D+ t7 H3 H
Dim maxdi As Double
7 _6 I7 I0 `. d, I A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)5 F; B# _/ f F9 v9 W8 a
A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
$ |. u0 L |* o/ @ A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
; G4 a# ?; z0 |; W" Z% U ]- s# J '判断四点是否共线
* m, c' ~. ~# V6 T! a- _) b$ H If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then: h6 D) \% @, e3 K. M- J
'取得距离最远的两个点。 ?. K. j% |- B/ D) f8 Q* O
maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _
' g7 C2 l( x# d P8 y GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))5 N& {1 m, G5 j3 d3 _
If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2, Q. A6 L+ E) H6 C: j: ?
If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3
9 y, U% a" f2 H; \3 a If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4
& _' p: C$ j" i If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt36 k+ S V0 s' z# ]! A3 u& k
If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt46 K5 |" z( a* ]3 Q
If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt41 W# p0 }1 t6 G
'画直线
9 O* g! b8 ^, K3 L) \ Select Case line1.ObjectName
! ]: _, x7 y( A Case "AcDbLine"
8 A4 }5 G9 ~8 c( |: p5 O line1.StartPoint = lpt1. u. T3 U( L' V# A; l$ E0 e; |3 {
line1.EndPoint = lpt2
& {, ~9 x- e' d$ o, \ line2.Delete N+ b9 [/ S( K
unite2Line = True
# g- T- A# r: G% |! G8 @3 E Case "AcDbPolyline"
3 b; I0 d# v8 b* M2 A+ \ Dim newPline As AcadLWPolyline+ {) S: \! E! p8 i: \+ `
Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)
9 @0 i% S- E6 C' y: l2 _ newPline.Layer = line1.Layer: u. ]/ W6 y# k: B# R6 g
newPline.color = line1.color; I9 Y9 k9 `! V, @
newPline.Linetype = line1.Linetype2 x$ ?, K3 z& y( P3 ?/ m
line1.Delete. i8 t/ ]- `$ M* H) [! ^, ?
line2.Delete' _5 ]' j% e8 }7 s
Set line1 = newPline
) S8 U& ^% R7 t" F. N5 F unite2Line = True$ O, f% Z: h7 r
End Select# b% F8 c6 Q: \5 p) J6 Q- w( u2 W
Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."
) o7 O4 ?4 }4 z( O8 j, _ End If
, T; v. I4 b" t! iEnd Function; p+ B3 F7 K. b5 e
, H7 u$ M; l- z9 }0 h% d2 p! x3 c
( M+ Y6 H B0 X" Z, l
'以下是上述代码调用的函数?+ k0 p/ P8 d* T' x0 ~
: s! ]$ a2 n7 n9 {! ^' L
) d: `% G+ T0 F+ [3 K8 F" s9 F'创建轻量多段线(只有两个顶点的直线多段线): b# w$ N2 I a* `0 s2 g
Public Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline m2 n d9 i* ~& m
Dim objPline As AcadLWPolyline9 u6 x) z" ?0 s) U- }1 q
Dim ptArr(0 To 3) As Double
M" ^1 M) J% t( C! b
3 d$ T& Q; \) C5 G; T `. N" [ ptArr(0) = ptSt(0)6 U# K/ [8 R, ?+ J) V# z) I
ptArr(1) = ptSt(1)
1 u: \0 r- V! j ptArr(2) = ptEn(0) w- e( ^! b/ y6 i3 I2 C
ptArr(3) = ptEn(1)
5 i* O" {3 P& X, \. {" N/ I 5 o& Y( B! f0 H7 \+ l
Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)
( z$ [6 x5 l$ ^7 H objPline.ConstantWidth = width
2 v/ s& a* G; S objPline.Update
( T( u+ V8 s3 ^% y2 X2 Z% e) J Set AddLWPlineSeg = objPline
4 D- |. T+ K+ t* Q) [1 K+ t- M9 W2 p. |End Function
- o1 _2 H: V" [0 Z; R" |5 TPublic Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)! m' g e x1 J+ ^( D
'本函数得到线的端点,其中point1为Y坐标较小的点( x- r4 p) Y- u( I" n5 f- e
Dim p1(2) As Double
* C3 D( K% C3 u3 D( P0 j/ x Dim p2(2) As Double u5 Z# e g8 z* q! o
Dim k As Integer
! K7 G" n, r% l" o! Z5 N On Error Resume Next
8 m. U) Y' u# f4 }2 F Select Case ent.ObjectName
! b6 I* Q8 K6 o9 d# y Case "AcDbLine"% T8 w9 I0 k/ e5 u
Point1 = ent.StartPoint+ ?) z, R5 r. a3 r" D
Point2 = ent.EndPoint
7 Z9 N+ V- C+ ? If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then; L/ F/ v _: O' S. t* B7 X3 f
Point1 = ent.EndPoint
3 F% a) D, p$ ^ Point2 = ent.StartPoint* z! B, Y4 e4 L l$ I
End If
" M. s D$ H* p( A+ G; |+ w5 B Case "AcDbPolyline"
- W2 N; k. i6 I Dim entCo As Variant1 S# F* I9 p1 ]' {4 X, Y0 q
entCo = ent.Coordinates
4 x- e! T+ C! u ~ k = UBound(entCo)# }" k( P! t! D; Y- x) A7 q
If k >= 3 Then
7 N; r% n {" K3 N* L p1(0) = entCo(0): p1(1) = entCo(1)) ~: O; Z$ F& B8 q1 R
p2(0) = entCo(k - 1): p2(1) = entCo(k)
2 q- w3 U4 T0 w* G+ I$ w If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then
# n+ z% U* E% m' ]% | p2(0) = entCo(0): p2(1) = entCo(1)
L; i" J$ X3 r$ Q- d" w, _. h p1(0) = entCo(k - 1): p1(1) = entCo(k)' z e) u. L: W. V& J
End If/ K5 S, k, o' w& f$ i- M$ P
Point1 = p1: Point2 = p2; n# e$ b8 D9 Y# g4 T# A' _
End If# ^4 M' m' o' c- m' }1 `& v
End Select
( G& g" o( Z, g5 q5 kEnd Function
1 Z& B* K% t9 t$ Y5 GPublic Function PI() As Double
9 t" ^0 b# c: ^: m& b& ~- {: q/ R PI = Atn(1) * 48 ]( ^6 e6 M2 I
End Function
" }4 }& [6 N- z n v( ?" uPublic Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
( |. r' T, p$ z: h '选择实体,直到用户取消操作" ]6 X( ~* b V# P
On Error Resume Next
8 C; u4 e7 G3 ~& ]2 P% C% {' CStartLoop:) O- {& b6 b6 J' I
ThisDrawing.Utility.GetEntity ent, pt, Prompt6 c, z2 N0 o$ F+ X! v% R% m
If Err Then
( x/ A$ j9 L9 S3 ^7 e1 O If ThisDrawing.GetVariable("errno") = 7 Then5 R4 G0 X7 A, R$ r* l; f; M) t' ~
Err.Clear
7 A8 E! ]; K; q) @ GoTo StartLoop
/ ^$ P! v5 F& W3 ~ `% u9 V Else
0 l, M- r% _3 k% w5 H$ d" v6 @7 a Err.Raise vbObjectError + 5, , "用户取消操作". D1 ~2 \; T7 W- O
End If
$ w( a" W6 C( ~/ ]5 t; x4 @ End If4 [& v7 _5 a* h/ N* S% s, v/ Y
End Sub8 Z; C+ H) c5 V3 \
Public Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())8 K* D- A7 O, }5 _1 c& Z0 G7 }% G# e
'选择某一类型的实体,如果选择错误则继续,按ESC退出
& K0 j3 ?) Q' W0 [, Y& g3 I'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等
- r l0 j5 W' n! l; }- XDim i As Integer
7 ?: p* C. n! p2 LDim pd As Boolean
3 \" m. [4 B7 j+ f+ w) x2 l# K, Lpd = False; Q9 ^$ P* H" U' z" O; m
Do
* w* Y+ Y8 m; ^ GetEntityEx ent, pickedPoint, Prompt4 |' D; a0 p& m9 ]0 p5 c# w
6 m: r$ t7 O& l1 s& x% x+ t
If ent Is Nothing Then
+ Y T- b) k( @ Exit Do
& c. Y1 x8 S% u/ m& R0 ~ ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
2 D1 P4 N6 a" z& K! d0 S" m+ P Exit Do8 f6 G: b$ ^& ]& C* y, }
Else0 j/ F5 \" K4 N& T4 B3 O3 ^8 H
For i = LBound(gType) To UBound(gType)8 F, T X' F& t8 ~% ?
If UCase(ent.ObjectName) Like UCase(gType(i)) Then
+ D+ ~4 {9 m$ m$ Q& o2 h Exit Do/ e/ t4 K$ u, b2 D8 Z d- Q$ b
Else
$ E3 x- {1 b+ S7 d8 g3 G3 S: [ pd = True6 b, A# F" R g4 I, Z& Q9 @
End If1 [! f5 ]+ b% g
Next i3 {+ i6 k! O! j
If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
+ n6 K/ M4 g. N; V, @, O* g End If# n7 q3 T+ s# L7 F0 S+ q
Loop8 E/ O" @1 x C. u$ ^
# d/ Y8 F, n; j1 Q
End Sub
* J( C* X" m7 D$ Q) R7 u$ d6 h'计算两点之间距离- A- o* ]1 N0 _" F8 d+ {3 h. q
Public Function GetDistance(sp As Variant, ep As Variant) As Double
) w2 w! C! |5 Q2 v; n Dim X As Double( g0 [; i1 B P& W3 {6 Z: _# A% X; M, |
Dim y As Double4 y! D) n9 r# g3 N) [; c7 ?
Dim z As Double# m- I/ i4 h3 \
0 E! G+ ?" I3 P' L) D X = sp(0) - ep(0)0 P9 q( M1 [$ k# g
y = sp(1) - ep(1)! @0 ]1 c1 ?2 _" O% M* [/ D* w/ T b
z = sp(2) - ep(2)) d9 C1 z' `! ?: g# q$ V8 H
8 {% q* ?7 H9 ^( @ GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))
8 r M/ T4 _1 m8 [0 v6 XEnd Function S: {, u$ P& P9 Z7 @
'返回两个Double类型变量的最大值! K" H+ \1 O+ ^; o L% M
Public Function MaxDouble(ByVal a As Double, ParamArray b()) As Double I/ }" x# B2 t! W
MaxDouble = a
5 D* ^1 J `% f0 P* A7 q' O1 _( M Dim i As Integer% I% n" C; H1 U: p% q
For i = LBound(b) To UBound(b)5 Z; u6 F2 a( o4 ^% M
If b(i) > MaxDouble Then MaxDouble = b(i)
9 |6 U0 g6 ~) e1 i# j7 z Next i
$ i% {" F1 e6 t) m, \End Function+ ]2 j' `: a% F0 f$ q) K
Public Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet2 j% a3 \2 f2 ^2 K" Z% y$ z6 L5 k
'返回一个空白选择集- U/ x5 n) j* m+ s
9 o- `8 F8 g6 z g, k# _ ]/ R% Y
Dim ss As AcadSelectionSet5 ^8 Y$ ^6 e& y+ H- d
( p6 w" b! [* P) ~7 Q" i0 f
On Error Resume Next
( k' B7 ^$ X+ }. c! ? H+ _7 V) f Set ss = ThisDrawing.SelectionSets(ssName)
6 E) n* `" j- U3 F" E: a; b If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)# u2 v% Z% S. J' z" L
ss.Clear# I( J$ d- v; A }7 O1 r, a
Set CreateSelectionSet = ss- [1 i3 F+ @ f) m
End Function
- V. E( @5 u# P9 }3 Z7 c% T+ T1 F" oPublic Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())& T: G6 Z: L7 Q+ V5 o& I5 Y
'用数组方式填充一对变量以用作为选择集过滤器使用" U: T! L' P7 t; I9 n
Dim fType() As Integer, fData()
" ^. x8 ^4 E9 |5 G/ Q Dim index As Long, i As Long: W% q6 C8 C5 j
2 d3 G' E: _$ ^ index = LBound(gCodes) - 19 u* |' {: Z8 L
I- [8 K$ p# [: s# b1 R0 P
For i = LBound(gCodes) To UBound(gCodes) Step 2
# w9 b: g6 o. g) f index = index + 1: ^6 D" q; Z( i* s( Q1 \
ReDim Preserve fType(0 To index)$ C T* h' o* O) w
ReDim Preserve fData(0 To index)4 r0 ~+ q5 g7 M5 h- y5 i1 e6 s. Z1 ?
fType(index) = CInt(gCodes(i))# ]) L: i6 L% t3 e
fData(index) = gCodes(i + 1)" c6 h5 }- k6 s+ S+ x
Next, V* J! t: K. _8 h1 P1 O7 B! H
typeArray = fType: dataArray = fData
8 p s2 ~9 Q( z( }9 _ x6 jEnd Sub6 C5 E( r4 M5 |
8 r# P q6 g$ p- y! Y" y$ a0 V; Q
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|