|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
$ K2 G: k# d: Q1 U
6 T" P% A; e+ P, b6 h. _Sub LianX()
8 t& C/ I# [/ V$ C1 Y8 P9 P$ fOn Error GoTo xx, L2 p& @2 g2 p6 _4 O" o
Dim ssetObj As AcadSelectionSet
% t5 Q# Y% q ]+ w& _* d7 I Set ssetObj = CreateSelectionSet("uniteSS"
1 ^8 _& s8 W4 J3 W" y Dim fType, fData
4 q( a5 J* D% L' q- a- i1 V BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"6 d7 g( ]3 J/ p w/ z, H
'屏选直线或多段线
' {; a$ s5 P' n) ^9 F) } ssetObj.SelectOnScreen fType, fData
1 V/ p$ V$ s% _# Y2 \$ Y3 [: f* i Dim i As Integer, n8 L8 z# I2 ~ ?0 W9 j9 w* T
If ssetObj.Count <= 1 Then
0 J1 p4 S8 f0 @ f ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"& [1 I- @1 F5 |( y5 P- ^8 \5 h
Exit Sub( d9 c" ^2 A) F
End If
" P$ O9 [) k5 J& p# v" C' B. d
{- P2 A0 X& f2 ]9 J$ D Dim line1 As Object' u: j5 c4 X1 n4 ~
Dim line2 As Object
6 z' W5 k3 v3 W$ Y! H! | * Q% t j- D' I5 v
Set line1 = ssetObj(0)5 w8 \" _3 `8 N, ]$ M+ N3 e
Dim pd As Boolean
3 |7 f2 S3 E0 N/ `' |7 x) O5 E. C For i = 1 To ssetObj.Count
- Y Q1 n t) L# e Set line2 = ssetObj(i)3 F9 Q- [3 W, B9 H
'连接线
. l5 Q. V4 p! e/ c pd = unite2Line(line1, line2)* Y0 I! f, m; r! s
'如果连接不成功,则退出命令。. A) @: ~7 z f: B3 m6 A
If Not pd Then ssetObj.Delete: Exit Sub
. j$ ]0 t- |: {0 _' M6 G L Next$ @ p, M+ g1 H7 j
xx:
0 O: V1 |, e0 `' f3 S8 T Select Case line1.ObjectName7 y: m5 I: {1 I; l" c$ t# L! U
Case "AcDbLine"0 }, G( l0 h* I
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."$ _' T$ n0 u, c! e7 o# V3 _3 T6 l$ l
Case "AcDbPolyline"! o6 p3 \- Z0 t0 a6 e5 a, v2 ^1 m
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."
1 W# t" M# V- v0 M G `/ B End Select
( X& h, ? h* [* ?0 N! ~- | ssetObj.Delete" h9 C& X7 f& l5 [& l
End Sub
$ t2 ^3 a0 I8 }
u+ s' ]" h' M: U; QSub uniteline()- [! O. O! Q( D
On Error Resume Next
9 h: G: s, y: D '取得线
2 ~2 j; M% V2 R/ W: A Dim line1 As Object& H$ G2 g4 [: v, U$ }. K+ Q4 F- p
Dim line2 As Object& ]4 j# C+ ` a* [1 d# ?: q
Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity% O9 R' l8 ^9 I/ B! ]. G! i" M; S' e
Dim lpt1, lpt2 As Variant0 Y3 M$ g% [9 a
8 f7 P& n: `: [6 O9 n2 W$ J
gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"1 I" e# N* U4 {1 ]* D
If line1 Is Nothing Then
: d0 Z/ d D2 q( m A7 T- e; Y ThisDrawing.Utility.Prompt "用户取消,退出命令。"
5 g" b3 Z' G4 o. A; ? Exit Sub
+ Q' ^) o2 A x4 y$ u End If
" G0 g* B a% y7 s- L0 q+ {$ a 4 Q- f3 @; L {9 C. t, B
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"
3 t& y6 W2 a4 x- k9 [4 \, l0 T If line2 Is Nothing Then4 B e- g% g- T5 f+ ~. Q; ?
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
, |% \% D( v3 U, ^ Exit Sub
|0 N9 T K( n5 a; `7 O9 I End If
! t1 J1 @. l9 |3 ?/ l4 v '连接线
; E: e) M: b# e" u' h6 H unite2Line line1, line28 ]( A7 [* x* r
End Sub
2 L& g( G9 Z" J, P" _1 l- l7 L; ], u
# d. w" Z- w; g/ |" t t+ r$ RFunction unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean) d4 v) z4 l; G! {! D$ o8 F6 ]
'连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false
4 K) |4 U* }4 W' D* Q5 COn Error Resume Next
$ @! v# s* F# Z6 } unite2Line = False
6 z: ?* w6 _' ^$ b * V7 |# ?( j' P$ z* V; W+ ^+ o% c
If line1.Handle = line2.Handle Then% t& M) `8 f% D( a J1 _! ~$ a/ L
ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"% l! u- Q) ~8 Z D
Exit Function
- W; o4 {" W$ i; p; T$ q4 ^/ m End If
3 H" A1 K, |% I- q$ t
7 C E/ F# @0 I getLinePoint line1, pt1, pt25 p4 d% {3 w% `. J" a
getLinePoint line2, pt3, pt4
$ @+ c k( C) F# H; Q- V. @
! t7 i% J) d: M Dim A1, A2, A3 As Double
& v7 P- P, t- s4 b* z1 K Dim maxdi As Double
* h8 D1 g8 j$ S' N6 P A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
: m; z: K r( p% i, u A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)" p0 ?$ @ B/ j
A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
3 w4 J& `9 \! J '判断四点是否共线2 I. }& g7 v* r0 o7 ?5 p" U: j$ J& Q' T
If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then
/ e6 o; j1 P. u" W6 E. ] '取得距离最远的两个点。
$ J! d. O0 Y; W8 N maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _: z: o# J' c% B: F3 @& u
GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4)); e3 _* X- ~. b+ o
If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2
" I$ s7 V. J' {' |' {" J K' J2 f If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt31 C3 j, a, c h: {4 p( y
If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4/ t9 M) E0 L& _2 S: k' a
If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3
1 H/ j4 a' P3 `3 [( b) K If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4+ }, K R3 ^) R9 o
If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4
" |$ L* I* e/ C1 U6 s: K( e '画直线. B7 J4 K5 `+ P' o, q
Select Case line1.ObjectName- t( x, k2 Y" x0 b' M* B5 F0 _
Case "AcDbLine"
8 F+ T$ f7 r) h line1.StartPoint = lpt1
9 z9 R6 C5 U9 E' G line1.EndPoint = lpt2
: b9 x/ l+ I3 |6 b7 w* R line2.Delete5 S7 D: S T8 ]
unite2Line = True
7 B$ t2 [6 i/ {1 O5 U5 H Case "AcDbPolyline"& [8 h& `- I1 x6 d) x; p* b0 }
Dim newPline As AcadLWPolyline6 G, n0 ]& x o$ w% ]
Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)& y9 j. \7 }6 X1 J$ |" I6 q# j0 Y0 \
newPline.Layer = line1.Layer* f' H9 F/ L$ b9 K8 v! e x
newPline.color = line1.color' y7 r5 l, j# m1 ]
newPline.Linetype = line1.Linetype
; z7 _5 T: x, M line1.Delete
' {9 ]/ n1 }$ C! }* ] line2.Delete7 W3 [ O* b) ~9 O3 a6 q
Set line1 = newPline
- ]" q( @- e- t4 Q/ F8 X5 ` unite2Line = True
- ^$ f+ N _$ L, p0 C End Select& u+ ^4 o! L7 [
Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."
7 R: d4 x+ g; M) A) `1 E8 w/ R( S4 i End If
7 }9 a* y `5 t" k# wEnd Function
2 e; ]& i5 U' _0 ?0 `
, ]& T8 j; R' `$ E0 U% ?* L9 O7 X8 K% t8 G, ~2 K; S
) x- J5 ?! W) G; S* T( B8 J0 F0 m'以下是上述代码调用的函数?' @# P( n0 B- E% H: u3 H2 z
8 u, W! D2 Q) ^' |
; X3 I% _+ i( e. V* d'创建轻量多段线(只有两个顶点的直线多段线)& q0 l, G/ l6 X2 H9 D
Public Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline
& k5 W* j- F% V7 n& h Dim objPline As AcadLWPolyline
5 ~8 V+ q* V" E& G Dim ptArr(0 To 3) As Double; l4 ^, N+ ]' f! L% L0 }
# \6 m8 e8 ]& J3 L5 U) B k
ptArr(0) = ptSt(0)
; L7 V* r, G* e9 q8 i& M: Q+ W" {) Q0 n ptArr(1) = ptSt(1)
8 ?, u, |+ d% [4 M ptArr(2) = ptEn(0)
) n1 H( S, p! t0 H- R ptArr(3) = ptEn(1); P4 I, @8 a1 m# G7 z3 l
" X& Z( D( V$ Y1 Q x( M
Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)7 R+ R+ u$ B X8 C; r0 ~, a6 x0 `" b2 A
objPline.ConstantWidth = width
. v6 M' z- W7 I% [0 d/ @! j+ T( u objPline.Update8 j( D1 b1 w0 q+ s
Set AddLWPlineSeg = objPline
/ {3 w* z5 P$ _) }5 AEnd Function
% P; x* n$ e2 `. z m s, uPublic Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)
2 D) S5 E( @5 P6 `0 W1 ? '本函数得到线的端点,其中point1为Y坐标较小的点* `& z+ }, Z- K3 [" K! u* _( u6 J O
Dim p1(2) As Double
! ?1 M# F/ K) } Dim p2(2) As Double% B) V0 C" L P3 V
Dim k As Integer2 I+ X* E. u6 i3 T
On Error Resume Next
- m+ l2 @0 V# ^) Y* Z! C! u Select Case ent.ObjectName
% H+ o) ?# C# \6 V3 M" r Case "AcDbLine"8 G8 n4 W" C( U0 ]+ e+ [ L
Point1 = ent.StartPoint
# O) e9 j0 M b( t Point2 = ent.EndPoint! h; g9 A2 \9 B- r7 N
If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then$ h! L, M; a7 W- ^8 `' G! c f
Point1 = ent.EndPoint$ O6 z# A/ ^" R5 R2 z% t
Point2 = ent.StartPoint
* q1 d# f2 v& x- f3 v End If5 e, L% i; ?; R& L
Case "AcDbPolyline") z% z/ E. l3 W7 m- C
Dim entCo As Variant6 s n% Q/ i7 y8 N
entCo = ent.Coordinates! W* m; z. z5 H- f
k = UBound(entCo)& o: T& w1 h* C& o
If k >= 3 Then' y8 F/ }( z. m- o3 I$ n% h& B
p1(0) = entCo(0): p1(1) = entCo(1)
\: Z' W) J0 z9 p$ @3 l, x p2(0) = entCo(k - 1): p2(1) = entCo(k) R: q5 M7 ~# G7 H% p
If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then
: H5 j; g3 a& p: M' [; Q p2(0) = entCo(0): p2(1) = entCo(1)
: {1 b. n$ ~% m6 A6 H0 G p1(0) = entCo(k - 1): p1(1) = entCo(k)4 L0 C4 ]3 M D) o) L
End If
`5 m3 |7 \# f+ S4 O5 o Point1 = p1: Point2 = p2
+ u8 ^9 l/ M1 N4 S; s End If
3 D' C' V! {+ {& n End Select! N# I6 F' P8 w+ N3 \3 R! m$ Z/ I
End Function
. g4 l! ?& E- ]/ X: O) x& K* gPublic Function PI() As Double
4 w1 x1 b4 d1 ?; I* i2 b2 B PI = Atn(1) * 4
/ e6 G( I: L. X$ { h5 zEnd Function+ f$ B% v% s8 ^) l" H6 e8 q; P# i
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)
! P' @" f. V9 C$ x2 ` '选择实体,直到用户取消操作
$ f4 ^5 T( ?5 t& R On Error Resume Next. q. K; y# h$ e
StartLoop:
& B, X$ M/ c/ D q ~: O, M ThisDrawing.Utility.GetEntity ent, pt, Prompt
' N# b5 E9 g, m% {, p% C& U If Err Then
, ?+ [$ P# P/ [ q- o6 m If ThisDrawing.GetVariable("errno") = 7 Then
3 J% K" c) f4 y& ~7 y, B Err.Clear& d* f& q/ H: G/ W# W0 T$ w
GoTo StartLoop
; B' H N8 o% |7 G9 U$ k6 t; n; A Else' X5 {0 s6 v( _ j5 J3 O/ s" h3 _
Err.Raise vbObjectError + 5, , "用户取消操作"* A4 Y! W% N! s
End If
+ ~. L* f( d/ ~2 \- D6 R End If
% Q4 ^ `" x- k' d: @End Sub
" |+ R! r* h6 r0 B& r- O% }' { }( V7 hPublic Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())
! m) M' `! F1 \1 f5 x2 F% V$ k'选择某一类型的实体,如果选择错误则继续,按ESC退出
+ ]; v! C2 z8 C; C, p: [+ M$ N5 J'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等. b& u4 K) R- ]+ Y0 g9 a
Dim i As Integer
3 R- U2 ?# n. v9 Y, _& A5 I3 S6 @Dim pd As Boolean
8 ^2 H. B' |8 J2 Epd = False7 K5 P( f* S, Z3 i
Do/ S6 _8 ^+ [1 A* @
GetEntityEx ent, pickedPoint, Prompt
) h9 D; i8 P# s4 r5 G * _. |& s6 B4 c& n5 l/ c
If ent Is Nothing Then$ S# w) L. }( g: P
Exit Do
% Z$ u: N8 D" e ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then& v5 N h! |3 K5 I! B
Exit Do6 `$ R5 r* b0 Z$ M( j, A7 V8 T
Else
p$ M! V* e( t9 g S5 f) v, Z For i = LBound(gType) To UBound(gType)! Z J! P( G% s, _* N4 N- N
If UCase(ent.ObjectName) Like UCase(gType(i)) Then
6 U- z% K! p$ r: c) O Exit Do$ O% I3 }& F* G1 U
Else
" X7 U8 Z) |& Y$ y+ c9 d* W pd = True
% Y5 ?; l% B: a; T& o. B; I1 M End If
# o. w" {/ @/ H. i Next i
/ x- c' k% D) L* u' X: j1 k) I; |; h If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
) ^5 }( G( j! Z. f' U5 h End If
& k0 ?$ H& l a0 u( D+ dLoop( Z( ?7 @5 L, g; t; K9 E, A4 Y
2 E. h. K' _. C1 QEnd Sub/ e+ E& e! b4 W- b# A, i, n
'计算两点之间距离
5 W' K. J V- f F- B8 y- R% zPublic Function GetDistance(sp As Variant, ep As Variant) As Double. C3 o) S ?3 {/ w6 a
Dim X As Double
: [. f5 Q! d2 k x: J$ @# S Dim y As Double5 L' F1 G% h9 G
Dim z As Double
5 a, `6 M' Z0 m( z% ^! m . x; {* Q3 [ D6 a
X = sp(0) - ep(0)* @2 J5 ]( r" l6 h
y = sp(1) - ep(1)% {& G/ S: t% n6 l7 s
z = sp(2) - ep(2)
+ I& e% T' ~( ^& ~% e+ ]2 B 2 D" H8 O$ d! s, h: E
GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))
5 @" Z9 b9 F* x' P0 p# B. OEnd Function3 l, N5 H6 J. P1 y
'返回两个Double类型变量的最大值# g( i, ^9 c( [0 s
Public Function MaxDouble(ByVal a As Double, ParamArray b()) As Double" d, e" R; I+ t' F! @: S
MaxDouble = a+ a# D' k9 y! ]$ w' a2 m8 l
Dim i As Integer: x' f( A4 s6 D! S
For i = LBound(b) To UBound(b)
5 e+ Y3 Y: Z9 Z; t8 }, I If b(i) > MaxDouble Then MaxDouble = b(i), b6 S' n" l& f8 k* H
Next i
4 v" s" _- U* n" ~8 UEnd Function
+ ^% ], f& P KPublic Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet3 K1 Q. b; u2 b# B. R# t
'返回一个空白选择集8 q) a7 D4 f u# J9 [1 O* z, d
% q. Y4 ^" |7 V @/ Y1 o Dim ss As AcadSelectionSet% I; @) A# H1 x5 D# L' v+ f5 j. [7 Y- l
: |' m( T( }: i. ? On Error Resume Next% c: O6 @" D+ \$ A3 x- w
Set ss = ThisDrawing.SelectionSets(ssName)
/ h& c: q1 d# B1 H' u4 q If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)
: I7 |7 M3 |4 r ss.Clear
: @8 d, V5 a( u+ a) w9 z* |4 x Set CreateSelectionSet = ss
8 {" ?" a( g' q0 ^" UEnd Function# N3 R1 Q! j5 R: u4 A) h8 f0 g3 G
Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())
" T: g I& r7 C+ p Z9 F3 f3 Y* U- \$ ] '用数组方式填充一对变量以用作为选择集过滤器使用
$ T) N1 }/ X# k- D# z Dim fType() As Integer, fData()
1 M' w: E$ O) x+ N$ c0 B Dim index As Long, i As Long
! q ]+ Y& s+ b3 t4 r+ n' _ ! T5 H4 c! ]( W) c
index = LBound(gCodes) - 1: l' R5 v: R. a5 O6 C3 Y
% G3 w+ S, S g H8 Z For i = LBound(gCodes) To UBound(gCodes) Step 2* z b, j. W- l! r# \/ b
index = index + 1
0 |4 ?$ C% p) t% r ReDim Preserve fType(0 To index)8 H |( d$ g) F: ` T
ReDim Preserve fData(0 To index)( U! h3 \9 c* k' }* H3 u6 B' k/ Z
fType(index) = CInt(gCodes(i))
# y( H6 U2 _" S, _ fData(index) = gCodes(i + 1)7 J0 O. B2 `1 j# r' _; K
Next
" X1 u" h3 Y+ \9 Z ^ typeArray = fType: dataArray = fData9 ~( ]$ j, u; I" a5 ^ B; l7 a
End Sub. R% z2 R& Z2 d7 v L
Z0 M5 K8 B' D5 F4 @. w# _
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|