|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
0 r0 [' q' l, g& o. ^* B4 t/ i, D2 F. l+ c
Sub LianX()
* D5 V& k4 d: ]" q' o5 F- VOn Error GoTo xx! S, J6 {6 x% }5 N4 ~( E
Dim ssetObj As AcadSelectionSet
+ `* `0 f+ `% u3 ^8 x2 i Set ssetObj = CreateSelectionSet("uniteSS"
+ [: t' q8 H. s: n1 D% \7 ^ Dim fType, fData6 N. I( h" N7 u0 l& R* N0 v4 Y
BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"$ O% u& r6 k) o; w1 S
'屏选直线或多段线4 y) w' g8 b1 B# C" o; [, c! k
ssetObj.SelectOnScreen fType, fData
1 w! @7 p7 B. ~, i6 { Dim i As Integer- _% ^! x. t t( [
If ssetObj.Count <= 1 Then
: I* N3 H9 k+ r5 x8 A ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"
- h( W6 {, b( q ^& W Exit Sub O9 A0 f- t. e9 f0 }6 t( f
End If& E" l9 O1 i* V) d: X
- R7 Y1 [1 ?, A& \ Dim line1 As Object- I% b, B) m& _0 f L
Dim line2 As Object
$ [# @6 c, T- O n4 h+ R
0 i6 L" n* |$ ]) }" R/ I) }& R' Y: _ Set line1 = ssetObj(0)( G7 s. X7 i L! e @
Dim pd As Boolean8 |$ u# m0 v' j2 u
For i = 1 To ssetObj.Count- e! }2 R4 m$ a* x2 I. f
Set line2 = ssetObj(i)2 C* ]4 d$ @# A. n/ S$ j9 H/ P
'连接线
3 M l1 l: U4 [& @& s3 } pd = unite2Line(line1, line2)
, S5 W$ v) n p& m! R' p '如果连接不成功,则退出命令。; b) y. E: J% x# G! j8 n, b0 `
If Not pd Then ssetObj.Delete: Exit Sub
+ F' r! O! G% W( | Next3 S. q" \9 k/ b' o$ C* `% ^- f
xx:
# S8 s3 c) ?* E' ?& ^. O- T- ^ Select Case line1.ObjectName
- V4 G2 A5 x: _! b Case "AcDbLine"
( ]% Y7 l1 e( \) Z" N8 J ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."
3 j* @# [; j- C0 L) M Case "AcDbPolyline": L- W! [. O z
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."6 ]* w" q# x: E" F, N. {; _# C" q
End Select
( P3 u* G, S8 K) o i. g ssetObj.Delete
9 n# m" g0 D6 F# OEnd Sub- e9 Q K- H& L5 k5 Q
9 m6 `* E+ }& W( o5 e! A
Sub uniteline()0 R* W* @) m, }, N; j5 O
On Error Resume Next
3 a8 _0 k& L: u '取得线, D0 u) [& S) y& b! a0 r+ d3 w" z3 y
Dim line1 As Object5 I; Q! J4 Y" L) ^% k
Dim line2 As Object
( o, {! m2 q. i; R( j Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity
' c4 Q* b9 H( W; L3 j& X1 O% ` Dim lpt1, lpt2 As Variant# ?6 D) i8 q9 l' v9 G( T" z
2 V# B) F# L2 Z2 i7 D, I gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"9 `, |2 Y* S7 w7 L: r0 x
If line1 Is Nothing Then% C8 `# ~$ Q% T9 V& x( s k- M
ThisDrawing.Utility.Prompt "用户取消,退出命令。"+ W6 U9 p+ T6 w1 M! E
Exit Sub/ Y: R! |1 G5 N# |/ ]% {
End If
8 f) [, v4 G- l, u
) }& M0 s' V( q4 s* k2 ~1 a! K2 Q gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline". F( X% d, D4 T0 h* K0 T- v/ o
If line2 Is Nothing Then3 O0 e4 o; c5 J/ k8 `7 e$ D
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
5 J- R: K! ]% ~- o& _4 [. h Exit Sub
2 M( A+ s% m3 _! } End If
3 z, }% P/ Z1 a '连接线
% B0 `. F7 J- K unite2Line line1, line2$ X- p; M6 m$ H( U$ I
End Sub q% h0 \: y8 ?1 {! V
- y. H+ w+ ?5 {; ?5 y: _
: k0 Y% ^7 r' J, H$ `( b# N, h
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean
7 l4 R/ D$ } F) j) y+ J '连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false" ?8 q7 q1 ^5 A9 G2 R& |( y
On Error Resume Next- c' d/ S' g$ V; [2 p3 k* ?' [
unite2Line = False
: c/ W6 u9 \+ b4 n; l 1 e2 [+ m% M! Z- {
If line1.Handle = line2.Handle Then
4 _, E; B' a1 j9 z" {& j ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"
+ e. Z# H6 f3 z& h9 f5 J/ s Exit Function
7 p) X4 `7 F: x Q* n End If
4 F2 j# i7 F7 |% [9 Z
+ T- _+ g2 k$ a+ R getLinePoint line1, pt1, pt2
, U4 J9 n2 g+ B& m0 q; t getLinePoint line2, pt3, pt4+ t- ? x7 V$ L k7 e
. E* e0 f( x% g
Dim A1, A2, A3 As Double
/ d7 e6 U7 R- Q# [( T R& r9 r Dim maxdi As Double
: W* `+ T1 @9 ~# ?: v* V A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
0 D A8 u7 q0 b A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
( X9 Y' }+ D! D o A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)7 y4 n0 _5 t& A, w9 Q0 V9 H# j& A
'判断四点是否共线+ ? d0 s2 u$ H4 ^$ \& ^
If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then' {; \- }1 S/ T- z, }5 o
'取得距离最远的两个点。6 _$ v* }$ }! X6 |0 E
maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _0 T# {/ b$ p) L- Y. K
GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))
* ~. W8 u: _. M! B0 ] If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2& j. Q# j6 j w5 A4 n6 q- {
If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3; {/ o8 Y( F- f7 q( W) R( T
If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4: z+ o0 [6 G* Q. B+ u5 Z1 u9 ~
If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3
; _4 a$ V3 \- c7 U" @; b, j If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4* b! Y# u- D! x/ A
If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4
' H0 m% x2 c1 c3 W) M6 b '画直线
4 ~6 P5 m& u' K; q/ A% G Select Case line1.ObjectName
7 D" L; N( E3 F Case "AcDbLine"
5 B' |& O) ` I2 t# G) [ line1.StartPoint = lpt1; {3 S* I9 H8 x: O9 d. C" n }( _
line1.EndPoint = lpt2' l, V6 o j8 O- s5 W' n: N
line2.Delete
^) s4 O* `* G& m7 f unite2Line = True
5 t4 C6 Y. K* @( _ Case "AcDbPolyline"
5 u* u) u6 ~. o) r1 o+ r2 Z$ x0 U, u5 e Dim newPline As AcadLWPolyline
) ^% W3 s, e' ?0 O Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)
+ Y$ S1 ?1 ]$ v. Q1 T) O2 d newPline.Layer = line1.Layer
/ s; L' ~3 b' E! Q2 x. k s newPline.color = line1.color
) N6 y8 }# ~2 O( w5 ~ @# Z newPline.Linetype = line1.Linetype- {! _! R( Q: h# ]
line1.Delete
# ]6 q: z3 h4 m* y9 [4 m' M6 J line2.Delete# K& \# w N# m( m0 m0 T: _3 H
Set line1 = newPline
: H( `" \, c0 a/ q. X$ g unite2Line = True4 ^3 ?/ I) @! S# s4 x8 ?" t& |4 u
End Select- L4 B" v! N1 d/ n
Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."
0 K( M5 S$ E' O0 t End If+ }3 {9 D9 d: G, A: { b6 B+ [
End Function
1 E: k" }, r2 u3 z+ G, q
$ R2 |! c+ B4 U+ V5 P% H. H2 r: ?/ B" | m' b
. P% ]6 [4 O8 i7 s c
'以下是上述代码调用的函数?
+ l ~ b8 g6 s( J) ?
0 e, a m4 E4 p/ Z6 m
2 e' q: a. Y! w: A# f'创建轻量多段线(只有两个顶点的直线多段线)2 V5 j( h; p* X6 X* |$ N4 V- G
Public Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline: T0 E7 i1 ? |! E2 m: F
Dim objPline As AcadLWPolyline2 [) N( w, k. F, `' J4 [$ J" |
Dim ptArr(0 To 3) As Double
' u/ s5 T" |, N
" ]/ K' ?' }/ u. @$ Q ptArr(0) = ptSt(0)
) |- i5 w% W$ f; f8 p! k9 \0 s2 m) T ptArr(1) = ptSt(1)
f( [/ R. k; i1 y# \, O4 E ptArr(2) = ptEn(0)
. L$ _- R; V/ c N# H' @! g1 M ptArr(3) = ptEn(1). K/ q( H5 ]$ Q4 F
) S2 z2 H- J% H, `: x Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)! Q" S: M" d# W" O( P! o
objPline.ConstantWidth = width
# A9 R+ f m8 E. e objPline.Update
# C9 R+ h3 ~/ |- o; p( y# \ Set AddLWPlineSeg = objPline! z) |( `- k0 M" }4 A% d
End Function
+ q7 [4 U) h5 a9 Q3 E' \Public Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)' J+ {: ^! G9 g$ w8 Z
'本函数得到线的端点,其中point1为Y坐标较小的点
2 C. N/ a3 @+ M" x1 T5 ^" s5 V Dim p1(2) As Double
, I; p( O0 p8 e6 M$ y8 E# J7 j Dim p2(2) As Double
4 V- k! x. x; I! f7 \% n E* ^) X Dim k As Integer" K4 c; D- P. l3 d" j
On Error Resume Next
m" `8 L- k8 I: A Y Select Case ent.ObjectName
6 a# J7 _% X' d Case "AcDbLine"9 `/ j v* Z9 {' b2 L ]3 [. C
Point1 = ent.StartPoint
0 ]! ]& N7 ]- y+ F) Q Point2 = ent.EndPoint
) f( J# ~% J4 ?& H If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then
" p5 A) I& l& [ Point1 = ent.EndPoint( n! O5 l9 u- a) w1 O2 X+ Q
Point2 = ent.StartPoint3 S( l$ o. F* @
End If
$ x2 M( p6 |" T' t# U# _' I8 Z# j9 G Case "AcDbPolyline"+ ^: L9 S2 c# a3 g; m4 @
Dim entCo As Variant
" u6 m# `) q9 A6 @9 x1 k5 ?" u entCo = ent.Coordinates
8 M8 ~) ?$ m' _' ]% u9 D& c/ A k = UBound(entCo)' R4 M9 G( e0 E+ j
If k >= 3 Then
& f, j& T C$ `6 { L- a U p1(0) = entCo(0): p1(1) = entCo(1)& F% \6 b# h. I8 G1 q; x
p2(0) = entCo(k - 1): p2(1) = entCo(k)
" p) e* w4 F! a If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then/ Q' r& t0 L! V" W9 M
p2(0) = entCo(0): p2(1) = entCo(1), X7 L0 z F9 T7 g& a4 l; ?) Z d
p1(0) = entCo(k - 1): p1(1) = entCo(k)
: _. K2 h/ B' |: | End If
- Q' ]+ L# `3 V" d% \$ l Point1 = p1: Point2 = p2( _( b; n f- Q b7 Z" M/ I# [
End If6 J* j' P3 E5 ]1 u
End Select
, C- e: k4 T9 e7 i) FEnd Function
1 G, ^3 {" X! K' ePublic Function PI() As Double2 m1 ]; W$ q( D0 ]4 t
PI = Atn(1) * 4
. z2 l4 `2 U8 h6 I* A7 j% `, PEnd Function/ d3 v0 r1 O( W$ ~" z8 Q& A0 p
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
$ N- Z9 ?9 s$ P; i '选择实体,直到用户取消操作
, E$ p8 |; F. y3 |4 n On Error Resume Next
_- Z7 E4 v6 N% UStartLoop:
* }/ I7 `4 e ?3 r% t ThisDrawing.Utility.GetEntity ent, pt, Prompt
) ^( }" ]1 x' {8 i3 w If Err Then: \ j) D+ M2 N# f# X( w+ w6 F
If ThisDrawing.GetVariable("errno") = 7 Then
C/ O8 L# ~+ R' b) y# ` Err.Clear/ E: U! Y) ~ q/ ^* n
GoTo StartLoop2 h: ^* `/ A9 Y1 c" |3 O; V! y* r
Else4 T7 H8 M& ]9 a+ }9 [) V
Err.Raise vbObjectError + 5, , "用户取消操作"
) y# y5 D3 V" K End If
: H" T5 V0 B0 T! z0 ~ End If
: [ ]6 x$ r4 p9 w, X2 X6 N8 REnd Sub
. G$ c4 s/ F$ F3 [ T" }, ]Public Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())7 h8 ]" L; y, `- L1 V& p* v
'选择某一类型的实体,如果选择错误则继续,按ESC退出
9 C* m2 R, U6 g! i'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等0 ^; G" Q s8 P# z- a
Dim i As Integer8 y) m. n# C2 }( u8 x9 }! g5 y$ U: @
Dim pd As Boolean% P p4 ?4 g5 a2 A/ S! T) [, R
pd = False
/ k |7 H) g9 ADo
) ^ m. M. u7 y7 ^, ], w; V/ h$ | GetEntityEx ent, pickedPoint, Prompt' W* H; U1 G4 R/ {5 H/ @' q
; V. V+ D n/ V r- B7 `8 Y If ent Is Nothing Then2 `7 H& {6 ]9 b, }+ J: K' W# b4 p
Exit Do
b1 X4 @* ]$ B# Y+ ]) ], \ ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
1 R; B3 P2 h( c; u Exit Do
) X0 ?# W8 Q) t8 k Else
. q3 B1 f8 M. F% s- j, f For i = LBound(gType) To UBound(gType)+ a4 M' F; ?9 A. w% o( X
If UCase(ent.ObjectName) Like UCase(gType(i)) Then
' m' S. C2 @) F: Z) t Exit Do4 `& L; u% ]: p z; z7 G
Else
; s$ p3 u" a, A {- b8 D pd = True/ `# R- V: |5 o7 y
End If
% G0 e0 x* Z, ~ Next i3 J* l4 p! a+ l8 }$ Y# h# c
If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
' T# N7 E" I, Y7 d" H End If" b+ [ H0 d8 q! L8 W6 a
Loop
n- _* Y) K- R; O# \( ?
- t& c9 l& C# ]/ W( v( k" t8 {8 j" ^% XEnd Sub
& D: `- `3 m9 @ i7 m4 K7 F' p/ P: _'计算两点之间距离. l) N2 P- p+ @$ A0 d
Public Function GetDistance(sp As Variant, ep As Variant) As Double' a0 W a8 H N k. r6 H
Dim X As Double4 N6 F# s% k. M$ d* L7 H" w8 H+ O
Dim y As Double7 h# `) s! x; C
Dim z As Double: Y& b1 s. D7 I0 T3 g- V
! `8 p I8 g. \ X = sp(0) - ep(0)
2 ^* s, {1 ~1 v! B1 O/ ] H y = sp(1) - ep(1)
+ u" q$ C" b- D8 Y0 K x z = sp(2) - ep(2)
9 o9 q9 _; n8 J2 \
! `3 g0 i: ]4 U: ^4 h" g" v GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))4 J6 y/ n/ L8 _* Z6 n9 s/ g
End Function
8 j4 _! W1 c; D+ [* h" x'返回两个Double类型变量的最大值
9 f0 R, |3 a# D% A6 g7 e, zPublic Function MaxDouble(ByVal a As Double, ParamArray b()) As Double1 q# c6 [1 H) z* _
MaxDouble = a
) N2 m) M5 _' J' N: f/ V Dim i As Integer
% `" K% j! s0 s For i = LBound(b) To UBound(b)
# C% @' H9 u$ [( E If b(i) > MaxDouble Then MaxDouble = b(i): `' a/ I$ R6 H" @0 k A
Next i; |1 @0 T% a: L
End Function8 Q+ W& |" [. @" q% b" B7 {
Public Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet
9 X& U' ?" ]7 K6 C1 m, I) U9 P% A '返回一个空白选择集# h! A# l$ S/ W+ T; x
4 ^0 e- [ J+ a4 P% y
Dim ss As AcadSelectionSet. b9 ~1 v E2 G' B1 @
# J) X! O4 W% e5 @* s7 r
On Error Resume Next
0 N' [# `& E' S3 w" n Set ss = ThisDrawing.SelectionSets(ssName)1 ]; q! t1 H! S. }" X6 D
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)0 b5 \( ~$ W/ P* B) x1 k
ss.Clear" z0 j3 n. R Y/ ?. m2 a5 i
Set CreateSelectionSet = ss
" X9 V' t+ q5 ?: SEnd Function
# o5 B! H! h) G* |Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes()). l+ P$ l) Z5 X8 a0 j* ^! e
'用数组方式填充一对变量以用作为选择集过滤器使用
# Y \+ X/ V0 G3 }$ f* J7 S Dim fType() As Integer, fData()
/ q, h2 f! ]( c2 h6 w8 R7 Q$ M Dim index As Long, i As Long- z4 F i' p8 Z8 }: ]. E; B. @4 Z
O; k# q$ l! i( y o
index = LBound(gCodes) - 19 G" A! K* ?2 y) D
+ e2 t. G/ P5 f: c
For i = LBound(gCodes) To UBound(gCodes) Step 2
1 ]" M% j8 L% \+ g index = index + 1
b- J9 f% } a7 c, r4 m ReDim Preserve fType(0 To index)
8 {' l3 P8 P$ T7 Z8 `& z ReDim Preserve fData(0 To index), M$ Z$ x- T( u! s; R* R
fType(index) = CInt(gCodes(i))) g9 i( ~( s/ E2 V' w
fData(index) = gCodes(i + 1)
. M6 j2 l7 C% W, Y7 e4 K0 c& J Next
5 k& |. ~/ X4 m+ n) v, w, G typeArray = fType: dataArray = fData
7 k$ \2 I! `! K. A( T' \End Sub
. M2 j4 B5 V# S* f5 a7 q: {4 F( e$ Q0 P1 C# Q2 { r2 {( @& ?
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|