|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
) S: g# d, P: D; u6 ^7 U
% G& s( B+ Q6 j v5 T: }Sub LianX()
+ O/ U% y1 i- e1 fOn Error GoTo xx
0 o$ ~ j1 v' e$ ~ Dim ssetObj As AcadSelectionSet
6 B- x( \/ ?! a Set ssetObj = CreateSelectionSet("uniteSS"
# O4 E* b p7 Z1 r9 e6 C* m | Dim fType, fData
& J6 z1 d1 q& c$ F4 p- Q BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
0 G) S) d5 f" h '屏选直线或多段线
* p. Y C2 M3 N ssetObj.SelectOnScreen fType, fData8 b E4 H* b' _
Dim i As Integer
% n7 ^9 ?5 n V. _ If ssetObj.Count <= 1 Then; M M- e( Z: V# G z
ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"
8 ~7 n- a( s- c0 Q6 l3 g9 T Exit Sub. Z1 p3 M3 E8 p" [: p1 ]/ O
End If4 Z! |5 g4 ~. B+ ~( c- f3 J5 \
. a/ I) J9 X v0 n/ |4 d; ^: _ Dim line1 As Object
- h9 y r; k0 @/ E Dim line2 As Object8 x$ Y2 @" P0 `5 Q) a
# N& v, k6 ]- F$ [9 X1 j8 j i Set line1 = ssetObj(0)" u4 _; K" F" d5 E( R4 [" d* @2 h
Dim pd As Boolean
0 \2 X; E7 ~$ ^' v9 A For i = 1 To ssetObj.Count
5 o1 h$ {# T! C; G3 R% Z$ a3 G Set line2 = ssetObj(i)
$ ]# |* |' n7 ~/ U# z/ g4 O3 X$ ?6 c '连接线( x8 C4 L6 [% t- ]6 x
pd = unite2Line(line1, line2)
1 o* [4 e6 ]9 l '如果连接不成功,则退出命令。
# ~& g8 W) H: K+ }/ e$ P; y If Not pd Then ssetObj.Delete: Exit Sub0 U! ^& s) t6 R
Next
7 }/ b) i' } @2 _xx:6 [6 |$ c# h/ ?8 N
Select Case line1.ObjectName
% |3 O2 r. h3 F* R" `8 O7 @1 m Case "AcDbLine"! b1 B C/ @% |) w0 P
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."
5 b' V% G$ O2 q Case "AcDbPolyline"# W3 P) V3 o; f
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."8 A+ B( S( ]3 l' \" l
End Select
7 \7 _9 Z+ ]( W/ ^( I ssetObj.Delete$ c4 d/ n: W' G. d! @3 u+ ]
End Sub# L& q' Y8 i) d, F
. {) r% a3 [. h1 e9 Q* h- A0 b- t
Sub uniteline()
$ W4 Y) |3 I/ W4 D9 C( h' f% j, ]( w On Error Resume Next3 ^( }* Z" L8 J0 Q; w: T. M G3 B. o n* ]
'取得线. `! k1 o- Z5 W
Dim line1 As Object; R8 l+ j* D! t, p$ {6 o
Dim line2 As Object
% j: j* B- W9 M* ^ Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity
- C. _/ l" w' }% o$ A Dim lpt1, lpt2 As Variant
% n/ j3 v6 v# ~ 1 i$ B$ K% y, ]8 ]3 N9 |/ y
gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"& r) g( U5 R/ h! \/ {
If line1 Is Nothing Then
8 J. s& X7 b1 b7 Z: Q ThisDrawing.Utility.Prompt "用户取消,退出命令。"
- U& ?) ~) o5 ~, r, O1 d Exit Sub0 }# l, _ @! n+ h. y3 B9 T
End If o' H* j( B- I
& j6 T/ A: R: ^* j! M/ B gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"6 U% P5 W; D! P! q
If line2 Is Nothing Then
6 f3 x/ w2 z: K9 F: c& L, D' Y ThisDrawing.Utility.Prompt "用户取消,退出命令。"
3 G1 y8 p/ P; A4 z: c8 p' K Exit Sub
8 I0 m8 W& d7 r [; F3 H End If0 _( J. O; ^% \ y' \. h2 Z
'连接线% H7 Y' f5 \/ _9 \$ R+ t
unite2Line line1, line2
% l* g$ u. |0 S5 g9 u1 C/ oEnd Sub& K( v6 g# v7 m, e, A
4 f1 p% m4 w7 e" o) u3 w
; n; L3 q5 x: ^' K: S8 G/ WFunction unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean
/ F8 T( h2 c2 w5 q '连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false7 b) s6 {8 {3 t
On Error Resume Next
! o3 W( R* X1 l8 r$ u3 l' m( L$ F unite2Line = False
' C3 ~& _0 ]; x* p8 f & Z; u, f. x' }! o7 x. b
If line1.Handle = line2.Handle Then3 A% F) k: e' a, _# z" ]" `
ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"9 M) N# w$ o# n* j
Exit Function
6 Y) u% d( z) m End If9 U1 f& g i! ?; V+ l5 r$ J
- T4 t* F! w, h2 k% ^" v' M5 `$ n+ m
getLinePoint line1, pt1, pt2
7 |* i' T8 {0 w getLinePoint line2, pt3, pt4
) C1 x9 f( H2 d1 e # j O2 q; q: O# W6 |% m" r
Dim A1, A2, A3 As Double
" ^- i0 q9 w+ U1 ? Dim maxdi As Double
! ~7 d# Z, M. o A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
/ v+ K+ O- [6 J. F A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
0 v; D/ E& U7 D0 S A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
0 v" ] t# V5 J+ l6 _9 n '判断四点是否共线
$ h( B; Q1 F3 n7 L. Q If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then2 B2 r( _3 | d* _2 b6 k. n
'取得距离最远的两个点。
! j( N( \ }+ l, m5 P3 J maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _- E8 v% [' {! k
GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))9 x5 _$ Y8 ]$ S2 ]( b* u- ]4 @
If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2
7 O9 f- k0 E# O$ h: d5 B If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3
7 v' x% N& ?. F4 \ If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4
. K* _; T x8 R If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3% J, c( R7 }8 P
If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4% A, H$ d! o7 W; H1 W7 {7 ~& q
If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4
6 y' T, x" D8 ^& ~2 Y/ Q2 \ '画直线
) s# y* S: K& O) c Select Case line1.ObjectName. M5 W) w! W+ C2 f* a _9 @0 E% |
Case "AcDbLine"
' u: v, z. n2 t2 \9 ]/ I! t) Y line1.StartPoint = lpt1
5 ~* s) G" y: A& F6 { line1.EndPoint = lpt2# B9 p5 C% e5 ]! X2 T
line2.Delete* p% |7 K6 G* |2 [
unite2Line = True
$ y+ T9 {. P1 x6 h4 P; G: X4 d! ^ Case "AcDbPolyline"
- O, A. N1 z3 [$ } Dim newPline As AcadLWPolyline" `7 u, H; i7 x T$ n
Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)
A( D8 U. U6 i, _9 H2 W newPline.Layer = line1.Layer. k% Y5 ^; V# o' P* ]& m2 N. E
newPline.color = line1.color/ W7 h& l0 n7 x& |$ R6 s
newPline.Linetype = line1.Linetype
0 D+ ]* M, V' \3 k line1.Delete% u7 r; f" B n+ A
line2.Delete: H' `# x- q) {& M9 |4 ~) |
Set line1 = newPline
" W% ~' I6 C7 O" X3 p0 g4 _ unite2Line = True$ P* s9 |7 _) z4 [
End Select4 \( C7 h( ~0 q5 f i' x
Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."1 l) q" ~' }. C1 Z; _0 F) V
End If- e4 F% O& j9 p( K7 N. }4 J8 @. N
End Function
: m, a2 p! I- z* t8 G
; r5 x2 f# L/ _* F5 p! n
6 v, c( Q9 j9 ]. j/ h8 a6 k6 K0 f0 s6 [
! G8 q, O* z! C. o/ x8 `0 h'以下是上述代码调用的函数?
4 n, d8 [0 P2 X9 b5 V
' K+ P7 i/ Q. N9 ]* }: q! |# t3 e7 I9 k1 c9 U C
'创建轻量多段线(只有两个顶点的直线多段线)
' ^' Y$ n3 D5 T- EPublic Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline
; J" f. X+ K" \* D7 z, m$ B3 a' r0 X Dim objPline As AcadLWPolyline
+ y& [# T* a0 ] Dim ptArr(0 To 3) As Double
( W5 u4 l' z$ z: D7 T! h
/ h) M M- Z% v3 i' Y: @1 h ptArr(0) = ptSt(0)4 F2 r- [9 T7 n" O( b! _; x$ D
ptArr(1) = ptSt(1)4 {+ y5 E2 F+ B0 A
ptArr(2) = ptEn(0)1 W8 @, P+ G! |( s0 t( ]5 A
ptArr(3) = ptEn(1)' R! R, |7 ~8 M$ s9 n! [
% E; t) b1 D' |' d3 a) L/ z5 ^
Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)
2 w# N4 A- n0 h5 z- `# `$ @ objPline.ConstantWidth = width( b0 q, G1 c2 t& M
objPline.Update; T4 L& ^2 [) K) i9 n6 n8 N
Set AddLWPlineSeg = objPline# g% ^( D7 N7 E. f3 U0 C
End Function; `+ ` J; M- {& }: V6 K
Public Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)
# A. F& U) _' [1 o2 v4 {$ [0 S '本函数得到线的端点,其中point1为Y坐标较小的点' i' h) c; i, t7 L) Q$ t2 h
Dim p1(2) As Double0 w$ c+ `# R: C
Dim p2(2) As Double+ v' u1 C6 E8 G8 D) u
Dim k As Integer
/ j( h: y9 `! U$ _ On Error Resume Next& [+ t* H/ {- p8 {- _, n$ B. J
Select Case ent.ObjectName3 L7 x+ @; ~& x) d. `
Case "AcDbLine"" P* ]2 f( a2 u3 L! _! _
Point1 = ent.StartPoint8 Y2 I$ R4 Z" C# r- c- ~8 k3 `
Point2 = ent.EndPoint8 P( X* w' i+ D! |/ {% Z$ H, h1 U
If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then
( ?* A3 K% d& f W0 y( X" z Z Point1 = ent.EndPoint1 O; x6 o) Z+ k7 t J) q/ ]
Point2 = ent.StartPoint
7 a- F; S; v% e End If' m+ u9 |! r% U% i6 d4 l4 }& e( v; x
Case "AcDbPolyline"
* i3 x# v) y6 G! I" U- s Dim entCo As Variant
& u/ B5 g. n- t entCo = ent.Coordinates
J' ^" }/ z5 f: i7 [7 l k = UBound(entCo)9 c7 |0 F8 m* b5 D' B! _" m' e
If k >= 3 Then* ?, q9 v' p7 t( v5 O
p1(0) = entCo(0): p1(1) = entCo(1)
$ h! D0 w% u' _; }+ b0 y6 R4 y3 b. @ p2(0) = entCo(k - 1): p2(1) = entCo(k)6 d1 @$ x- P$ c- `3 n
If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then
) j6 s/ c; h7 J$ w' _' ` p2(0) = entCo(0): p2(1) = entCo(1)
& o. q5 `6 ~5 g p1(0) = entCo(k - 1): p1(1) = entCo(k)
9 ~8 }7 Z/ d' a' i8 z- z End If
$ T! P6 `9 {8 j7 Y2 ` Point1 = p1: Point2 = p2
% B5 x# i7 }8 ?/ N% _$ |) Y" W End If
+ I; m; \# `$ h. s6 d- t# {6 C, E End Select1 e. Z, J3 R* s- w3 X! t7 i
End Function/ C ]5 {+ P9 C$ ^8 m/ C
Public Function PI() As Double) z W" H0 m G4 _% \
PI = Atn(1) * 4
. u4 C! H* n( n0 u: i) B XEnd Function, T; S0 R# d: n. q( d& |5 ^. p8 j
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
' G; U L+ T, j! A '选择实体,直到用户取消操作
2 }. [. \7 l+ @" S+ u On Error Resume Next8 Q. k! x" v3 m4 S
StartLoop:+ J/ c! q- y- K8 g r- @
ThisDrawing.Utility.GetEntity ent, pt, Prompt
7 P& m0 j) q7 t! q7 h If Err Then
: Q' C/ e2 _( Z, Y; v% w If ThisDrawing.GetVariable("errno") = 7 Then/ v1 X+ j5 o N, `
Err.Clear
$ z, `2 V& X5 F' C% F. B GoTo StartLoop3 a4 ^& H( v! ?% l
Else
% p( a$ G; }* \! j. d3 \' @7 y0 r$ v: i Err.Raise vbObjectError + 5, , "用户取消操作"
' ^% @" H! A H+ Y: F: e End If
. r/ {+ S. [- _5 q# z! H: @ End If
+ O4 y1 c0 u) B+ X+ F/ A6 gEnd Sub
! ]8 C; Z1 I. Y$ h$ r9 YPublic Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())" Y- Y9 D8 |$ s/ N0 o6 C# f
'选择某一类型的实体,如果选择错误则继续,按ESC退出
7 z/ Q; S% f4 I, {' v. A, J'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等
( W# N: u0 l* n( s0 x6 ODim i As Integer
# x# ]! o# u+ aDim pd As Boolean/ Q. i+ c% C, J" [7 G3 I* s* ?
pd = False
3 J* B7 b' X, l9 |Do e/ n5 T: n" `; e* ]* }: s
GetEntityEx ent, pickedPoint, Prompt5 ]' c4 }5 S6 u {, U
% l, g# \/ D7 F. j3 p1 e" e# v If ent Is Nothing Then9 Z0 h. N3 o; b+ \. w2 S
Exit Do
0 ?5 v/ P' t, N+ E+ ~ ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then) r s4 R- f: \+ O! s. y
Exit Do4 N, L2 v( \6 F, u; k% I: y5 N
Else
4 \4 W0 r5 u% s% @: l For i = LBound(gType) To UBound(gType)
/ f- ] e: K; @8 Y+ G8 V8 o If UCase(ent.ObjectName) Like UCase(gType(i)) Then
( W6 ]. _& E! G$ A/ g( W+ n) ~8 W6 G Exit Do
& L, a5 _* z! h. | Else
5 n' r! F b8 V pd = True
9 }8 w# j1 {1 S) r9 F: F/ b End If% t5 c: ~8 d- F/ `) `
Next i. C$ f, U* L$ `: ]' N! s
If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."* N$ L$ ^6 h' _& j
End If
" H( E; A8 x: o9 CLoop0 [ j* l3 `' o: q9 j
6 a& u( ?& u+ ?5 A1 u1 ^7 Y! IEnd Sub8 f& W9 j6 \& `
'计算两点之间距离- b) C5 y$ \4 ]$ ]( S# {
Public Function GetDistance(sp As Variant, ep As Variant) As Double% L& o- \6 ?! v: Z1 L- w9 A$ D
Dim X As Double
; E( }3 \& o3 t/ E# l# b Dim y As Double3 @1 z4 @( i, `, W
Dim z As Double
0 f- w" N3 m- @: O/ C $ m* H+ X* T- D
X = sp(0) - ep(0)
: t+ r$ m* m5 o7 l/ o# t. ]9 X y = sp(1) - ep(1)
; q! b( g4 p. r; ` z = sp(2) - ep(2)& ?9 t& S6 G4 K: n6 m R E0 F
0 X1 V. G0 Z8 Q$ b
GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))
# n, `4 W! `8 z6 r9 I" l9 lEnd Function
& ~; m; u( \( L: K3 j8 J'返回两个Double类型变量的最大值
* N( }0 R8 q8 ]+ qPublic Function MaxDouble(ByVal a As Double, ParamArray b()) As Double
- {3 h* |, N. Z# ?- n p MaxDouble = a! F0 w) ]! K7 i6 {( S" |, l5 W y6 ?
Dim i As Integer! r, C. I& _1 `. k4 d. b
For i = LBound(b) To UBound(b)
. G3 s, z! q7 ]7 i If b(i) > MaxDouble Then MaxDouble = b(i)2 K" d, l; N, q
Next i
# y2 N2 S* e8 _4 W4 U$ fEnd Function
3 g# p! S2 |8 V+ n0 MPublic Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet
7 O/ u# N" ^/ R8 T) n6 ~" T3 W '返回一个空白选择集3 B4 L S! y. f; O8 x
, Z9 O7 w: ~2 F& I' e. M5 p Dim ss As AcadSelectionSet
; ~! F% y! W0 Y4 J
- @/ q! f3 N5 g On Error Resume Next/ z6 _3 K4 O; k; ?( W! {8 R
Set ss = ThisDrawing.SelectionSets(ssName)# K w6 d" i8 S2 C. w7 E3 K% T l5 G
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)" l% T( n& K/ g6 J& S! D( S3 Y
ss.Clear
+ _' e- f$ ?4 k; Y6 p# M% i Set CreateSelectionSet = ss
" X1 |: A/ m, u- G. ?% B! A! rEnd Function
; ]+ v% ^ s. G4 xPublic Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())% K- p1 z7 {5 ^+ F1 ^4 ]
'用数组方式填充一对变量以用作为选择集过滤器使用& z/ }- u: s; x! M, }% l% A
Dim fType() As Integer, fData()
" u1 j( |: [' X. W; S( J Dim index As Long, i As Long
( b" m/ l. d. }" ~% V! J / B5 I9 K! A4 E/ f# B
index = LBound(gCodes) - 1+ m0 T/ |* x/ b) B7 a. T( a0 r
s( }6 P8 I5 a6 e% ?7 F# G+ a For i = LBound(gCodes) To UBound(gCodes) Step 2
1 Q( h$ ^( N9 m9 y index = index + 1# c6 l6 x% b* t# X: V- W
ReDim Preserve fType(0 To index)
% D, M1 ?! T. @1 n6 ^; Q9 [ \ ReDim Preserve fData(0 To index)
( R% k9 N5 ^! P$ a3 j/ _ fType(index) = CInt(gCodes(i))
% z+ J* l7 Z" S4 M( Y* V* s2 L fData(index) = gCodes(i + 1)6 G/ j& W+ `7 g+ A% q4 y; `
Next
, l$ l0 G1 G5 |' t typeArray = fType: dataArray = fData
, T* g. Y3 s# M8 JEnd Sub
9 ], G9 z% F0 |* ~, g: @; I5 S8 _, @. V2 u# K- w) x
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|