|
|
发表于 2008-7-29 18:02:40
|
显示全部楼层
来自: 中国江苏镇江
VBA的我不忽悠人!
9 m6 T* m: n) d# i7 ^- s6 X9 \) g6 ]. e
Sub LianX()
5 R9 R4 K1 p1 c POn Error GoTo xx/ `; ~& n( t( C$ c
Dim ssetObj As AcadSelectionSet
* ], N& g% p* e/ f0 `( c Set ssetObj = CreateSelectionSet("uniteSS" - E. j' v0 F, g2 q5 j2 g4 O0 t
Dim fType, fData
/ l* u# q2 J5 F( q% p BuildFilter fType, fData, -4, "<or", 0, "line", 0, "LWPolyline", -4, "or>"
7 x, s2 ^ ?" G" Z* w '屏选直线或多段线
4 _- q, o) o5 j% H+ |! P ssetObj.SelectOnScreen fType, fData: h; u$ S3 O# [1 q3 x' s
Dim i As Integer. v# t# G0 ~7 t7 e( y/ N; ?+ x
If ssetObj.Count <= 1 Then, ?3 p. \' n7 v# z
ThisDrawing.Utility.Prompt "选择的线少于两个,退出命令。"4 S" a+ D6 p! A( `. m. L
Exit Sub4 Q1 F8 N% }, b6 A+ _ E
End If2 H8 l1 M S% {3 n, `* B
/ t7 e4 `- m" ^1 R% a$ t: W Dim line1 As Object
f' M* k' z+ c, J Dim line2 As Object# a9 s6 `% { v3 J P; P
. ?! u A) s2 F8 X: e7 t Set line1 = ssetObj(0)+ _, w# f( o9 p* P# ^
Dim pd As Boolean
% ^$ C# k' `. s ^* V For i = 1 To ssetObj.Count. H3 R* X1 s0 o( _9 T! U" l
Set line2 = ssetObj(i)
# L) D1 Y, K: B R+ { '连接线
1 U9 C" K. q" r: P; ? pd = unite2Line(line1, line2)4 I# T' S$ i* V& v7 F( `6 Y
'如果连接不成功,则退出命令。7 e2 g& t/ y' V; j6 d" P3 ?8 ~: ^
If Not pd Then ssetObj.Delete: Exit Sub
( u7 e! i5 L3 ]( }( F0 r' R9 n Next0 V" Z% {4 @% D/ k# M1 {% m
xx:, z q+ ~: |. R
Select Case line1.ObjectName
! j: _( _/ h3 g- G) o& E9 N: n Case "AcDbLine"
0 [, ]7 t' }* E8 V ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为直线."$ U# _& Z4 e0 G" a: _. n
Case "AcDbPolyline"# r/ V& S2 h5 V7 C
ThisDrawing.Utility.Prompt ssetObj.Count & "条线段已连接为多段线."
: J) ]6 _% v7 Z& p End Select( @& @( r- V" j4 @
ssetObj.Delete2 C# O' ]7 R* ^8 _# M
End Sub
' S5 W- ^+ F; z
3 `. W$ U; z9 n! b1 y/ LSub uniteline()
9 @9 ]$ S9 s6 R3 m On Error Resume Next. @% r0 R; j$ _2 H) X* ^$ `$ ^5 ^
'取得线
4 Z" D; r) b2 J R; k9 Y( W Dim line1 As Object' M s9 Z# l8 `
Dim line2 As Object
+ G- [- ^! z9 P( x0 z Dim pt1, pt2, pt3, pt4, basePnt As AcadEntity
7 ^5 M. ]7 H9 l# d" l* f& a Dim lpt1, lpt2 As Variant9 p8 q* U0 a6 K9 z8 o( }% \
7 L9 @* I' z, P E. P, ^$ P gwGetEntity line1, basePnt, "请选择第一根直线或多段线:", "AcDbLine", "AcDbPolyline"
( t3 d5 D! ]6 N7 K* ^# ] If line1 Is Nothing Then) E8 w4 k& K+ V3 a
ThisDrawing.Utility.Prompt "用户取消,退出命令。"
8 O% c+ M! n$ U* a" y; Z$ E Exit Sub
) y3 W9 B; Q9 F& z5 g# z$ _+ z End If# r1 `. \! f1 ^0 O( T- N
3 n( P/ A8 d6 S4 x5 d* \
gwGetEntity line2, basePnt, "请选择第二根直线或多段线:", "AcDbLine", "AcDbPolyline"
+ n% }( ?) u4 u3 ~ If line2 Is Nothing Then+ U/ w$ C) O1 m: C0 f) G* ], B# `
ThisDrawing.Utility.Prompt "用户取消,退出命令。"# s6 m# X8 Q7 `% V# C! p" G; u
Exit Sub. \% ?0 {, G4 C
End If4 q% m4 }/ P" Y7 M: F/ ~+ T" y' O
'连接线
1 ~ b8 L6 i! H \2 K! _ unite2Line line1, line2
) x) f$ J( N; I6 hEnd Sub' @* ~9 a/ } r1 F: }; v$ o
/ g" D, c0 N( g3 A; v: a' J9 ~/ i' d3 R9 J! u1 g
Function unite2Line(ByRef line1 As Object, ByVal line2 As Object) As Boolean
; L2 ^1 a) n$ @$ ? '连接线函数,连接后的线返回到变量line1中,如果连接成功,unite2Line返回true,否则为false
9 P$ o3 _0 T" C' x& k% POn Error Resume Next: @5 Z; d, ?- f' e O3 O
unite2Line = False
- B. o/ c" Y8 W
; R7 G: T" g* o( [. f" s! L% @ If line1.Handle = line2.Handle Then
/ U: j: s! y% G8 [9 i- |9 x ThisDrawing.Utility.Prompt "选择的是同一直线或多段线,退出命令。"4 g' ~' n' ]- I% \7 B( Q
Exit Function
6 J0 ?. \2 K) y* C7 T" A End If
. L& Y6 e/ D7 J( G. D % U5 `" p' Z K/ f
getLinePoint line1, pt1, pt2
4 D T$ W) f/ p2 Y getLinePoint line2, pt3, pt4
4 M3 ~2 u1 H* X( V2 A! @
( y. ?. A( s5 R6 r, S+ h Dim A1, A2, A3 As Double
, w; j% J( }5 x$ \' k Dim maxdi As Double
( F5 O, z% b* P( L A1 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
4 v: \2 x6 |' C5 V8 ~ A2 = ThisDrawing.Utility.AngleFromXAxis(pt3, pt4)
5 @* n9 V0 \9 n# }& `0 q A3 = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
4 I) ^1 H: V b# \4 v7 ?; {" f '判断四点是否共线
! Y& K: F! N7 {" W. P If Abs(A1 - A2) < 0.0000001 And (Abs(A1 - A3) < 0.0000001 Or Abs(Abs(A1 - A3) - PI) < 0.0000001) Then: n. t! ]* n/ b" W0 F: g
'取得距离最远的两个点。
5 x) P" ^( Y; U2 B* t7 y maxdi = MaxDouble(GetDistance(pt1, pt2), GetDistance(pt1, pt3), GetDistance(pt1, pt4), _5 c3 H, C, V# p3 c8 Q
GetDistance(pt2, pt3), GetDistance(pt2, pt4), GetDistance(pt3, pt4))
) ~: h' D9 C. O) B5 ? If GetDistance(pt1, pt2) = maxdi Then lpt1 = pt1: lpt2 = pt2
. \/ f' j, [7 P" R5 S l2 B, S If GetDistance(pt1, pt3) = maxdi Then lpt1 = pt1: lpt2 = pt3
" I e& L( T+ } If GetDistance(pt1, pt4) = maxdi Then lpt1 = pt1: lpt2 = pt4
( K6 e U: _5 K. n If GetDistance(pt2, pt3) = maxdi Then lpt1 = pt2: lpt2 = pt3
9 s7 g& z: ^ q! l6 m/ E6 @, b If GetDistance(pt2, pt4) = maxdi Then lpt1 = pt2: lpt2 = pt4* n, O3 c3 |$ c/ A' i: U) |
If GetDistance(pt3, pt4) = maxdi Then lpt1 = pt3: lpt2 = pt4
$ n. v3 a( [6 g6 \7 A '画直线& F( ?3 W" L7 `* b9 u
Select Case line1.ObjectName! c n6 A0 l' z; g& H! `
Case "AcDbLine"
+ J( \# I/ s- F) V3 r line1.StartPoint = lpt1
3 {5 R! {5 E9 k( `0 y3 O line1.EndPoint = lpt27 m* O6 y- v- G' |. u" W
line2.Delete
- p( r: c+ `2 g4 o9 k. `# I% ^4 b unite2Line = True! t- f- K5 K( w
Case "AcDbPolyline" f, E u# n- n
Dim newPline As AcadLWPolyline$ u, A7 C& V0 E* k/ J2 ]1 X
Set newPline = AddLWPlineSeg(lpt1, lpt2, line1.ConstantWidth)
) l- j, r3 j% e. @9 ` newPline.Layer = line1.Layer
4 I2 Y! V5 _% e1 @2 `* f* M7 y newPline.color = line1.color
7 Z3 h" u6 c W' _* I newPline.Linetype = line1.Linetype
- p& n, c% e2 U! s# u( w- G) t line1.Delete
! s5 ]+ ^$ F6 Y* x0 p2 m2 V8 S line2.Delete* g, @0 D, n) s$ a, y1 P0 g1 j" |
Set line1 = newPline, s4 _4 ]/ j j+ n7 `2 O- q
unite2Line = True
8 a: ~( z1 E7 q8 U End Select
1 m! ^3 L; B, } Else: ThisDrawing.Utility.Prompt "两线不在同一直线上,退出命令."
/ a6 K5 n( v l% k End If
" d+ m# C) S4 G# k+ b0 k+ oEnd Function& Q8 T/ R0 u& b9 z5 d! |; s3 r- A
" I1 m9 B' W3 y+ m7 ]
: K. f- `+ O& D5 R ^% y" R) V5 F5 h/ R# ], \0 _' Y0 W3 i
'以下是上述代码调用的函数?
4 X+ v$ D1 H6 ~- I
4 {/ o# @ _2 R% h9 x( Z# _: Q/ B. u
6 Q2 X) }7 d" f'创建轻量多段线(只有两个顶点的直线多段线)7 W. o% d$ M5 ]0 f& L) N# z8 t
Public Function AddLWPlineSeg(ByVal ptSt As Variant, ByVal ptEn As Variant, Optional ByVal width As Double = 0) As AcadLWPolyline
1 R5 O' o' g+ A" P- y9 {9 @1 n, ?8 _ Dim objPline As AcadLWPolyline
. W: X1 o I. p) p3 S' F Dim ptArr(0 To 3) As Double
( p& c- w4 v# K8 j5 c& T3 }: f
2 t* }: [; y/ D. P ptArr(0) = ptSt(0)6 s5 X9 \9 C! ~- q& V
ptArr(1) = ptSt(1)
& |: A! y' a; \: N6 W ptArr(2) = ptEn(0)
, v a& q& a& ^. N7 u$ o ptArr(3) = ptEn(1)
: j, C7 U0 p9 k9 S& o/ T
2 q; F) }# G% ?' N: {* }1 D+ y# r Set objPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptArr)' u w) t7 k- O* ]: O/ \5 H3 _/ E
objPline.ConstantWidth = width
$ F$ @' `1 p% h/ j objPline.Update
! [) d$ B$ u# X Set AddLWPlineSeg = objPline6 @" |. ]1 ]1 f; D6 ~, t4 @
End Function0 V' Y0 I8 ~6 N6 f5 ~
Public Function getLinePoint(ent As AcadEntity, ByRef Point1 As Variant, ByRef Point2 As Variant)
% i: ^7 H" g- a! s$ \ '本函数得到线的端点,其中point1为Y坐标较小的点
9 @7 }8 f1 L4 `7 M% ]0 V Dim p1(2) As Double
2 G* g8 a# v' f- g0 d Dim p2(2) As Double: Q: W0 f0 Q! ]! ^# R, d
Dim k As Integer
( x" q! X( Z5 A. [3 d6 X On Error Resume Next
0 B5 ?6 @2 p/ q. L Select Case ent.ObjectName$ n# ~1 J. t8 O0 G: ?" n# Q% O D3 l
Case "AcDbLine"+ v7 K$ Q2 o7 W# s2 F# j
Point1 = ent.StartPoint7 Y z0 o8 z" h% P6 o- r8 I+ t; d
Point2 = ent.EndPoint
* V [ C/ o4 n If ThisDrawing.Utility.AngleFromXAxis(Point1, Point2) >= PI Then
. p4 j& j I( a5 L+ K0 x Point1 = ent.EndPoint* G& U$ Y& @6 U ?) _
Point2 = ent.StartPoint
3 ~3 p# j" c7 q5 ^2 z End If
2 H: @- F) @& D4 G; u2 G Case "AcDbPolyline". l! N* h! d, l" u
Dim entCo As Variant! B1 D# {2 b& n, R% P" p
entCo = ent.Coordinates2 f' ^! f1 Y w. H! A4 B$ d
k = UBound(entCo)6 j0 ?: _0 h( }& W) D, k8 Q
If k >= 3 Then$ G; b7 z3 ?) I+ z2 Q
p1(0) = entCo(0): p1(1) = entCo(1)" `3 V7 ]0 Z4 a4 ~
p2(0) = entCo(k - 1): p2(1) = entCo(k)
" v8 H8 Z$ x+ G6 ^3 I e( e" ^ If ThisDrawing.Utility.AngleFromXAxis(p1, p2) >= PI Then$ ?8 T6 ]+ B2 a
p2(0) = entCo(0): p2(1) = entCo(1)$ H0 @- X2 v8 w% E% ]
p1(0) = entCo(k - 1): p1(1) = entCo(k)
+ h, l" G/ C6 K: e/ B6 O! N4 \ End If
+ n7 c2 h( Y. J" W3 k d. E# j Point1 = p1: Point2 = p2, D: ?+ V# O( T9 ]4 G4 |5 e# K
End If5 |$ ]! r4 d5 Y
End Select
% _% F' z+ k: P) L' c& O! C: k, F6 AEnd Function
9 r$ d3 m8 G9 Z; G- g0 t6 Y2 [Public Function PI() As Double( I( J1 @& u: K3 `4 F# ?* v$ F) B
PI = Atn(1) * 4
# K0 w/ v0 J, V6 p. {& a4 t' ~8 cEnd Function/ g& f6 u6 {* \( `
Public Sub GetEntityEx(ent As Object, pickedPoint, Optional Prompt)0 C& p2 b5 w" a1 V# H5 e
'选择实体,直到用户取消操作
/ ~! r C3 @" w7 s; t On Error Resume Next
! p- |: j+ ^* `8 [StartLoop:2 E% e* f( F1 ^ l
ThisDrawing.Utility.GetEntity ent, pt, Prompt
; w5 b9 U2 y. W+ _ J6 U If Err Then
2 ^3 I' t% z; v If ThisDrawing.GetVariable("errno") = 7 Then
6 b' t) r' D: y" b/ ~ Err.Clear
& O3 i ~; c. x: X3 L! c GoTo StartLoop) H1 k( R1 u: \' J- H% h, I8 q! Q. ?
Else: `) y6 w, K( Q: x) @! |! ?
Err.Raise vbObjectError + 5, , "用户取消操作"
& V# }+ h @% ^+ |" d4 ?) X2 B End If/ n) u+ x% c5 ]
End If& w: G( ?& R( f, v7 X- c/ N; K
End Sub
! v, {3 }8 K, h2 v1 }Public Sub gwGetEntity(ent As Object, pickedPoint, Prompt As String, ParamArray gType())
: q7 o2 \7 r* J" A1 @; J0 A( U2 N'选择某一类型的实体,如果选择错误则继续,按ESC退出
& s: m' U) g, N* v9 S'gtype是实体名称,不区分大小写,可以用通配符号,如"AcDbBlockReference","acdb*text"等- z, F2 ^! n/ F3 j4 v
Dim i As Integer
6 ] R5 `8 b/ L1 {Dim pd As Boolean
$ R4 E. d! I; T5 U' A* }pd = False8 s0 i4 b' [$ b" h" N! M5 P6 K
Do
! _( f6 \# b* S6 N W GetEntityEx ent, pickedPoint, Prompt
3 \9 b, Z- i) F' n8 S& v" T/ b , _: m/ e% c/ h
If ent Is Nothing Then0 ]$ ?. P& c# m3 V4 A
Exit Do& g) `8 B! x3 Z, G* \: e
ElseIf UBound(gType) - LBound(gType) + 1 = 0 Then
( a' W* @5 [: T/ [9 r4 X3 U# M Exit Do0 d9 R& j7 ]4 H& }3 _9 m' S! V
Else# V; ~ y6 H" `. p
For i = LBound(gType) To UBound(gType)3 v- M7 w7 ?& N+ d# e$ }
If UCase(ent.ObjectName) Like UCase(gType(i)) Then" {" [: ]* F$ ^4 {$ F
Exit Do
9 @) J% |8 E; X. j Else: L4 o0 h6 D5 \) T* E/ D6 R
pd = True
7 A4 W2 d8 }& a9 ?" u End If
" J: T V6 R7 t- u- \ Next i
/ z1 v4 G& [+ N8 T& O. a2 }$ C If pd Then ThisDrawing.Utility.Prompt "选择的实体不符合要求."
% Y' T& |9 _/ R4 W1 B1 l# F. Q. B- t/ ~ End If
5 Y! V1 n/ z& u% K0 @7 Q, J1 A- _Loop
" V1 ]* v0 ]- Q2 O" D" i8 R( h" C5 B
# @+ j- {5 h$ @; _End Sub2 ?) K6 L/ A: x1 n" U! G& c
'计算两点之间距离6 R) k& z7 r) @- l
Public Function GetDistance(sp As Variant, ep As Variant) As Double
4 Z& z6 |# V% A Dim X As Double
' ^' d+ R! w% X ` Dim y As Double! w! E7 E6 g& [2 p9 C% t! q+ e
Dim z As Double
( E; o: \1 X* N& I' D
% @! Z- m) Q* I. ]% Q' b1 m: ? X = sp(0) - ep(0)
3 f, H3 \; l! \( T& m& r: s y = sp(1) - ep(1)
% P2 v6 s! I6 d4 Z& B z = sp(2) - ep(2)' p- y6 J8 d$ i- P* D
- d3 k, g% b5 Q( I0 P
GetDistance = Sqr((X ^ 2) + (y ^ 2) + (z ^ 2))7 [2 o0 M1 k+ c, T
End Function8 z+ ^5 `* ^6 Z" a* h* Z0 W
'返回两个Double类型变量的最大值
8 _5 b9 a4 V1 V/ U7 ?4 M$ N- FPublic Function MaxDouble(ByVal a As Double, ParamArray b()) As Double2 t3 c+ D" J* X
MaxDouble = a, [2 k5 [3 d# m6 D
Dim i As Integer- z# Z0 X K4 A5 {; ^( z
For i = LBound(b) To UBound(b)( s4 j; g+ Y$ G! Y4 A, m
If b(i) > MaxDouble Then MaxDouble = b(i)
, n* t) b; `' q4 E T7 l! J Next i
& K. P* U2 q# s& F) ?1 JEnd Function
; H! w8 O. R7 c/ k& p9 bPublic Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet4 H" q- Z( E" H) m: u# t
'返回一个空白选择集
1 m2 T& X' y3 H# r6 }+ `
" ` q" \7 S7 j Dim ss As AcadSelectionSet) ?4 ^: j9 Y% j8 }2 B& Q Z
# p$ F% o4 m" l4 i6 r
On Error Resume Next; c3 q' \7 x9 e% I3 r% I: n
Set ss = ThisDrawing.SelectionSets(ssName)# n( j) d5 q4 S# d) J
If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)
( a! Q3 f- v" O" g1 x" Q ss.Clear9 w1 M: h2 |9 y+ e. [' R
Set CreateSelectionSet = ss
Z( i7 C! H F6 _; }3 z$ jEnd Function
$ V7 R6 o- y1 ]! X5 H3 pPublic Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())
2 b' s! N( i% ], m3 g; W( M- c '用数组方式填充一对变量以用作为选择集过滤器使用
9 g* }2 _4 D, H/ x1 W# g/ o$ v$ U Dim fType() As Integer, fData()
) x; i( q& D& @5 Z Dim index As Long, i As Long
, M+ Q* A1 L8 }
2 T" o( g9 x( H- [0 ~# T index = LBound(gCodes) - 1
, M1 m0 l, r$ {2 _( r$ L
4 e, N4 K. C# @ For i = LBound(gCodes) To UBound(gCodes) Step 29 R( i9 r$ C/ q# U
index = index + 1
! h# C8 n1 |) Z$ K4 G ReDim Preserve fType(0 To index)
. k/ ]' r1 Q" a+ j$ e* \* ?# h0 h* K9 J# l ReDim Preserve fData(0 To index)
* B/ g* S- C1 t) M3 r9 e; ` fType(index) = CInt(gCodes(i))' x+ n+ j# I8 u& `/ U2 U8 b
fData(index) = gCodes(i + 1)
1 R: F* W* ]+ q/ ] H" ] Next
6 \: n y }' Z$ k \; m/ ^" J3 R! F typeArray = fType: dataArray = fData
+ n% x6 ]- Q8 w; o5 n8 [End Sub/ u, S0 J( u* ~ Q6 Z
/ X# l/ L6 X! w/ Y) r- `- w
[ 本帖最后由 xiaoma76 于 2008-7-29 18:10 编辑 ] |
评分
-
查看全部评分
|