|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
7 M1 J- [# [# u. L" |& _/ M, q. |9 l9 _; \. H% k0 B
Sub LianX()
0 l U U2 C1 o2 _% a( \8 w eOn Error GoTo xx# A4 d1 F' e' J0 ]
Dim ssetObj As AcadSelectionSet' r8 t, X9 `( u6 w' R
Set ssetObj = CreateSelectionSet("uniteSS"
) B, x! v. V, o3 @# z Dim fType, fData
/ G. b3 V |3 |0 ` Z BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
/ w, u6 R" ]8 c: T+ ?9 W0 s' o '屏选直线或多段线
# r0 I! x. Q* [& @ Y4 d9 ~ ssetObj.SelectOnScreen fType, fData, |, ~. [) Q8 ?& s( A, j
Dim i As Integer
- `9 G) d1 i- Y+ T, h2 x If ssetObj.Count <= 1 Then: Y; Y8 X! [. X# d6 Z
ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"
* @% F- |0 F0 _ A% |+ ?7 @2 X Exit Sub
! q2 L+ X# G, p5 B1 c" o End If
' l8 c2 R: \' U- r
8 Y* w+ R2 F+ D" X6 a4 x Dim line1 As Object
$ h! E# h/ n% Z4 v6 X; S6 x3 N Dim line2 As Object* U" X( |3 t) l+ d( H( h
' C) N( s1 }6 z4 Y4 l
Set line1 = ssetObj(0)4 B8 \6 W7 u* N. \: E3 W
Dim pd As Boolean
) y, m& W# h9 z1 `! \$ K For i = 1 To ssetObj.Count
8 n# G; R v" ~ Set line2 = ssetObj(i)5 O' r; r# M7 m
'连接线
* b* q6 n" Z( i9 M5 V pd = unite2Line(line1, line2)
# H; ?: `4 X- I) C/ X b7 [9 w+ t+ U '如果连接不成功,则退出命令。
, F* I3 U; {/ |8 g+ y+ v. r If Not pd Then ssetObj.Delete: Exit Sub
( N- b7 J2 [8 c8 D3 c# X" _ Next
' U' Q R* X. s3 G1 Exx:
1 h( @( a3 D+ n Select Case line1.ObjectName6 S: M/ ~: X7 f5 y
Case "AcDbLine"+ I9 s4 r# B$ o2 ]& t, R" m1 i" _
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."# ~" e9 B! Y, u% g5 E- ]
Case "AcDbPolyline"! a7 j0 v% b) W) U
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."! c# v% V" t/ {1 D0 z7 z/ Q) [
End Select3 _" v1 N/ l2 H" R) ]- E. o
ssetObj.Delete+ s# n4 M3 N3 ^# K; s9 O3 i9 ^5 _; q8 s4 i
End Sub, l' W' D4 I! w$ T8 b2 x
, g0 T( @0 L$ [# L7 U+ X& C
Sub uniteline()9 Y! f) Q. R3 U! ~
On Error Resume Next
( H: @3 R: R( ^, ~4 [- H, i* C '取得线
# S" X4 l9 X2 @; Q* m2 {2 t Dim line1 As Object1 `# E3 y" C. ~3 E* ^
Dim line2 As Object# [, \2 v9 d$ m( k% f, S5 O
Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity& e. A. ]9 p% o3 [8 a
Dim lpt1, lpt2 As Variant, S0 D& h/ {0 ]0 y# ~' t
6 g! y+ W! ^8 V+ Y4 I/ O
gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"
. G+ p/ h6 [# W- w+ ~ If line1 Is Nothing Then
5 w% {' `! B5 w7 m! r: a1 w0 c ThisDrawing.Utility.Prompt "用户取消,退出命令。"
2 f# a+ Q6 ]) j( R) m* o Exit Sub
' y. p4 Y. C' e3 n$ o End If9 l* c( P! l' O$ J7 \$ s
# U3 w& { g) s0 \9 M9 M6 l
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"1 P- C: E5 d! e5 R- Y" p" V3 x
If line2 Is Nothing Then& R. j8 e, h" L$ G5 L8 z
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
/ P1 L( Y0 k8 K2 c1 O- e Exit Sub7 q6 F% P" r k
End If' r7 a3 D/ |8 S" X: d
'连接线
& q) s# a6 Z! j+ c unite2Line line1, line2
2 U% D0 X% W3 R& m j w. XEnd Sub+ \) i$ ?( A$ u( f# ]4 G" K
( ] X( {2 m7 z; ^3 g- D
, }1 `" o9 [, R
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean/ O4 B7 [3 c. ^' r
'连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false
8 C9 h8 u+ u/ p6 E* ^) ZOn Error Resume Next
+ }9 {, m+ l. s unite2Line = False! ~/ E8 Q% N; C+ `% @2 P" u0 I
7 ]9 q, E5 N! S) |
If line1.Handle = line2.Handle Then
4 B4 B' }5 s/ m& K- m9 u) |# g ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"& N# a( j; P9 {% t. v
Exit Function
( h9 b# N+ f6 `7 T- X$ a9 B3 O+ S End If
1 V2 n- P/ l* Q, ?! v+ D$ e* u ' o# f$ ?% B- [' R: ]/ y! k
getLinePoint line1, pt1, pt22 X9 P1 J; o& z& Z) i" E
getLinePoint line2, pt3, pt4" t+ ^2 T! j: y! Y. t
- y+ J5 G+ u; b6 u3 M Dim A1, A2, A3 As Double; f6 x1 P, n# p$ L6 Q: t8 @
Dim maxdi As Double0 h+ s$ C, B! i# A
A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
0 F; y1 i" A& p6 l8 ] A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
3 O2 u: q! \& y0 c1 s: Q A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)8 M- i/ s9 E& N6 w; \
'判断四点是否共线
/ k- {3 j% \- n' g; p f If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then- J! W7 k0 u9 C7 J& ]
'取得距离最远的两个点。
1 x6 d* ~9 p J) i3 E0 Y maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _( [' v0 f* a% q7 j
GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))
( a' y$ m* I% A( x If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2; w W6 R% a5 J8 i; D
If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3
; O) f( N" e: o1 o% K' C5 a If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4" w6 x; s1 P9 V5 |6 i! Z
If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3% C5 Z$ A0 B. r; r6 g, H5 z5 @
If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4% Y. p& K* J) L9 `/ v1 ?- b
If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4' r1 L0 D: D+ p# D* R8 R( r
'画直线
& O* ~. ~8 G* g8 |' S$ S) t% P Select Case line1.ObjectName- ]% X* {+ o7 B ^( U: h
Case "AcDbLine"4 Y. F+ J# J$ w7 r! q7 m, H5 s" l
line1.StartPoint = lpt1
$ R2 h+ f5 ~, x9 e5 x, R' ] line1.EndPoint = lpt2% P( B7 R* s& B# c# y; b7 @% U
line2.Delete
& Y5 y" p# t5 R& N' Q( N unite2Line = True- W7 y8 w8 x" _0 A! @
Case "AcDbPolyline"
/ E6 D' e Q' n6 P1 w Dim newPline As AcadLWPolyline: l8 y$ [+ A: u3 B" X
Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)" L5 t' d& q. v: f! A/ z4 [
newPline.Layer = line1.Layer1 [. M3 k) Z( h" }' j8 q
newPline.color = line1.color2 b {% P/ e- e6 g/ U% F! r
newPline.Linetype = line1.Linetype5 P9 |7 l4 g4 l: R' e
line1.Delete
8 Y! V' S: K4 k8 ]5 z1 R) ? line2.Delete
+ `8 @1 H" I* ^: N: K/ Y Set line1 = newPline
* Q2 J" {. Y' h( d unite2Line = True4 |: V8 l* [" k# @1 C; D
End Select" P2 C l/ I5 c8 G$ q) m. u' Y
Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."
$ G9 i, Z/ ]0 ~4 [! Q End If8 V i K! W" y" [
End Function$ p) x/ a; v5 A6 C( @ t
1 r1 [) P( x! a5 I& A
: |! v( B- p) e$ E3 }* o$ V1 U: j$ L. ]" w q" k
'以下是上述代码调用的函数?
! p. P' y0 p3 E& e M/ E0 z q6 f# C! F* ]
: B- Q1 r% M( ]
'创建轻量多段线(只有两个顶点的直线多段线)) N6 U0 t0 I- W7 p9 m* {
Public Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline2 x" E: Y$ i4 A" b
Dim objPline As AcadLWPolyline
3 U" _ h7 @2 [/ R y/ p Dim ptArr(0 To 3) As Double
) x+ f% n% t: W7 ]/ u- X 0 x1 W4 D. D: O0 v% |
ptArr(0) = ptSt(0)
: `8 ~6 Z1 W3 O4 X1 i ptArr(1) = ptSt(1): ~' }2 U6 l7 N: B5 T6 ~
ptArr(2) = ptEn(0)2 \0 r1 A7 h( S! ]1 x; @
ptArr(3) = ptEn(1)
/ P3 R+ D( a' {; ~ $ D, B5 \; q5 @1 m. M" J2 H
Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)
3 p2 D7 N7 [- u objPline.ConstantWidth = width
7 o7 G$ R( y9 p3 E* {' V objPline.Update2 H5 W- k2 z1 F9 n# i0 _: K& Y8 v
Set AddLWPlineSeg = objPline
% O6 i* B/ J: }0 v" REnd Function
6 ]* `9 O; \/ HPublic Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)2 y5 g! i+ c. r! [3 }. a: R/ y
'本函数得到线的端点,其中point1为Y坐标较小的点0 g+ k8 P" {: L0 \
Dim p1(2) As Double
' @! b+ D6 h9 o9 H3 `! n Dim p2(2) As Double
, Q9 P" _0 ^- ?4 V. G Dim k As Integer$ B( f' W1 `, Q1 G2 e; H5 g: E, G
On Error Resume Next
" X* F# \- Q0 i Select Case ent.ObjectName
( g% J/ t) a4 q Case "AcDbLine"
3 a' s. X) D1 h. |% R/ ]: H0 u' K Point1 = ent.StartPoint
$ R( C8 t$ g5 |/ r1 M: e! ? Point2 = ent.EndPoint
9 f! C' K7 {6 @! |3 z$ M5 @ If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then
0 r8 w. T7 i8 _, d7 C, _! i Point1 = ent.EndPoint
& O: Q! r: E: S' H9 l+ E* | Point2 = ent.StartPoint$ u5 N& b! }1 O' N' e6 `/ r& T3 M
End If2 `9 a# K; P' y T$ p
Case "AcDbPolyline"
1 ~2 g" ?% S8 Y! f: ^ Dim entCo As Variant6 p1 t% g7 \1 R( c! R" }- ]
entCo = ent.Coordinates$ O8 b3 v) Q$ O" y
k = UBound(entCo)- I- i( L2 k, L! ^; J
If k >= 3 Then5 Y, d; @9 i# s8 p9 S: M
p1(0) = entCo(0): p1(1) = entCo(1)* C, Z7 b3 |, g8 I3 G
p2(0) = entCo(k - 1): p2(1) = entCo(k)
: X A' N$ n K" j If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then
7 N% F4 m- |- C p5 I r# W4 [ p2(0) = entCo(0): p2(1) = entCo(1)
3 K' i8 L$ I% T p1(0) = entCo(k - 1): p1(1) = entCo(k)
. M) y* p9 i& }, @7 r0 ^+ T9 P% F: E$ E End If5 ^/ c6 t# }% G- b+ ?$ d
Point1 = p1: Point2 = p2) |' ?$ I( c& L' D
End If! C/ f/ T! E7 t! F
End Select
8 X. {5 J# \3 c) p/ a3 P eEnd Function' r" \+ v: u9 y7 O
Public Function PI() As Double
9 G) y$ P$ e$ ?4 j* a Z PI = Atn(1) * 4* r8 w8 l x! Q) D
End Function) i; ^) x$ U+ Z- ~7 t
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
$ ]) K+ J8 w; H '选择实体,直到用户取消操作( U n- Q5 j+ a+ L
On Error Resume Next' W, ]% ?% c; M& o5 f6 O' c
StartLoop:6 N( m5 j# E; V- x9 p" R' }+ Q
ThisDrawing.Utility.GetEntity ent, pt, Prompt# ~' D, M( c, I/ p
If Err Then, r f: T- y2 H# c, I( i
If ThisDrawing.GetVariable("errno") = 7 Then: e8 |7 K F7 t# H6 C$ S
Err.Clear
+ z7 e8 t. y1 H/ c+ o GoTo StartLoop: ]; F N6 z) _# @+ O
Else
7 f7 G* e' u1 Q& ?. _1 w, W Err.Raise vbObjectError + 5, , "用户取消操作"
' L% o: w7 x G) } End If3 _: }" |" Z1 U# U2 \4 O# D
End If$ E* P" @- l# i% ^
End Sub
0 H6 P" ]" p) ePublic Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())
/ Q. q; G. C/ R* v3 }- q'选择某一类型的实体,如果选择错误则继续,按ESC退出9 d* M# a7 @" z9 {6 u
'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等
" L& F! \# n9 p/ T$ |Dim i As Integer
7 X1 |. w+ P+ ^$ j4 g0 G: C7 g# EDim pd As Boolean! A1 f/ ] ?/ i
pd = False
, A! k6 u7 Q( r6 \Do7 F' D) V$ N, A4 r1 _; E
GetEntityEx ent, pickedPoint, Prompt
( O+ X6 M6 X- h; g 2 S. [$ @6 }4 R
If ent Is Nothing Then
3 }$ R( Q" @ l ^' {) ~" S Exit Do
. |0 u" {( R- y& g/ S8 u) v( M5 G2 T ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
( m7 s' N4 w- B+ K" m/ b Exit Do
9 s+ M" K3 [2 D. F# E Else; j! E$ \, l8 q6 `
For i = LBound(gType) To UBound(gType)' ?; i2 v8 `1 q7 ?. O
If UCase(ent.ObjectName) Like UCase(gType(i)) Then
, p: b0 l5 j6 V; @0 o& \ Exit Do
& \, C7 R, D! p1 Z& J Else7 m3 V* n" G% U9 V6 ?
pd = True
- m% m- D. }& w b2 K8 j2 o End If9 o0 n) L4 N- V5 ^& N: Y7 I
Next i
/ I" E* J. s( D3 T! t% { If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
) S& K' j) U$ J End If! g& T( D; `, }' ^# m' Y
Loop$ L* g0 ^& N& D
& E! c% s& q) Y( q, q+ e. nEnd Sub
% @' y/ G- ?: c8 x0 p'计算两点之间距离# B, ^$ D- s- S$ i( Y
Public Function GetDistance(sp As Variant, ep As Variant) As Double
1 Q; G2 B4 J$ h Dim X As Double
: d2 {7 |: o4 W& u Dim y As Double
2 u) g6 ~( J. _9 j: G Dim z As Double; @6 p) H# c R/ D" S: k
R3 O5 i5 N9 K% A5 l& X X = sp(0) - ep(0)
8 P9 v3 ]' n, f7 A" U y = sp(1) - ep(1)
, E, ] W3 j3 h" `5 S7 M' B z = sp(2) - ep(2)' A2 \# i6 g6 ]8 Y
$ N3 h! n) D& Z+ C1 G( l+ b GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))
0 ~8 T d; X: `3 [" }' X5 v, X: [End Function
4 n' l0 E9 Q& W+ l3 {! Y/ B'返回两个Double类型变量的最大值
5 b6 ]8 }! V2 E& y% C# BPublic Function MaxDouble(ByVal a As Double, ParamArray b()) As Double
* h& r2 P" P2 l/ g! D0 U MaxDouble = a0 \( @; |/ l: ]: x) C5 G
Dim i As Integer
9 s0 X! m% R6 \# W! ~ For i = LBound(b) To UBound(b)" P3 m) w! ?. S$ A9 ` ~
If b(i) > MaxDouble Then MaxDouble = b(i)
- ?* {; L Y# F2 y" K7 X Next i; @( c) @7 B! ~9 ~/ Z( k; q( M
End Function
7 I1 I, E% W( e$ T! ~) SPublic Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet8 R4 `% Z1 [# Q( _3 Y
'返回一个空白选择集
$ q" H+ r9 D+ T+ M/ _: a5 M1 j7 J
6 a3 {% A# [( L* L" J i( D( C Dim ss As AcadSelectionSet# D+ f7 C) f$ G/ X" ?( q0 _9 Z
0 V8 o6 l# W& ~0 x: s$ ]& o% |4 T) S
On Error Resume Next- F) J4 M3 T5 V& I: T% t- X
Set ss = ThisDrawing.SelectionSets(ssName)& R: k* d$ h! x& @
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)
/ ]# P4 @$ y8 J2 F5 w ss.Clear
# G( L$ a0 S* Z6 Q/ h. B Set CreateSelectionSet = ss
1 U1 T6 B( e8 L2 b( e( TEnd Function# b. I4 j8 ] j1 O5 \ [
Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())% [- f6 R- i9 ?! H9 f6 n
'用数组方式填充一对变量以用作为选择集过滤器使用
2 T/ m4 {" H0 ?4 D. @" x Dim fType() As Integer, fData()0 e& J- Z2 _5 j" O- ?
Dim index As Long, i As Long% B/ I8 B$ m, F: B+ l8 w6 @+ ?
- {' e, I$ B( h! h/ O4 ?
index = LBound(gCodes) - 1/ \6 m- U! i: L! T% X# _; O+ [' L: p
6 X5 [& D. x- t. d# Z% P7 C For i = LBound(gCodes) To UBound(gCodes) Step 2
. X5 X0 w+ j3 _4 \! t# G5 N index = index + 1& o6 b( w4 s8 [6 W0 Y5 y
ReDim Preserve fType(0 To index)
+ y- ^2 l/ n, R5 V1 o- F/ y ReDim Preserve fData(0 To index)9 R: L* Z7 m s% w, W
fType(index) = CInt(gCodes(i))2 _ ?9 t, A, f! h! x% n8 o
fData(index) = gCodes(i + 1)
" C* n3 K' ~* b Next
! I6 ?" B: w# B! e& w: p typeArray = fType: dataArray = fData2 t5 S* k+ h) L3 E* {7 E
End Sub
# b4 K2 U: [% z, W' [/ f. q# A
7 ^0 g. [& R. u0 z[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|