|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
4 r7 P& V O1 T# S( Y% S: K, w3 H5 k; @- k, m& ^5 u
Sub LianX() v; a4 \+ O! Z+ [# W
On Error GoTo xx
' Z6 C6 M9 B; u0 A. Y8 X) E5 m Dim ssetObj As AcadSelectionSet
" ?- }$ A; r" z2 v- [! r$ G* e) s Set ssetObj = CreateSelectionSet("uniteSS"
- b' _# Q8 y0 [: {8 I: I" m Dim fType, fData9 P+ ~ F9 b( w* F) C! V; j
BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
]' }3 y; V V" l8 W '屏选直线或多段线$ R+ d7 g& P+ u5 V/ g" {3 u
ssetObj.SelectOnScreen fType, fData: l; w5 b. B8 u2 J! L
Dim i As Integer+ i5 {" v8 |8 f6 @3 p0 x
If ssetObj.Count <= 1 Then) f# {6 ]/ h6 o' j# R" R2 g
ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"
5 o/ M+ s5 j3 {9 x6 x1 b7 n Exit Sub7 T W! f# z9 t9 |0 W- X5 T
End If$ t. j1 L3 b6 a" O, J1 U8 g
! z1 \, z$ J9 B Dim line1 As Object
- {# r9 [: P. s4 w3 P Dim line2 As Object
$ a: q( ^6 |+ x8 ^: y3 T9 g
7 M6 [) l9 h- `# }4 J8 s Set line1 = ssetObj(0)& x$ k* n0 N. z5 c2 o5 a# b
Dim pd As Boolean
& s& g n, Z4 `6 i For i = 1 To ssetObj.Count
: O6 m* L1 ]/ X0 j) q Set line2 = ssetObj(i)3 h3 x) ]. H* E' \8 q9 l0 d. @
'连接线
3 t4 o! X3 ^1 Q- \ pd = unite2Line(line1, line2)8 Z* m( |8 P. l4 R4 A
'如果连接不成功,则退出命令。8 M4 T, C3 j f2 j7 c+ h; M g
If Not pd Then ssetObj.Delete: Exit Sub
% H+ ?' e/ f' O0 { Next- ^6 ~. j* \9 o5 X) F! D) Y' U
xx:3 Z8 t) v$ ]5 s( f& e" N
Select Case line1.ObjectName* D+ s* r8 m# g5 b2 d
Case "AcDbLine"/ }( I7 [9 X, K* T* \3 t
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线." v( k/ L: }6 J
Case "AcDbPolyline": u6 _, A2 B# [9 K
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."
& X# p% _+ t1 ^! @( H End Select
Z+ z& C( p7 d6 l( t ssetObj.Delete
# a# w# |7 [; K p+ ?1 [End Sub
- V4 E" F& z; T9 Y: M4 n# B, t3 N" \) C0 V' q$ O
Sub uniteline()
$ B3 r3 B) l6 U Q. d( }- ~, t On Error Resume Next
3 P7 K5 S8 S, g5 H. y '取得线, A. A0 x. B0 G, I. ?0 e" `. e7 o4 S
Dim line1 As Object: \' ^/ d9 D6 |7 k; z7 f: H4 B2 W2 w2 t
Dim line2 As Object/ h+ c# o! m/ h! s7 h8 D2 l3 d; ^9 }
Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity6 F' f: x3 c: Y# i m6 Z/ D
Dim lpt1, lpt2 As Variant
. g$ p/ e% `8 |. u: y ' U* z2 M" d3 ^
gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"9 i& k8 Q# \* P# O
If line1 Is Nothing Then P, t! z7 X7 p3 \2 o
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
* l: c7 V2 {, Q4 p Exit Sub" Q5 U/ E2 `0 A( A
End If
# M* V5 o H# D* B ! `- w& Q# x& `8 t
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"8 q: b/ W& {8 m# v
If line2 Is Nothing Then
( y: A, _9 A9 l% R& O$ I h" o$ z ThisDrawing.Utility.Prompt "用户取消,退出命令。"
9 B6 W$ v: ^4 J) L, o' t Exit Sub
: Y# D |6 [% G3 }8 D End If' b `& P# R* N. Y' L0 h/ W% H
'连接线
8 N. `- ~; S9 T8 n" B1 F4 o unite2Line line1, line2
% y3 u& a) E% CEnd Sub9 O' D D/ l! Y, ?
$ ?& x, V9 ?# J' ^- n e0 t# G4 H4 y2 j2 `& H8 ^
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean$ a" u3 @9 _( V8 `$ v
'连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false6 w- I- w( {& x1 _/ l3 N I
On Error Resume Next
; q8 @) x/ R6 t6 K5 @) n A unite2Line = False6 V) U' Y( }( ^. i
3 t' [( f( ^% h If line1.Handle = line2.Handle Then
, F1 X' o; q# J! q. s ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"
: z3 [, E8 M; i' K+ S" ]5 M5 K1 \ Exit Function. Z, q- }$ t; u! v/ l1 E0 U
End If
- z+ B5 ^; F3 [9 [/ R* k, n 1 N6 Z. E [8 m% l
getLinePoint line1, pt1, pt2
7 [$ U2 l& W' S f6 \" N getLinePoint line2, pt3, pt42 ~- L* J% \/ J; H. D
+ o: ]' U$ |- x/ s' z8 l5 [6 A9 o
Dim A1, A2, A3 As Double" |4 M" d1 |1 v' E! C# N
Dim maxdi As Double
8 |4 s: g- i6 p A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
# `8 x& v6 U3 U/ q Y A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
6 T1 u5 |& w2 T9 y, H1 c2 p/ Y A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
* p0 J; E F, F% B '判断四点是否共线
* F: m) n- O" `* B4 t" i- f [ If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then
/ ?6 l' ^; q x% t, Y '取得距离最远的两个点。+ Y# a S+ P* @8 s1 L# Y$ \/ s
maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _
; W4 z0 _4 M' z! H [6 a GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))
$ v5 }2 @0 p9 H. ?5 ~3 c7 K If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt20 |5 X1 P6 x! B% e7 f1 T: F1 M% @
If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3. \' V1 h3 h1 |( d5 w
If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt41 a# p& t) I) M- ]
If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3
2 @0 I7 V: s% z- h' b4 `9 n, Q If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4
' C" u* R9 ~- Y If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4! s/ V: S3 T; z# C( z1 t% L
'画直线
7 g( K: e9 |3 j( A s9 x Select Case line1.ObjectName
0 N+ E# u6 l9 Y$ w( t7 w9 P! N Case "AcDbLine"3 L( w$ _9 |* t
line1.StartPoint = lpt1, e# m1 [- f3 I0 D
line1.EndPoint = lpt2
, q6 \7 `( t- H0 H line2.Delete
( c: q# f+ |) L+ \0 w0 x) Y unite2Line = True# A$ v' L& U/ [. H5 R9 |/ k& O; \
Case "AcDbPolyline"
! t# m+ E2 z$ T+ u9 p Dim newPline As AcadLWPolyline
/ l5 H2 v" Y3 P7 Z1 f Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)( C, g8 D- P$ W" |3 c
newPline.Layer = line1.Layer
4 y# c# p6 a0 c+ y0 c( j newPline.color = line1.color8 V W5 U+ R% C+ m8 b* j3 o, C
newPline.Linetype = line1.Linetype
% _/ I: l5 d4 i3 z7 C" W line1.Delete" V6 z/ t1 j" Q
line2.Delete' y/ V, f b. K# z) z, S7 l' w1 Z
Set line1 = newPline: T0 n. [# J( C' Z# n( b
unite2Line = True8 Q5 ~/ b- v% [9 V* ^; d# b
End Select
+ W! h! v. d2 G- z' x! @ Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."- d1 J2 S8 r* f' G" _* r
End If6 [0 X( O/ x, P/ w7 S M6 g S- e
End Function
h9 B# T. A$ @& i& V7 j# ?( w- \9 h0 E7 q' ^5 ]
0 V6 [2 M6 ]" f- }8 W5 g/ D7 ~: J- p q7 Q; n8 b
'以下是上述代码调用的函数?9 O' V0 p2 d$ K% C# M2 b5 Q& Q1 A
7 d: V( V T# I3 x! i; V0 h0 o
$ T$ k) w6 B1 R; q$ _7 C% i0 ]
'创建轻量多段线(只有两个顶点的直线多段线)
. C S6 A) V; c8 qPublic Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline
) P- b* X9 ^+ y8 w7 K* I8 V Dim objPline As AcadLWPolyline
+ h) o" x# i6 }. P3 ] Dim ptArr(0 To 3) As Double
3 ^2 r+ @5 z; r* M! C1 c4 d
. V$ `" [2 [/ k ptArr(0) = ptSt(0)
2 F6 O! F! t$ A4 V& T: p9 f w# W! u ptArr(1) = ptSt(1)
+ @6 V# E D; O1 V# r7 y! Q ptArr(2) = ptEn(0)
) X( v8 x* M& L4 ? ptArr(3) = ptEn(1)
2 w5 U5 F- v! F0 y1 [) D5 _ $ r3 l2 P8 E" Y' U3 M5 ~
Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)
S" I: L1 U: _0 m/ g2 K objPline.ConstantWidth = width9 E7 x7 R. `2 s; t
objPline.Update
- s' R) ^+ d! s$ i' q* M9 R, n Set AddLWPlineSeg = objPline
5 q9 c0 H7 b$ o3 F4 E: ?1 L3 bEnd Function1 t, p# ^* m" h% a) t# z' Q
Public Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant); G3 e {7 K" r+ z& a
'本函数得到线的端点,其中point1为Y坐标较小的点2 B' a* n2 W9 f9 J2 w# t
Dim p1(2) As Double. [$ j" }1 ~: p
Dim p2(2) As Double
; i6 [/ c. y) F+ v5 I( P I$ ] Dim k As Integer
' {) h6 V/ K/ H5 r. ]" I" T On Error Resume Next0 p& d- I- M7 P1 I/ ]% C8 D' Q
Select Case ent.ObjectName% W) r2 H- h9 A- C) `
Case "AcDbLine"
, M) r8 z5 x' e A. a: d9 L/ V Point1 = ent.StartPoint4 k% e9 u3 j! I% e c. {7 o( e/ l
Point2 = ent.EndPoint5 R2 P6 h7 F ~4 Z
If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then* E! S) n2 U: E9 z8 T8 Q
Point1 = ent.EndPoint
+ q9 t$ q: m8 k. _# { Point2 = ent.StartPoint- C) N( Q; V6 C0 e4 `
End If0 Q, k' X" B1 r f: |* m0 [- |
Case "AcDbPolyline"
# f5 D+ X. o# t( a Dim entCo As Variant
# e) f9 N( D2 v0 e' V" i1 R) T entCo = ent.Coordinates+ \2 Z: w8 v) ?1 k0 ^( I& t
k = UBound(entCo)
& N8 f) `1 h2 c! [0 M" n! A/ H0 U If k >= 3 Then! [; E) D% i7 H( d# t
p1(0) = entCo(0): p1(1) = entCo(1)0 K. |! o' w* O: H$ }2 ^
p2(0) = entCo(k - 1): p2(1) = entCo(k)
" s6 E' C6 A: d4 {2 t: y If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then
, d) o2 v5 i( W5 a) g1 h' K p2(0) = entCo(0): p2(1) = entCo(1)' X2 C3 w6 [* K
p1(0) = entCo(k - 1): p1(1) = entCo(k)
7 P; Q D Z% Z/ r# E! N End If- C3 u* N1 w+ H7 O9 g+ H4 s
Point1 = p1: Point2 = p2
+ Z v/ V3 `: r1 J, R: Q0 u% I$ \ End If, t0 U- F/ F7 K. P
End Select
# u; i' b, G5 OEnd Function
1 e+ C5 X/ t- ~, J8 R4 a' N ~! \Public Function PI() As Double
. N( V0 T% N7 J/ t PI = Atn(1) * 48 e- e/ R+ s! L7 N; `
End Function8 S& f, U4 s2 W$ `/ g! h
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
% |; R# \1 }! A1 m4 n' I; A '选择实体,直到用户取消操作' n) u# u# z) j8 g) O
On Error Resume Next
% ]& M& V3 m" K k) QStartLoop:) r; h- p1 ], ^0 q
ThisDrawing.Utility.GetEntity ent, pt, Prompt
. v3 F w2 _4 o: p/ p7 c If Err Then
( O1 x5 m& @8 |" n6 ~ If ThisDrawing.GetVariable("errno") = 7 Then
5 ^/ K1 j; M- V$ ^$ |9 q j2 c9 o Err.Clear, `" s9 Y9 K# T: ~% ~# g
GoTo StartLoop- ?1 M$ ?7 v7 Y: q* ?5 v5 U8 n& `
Else
, g. i, n2 h6 F G. E Err.Raise vbObjectError + 5, , "用户取消操作"
; _% q; t, S$ V! f# h4 A' m End If
7 D5 X; A9 W" e0 R$ u End If, M% g* ?) J- q9 L% d# [* T2 t* W
End Sub
: n5 c& s, u6 ~1 p$ ]4 wPublic Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())! ?1 z' b# Y" g2 ], V
'选择某一类型的实体,如果选择错误则继续,按ESC退出
r1 v4 h! o; M% U N- A'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等
7 X/ G! w! h: a2 ~Dim i As Integer
5 ^3 f) ^3 s( C! ?9 R+ H" T- PDim pd As Boolean$ R& V: R i5 X$ U6 r1 q4 ~2 l
pd = False
1 b5 r1 ^" |- d( f6 qDo
( Y* P! S1 z" ?/ l GetEntityEx ent, pickedPoint, Prompt
0 D- J( L4 `; r' B5 E. j9 K/ ?5 F - ?# k3 R1 t q4 E/ ?( ^
If ent Is Nothing Then
3 N( a8 d o+ {2 S- h0 J0 T X$ t Exit Do; P* `6 `& _9 S
ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
& X" _9 c5 z1 I. r5 |& H Exit Do
- g2 \7 P G2 E: W7 F5 [0 ~ Else" B' D+ V: A2 C- M' G
For i = LBound(gType) To UBound(gType)
; _, q: Q% r' l2 Q If UCase(ent.ObjectName) Like UCase(gType(i)) Then
8 V$ X I1 Z+ z7 K7 O Exit Do
# \0 ^8 Z g1 s! G& C+ `" J$ { Else
6 ]4 I- ~* _% c2 [6 J pd = True
- N8 W4 Y+ ~* |4 S End If8 }$ E0 r+ V: g, [ m8 ?* E2 x
Next i1 T2 b M+ w, o. X& c
If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
' ]. b7 }" p) S! b' }, g, ]& e End If! ?: A7 F/ H+ V2 `3 q7 F5 `
Loop. S2 l7 F7 O! V! n+ `
- C: O$ |, e1 M0 i% v
End Sub% C) Q7 z% o) ]5 d) j. B
'计算两点之间距离9 j4 y- q- x$ r5 y1 W* ]4 _& Y
Public Function GetDistance(sp As Variant, ep As Variant) As Double' R! R- S( ]4 K
Dim X As Double
6 p2 t1 c0 z. N: f+ m' r/ M Dim y As Double
2 r: Q6 r' _2 O* M$ E9 v( ^& d Dim z As Double+ Z) p0 M' { j6 r
8 |3 F" F8 L2 k. a" K- x X = sp(0) - ep(0)
) D, t- @$ O# M2 { y = sp(1) - ep(1)! \* w6 B1 @! b7 ^
z = sp(2) - ep(2)0 R k* G( s5 I& X- T' h! h
; Q- l6 r( X2 V0 ` q3 r6 R, @
GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))0 n3 s: F" K1 R1 k4 h: Q
End Function
" ~" _& P$ m8 l9 C7 f'返回两个Double类型变量的最大值
9 a" v t- I$ b8 b. Y1 m6 Y# |Public Function MaxDouble(ByVal a As Double, ParamArray b()) As Double6 W7 Q" p$ j" k5 x6 e
MaxDouble = a5 D" U4 w$ R1 N: E2 M
Dim i As Integer5 ^3 K4 D% |7 [0 L t ^
For i = LBound(b) To UBound(b)5 f9 \# _3 d* G; d8 A
If b(i) > MaxDouble Then MaxDouble = b(i)& N( U% r0 }4 Z! n% h
Next i
- N% g6 j; Y3 y4 TEnd Function6 {; j3 T' L8 S' B0 q0 w3 W' M
Public Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet6 ]" w5 Z, j6 m# Q
'返回一个空白选择集
4 Q. [: V& T8 z6 l5 v
3 b' j$ E3 E1 ^* V9 h" b' E! y Dim ss As AcadSelectionSet1 T+ p# V* d2 b. X
9 [0 f! H' |# |
On Error Resume Next$ Z$ F# Y6 ]7 z- A6 c; r" r2 s
Set ss = ThisDrawing.SelectionSets(ssName)4 D5 e' R6 ?! n& m
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)- z X. m8 K+ g) c: s
ss.Clear! a% S0 }3 \9 S. Z' m
Set CreateSelectionSet = ss0 f4 U9 F4 M! H% K, ~
End Function1 O4 G; } M& H: z
Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())( F% G+ n% `" z, }7 c7 y% D
'用数组方式填充一对变量以用作为选择集过滤器使用
! F8 U' d* k$ A0 d* J" ` Dim fType() As Integer, fData(); F# a! S% J0 v2 h* B6 \
Dim index As Long, i As Long% s3 d8 o+ h0 E( D" `; {; ^
5 h. s5 o& V3 w! N, Q: C8 w index = LBound(gCodes) - 1, b- b4 X, E8 H- B& N$ o" C
9 h2 ?! [/ N7 t, A
For i = LBound(gCodes) To UBound(gCodes) Step 2: l( n8 S' ]6 [9 x. A1 }
index = index + 1/ K: m' m7 N3 Q" h1 y5 h0 O* ^
ReDim Preserve fType(0 To index)
" a6 d. f8 e, [. e ReDim Preserve fData(0 To index) ^( J4 M: P8 ^" f
fType(index) = CInt(gCodes(i))7 O9 J1 [1 H t6 p' S. h, w2 D
fData(index) = gCodes(i + 1)+ T+ F1 Y+ X4 H
Next6 c7 e8 g8 [6 P) e- L1 @$ }
typeArray = fType: dataArray = fData" H7 l0 K3 X, U z8 u. S4 X
End Sub
P9 }. Q' h- w: }, R7 G# ~; _: m" O" `+ d e$ G
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|