張向良
摘 要:Excel與AutoCAD表單是工作中常見的兩種工具,由于AutoCAD與Excel屬于兩個不同的信息系統,傳統的人工填寫的工作方式已經使得AutoCAD與Excel之間的信息交互越來越難以滿足工作需求。文章將探討在AutoCAD結構化表單與Excel之間進行高效數據交換的方法,介紹OLE、Excel對象模型、AutoCAD圖形數據庫結構等前置技術知識以及數據交換的具體實現方式,以期為相關的數據采集工作提供高效的解決方案。
關鍵詞:Excel;AutoCAD;結構化表單;OLE;ObjectARX;二次開發
中圖分類號:TP399 文獻標志碼:A 文章編號:2095-2945(2017)34-0093-02
引言
Excel作為最為人所熟悉的數據統計工具,被很多企業選擇與使用,而AutoCAD在工程中的應用同樣極為廣泛。很多時候需要在這兩個平臺間傳遞數據,以作者所在的航空制造業某部門為例,工作時就需要將保存于AutoCAD圖表中的產品信息錄入到Excel服務器中,這些數據在后一平臺上進行集中管理。本文將探討在AutoCAD與Excel兩平臺間自動交換數據的方法,以及如何在基于ObjectARX(VC)開發的程序中實現。該方法用程序代替人工操作,在為設計人員提供方便的同時也保證了數據采集的可靠性。
1 運行環境概述
Excel是Microsoft發布的一款廣為人知的數據統計工具。本文討論Excel與AutoCAD圖表的數據交換,未涉及Excel的其它定制功能.結構化AutoCAD表單是在AutoCAD圖形中加入帶有附加信息的圖元,如擴展數據、擴展記錄、自定義實體、塊參照等。以帶屬性的塊參照為例,由于屬性是一種包含了標簽、提示和值的結構體,而不像普通的文字或多行文字那樣只有一個值,這使得計算機能夠“理解”用戶所輸入的內容(而不是簡單地將其視為一個字符串)。這為后期的數據采集與分析提供了極大的方便。
由于windows會為每個進程分配獨立的地址空間(用戶空間),進程不能夠以任何方式讀寫其他進程用戶空間的數據[1]。即使使用系統API,也無法確定所需要讀、寫的數據的地址。所以需要使用一種能夠跨越進程邊界通信的方法,即OLE技術。
2 OLE技術與Excel對象模型
基于COM的OLE2(業內簡稱OLE)是一種Microsoft推出的一種windows下的對象通信技術,經過多年的擴充和演化,現已變成了在桌面系統上進行程序通信的一個技術總稱[2]。使用OLE方式讀寫Excel,需要首先創建一個Excel對象(或通過其它途徑獲得一個),然后通過Excel預留的接口調用它所提供的服務,就像Excel本身在操作單元格一樣。
為此需要了解Excel的程序結構,也就是對象模型。Microsoft在Excel 2007開發人員參考中提供了Excel對象模型參考,詳細地描述了各種對象的屬性和方法。對于讀寫Excel而言需要用到其中的3對象:_Application、_Worksheet和Range。_Application代表Excel應用程序,一個_Application 對象中包含若干個工作簿_Workbook,后者又包含多個工作表_Worksheet,而Range則代表一個區域,當然也可以是1個單元格,如圖1。
首先需要獲得_Application對象,進而使用其AttachDispatch函數獲得_Worksheet對象、Range對象,然后便可使用SetItem和GetItem函數讀寫單元格里的內容。
3 AutoCAD圖形數據庫
讀寫結構化的AutoCAD表單需要了解AutoCAD圖形數據庫的結構。每個承載表單的dwg文件就是一個AutoCAD圖形數據庫AcDbDatabase[3],其中包含了塊表AcDbBlockTable,塊表中包含了模型空間ACDB_MODEL_SPACE,而用戶所繪制的圖形、文字等實體就存在于模型空間中。
ObjectARX(VC)提供了相關的類庫與函數來訪問上述對象。首先獲得當前活動圖形數據庫的塊表,獲得包含結構化數據的塊定義,然后檢索模型空間中的此塊定義的塊參照AcDbBlockReference。需要讀取的數據,也就是屬性AcDbAttribute的值,就包含在這些塊參照中。
4 數據結構的設計
至此已經擁有了外部讀寫Excel和讀寫結構化AutoCAD表單中數據的方法。只需設計編寫承載數據的載體,將上述三者連接起來封裝成命令,便可以實現結構化AutoCAD表單與Excel之間的一鍵式數據交換.命令通過以下步驟實現:(1)使用OLE方式獲得Excel實例。(2)讀取結構化AutoCAD表單,將數據存入中繼數據結構。(3)讀寫Excel與寫入AutoCAD表單,如圖2。
所述的步驟(1)使用OLE方式獲得Excel實例:首先獲得_Application對象的COM類型標識符,之后COM庫會從系統注冊表中找到對應組件的程序路徑等信息,用以獲取運行中的Excel實例的IUnkown接口,并通過該接口查詢到IDispatch接口。部分代碼如下:
CLSIDFromProgID(L"Excel.Application", &clsid);
GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
pUnk->QueryInterface(IID_IDispatch, (void**)&pDisp);
...
再用_Application對象的AttachDispatch函數獲得_Worksheet對象,進而Range對象。在此不再贅述。endprint
步驟(2)讀取結構化AutoCAD表單:首先獲得當前活動圖形數據庫的塊表,獲得包含結構化數據的塊定義,然后檢索模型空間中的此塊定義的塊參照AcDbBlockReference。建立一個屬性遍歷器,遍歷塊參照中的屬性,根據屬性的標簽不同把它的值用textString函數讀入到TemplateItem結構對應的變量中。部分代碼如下:
attIt = pBlkRef->attributeIterator();
for (attIt->start();!attIt->done();attIt->step())
{
es = acdbOpenObject(pAtt,attIt->objectId(),AcDb::kForRead);
if (es==Acad::eOk)
{
CString strTag = pAtt->tag();
if (strTag.CompareNoCase(_T("序列號"))==0)
XuLieHao = pAtt->textString();
...
pAtt->close();
}
}
delete attIt;
...
步驟(3)讀寫Excel與寫入AutoCAD表單:根據Excel表單的要求使用SetItem函數讀寫單元格,內容取決于中繼數據結構TemplateItem中封裝的函數。在向Excel寫入數據后,還應用GetItem讀取相關信息并回寫到AutoCDA圖形數據庫中。
5 結束語
本文針對AutoCAD與Excel之間數據交互效率低的問題探討了使用基于ObjectARX(VC)開發的程序讀取結構化AutoCAD表單中的數據,并使用OLE技術將之導入Excel的方法。整個過程全部由程序自動完成,極大地提高了工作效率,同時避免了人工操作可能出現的種種失誤,為相關數據采集工作提供了高效的解決方案。
參考文獻:
[1]王艷平,張錚.Windows程序設計(第2版)[M].人民郵電出版社,2008.
[2]余英,梁剛.VisualC++實踐與提高COM和COM+篇[M].中國鐵道出版社,2001.
[3]張帆,朱文俊.AutoCAD ObjectARX(VC)開發基礎與實例教程[M].中國電力出版社,2014.endprint