沈 超
(昆明有色冶金設(shè)計研究院股份公司,云南昆明650051)
進入21世紀,高層建筑在國內(nèi)發(fā)展迅速,設(shè)計思想和結(jié)構(gòu)體系不斷更新并日趨多樣化,這也給高層結(jié)構(gòu)的設(shè)計與分析提出了更高的要求。在高層結(jié)構(gòu)設(shè)計中,構(gòu)件的應(yīng)力分析是一個重要環(huán)節(jié),PKPM軟件的有限元分析模塊“SATWE”在高層建筑的構(gòu)件應(yīng)力分析方面被廣泛應(yīng)用。
實際工作中,結(jié)構(gòu)設(shè)計師需對數(shù)據(jù)進一步分析、計算。雖然SATWE可將構(gòu)件的數(shù)據(jù)導(dǎo)出為文本文件,但對數(shù)據(jù)進行手工分析,不僅耗時還容易出錯,此種情況下通過編程來對導(dǎo)出的信息和數(shù)據(jù)進行分析計算,程序不需要復(fù)雜的功能和結(jié)構(gòu),“數(shù)據(jù)讀取——處理——結(jié)果輸出”的三步驟模式即可。因此,選擇一個功能滿足要求且簡單、適用的平臺來進行程序編寫無疑可以提升工作效率,而Excel VBA是可選方案之一。
文章從編程的角度簡述了Excel VBA具備的優(yōu)勢,介紹了如何對SATWE導(dǎo)出文件中的數(shù)據(jù)和信息進行利用。分析了“文件打開及文本讀取”、“中間計算”及“結(jié)果顯示”三個過程可能涉及到的編程元素,最后對程序的設(shè)計、編碼提出建議。
VBA是上世紀90年代出現(xiàn)的微軟Office平臺二次開發(fā)工具,Excel VBA是成員之一。雖然在今天看來它無論語言特性及功能均無法與當下主流的開發(fā)平臺同日而語,甚至微軟公司也推薦使用VSTO取代VBA作為Office下新的開發(fā)工具。但對于SATWE的構(gòu)件信息分析計算,Excel VBA依然具備以下優(yōu)勢:①適用于普通的分析計算。對SATWE構(gòu)件數(shù)據(jù)的計算,即非專業(yè)軟件開發(fā)且不涉及復(fù)雜的數(shù)值計算,沒有了繁復(fù)的對象間邏輯關(guān)系及處理流程。能支持面向過程編程并且有一定數(shù)據(jù)精確度的語言都可以勝任此類程序的開發(fā),VBA完全可以滿足上述要求。②簡單易學、功能強大。VBA是VB語言的子集,包含了VB常用的語法,放棄了一些復(fù)雜的語言特性。對于非專業(yè)編程人員,學習VBA要比學習主流的編程語言更加容易。同時,作為基于對象的編程語言,VBA除可以訪問Excel內(nèi)部的諸多功能,也可以訪問Windows文件系統(tǒng)等外部對象,具備Windows窗體顯示等能力,可以勝任一些需求較高的編程場合,至今依然是非專業(yè)編程領(lǐng)域的重要工具。③Excel的平臺優(yōu)勢。Excel本身就是專門的數(shù)值處理工具,原生具備強大而豐富的數(shù)值處理能力。Excel VBA可以直接調(diào)用Excel內(nèi)置的函數(shù)和對象,通過編程實現(xiàn)絕大部分Excel功能,這一便利性是許多編程語言所不具備的。④易于開發(fā)和部署。作為VBA成員之一的Excel VBA其開發(fā)環(huán)境已經(jīng)內(nèi)嵌在Excel軟件之中,無需單獨安裝,編碼及調(diào)試較為便利。開發(fā)完成的程序以“帶宏的Excel表格”形式發(fā)布,無需安裝。
在了解了VBA的優(yōu)勢之后,下面將討論如何將Excel VBA運用到SATWE構(gòu)件數(shù)據(jù)的分析計算中。
從SATWE導(dǎo)出文件中包含了構(gòu)件有關(guān)的文本說明及數(shù)據(jù)。要識別并利用這些信息需要用到Excel VBA的外部文件訪問對象、對話框及文本讀取對象。首先,要了解導(dǎo)出文件的內(nèi)容構(gòu)成。
SATWE導(dǎo)出的構(gòu)件信息文件由4個部分組成:①構(gòu)件幾何材料信息;②標準內(nèi)力信息;③構(gòu)件設(shè)計驗算信息;④荷載組合分項系數(shù)說明,每個部分均包含有文本信息及數(shù)據(jù)。
打開一個SATWE構(gòu)件信息文件應(yīng)先取得包含完整路徑的文件名稱。既可以采用系統(tǒng)默認的名稱(如:MemoInfor.txt)保存到固定的文件夾,也可以通過文件對話框來獲取。前者寫成一個字符串常量即可,但考慮到應(yīng)用的靈活性,建議以文件對話框來獲取被分析文件的名稱,如表2.1中的示例代碼。
文件對話框的申明類型及初始化方式見第1、4行,當FileDialog對象show方法返回值為-1時說明用戶按下了確定打開文件的按鈕,通過SelectItems返回完整的文件路徑(行 5)。代碼中fileName被顯式申明為"",以備用戶按下取消按鈕時能確定地返回空字符串,fd對象在使用后也被顯式地關(guān)閉。(因篇幅有限,本文不對代碼中對象成員、方法、參數(shù)的使用方式及含義進行詳述,相關(guān)對象及語法的信息可參考VBA說明文檔或手冊)。
讀取信息時,可根據(jù)需要讀取部分文本也可以一次讀取整個文件的內(nèi)容。文章中的代碼采用標示識別的讀取方式(分別設(shè)定開始及結(jié)束的文本標示),通過不同的標示設(shè)定既可以獲取某個部分的文本內(nèi)容,也可以一次讀取整個文件。
在獲取文件完整路徑后可以使用系統(tǒng)的File-SystemObject對象獲得文件的訪問權(quán),之后通過OpenTextFile方法以文本方式打開文件,并用ReadLine方法的迭代獲取整個文件的文本內(nèi)容。
表2 打開文件代碼Tab.2 Open-file code
代碼1到3行申明并初始化了讀取文本文件的對象,從第4行開始的Do While循環(huán)將依次遍歷整個文本文件,當開始讀取標志被找到后can Read被設(shè)為True,通過第9行的代碼處理將要讀取的字符串,直至碰到終止讀取標志或者文件尾,讀取后的字符串存放到一個動態(tài)的字符串數(shù)組中。
進行分析計算之前需要對已經(jīng)讀取的文本中包括的信息和數(shù)據(jù)進行識別和讀取。
對于文本信息的提取直接使用VBA中的部分字符串截取函數(shù)Mid,Mid可以靈活地分離字符串中的部分內(nèi)容,對信息的定位就需要用到mid。以導(dǎo)出文件第二部分“標準內(nèi)力信息”為例,需了解11種荷載工況分別對應(yīng)的內(nèi)力或工況號,以便在讀取工況數(shù)據(jù)矩陣的時候加以識別。通常這11種內(nèi)力信息的順序是固定的,但如果SATWE模塊升級后相關(guān)內(nèi)力信息的排布位置如果發(fā)生變化,需要修改代碼以適應(yīng)。要靈活應(yīng)對變化,可在讀取工況文本說明后,對每種工況的編號做識別。
圖1 標準內(nèi)力信息的文本Fig.1 text of standard internal force information
工況信息的讀取見圖1。每種工況的編號均在正反括號內(nèi),且在一行中只出現(xiàn)一次,使用InStr函數(shù)定位正反括號的位置,就可以直接讀出工況的編號數(shù)字,轉(zhuǎn)為整型變量即可。對于工況類型的判斷可以采用標志詞的判斷法,如“X方向地震”、“Y向風力”等,同樣使用InStr函數(shù),如果返回值不為0則表示文本包含標志詞,用于判斷的標志詞可以作為字符常量寫入代碼或者存放于Excel工作表待使用時再讀取。
圖2 荷載工況數(shù)值矩陣Fig.2 Values matrix of load case
荷載工況數(shù)據(jù)處理需要將讀取后的行文本轉(zhuǎn)為數(shù)字,見圖2。荷載工況的數(shù)據(jù)通過空格字符分開,可采用Split函數(shù)進行分離,工況數(shù)據(jù)文本間的空格數(shù)量不一,最少有3個,多的有5個,分離標志字符串可設(shè)為3個空格字符串。低于3個空格時可能會將部分空格字符分離為獨立字符串,產(chǎn)生垃圾數(shù)據(jù),使用3個空格進行分離后的每個字符串只包含1個工況數(shù)據(jù),多余的空格可以通過Trim函數(shù)去除。
分離并轉(zhuǎn)換后的數(shù)字可存入結(jié)構(gòu)體類型,使用type關(guān)鍵詞定義(如將其定義為“BeamLoadData”類型),再申明BeamLoadData類型的動態(tài)數(shù)組,即可將整個工況數(shù)據(jù)存入,并根據(jù)需要進行調(diào)用。需要注意的是:梁構(gòu)件的位置信息與其它構(gòu)件不同,圖2顯示的是梁構(gòu)件的情況,如果結(jié)構(gòu)體以單個工況下各位置的數(shù)據(jù)作為成員(即文本中一行的數(shù)據(jù)作為一個結(jié)構(gòu)體類型)就需要針對其它構(gòu)件的數(shù)據(jù)構(gòu)成來定義結(jié)構(gòu)體;如果以構(gòu)件各位置下的工況數(shù)據(jù)作為成員(文本中的一列作為一個結(jié)構(gòu)體類型),則不需要針對不同構(gòu)件定義結(jié)構(gòu)體類型,但建議在結(jié)構(gòu)體中增加一個字符串成員以標示本列數(shù)據(jù)屬于哪個位置。具體采用何種定義方式,視實際分析計算的需要而定。
其它部分的信息及數(shù)據(jù)讀取方式可以參照上文示例,文本信息轉(zhuǎn)換為數(shù)值和可識別信息后就能被用于計算、分析。因?qū)?shù)據(jù)的利用方式各有不同,有關(guān)具體計算過程的編碼就不在此討論。
數(shù)據(jù)在計算完成后需要將計算的結(jié)果呈現(xiàn)給使用人員,以便在設(shè)計工作中參考使用。不同的計算需求形成的結(jié)果數(shù)據(jù)的形態(tài)各有不同,本文將以二維矩陣為例描述結(jié)果輸出的方式。
以圖3的顯示的結(jié)果數(shù)據(jù)為例,計算各種系數(shù)組合情況下構(gòu)件各位置的受力的復(fù)合值,行數(shù)據(jù)為分項系數(shù)編號,列為構(gòu)件位置。Excel VBA的便利性之一就是可以直接將數(shù)據(jù)寫入Excel表格,通過Sheets對象的Cells方法可以直接對單元格的內(nèi)容進行讀寫,將計算結(jié)果寫入指定的表格之中。
圖3中單元格右上角的紅色標記是單元格注釋,內(nèi)容是數(shù)值的計算過程。對于比較復(fù)雜的計算,如果能將參與計算的數(shù)值及計算方式列出,不僅有利于程序調(diào)試,也可以為使用者提供參考。圖4為計算過程顯示示例。
圖3 計算結(jié)果顯示Fig.3 Calculation results display
圖4 單元格注釋Fig.4 Cells comment
當鼠標移動到單元格之上時注釋文本就會自動顯示。要對單元格添加注釋可以通過表3中的代碼實現(xiàn)。
表3 添加注釋代碼Tab.3 Adding comments code
選中要添加注釋的單元格(第2行),通過ActiveCell對象的AddComment方法添加注釋文本,通過 ActiveCell.Comment.Shape 對象的 Height 和Width屬性可以控制注釋顯示框的大小。
良好的設(shè)計和編碼不僅有利于用戶的使用、調(diào)試和修改也利于未來需求變化時的增加和改動。
VBA是事件驅(qū)動語言,用戶的操作都是通過對各種控件(如命令按鈕)或可編程元素(如特定的工作表、單元格)來觸發(fā)的。Excel VBA有3種可利用的界面:①Excel表格;②內(nèi)嵌的Windows窗體;③自定義工具欄。選用何種界面提供給用戶進行操作需要根據(jù)具體情況斟酌,上述3種操作界面各有優(yōu)劣。
Excel表格的優(yōu)勢是直觀,可放置各種控件,用戶打開表格即可見,不足之處是直接在表格上放置控件影響界面的美觀性,針對特定單元格進行編程要注意避免用戶無意間修改單元格內(nèi)容。使用Excel表格作為界面時1個工作表僅作單一用途,如:數(shù)據(jù)讀取、計算、結(jié)果顯示分別放置在不同的工作表,一表多用容易讓用戶產(chǎn)生歧義和誤解。僅顯示當前操作所需工作表,關(guān)閉暫時不需要的表格,如初始數(shù)據(jù)讀取時僅需要顯示當前工作表,將中間計算過程及結(jié)果顯示表格暫時關(guān)閉,待需要時再打開。
Windows窗體的優(yōu)勢是符合日常界面的操作習慣和視覺特征,窗體的控件和數(shù)據(jù)與工作表內(nèi)容相互獨立。Windows窗體是Excel VBA中一個強大的工具,將控件放置在窗體,工作表僅用于數(shù)據(jù)顯示是一種常用的設(shè)計風格。不過Excel中的窗體可選控件的數(shù)量有限,而且過多的窗體和過多的工作表一樣,都不利于用戶的使用。
自定義工具欄的直觀性和界面元素最少,可作為窗體的替代,優(yōu)勢是不占用表格顯示空間。由于可編程元素最少,建議用于基本功能的選擇而不是實際操作。如程序具備分析、計算兩個基本功能,可通過自定義工具欄來進行選擇。
動態(tài)數(shù)組是分析計算程序中最常用的數(shù)據(jù)容器,SATWE構(gòu)件信息中的數(shù)據(jù)大多以二維矩陣形式存放,結(jié)構(gòu)體與動態(tài)數(shù)組可以完整還原二維矩陣。Excel VBA還可以把Excel工作表用作數(shù)據(jù)容器,申明一個臨時工作表,將數(shù)據(jù)暫存并使用Excel內(nèi)置的功能進行預(yù)處理。
高內(nèi)聚、低耦合。把需求功能分解后按相互耦合的功能或函數(shù)來設(shè)計代碼。不要把順序執(zhí)行但不同的功能放在一個函數(shù)中,如文件名稱的獲取、內(nèi)容的讀取、字符串轉(zhuǎn)為數(shù)字三個功能可以設(shè)計為三個函數(shù),將文件名、內(nèi)容文本的字符數(shù)組等作為參數(shù)相互傳遞。中間的計算過程和結(jié)果顯示也風格為不同的函數(shù)。高內(nèi)聚、低耦合不僅有利于調(diào)試,也可以較好地應(yīng)對未來需求變化時候代碼的改變。
非界面控制代碼單獨存放。非界面控制類的代碼,應(yīng)該放置到公共代碼文件.bas中,而不是直接寫入工作表或者窗體的事件代碼,當界面發(fā)生改變時不會影響到界面控制之外的其它功能。
目前,昆明有色冶金設(shè)計院股份公司信息中心已經(jīng)參照文章內(nèi)容為公司結(jié)構(gòu)專業(yè)開發(fā)了一個SATWE構(gòu)件計算程序并投入使用。Excel VBA雖然是一門較老的語言,但在合理利用其特性的基礎(chǔ)上,也可以在結(jié)構(gòu)專業(yè)構(gòu)件數(shù)據(jù)、信息分析工作中發(fā)揮重要的作用。
[1]欒鈺.淺談SATWE進行結(jié)構(gòu)設(shè)計時應(yīng)注意的問題[J].山西建筑,2006,32(22):100-101.
[2]楊章偉,張婉婉.EXCEL VBA語法辭典[M].北京:機械工業(yè)出版社,2009.