编程实现海洋石油工程项目电伴热材料提取
2020-07-27丰兴盛杨富广黄太安王可民蒋小华史其麒
丰兴盛,杨富广,黄太安,王可民,蒋小华,史其麒
(海洋石油工程股份有限公司建造事业部,山东 青岛 266520)
建造事业部海洋石油工程项目电伴热带布置图包含图纸编号、材料规格数量、回路编号、管线编号、功率、坐标等信息,这些信息靠人工去逐条统计、分析、汇总,劳动强度大、需要时间多、错误率高。通过编程,可实现一键提取多张图纸的数据,并对数据进行分类汇总,提高效率和准确性。
本文中采用CSharp编程需要实现以下几点:
(1)从AutoCAD电伴热带布置图中提取每张图纸的页码、图纸号、版次、电伴热材料、回路编号、管线号、功率、坐标等信息;
(2)数据经整理,输入到所需EXCEL模板中;
(3)对同类材料进行汇总,输入到EXCEL表格文件中。
1 编程语言的选择
AutoCAD和Microsoft Office Excel都为C Sharp提供了方便使用的COM组件,本案例编程采用C Sharp语言。
AutoCAD为C Sharp提供的COM组件为Autodesk.AutoCAD.Interop.dll和Autodesk.AutoCAD.Interop.Common.dll;Microsoft Office Excel所提供的COM组件为Microsoft.Office.Interop.Excel.dll。
本案例所论述程序的编程语言为C Sharp,编程工具为Visual Studio 2019;AutoCAD版本为AutoCAD_Architecture_2017,Microsoft Office Excel版本为Microsoft Office 2013。EXCLE能实现不同版本兼容;AutoCAD版本不兼容,如使用其它版本的AutoCAD,需要引用对应AutoCAD版本的COM组件。
2 程序流程
手动统计电伴热材料时,先将电伴热布置图中的材料信息、管线编号、回路编号等信息录入到EXCEL表格中,再对材料进行汇总,本案例程序同样遵循这这种业务流程。程序的基本流程参照图1。
图1 程序流程
3 读取图纸信息
3.1 引用接口文件
在程序中添加引用,选择AutoCAD应用程序中的Autodesk.AutoCAD.Interop.dll和Autodesk.AutoCAD.Interop.Common.dll文件,引用后出现如图2两项。
图2 程序引用
在程序引用命名空间部分,添加:
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
这样C Sharp所开发的程序就和AutoCAD之间建立了通讯联系,可以调用AutoCAD的命令,完成电伴热带布置图信息的读取。
3.2 打开指定的电伴热图
打开指定的AutoCAD电伴热带布置图需要用到以下语句:
AcadApplication AcadApp= (AcadApplication)System.Runtime.
InteropServices.Marshal.GetActiveObject("AutoCAD.Application");
AcadDocument AcadDoc= AcadApp.Documents.Open(fileName, null, null);
其中fileName为电伴热带布置图文件全名(包含文件路径)。
3.3 读取信息
通过分析,电伴热带布置图数据提取所需的信息分布在图3的四个区域。
图3 图纸区域划分
区域1为图纸信息,包含所需的电伴热回路编号、对应管线号;
区域2包含电伴热功率信息;
区域3为图纸材料表,包含材料的规格、数量、描述等信息;
区域4为图框信息,包含图纸编号、版次信息。
通过对图纸区域的划分,就可以通过坐标点创建选择集,分别读取不同区域的信息。首先,创建全图的文本选择集,检索关键字,再通过关键字找到图框,获得图框的起点坐标。电伴热带布置图使用统一的图纸模板,图框大小及信息的相对位置是一致的,各区域的相对坐标可以通过图框的起点坐标和距离获得。
创建选择集使用AcadSelectionSetAdd方法,在命名空间Autodesk.AutoCAD.Interop中。使用Add方法,创建选择集后,选择集是空的,里面没有任何元素。要选择区域内文本(包括单行文本和多行文本),需要使用选择集过滤器,用Select方法来为选择集添加元素。Select的常见用法为:Select(AcSelect Mode, object Point1, object Point2, object FilterType, object FilterData)。其中,Mode为选择方法,包括框选、窗选等;Point1、Point2为选择范围的起点和终点;FilterType为一个Int16类型的一维数组,标识过滤器的类型(DXF组码);FilterData为object类型的一维数组,指定要过滤的值。FilterType和FilterData的数组元素数量相同,二者成对出现,组成过滤器列表。常见的过滤器DXF 组码如表1所示。
表1 DXF 组码表
通过以上介绍,已经清楚了选择集的创建,选择集过滤器的使用,那么创建一个选择集来选取整个图面的文本文字,可以用以下代码:
AcadSelectionSet mySelectionSet = AcadDoc.SelectionSets.Add("SelectKeyWord");
Int16[] FilterType = new Int16[7];
object[] FilterData = new object[7];
FilterType[0] = -4; FilterData[0] = " FilterType[1] = -4; FilterData[1] = " FilterType[2] = 0; FilterData[2] = "TEXT"; FilterType[3] = 0; FilterData[3] = "MTEXT"; FilterType[4] = -4; FilterData[4] = "OR>"; FilterType[5] = 8; FilterData[5] = "标准图框"; FilterType[6] = -4; FilterData[6] = "AND>"; double[] point01 = new double[3]; double[] point02 = new double[3]; point01[0] = double.MinValue; point01[1] = double.MinValue; point01[2] = 0; point02[0] = double.MaxValue; point02[1] = double.MaxValue; point02[2] = 0; mySelectionSet.Select(AcSelect.acSelectionSetCrossing, point01, point02, FilterType, FilterData); 通过选择集选择了全图面的单行文本和多行文本,接下来需要遍历选择集中的对象,通过比较对象的文本内容(TextString属性),找出关键字对象,获得它的插入点(单行文本或多行文本的InsertionPoint属性)。 double[] ptKeyWord; for (int i = 0; i < mySelectionSet.Count; i++) { AcadText st = mySelectionSet.Item(i) as AcadText; if (st != null) { if (st.TextString.IndexOf(keyWord) > -1) { ptKeyWord = st.InsertionPoint; break; } } else { AcadMText mt = mySelectionSet.Item(i) as AcadMText; if (mt.TextString.IndexOf(keyWord) > -1) { ptKeyWord = mt.InsertionPoint; break; } } } 需要注意的是,在选择集使用完成后,要及时删除选择集,电伴热图纸一次需要处理多张,如果没有及时删除选择集,下次将无法创建,会导致程序崩溃。也可以使用安全创建选择集的方法,在创建选择集之前,先遍历现有选择集,如果有名称相同的,则删除。 获得了关键字的插入点,下一步就可以通过插入点,选取一定范围,来查找图框对象,本案例中的图框对象为“LINE”,在设计选择集过滤器时将“TEXT”和“MTEXT”替换成“LINE”即可。符合要求的“LINE”对象起点(StartPoint属性)或终点(EndPoint属性)就是图框的基准点。接下来就是根据基准点划分区域,每个区域重复创建选择集、遍历选择集,不断读取文本对象。 数据的处理是将数据整理成需要的数据结构。在本案例中,是将图纸信息整理成跟EXCEL模板对应的数组,方便后期将数据录入EXCEL文件。 材料汇总需要计算所有图纸中相同规格材料的数量。可以使用字典,字典的关键字为材料的规格,字典的值为数量。在循环读取材料时,判断字典的关键字是否存在,如果存在,字典的值增加,如果不存在,则添加关键字和值。 在程序中添加引用,选择Microsoft Office Excel应用程序中的Microsoft.Office.Interop.Excel.dll文件,引用后出现以下项(图5)。 图4 程序引用 在程序引用命名空间部分,添加: using Microsoft.Office.Interop.Excel; 通过COM组件,将数据写入EXCEL,通常有两种方法,一种是通过循环行和列,将数据写入对应的单元格,另一种是直接将数组写入对应的单元格数组中。循环写入,在数据量大的时候,速度较慢;使用数组写入的方法速度快,在数据量大的时候,尤为突出,而且代码更简洁。本案例采用第二种方法。代码如下所示,其中arr为存储电伴热材料的一个二维数组: string path = System.Windows.Forms.Application.StartupPath; string fullName = path + @"/Data/Module.xlsx"; Application exlApp = new Application(); exlApp.ScreenUpdating = false; exlApp.Visible = false; Workbook wb = exlApp.Workbooks.Open(fullName); Worksheet ws = (Worksheet)wb.Sheets["内容"]; ws.Activate(); ws.Cells[3, 1].Resize[arr.GetLength(0), arr.GetLength(1)] = arr; exlApp.ScreenUpdating = true; exlApp.Visible = true; 通过程序开发,实现了海洋石油工程项目电伴热带布置图数据的自动提取,并将电伴热材料清单和材料汇总导入到EXCEL中,不必再费时费力逐条统计、汇总、录入电伴热材料数据,保证了数据的准确性和输出文件格式的一致性,极大提高了效率,以建造事业部的曹妃甸CEPI组块为例,电伴热带布置图约有600张,人工统计电伴热材料大约需要150~160个人工时,使用本案例中的程序几分钟就能完成。同时,在确保伴热带布置图标准化的情况下,建造事业部的国内项目均可以使用,具有良好的通用性和较为广阔的前景。4 数据处理及材料汇总
5 数据写入
5.1 引用接口文件
5.2 数据录入
6 结语