利用VBA程序语言绘制公路纵断面图

摘要:VBA作为一个集成的开发环境,能够使AutoCAD数据与其它的VBA应用程序,如Microsoft&nbspExcel软件,直接共享,实现无缝连接,交换数据。本文介绍如何利用VBA编程建立AutoCAD2000与Excel2000的通信,实现数据交换,快速绘制公路纵断面地面线。&nbsp
关键词:公路纵断面设计&nbsp地面线&nbspVBA&nbspAutoCAD与Excel的通信&nbsp
&nbsp
1&nbsp前言
纵断面设计图是道路纵断面设计的主要成果,也是道路设计的重要技术文件之一。在纵断面设计图上有两条主要的线:一条是地面线,它是根据中线上各桩点的高程而点绘的一条不规则的折线,反映了沿着中线地面的起伏变化;另一条是设计线,它是经过技术上、经济上以及美学上等多方面比较后定出的一条规则形状的几何线。
公路设计中,在没有专业设计软件辅助的情况下,绘制公路纵断面图是很繁琐的事,需要进行大量的、重复的操作,既劳神,又容易出错。特别在公路外业勘测阶段,需要在短时间内将所测量的中桩高程转化成纵断面图上的地面线,才可以进行路线纵坡设计,分析测量成果(选线)是否合理。
如何快速绘制公路纵断面地面线呢?答案是:利用Microsoft&nbspExcel、AutoCAD都提供的VBA功能,编制程序进行绘制,即把Microsoft&nbspExcel表格中的桩号、地面高程等信息读取出来,在AutoCAD文件里以文字、线条的方式写出来,就可绘出中桩地面线。
2&nbspVBA简介
Visual&nbspBasic&nbspfor&nbspApplication(VBA)是Microsoft面向最终用户的应用软件编程语言。它最早出现于Microsoft的Excel和Project中,如今VBA已成为VB和所有Office产品的组件。常用的绘图软件AutoCAD也已支持VBA作为二次开发工具。
VBA最大特点和最大优点是利用面向对象(OOP)的ActiveX&nbspAutomation技术,使语言的引擎在技术上与开发环境分离。它的功能在很大程度上依赖于它的客户显露的Automation接口。同时,由于VBA是基于ActiveX&nbspAutomation技术,它可以使用任何Automation技术的应用程序共同工作。
基于AutoCAD的VBA应用程序就是高级程序语言的计算功能与AutoCAD的绘图功能结合,使用VBA程序语句来控制对AutoCAD图形的操作。
VBA作为一个集成的开发环境,它提供了高质量的用户化编程能力,能够使AutoCAD数据与其它的VBA应用程序,如Microsoft&nbspExcel软件,直接共享,实现无缝连接,交换数据非常方便。
3&nbsp工作机理分析
在Microsoft&nbspExcel中,与表对应的对象是工作表(Sheet或Worksheet),与每一个表格方格对应的对象是单元格区域(range),它可以仅包括一个单元格(cell),也可以由多个单元格合并而成。工作表对象中的cells属性,在单元格的选择方面可以达到与range相同的效果,它是以行(row)和列(gol)作为参数的,对于行和列的选择可以采用变量的形式。在本例中,可设定工作表(Worksheet)的每一行第一列(cells(i,1))为中桩桩号,每一行第二列(cells(i,2))为对应的地面高程。
在AutoCAD中,没有与表对应的对象,但可以根据表中前后桩号定义水平距离,根据地面高程定义垂直距离,将表中数据理解为线条与文字对象的集合。这样,通过读取Microsoft&nbspExcel文件中的最小对象—单元格区域(cells(i,j))的主要信息,利用VBA建立AutoCAD与Excel的通信,然后在AutoCAD文件里指定的图层、位置画线条,书写文字。通过循环,遍历所有单元格区域(cells(i,j)),边读边写,最终完成纵断面地面线的绘制及桩号、地面高程的书写。
4&nbsp具体实现方法
4.1&nbsp&nbsp在AutoCAD中创建Excel应用程序
要编写存取Excel的应用程序,必须通过VBA将Excel中的对象能够让用户使用,这就需要参考&nbspExcel对象的数据库。其步骤如下:
4.1.1&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp打开AutoCAD的VBA编辑器(命令:VBAIDE);
4.1.2&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp选择“工具”\“引用”项,在弹出的“引用”对话框的“可使用的引用”列表框内,选择“Microsoft&nbspExcel&nbsp8.0&nbspObject&nbspLibrary”项;
4.1.3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp单击“确定”按钮;
4.1.4&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp接下来使用下列代码可创建完整的应用程序对象实例:
Dim&nbspExcel&nbspAs&nbspExcel.Application
'激活要与之通信的Excel应用程序
On&nbspError&nbspResume&nbspNext
&nbsp&nbsp&nbsp&nbsp&nbspSet&nbspExcel&nbsp=&nbspGetObject(,&nbsp"Excel.Application")
&nbsp&nbsp&nbsp&nbsp&nbspIf&nbspErr&nbsp<>&nbsp0&nbspThen
&nbsp&nbsp&nbsp&nbsp&nbspSet&nbspExcel&nbsp=&nbspCreateObject("Excel.Application")
&nbsp&nbsp&nbsp&nbsp&nbspEnd&nbspIf
4.2&nbsp&nbsp读入坐标点画地面线
4.2.1&nbsp&nbsp设定工作表(Worksheet)的每一行第一列(cells(i,1))为中桩桩号,每一行第二列(cells(i,2))为对应的地面高程。由于公路路线纵断面图水平方向比例为1:2000,垂直方向比例为1:200,故读入时,y坐标应乘以10倍。
4.2.2&nbsp&nbsp以(0,0,0)为原点,以桩号里程为x坐标,以10倍所对应的地面高程为y坐标,0为z坐标,定义某一桩号对应的地面点坐标;然后循环读取各里程桩号数据信息,定义各桩号所对应的地面点坐标;最后以直线段连接各地面点坐标,则为地面线。
4.2.3&nbsp&nbsp下述代码可读入Excel数据信息画地面线
Dim&nbspi&nbspAs&nbspInteger
&nbsp&nbsp&nbsp&nbspDim&nbsplineobj&nbspAs&nbspAcadLine
&nbsp&nbsp&nbsp&nbspDim&nbspsPnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbspePnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
‘读入坐标画地面线
Worksheets("sheet1").Activate
&nbsp&nbsp&nbsp&nbspi&nbsp=&nbsp3&nbsp&nbsp‘由第三行起
&nbsp&nbsp&nbsp&nbspDo&nbspUntil&nbspcells(i,&nbsp1).value&nbsp=&nbsp""
&nbsp&nbsp&nbsp&nbspIf&nbspcells(i&nbsp+&nbsp1,&nbsp1)&nbsp=&nbsp0&nbspThen
&nbsp&nbsp&nbsp&nbspExit&nbspDo
&nbsp&nbsp&nbsp&nbspEnd&nbspIf
&nbsp&nbsp&nbsp&nbspsPnt(0)&nbsp=&nbspcells(i,&nbsp1).value
&nbsp&nbsp&nbsp&nbspsPnt(1)&nbsp=&nbsp10&nbsp*&nbspcells(i,&nbsp2).value
&nbsp&nbsp&nbsp&nbspsPnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspePnt(0)&nbsp=&nbspcells(i&nbsp+&nbsp1,&nbsp1).value
&nbsp&nbsp&nbsp&nbspePnt(1)&nbsp=&nbsp10&nbsp*&nbspcells(i&nbsp+&nbsp1,&nbsp2).value
&nbsp&nbsp&nbsp&nbspePnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspSet&nbsplineobj&nbsp=&nbspThisDrawing.ModelSpace.AddLine(sPnt,&nbspePnt)
&nbsp&nbsp&nbsp&nbspi&nbsp=&nbspi&nbsp+&nbsp1
&nbsp&nbsp&nbsp&nbspLoop
4.3&nbsp&nbsp桩号及高程的写入
4.3.1&nbsp&nbsp定义文字的插入位置&nbsp&nbsp以桩号里程为x坐标,0为y坐标,0为z坐标,确定文字的插入点。
4.3.2&nbsp&nbsp以单行文字形式创建桩号及高程文字,定义文字的格式、字体、高度、倾斜角度。插入后的文字应逆时针旋转90度。
4.4&nbsp&nbsp辅助网格线的绘制
4.4.1&nbsp&nbsp辅助网格线能较为直观地表示桩号及地面高程的对应关系,有助于纵坡设计;
4.4.2&nbsp&nbsp以桩号里程为x坐标,0为y坐标,0为z坐标,确定网格线第一点;以桩号里程为x坐标,10倍所对应的地面高程为y坐标,0为z坐标,确定网格线第二点;两点连线,则为网格线。
5&nbsp&nbsp实例
5.1&nbsp&nbsp运行AutoCAD2000程序;
5.2&nbsp&nbsp打开AutoCAD的VBA编辑器(命令:VBAIDE);
5.3&nbsp&nbsp创建成下面的过程及代码,并运行之:
&nbsp
Sub&nbspZDM()
&nbsp&nbsp&nbsp&nbsp
&nbsp&nbsp&nbsp&nbspDim&nbspExcel&nbspAs&nbspExcel.Application
&nbsp&nbsp&nbsp&nbspDim&nbspExcelSheet&nbspAs&nbspObject
&nbsp&nbsp&nbsp&nbspDim&nbspExcelWorkbook&nbspAs&nbspObject
&nbsp&nbsp&nbsp&nbspDim&nbspi&nbspAs&nbspInteger
&nbsp&nbsp&nbsp&nbspDim&nbsplineobj&nbspAs&nbspAcadLine
&nbsp&nbsp&nbsp&nbspDim&nbspklineobj&nbspAs&nbspAcadLine
&nbsp&nbsp&nbsp&nbspDim&nbspsPnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbspePnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbspkPnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbsphPnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbspksPnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbspkePnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbspdmPnt(0&nbspTo&nbsp2)&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbsptextObj&nbspAs&nbspAcadText
&nbsp&nbsp&nbsp&nbspDim&nbsptxtStr&nbspAs&nbspString
&nbsp&nbsp&nbsp&nbspDim&nbspinsPnt&nbspAs&nbspVariant
&nbsp&nbsp&nbsp&nbspDim&nbsptxtHeight&nbspAs&nbspDouble
&nbsp&nbsp&nbsp&nbspDim&nbsplayObj&nbspAs&nbspAcadLayer
&nbsp&nbsp&nbsp&nbspDim&nbspnewLayer&nbspAs&nbspAcadLayer
&nbsp&nbsp&nbsp&nbspSet&nbsplayObj&nbsp=&nbspThisDrawing.Layers.Add("标注")
&nbsp&nbsp&nbsp&nbspSet&nbsplayObj&nbsp=&nbspThisDrawing.Layers.Add("地面线")
&nbsp&nbsp&nbsp&nbspSet&nbsplayObj&nbsp=&nbspThisDrawing.Layers.Add("网格线")
&nbsp&nbsp&nbsp&nbspDim&nbspatTxtobj&nbspAs&nbspAcadTextStyle
&nbsp&nbsp&nbsp&nbspSet&nbspatTxtobj&nbsp=&nbspThisDrawing.ActiveTextStyle
&nbsp&nbsp&nbsp&nbspatTxtobj.fontFile&nbsp=&nbsp"c:\windows\fonts\simfang.ttf"
&nbsp&nbsp&nbsp&nbsp
'创建Excel应用程序
&nbsp&nbsp&nbsp&nbspOn&nbspError&nbspResume&nbspNext
&nbsp&nbsp&nbsp&nbspSet&nbspExcel&nbsp=&nbspGetObject(,&nbsp"Excel.Application")
&nbsp&nbsp&nbsp&nbspIf&nbspErr&nbsp<>&nbsp0&nbspThen
&nbsp&nbsp&nbsp&nbsp&nbspSet&nbspExcel&nbsp=&nbspCreateObject("Excel.Application")
&nbsp&nbsp&nbsp&nbspEnd&nbspIf
&nbsp&nbsp&nbsp&nbsp'打开Excel表
&nbsp&nbsp&nbsp&nbspExcelName&nbsp=&nbspInputBox("路径:")
&nbsp&nbsp&nbsp&nbspExcel.Workbooks.Open&nbspExcelName
&nbsp&nbsp&nbsp&nbsp
&nbsp&nbsp&nbsp&nbsp'表格不可见
&nbsp&nbsp&nbsp&nbspExcel.Visible&nbsp=&nbspFalse
&nbsp&nbsp&nbsp&nbsp
&nbsp&nbsp&nbsp&nbsp'读入坐标点画地面线
&nbsp&nbsp&nbsp&nbspWorksheets("sheet1").Activate
&nbsp&nbsp&nbsp&nbspi&nbsp=&nbsp3
&nbsp&nbsp&nbsp&nbspDo&nbspUntil&nbspcells(i,&nbsp1).value&nbsp=&nbsp""
&nbsp&nbsp&nbsp&nbspIf&nbspcells(i&nbsp+&nbsp1,&nbsp1)&nbsp=&nbsp0&nbspThen
&nbsp&nbsp&nbsp&nbspExit&nbspDo
&nbsp&nbsp&nbsp&nbspEnd&nbspIf
&nbsp&nbsp&nbsp&nbspsPnt(0)&nbsp=&nbspcells(i,&nbsp1).value
&nbsp&nbsp&nbsp&nbspsPnt(1)&nbsp=&nbsp10&nbsp*&nbspcells(i,&nbsp2).value
&nbsp&nbsp&nbsp&nbspsPnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspePnt(0)&nbsp=&nbspcells(i&nbsp+&nbsp1,&nbsp1).value
&nbsp&nbsp&nbsp&nbspePnt(1)&nbsp=&nbsp10&nbsp*&nbspcells(i&nbsp+&nbsp1,&nbsp2).value
&nbsp&nbsp&nbsp&nbspePnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspSet&nbspnewLayer&nbsp=&nbspThisDrawing.Layers("地面线")
&nbsp&nbsp&nbsp&nbspThisDrawing.ActiveLayer&nbsp=&nbspnewLayer
&nbsp&nbsp&nbsp&nbspnewLayer.Color&nbsp=&nbspacWhite
&nbsp&nbsp&nbsp&nbspSet&nbsplineobj&nbsp=&nbspThisDrawing.ModelSpace.AddLine(sPnt,&nbspePnt)
&nbsp&nbsp&nbsp&nbspIf&nbspcells(i,&nbsp2)&nbsp=&nbsp""&nbspThen&nbsplineobj.Delete
&nbsp&nbsp&nbsp&nbspi&nbsp=&nbspi&nbsp+&nbsp1
&nbsp&nbsp&nbsp&nbspLoop
&nbsp&nbsp&nbsp&nbsp
'画辅助网格线及插入数据
&nbsp&nbsp&nbsp&nbspi&nbsp=&nbsp3
&nbsp&nbsp&nbsp&nbspDo&nbspUntil&nbspcells(i,&nbsp1).value&nbsp=&nbsp""
&nbsp&nbsp'画辅助网格线
&nbsp&nbsp&nbsp&nbspksPnt(0)&nbsp=&nbspcells(i,&nbsp1).value:&nbspksPnt(1)&nbsp=&nbsp0:&nbspksPnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspkePnt(0)&nbsp=&nbspcells(i,&nbsp1).value:&nbspkePnt(1)&nbsp=&nbsp10&nbsp*&nbspcells(i,&nbsp2).value:&nbspkePnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspdmPnt(0)&nbsp=&nbspcells(i,&nbsp1).value:&nbspdmPnt(1)&nbsp=&nbsp48:&nbspdmPnt(2)&nbsp=&nbsp0
&nbsp&nbsp&nbsp&nbspSet&nbspnewLayer&nbsp=&nbspThisDrawing.Layers("网格线")
&nbsp&nbsp&nbsp&nbspThisDrawing.ActiveLayer&nbsp=&nbspnewLayer
&nbsp&nbsp&nbsp&nbspnewLayer.Color&nbsp=&nbspacGreen
&nbsp&nbsp&nbsp&nbspSet&nbspklineobj&nbsp=&nbspThisDrawing.ModelSpace.AddLine(ksPnt,&nbspkePnt)
&nbsp&nbsp&nbsp'插入桩号
&nbsp&nbsp&nbsp&nbspSet&nbspnewLayer&nbsp=&nbspThisDrawing.Layers("标注")
&nbsp&nbsp&nbsp&nbspThisDrawing.ActiveLayer&nbsp=&nbspnewLayer
&nbsp&nbsp&nbsp&nbspnewLayer.Color&nbsp=&nbspacCyan
&nbsp&nbsp&nbsp&nbspa&nbsp=&nbspcells(i,&nbsp1).value
&nbsp&nbsp&nbsp&nbspb&nbsp=&nbspInt(a&nbsp/&nbsp1000)
&nbsp&nbsp&nbsp&nbspc&nbsp=&nbspFormat((a&nbsp-&nbspb&nbsp*&nbsp1000),&nbsp"000.000")
&nbsp&nbsp&nbsp&nbsp'd&nbsp=&nbspa&nbsp-&nbspInt(a)
&nbsp&nbsp&nbsp&nbspE&nbsp=&nbsp"+"&nbsp+&nbspFormat(c,&nbsp"000.000")
&nbsp&nbsp&nbsp&nbspIf&nbspc&nbsp=&nbsp0&nbspThen&nbspE&nbsp=&nbsp"K"&nbsp+&nbspLTrim(Str(b))
&nbsp&nbsp&nbsp&nbsptxtStr&nbsp=&nbspE
&nbsp&nbsp&nbsp&nbsptxtHeight&nbsp=&nbsp4
&nbsp&nbsp&nbsp&nbsptextObj.Rotation&nbsp=&nbsp3.14159&nbsp/&nbsp2
&nbsp&nbsp&nbsp&nbspinsPnt&nbsp=&nbspksPnt
&nbsp&nbsp&nbsp&nbspSet&nbsptextObj&nbsp=&nbspThisDrawing.ModelSpace.AddText(txtStr,&nbspinsPnt,&nbsptxtHeight)
&nbsp&nbsp&nbsp&nbspIf&nbspcells(i,&nbsp2)&nbsp=&nbsp""&nbspThen&nbsptextObj.Delete
&nbsp&nbsp&nbsp&nbsp'插入地面高程
&nbsp&nbsp&nbsp&nbsptxtStr&nbsp=&nbspFormat(cells(i,&nbsp2).value,&nbsp"###0.##0")
&nbsp&nbsp&nbsp&nbsptxtHeight&nbsp=&nbsp4
&nbsp&nbsp&nbsp&nbsptextObj.Rotation&nbsp=&nbsp3.14159&nbsp/&nbsp2
&nbsp&nbsp&nbsp&nbspinsPnt&nbsp=&nbspdmPnt
&nbsp&nbsp&nbsp&nbspSet&nbsptextObj&nbsp=&nbspThisDrawing.ModelSpace.AddText(txtStr,&nbspinsPnt,&nbsptxtHeight)
&nbsp&nbsp&nbsp&nbspi&nbsp=&nbspi&nbsp+&nbsp1
&nbsp&nbsp&nbsp&nbspLoop
&nbsp&nbsp&nbsp&nbspZoomAll
&nbsp
&nbsp&nbsp&nbsp&nbsp'该语句用来等待查看显示结果
&nbsp&nbsp&nbsp&nbspMsgBox&nbsp"按‘确定’键将关闭Excel的运行!"
&nbsp&nbsp&nbsp&nbsp
&nbsp&nbsp&nbsp&nbsp'保存传过来的数据
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspExcelWorkbook.Close
&nbsp&nbsp&nbsp&nbspExcelWorkbook.Save
&nbsp&nbsp&nbsp&nbsp'关闭Excel应用程序
&nbsp&nbsp&nbsp&nbspExcel.Application.Quit
&nbsp&nbsp&nbsp&nbsp'删除Excel应用程序实例
&nbsp&nbsp&nbsp&nbspSet&nbspExcel&nbsp=&nbspNothing
&nbsp
End&nbspSub
5.4&nbsp&nbsp&nbsp&nbsp运行上述代码后,将会弹出窗口,提示输入Excel文件的路径;输入后回车,就可以生成纵断面地面线,可以进行路线纵坡设计。
5.5&nbsp&nbsp&nbsp&nbsp本程序需要Microsoft&nbspExcel&nbsp2000和AutoCAD2000运行环境,编译后通过。
6&nbsp&nbsp结束语
6.1&nbsp&nbsp在经过综合分析、反复比较定出设计纵坡之后,可以确定各变坡点及其高程、竖曲线要素。在上述代码中,加入合适的词句,可以完整地绘制公路纵断面设计图。
6.2&nbsp&nbsp公路工程设计中,经常遇到许多类似的大量的、重复的、有逻辑性的操作,只要合理利用VBA,发挥其强大的功能,实现AutoCAD与Excel应用程序的无缝连接,快速交换数据,就可以在短时间内完成所需的设计工作,达到事半功倍的效果。

网友评论(2 条)

  1. xianghui99001 2008-10-08 03:35

    学到了,谢谢!

  2. txm 2009-12-01 13:59

    学会运用,那简直是没法说了,太棒了,太感谢您了

发表评论

您的邮箱不会被公开。* 为必填项