2014-11-19

利用AutoCAD 的Attribute(屬性)與Excel的結合應用

AutoCAD中,可以利用屬性(Attribute)功能來達成圖面上的資料匯出成如材料表之類的東西,不過這部份似乎運用在機械產業比較好用的感覺(個人見解啦),於營建業上,有運用到的,大概是測量點與門窗統計之類的功能....


要了解後續的內容,首先你可能需先熟悉下面幾個運用方法:

  1. 如何建立帶有屬性(Attribute)的圖塊(Block)...這個應該簡單
  2. 如何將圖面中特有的圖塊給篩選(屬性萃取)出來

早期AutoCAD要篩選出數據還蠻不方便的,你要建立對應的樣版檔再做,樣版檔的格式又有規定,您還需要查閱規格文件才能正確列出數據,不過新版的ACAD(不知道幾版以後開始,至少2008版就有,2005版就還沒有)已經可以很快速的建立篩選條件並與Excel做一定的整合,比如說:你在某樓層可以統計初各個窗戶的編號與數量,當然你要先做帶有屬性圖塊的內容並完整填入給個所有門窗才行..等

 以上拉雜一堆將導入本文的主要內容~~

一般建築圖面的門窗編號標示,一般僅標示編號,或是編號與寬度,至於高度與台度(dado)你就必須到門窗表去查詢,這樣的圖面不太能符合施工用軀體圖的需求(要帶很多圖面到現場才能施作),依我實做的方式是將必要的尺寸標示在圖面以方便模板師父施作,不過問題來了:標註D1門,我就要到門窗表查尺寸,然後回到施工圖做標示,一兩個門窗就算了,一個樓層平均都有二三十個門窗,加上在下已有老花現象,又是摘眼鏡查尺寸,又是戴眼鏡做尺寸標註,來回十次我就受不了,而且還會有看錯或填錯數據的風險...當然也就把腦筋放在如何快速處理這樣呆板的循環動作。

我的作法架構是:將所有門窗表必要的資訊填在Excel,在Autocad中只要打入門窗編號它就自動在Excel搜尋相關數據並丟到圖塊的屬性上,讓你填入....選用Excel的原因是因為易於編修

後端的資料厙,可以是文字擋(CSV)/Access(MDB)/Excel(XLS)..等,甚至你可丟MS SQL 或MySQL(<<--生意有做那麼大嗎??),最後我選擇利用Excel來做後端資料庫..

版本一
在AutoCAD中程式中建立Excel元件,去逐次搜尋ACAD中所指定的門窗編號,然後將如寬度/高度/台度等資訊傳回ACAD中並自動傳入屬性圖塊中且插入圖面中。(平均2-30秒)的動作,10秒搞定。)
或許您會說那還要10秒,那是因為我笨(程式寫得不好)..況且我不用人工去查表。之所以會那麼慢是因為兩個原因:
1. 每輸入一次編號,系統就建立一次Excel元件,因為是背景操作,所以在ACAD中感覺好像當機的樣子。
2. 利用Excel對沒個欄位做循序查詢,效能太爛

版本二
由上可知看來不得不打掉重練了..我改以資料庫的作法,利用ADO元件(ActiveX Data Objects)的方式來處理,好在ADO支援Excel的查詢,雖然Excel的資料筆數有限(65536筆),但對我的需求來說足夠了..^^ ,但把Excel當後端資料庫來用,我還是第一遭,裡面有不少的問題需要克服,不過終究走過來了...現在2秒鐘就搞定,這樣應該不笨了..呵呵..

這次的程式有幾個需要注意的問題,提供給有可能需要類似這種作法的大大參考
1.  ADO的資料庫連線字串,我是利用OLEDB作連線..(還有其他方式,可參MS的技術資料)
    Dim conn As ADODB.Connection
    Set conn = New ADODB.Connection
    conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
           "Data Source=" & ExcelFullFilePath & " ;" & _
           "Extended Properties=""Excel 8.0;"""

 其中 8.0表示可以開2003版Eexce 12.0好像2007版..

2. Recordset
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Dim sqlStr As String
sqlStr = "select * from [" & SheetName & "$]  where [NO]='" & XXX & "'"
 rs.Open sqlStr, conn, adOpenDynamic, adLockOptimistic
重點在T-SQL語法中,若你要查詢的Excel工作表為Sheet1記得要在工作表名後面加$號並以中括號([ ])包起來,如
Select * from [Sheet1$]
若要增加篩選條件where 則 欄位名也要以中括號包起來(否則會回覆程式錯誤),如
Select * from [Sheet1$] Where [NO]='W2'
原則上若你沒特別設定,程式認定Excel的第一列為欄位名稱

3.在ACAD中利用VBA來做InsertBlock動作時,程式內定是將屬性預設值給填上,並無方法可以填入你要的數據。你需要再額外將該Block元件中所有屬性物件給抽離出來,並替換由Excel的所篩選出來的數據。

或許你可以用SendCommand指令來完成上述作業也可,只是我覺得那種作法不太專業罷了...

4.在Excel中建立資料時需注意,整欄數據格式需一樣,這部份讓在下吃足了苦頭,網路上更查不到相關的內容報告。

若您的資料為數值,就必須全部是數值(Value),若為文字就需全部是文字(String) ,若是數字與文字混用,拍謝喔!程式撈出來該欄位的資料為空,這部份讓我苦惱好幾天,因為我們有時會利用運算處理後的內容,才會加以運用。

比如窗戶台度來說,若指定60公分,在軀體圖中我們一般會標示57.5(窗開口加大2.5cm以利安裝),不過並非所有門窗都有台度,如門就沒有,那我們會標示"-"表示無台度,這樣的情形ADO竟然無法判斷,我也嘗試將台度所有儲存格強制設定程文字,不知道是不是Excel擁有自動運算的關係,它並未強制轉換,當然ADO去撈資料時還是空內容。

(重點)但當該儲存格已設成文字,且你KeyIn有數值的數據,雖然程式在儲存格左上角會顯示一個綠色小標籤警告(其內容大致告知儲存格為文字型式但你輸入數值之類警告),可是呢!這時候程式竟然就順利撈到資料了,苦的是我要將台度數據重新KeyIn一次,這部份我再研究研究有啥好方法可以解決...目前就暫時用本方式吧...

以下是整個操作過程



建築設計常常在設計變更,每個樓層數十數百個門窗,每次若要一一檢核似乎是個大工程,似乎還需增加"更新資料"之類的的模組,待程式完成後再行撰文說明...

2014/12/06 關於Excel直接轉換成文字格式,目前先在Excel中寫個循環模組來刷資料,可以順利將某欄位的資料全轉換成文字格式...

6 則留言:

  1. 好程式,可分享嗎?

    回覆刪除
    回覆
    1. 你好:因為程式不完善,所以要跟您說聲抱歉..><

      刪除
  2. 可以向您討教一些cad抓資料進EXCEL的方式嗎?

    回覆刪除
    回覆
    1. 你好,若要由ACAD撈取屬性資料,你可以利用屬性萃取(ddattext)方式轉出成文字檔,再由EXCEL讀入,若是物件的話,我會的方法是由程式來處理..有個人交流歡迎MAIL聯繫

      刪除
  3. 您的發文~很棒!!拜託~可以再詳細教學一下~~我很想學習!!對我非常有幫助~~感謝!!

    回覆刪除
    回覆
    1. 其實我網誌,旨在提供營建自動化的想法,而非教學...><

      刪除