|
首先声明,由于对楼主所在行业一窍不通,只能通过楼主在帖中提供的信息来推测符合楼主要求的规则和方法,错误和遗漏在所难免,还望谅解,以下内容仅做为意见和建议供楼主参考:
$ w' I* H0 ?- f2 G/ G8 n一.由于楼主要求用EXCEL输出,所以用LISP是不合适的,这是VBA的长项;* w7 Y( S; p$ d' K' i- W3 V
二.楼主在"2.jpg"中提供的数据样例,疑似来自B1K46+360,而不是B1K46+350(详见附图)
2 J) M7 w. ?) J% H
5 D5 \' s# L" r5 v2 [& s' B# m
5 w+ l) z- T$ p3 c 以下按此数据来自B1K46+360看待;
' @$ R- S6 U6 Y三.初步拟定规则和方法如下:) V( k, b! B1 v0 D* Z
假定:
/ w( }; M" J) `; h6 I, p 1.所有需要处理的图形和注释都在已打开的当前DWG文件的当前布局,且所有图形和注释都在WCS的XY平面上,都是二维的;, Z2 c9 @% }2 k4 W, G# k4 \: e
2.位于"zhix"图层的所有直线都是某个横断面唯一的"路面中心"线,且所有横断面都有一条"路面中心"线;
# ^# J2 V$ \. L8 U! Z8 _9 R$ I9 M 3.每一条"路面中心"线都对应存在一个或多个Y座标小于"路面中心"线下端点Y座标的,位于"shuju"图层的单行文字,其中与"路面中心"线下端点几何距离最近者是该断面的"桩号",按其全部文字内容输出"桩号"数据;5 T: f+ B! @9 _( E
4.每一条"路面中心"线都有一条且仅有一条代表横截面的位于"sjx"图层的二维多段线与其相交;
8 E+ v; M6 b m8 D" E7 Y& f, C2 e 5.由于在图上测量得知"路面"部分最大斜度为1:0.03,所以,该多段线中角度为±0.05弧度,π/2±0.05弧度,π±0.05弧度和3π/2±0.05弧度的线段均不予理会,其它线段做为"边坡"看待,并按其与中心线的水平位置关系输出其"左右"数据,按其实测长度输出其"长度"数据,按其角度的余切值的绝对值输出"坡率"数据;! ]/ ] a% X, b( Z
6.输出的"xls"文件的路径和文件名,除扩展名外其它都与"dwg"文档相同
+ l# a4 @* Y0 ~4 W$ r0 e. p5 u4 d& s四.按以下规则编写的VBA代码如下:
4 ^8 ~. d# w# P+ M/ D! O- ) ]* V$ e' V- j! V( R) Q0 Z
- Sub HDM()& t4 K3 n: z+ ^5 ?( L, b* k: ?# F
- Dim Excel进程 As New Excel.Application, Excel文档 As Excel.WorkBook, Excel工作表 As Excel.Worksheet, Int行号 As Integer
* v( A- _5 m& J- D2 B - Dim Ss中心线 As AcadSelectionSet, Ss多段线 As AcadSelectionSet, Ss文字 As AcadSelectionSet, Ft(1) As Integer, Fd(1) As Variant
% `, I/ B) U; n3 I - Dim Lin中心线 As AcadLine, Txt文字 As AcadText, Ent多段线 As AcadEntity m7 D& g8 D5 `0 w, n$ d% s
- Dim Var中心线下端点 As Variant, Dbl文字与中心线最小距离 As Double, Dbl文字与中心线距离 As Double, Str桩号 As String
7 G( R% x. K! t4 U$ G9 G) b; N - Dim Var中心线与多段线交点 As Variant, Var多段线顶点 As Variant, Dbl线段起点(2) As Double, Dbl线段端点(2) As Double, Dbl线段角度 As Double, n+ ]2 z; n$ m! N0 U8 |6 `
- Dim Int循环变量 As Integer, Int循环步长 As Integer0 }6 X5 P( x" @+ o& z& R+ M1 L
- On Error Resume Next
4 k- K& D7 b2 a! s2 ~5 p - '创建三个选择集,分别选择中心线,横断面多段线和包含桩号的单行文字
( t9 V; G1 ?' @& T: Q# O. c6 h - With ThisDrawing.SelectionSets
2 f; S! H7 i& ?& G3 d# T; `+ g) u - Set Ss中心线 = .Add("中心线")- D# _$ G2 ^/ P. Y% ~( R
- Set Ss文字 = .Add("文字"). W, s" X! \# Q& Y
- Set Ss多段线 = .Add("多段线")
/ J0 G9 Y# A5 }- b$ X- u' w [ - End With
) G' f* X% ~. K2 p6 v - Ft(0) = 00 F, l0 r3 `! f/ \- ?; Y
- Fd(0) = "LINE"
, p, M: t: R Z2 C - Ft(1) = 8. C6 c( q3 l. X+ R2 A
- Fd(1) = "zhix"
3 ^) p E* d$ ]6 ~: J- V, q - Ss中心线.Select acSelectionSetAll, , , Ft, Fd5 c+ J" ^. {3 z+ D/ g
- Fd(0) = "TEXT"; s% s; w9 K+ q: g* O
- Fd(1) = "shuju"
7 x6 k- F" ] Q9 ?* o0 ^. l - Ss文字.Select acSelectionSetAll, , , Ft, Fd
( G; `' H" g# ]& a- }( K - Fd(0) = "POLYLINE,LWPOLYLINE"( z+ L# I7 t; T7 m/ c0 u' O. T
- Fd(1) = "sjx"- V# U5 S% p7 V3 u* J" R# F
- Ss多段线.Select acSelectionSetAll, , , Ft, Fd
3 g# [, N, ?; N1 d3 U- G0 q; G/ ]* n' Z - '创建新EXCEL文档
' V; [7 g% j8 V: w( X - Set Excel文档 = Excel进程.Workbooks.Add
- N+ I# L# ]3 g2 A+ T! z) J ^ - Set Excel工作表 = Excel文档.ActiveSheet
* ]5 [& C4 n+ J# H$ o% K- k - With Excel工作表
7 c( d7 S) m+ \6 C - '修改工作表名称,并在第一行写入表头文字
/ o$ }3 Q7 ?6 _! x0 Q, R - .Name = "横断面数据"$ J! _" d+ C! ~ J! E
- .Cells.Item(1, 1) = "桩号"
' R- \" F. A, ^' O! E, [, c8 T - .Cells.Item(1, 2) = "位置"
- q E, V# K: `% \$ A& b - '合并单元格
4 ^/ i: \2 u3 O# m - .Range("B1:C1").Merge# n. W( P( d4 T) U
- .Cells.Item(1, 4) = "长度"
5 E0 Q; z, h1 ~9 ? {; P( [ - .Cells.Item(1, 5) = "坡率"7 H6 V3 {# D8 D- x- g
- '设置单元格对齐方式为水平中心对齐$ T! K+ E6 ?+ I, K. _
- .Columns("A:E").HorizontalAlignment = xlCenter0 F# {( P$ {* f* u. {
- Int行号 = 1
0 j$ U) `( K0 o& G. n - With .Cells- B( {% K% L5 o/ L* \! X' K+ }
- '遍历中心线
# q: X7 v$ E G5 B( ] - For Each Lin中心线 In Ss中心线' G4 o9 z2 U7 F
- '提取中心线下端点
( F" u, L8 k% _5 |/ o* c - If Lin中心线.StartPoint(1) > Lin中心线.EndPoint(1) Then
0 A& N3 q6 e. k( d9 W - Var中心线下端点 = Lin中心线.EndPoint
" B- G `- V/ I4 H, u' w - Else
' j; X+ j: M& {, G, f - Var中心线下端点 = Lin中心线.StartPoint$ a$ ~' L h. T K( ^
- End If
! Z/ @3 `$ N- p6 Z - '遍历单行文字,找出与中心线对应的桩号并记录 C3 @: \3 W8 h
- Dbl文字与中心线最小距离 = 01 T6 H; r2 c; p$ K/ u: O" H4 a, e
- For Each Txt文字 In Ss文字
9 W' g4 t% A+ R- q - If Txt文字.InsertionPoint(1) < Var中心线下端点(1) Then
1 B' |0 ?! m7 Y! e! p6 ?( M - Dbl文字与中心线距离 = Sqr((Var中心线下端点(0) - Txt文字.InsertionPoint(0)) ^ 2 + (Var中心线下端点(1) - Txt文字.InsertionPoint(1)) ^ 2)- c& V( j( o& ^) ?* k6 t' N
- If Dbl文字与中心线最小距离 = 0 Or Dbl文字与中心线距离 < Dbl文字与中心线最小距离 Then
: Y; z% W, A0 s8 ~' q - Dbl文字与中心线最小距离 = Dbl文字与中心线距离
4 s. t8 { x; f6 s h! K - Str桩号 = Txt文字.TextString
) [8 u7 \- ?! z- x9 R, U/ b - End If
6 x$ n' L: R; x& B% Z; t3 j7 V - End If# G2 R6 C V9 J
- Next
8 G7 n" I( b0 k5 [7 x - '遍历横断面多段线
" w# q1 q3 C$ V; ?2 c9 z - For Each Ent多段线 In Ss多段线. h9 F" g- @+ Z( D* V9 R) ?0 S
- '检查多段线与中心线是否存在交点,如存在交点则输出数据$ m% L) o4 C: ~
- Var中心线与多段线交点 = Lin中心线.IntersectWith(Ent多段线, acExtendNone)
4 n* A1 h$ z9 Z+ F* x - If UBound(Var中心线与多段线交点) > 0 Then
& Z' U5 `3 H$ m/ s _( V7 @ - '提取多段线顶点坐标
- \" H6 U; L' A) J6 }6 d1 W - Var多段线顶点 = Ent多段线.Coordinates* }( K u$ I* s( n' L
- '按多段线类型选择读取坐标的方式& J8 Z: X4 Y$ V/ W" E! E" S
- If Ent多段线.ObjectName = "AcDb2dPolyline" Then# ]; e' X. }/ N0 s8 Z9 A$ ^
- Int循环步长 = 3( [! r' _7 ?* {- l6 k! L/ X0 _' K: d
- Else
6 g+ k# `& M. {7 r3 S - Int循环步长 = 2# m8 ]& P" O5 h' o/ R7 x& q
- End If
$ j" r; |) Y( |4 g - '从第一个顶点到倒数第二个顶点,逐点检查相邻顶点间线段的特性5 \: S8 l3 o. c1 d8 f3 A
- For Int循环变量 = 0 To UBound(Var多段线顶点) - Int循环步长 * 2 + 1 Step Int循环步长
- A7 |9 G. i2 H$ `/ d - '提取线段的起,端点1 U% } U. Q2 h6 J4 m
- Dbl线段起点(0) = Var多段线顶点(Int循环变量)& u7 s$ K# r: u9 v) ~ z2 q0 P1 M
- Dbl线段起点(1) = Var多段线顶点(Int循环变量 + 1)9 j/ m& O+ y G2 \
- Dbl线段端点(0) = Var多段线顶点(Int循环变量 + Int循环步长)
6 D" C1 C/ G2 X8 h6 A7 S9 x$ A - Dbl线段端点(1) = Var多段线顶点(Int循环变量 + Int循环步长 + 1)! s8 k2 ?2 O! J+ i5 K
- '提取线段角度
5 | J. E. W; g - Dbl线段角度 = ThisDrawing.Utility.AngleFromXAxis(Dbl线段起点, Dbl线段端点)" s& ]7 r5 H: |7 {; K+ V* n g( w" D
- '检查角度是否为"边坡",如果是则输出数据' K% g" }: N. n1 O/ k
- If Dbl线段角度 > 0.05 And Dbl线段角度 < ThisDrawing.Utility.AngleToReal(90, acDegrees) - 0.05 Or _
8 f$ z3 g! w+ y/ {# G2 { - Dbl线段角度 > ThisDrawing.Utility.AngleToReal(90, acDegrees) + 0.05 And _
; C' t* k `2 L3 a* `8 h - Dbl线段角度 < ThisDrawing.Utility.AngleToReal(180, acDegrees) - 0.05 Or _- ]# C, e4 ~* `: s4 D( n
- Dbl线段角度 > ThisDrawing.Utility.AngleToReal(180, acDegrees) + 0.05 And _
9 A: T: j) o5 x7 b7 V - Dbl线段角度 < ThisDrawing.Utility.AngleToReal(270, acDegrees) - 0.05 Or _
. j* H) ^5 C& J( H( X4 o' i0 X - Dbl线段角度 > ThisDrawing.Utility.AngleToReal(270, acDegrees) + 0.05 And _6 i: u( u- w% j: A! A
- Dbl线段角度 < ThisDrawing.Utility.AngleToReal(180, acDegrees) * 2 - 0.05 Then
8 ~, O: ^5 P. `6 y b1 ~ - 'EXCEL工作表中行号递加
3 L+ z/ I6 D# O+ Y - Int行号 = Int行号 + 1
M. E W1 S, u - '写入前面记录的桩号
! l! z3 ^' ]- B& J" t- a3 D: T - .Item(Int行号, 1) = Str桩号6 ^# @7 U; L% n1 o4 D. n6 y
- '判断该线段与中心线水平位置关系,并写入"左右"
* h) y5 p, y3 m5 P* ]! J - If Dbl线段起点(0) < Var中心线下端点(0) Then
8 o4 R. n& l4 C - .Item(Int行号, 2) = "左"% x" J/ _8 v. ]
- Else
8 Y0 D, X2 G9 o1 O' k5 n - .Item(Int行号, 3) = "右"1 e" X' Y# A6 h9 Z( f5 E
- End If
Z3 g* L, o. ~. h - '写入边坡长度
* l7 [ m2 v. R" S- y: h4 Q - .Item(Int行号, 4) = Sqr((Dbl线段起点(0) - Dbl线段端点(0)) ^ 2 + (Dbl线段起点(1) - Dbl线段端点(1)) ^ 2)
( ^# H3 @! w) D( }3 B4 j7 f - '写入坡率/ y i: Y( L' b8 R* m9 Z' A
- .Item(Int行号, 5) = Abs(1 / Tan(Dbl线段角度))
% [- n" t& E! y7 e+ f0 |2 ~% x* l - End If- c) F }+ N. a) v7 u
- Next
: j* M- o4 J. i4 i - Exit For, d, j3 ?0 P! K- W3 i
- End If
( _4 c; @6 s8 k8 a - Next
( E0 f8 g( Q5 V& _4 u5 J/ ~. z - Next* E& s/ {3 y6 g+ n+ p$ h$ N6 F
- End With
$ e- M5 U5 M4 e0 b0 e6 U5 w1 r - End With
$ D1 R& p: q; \0 ^ - '删除用过的选择集 ?+ b: A$ W+ Q! `
- Ss中心线.Delete
. S! c" q! O2 t A3 r$ Q4 S4 C - Ss文字.Delete% J" m* ~! K* C
- Ss多段线.Delete. l, b6 o) _: A
- '保存EXCEL文档并退出! n5 _: \7 V+ e) J4 {
- Excel文档.SaveAs Left(ThisDrawing.FullName, InStrRev(ThisDrawing.FullName, ".") - 1) & ".xls"( H. R5 `. ?- x N1 ~1 L2 k
- Excel进程.Quit
. E7 }4 d" t0 k2 Y - End Sub
- e; X5 x% u/ S4 ~. c9 u# s0 D
复制代码 " W7 U( g9 d5 p7 h/ s+ p _1 o
在使用此代码之前,务请在VBAIDE界面的"工具"菜单下打开"引用"对话框,正确设置对EXCEL类库的引用.1 y6 w4 \; l1 Z7 T* u
五.附件是包含上面代码和对EXCEL的引用的dvb文件,由于本人PC中安装的是EXCEL2003程序,如果使用者的EXCEL版本与本人不同,请自行修改引用.
) X0 S9 L7 r( q7 _4 F/ a. _( g+ D3 c
1 l& z! k- r5 }. ~9 M[ 本帖最后由 woaishuijia 于 2010-2-27 06:05 编辑 ] |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|