張宗科
(中國船舶工業(yè)集團公司第七○八研究所 上海200011)
通常而言,一條船的設(shè)計階段包括方案設(shè)計、技術(shù)設(shè)計、施工設(shè)計與完工設(shè)計。在專業(yè)分工組成上,分為總體、結(jié)構(gòu)、舾裝、輪機、電氣、空調(diào)、觀導(dǎo)等專業(yè)。圖紙文件目錄是船舶設(shè)計各專業(yè)圖紙文件的一份明細,它由總體專業(yè)加以匯總,其中所需的圖紙文件有關(guān)信息見圖1。一般在各設(shè)計階段的最后幾天才能提交,這樣留給總體專業(yè)匯總的時間非常緊迫,特別是對于軍船等時間節(jié)點要求“后墻不倒”而言,更是迫切。對于一條船來說,少則有幾百份設(shè)計圖紙文件,多則有上千份,因此匯總圖紙文件目錄是件十分繁瑣的事。有時歸檔的蠟紙打印好,對照圖紙實物逐份校對后,還要對圖紙文件目錄進行返工。如何利用各專業(yè)最終完成的圖紙文件將匯總目錄所需信息自動提取出來,從而減少人工工作量將是一件非常有意義的事。
圖1 圖紙文件目錄中所需的圖紙文件有關(guān)信息
AutoCAD作為工程技術(shù)人員使用的繪圖工具,具有多種二次開發(fā)方式,如內(nèi)嵌的AutoLISP/Visual LISP開發(fā)語言、VBA,以及ObjectARX與Visual Basic。利用VB編程對AutoCAD進行二次開發(fā),不僅可將AutoCAD當作自己VB程序中的一個圖形窗口,而且可實現(xiàn)使用AutoCAD直接繪圖自身所不能或不易實現(xiàn)的功能和效果。Word與Excel內(nèi)嵌了功能強大的VBA開發(fā)工具,在同作為Micorsoft公司產(chǎn)品的VB眼中看來,操控Word與Excel更是得心應(yīng)手。
七○八所軍船中心在圖紙文件設(shè)繪中都采用了標準圖框,這為圖紙文件信息的自動提取奠定了基礎(chǔ)[1,2]。在設(shè)計過程中,各專業(yè)圖紙文件存放于自己專業(yè)的文件夾內(nèi),進而組合形成一個不同設(shè)計階段的文件夾。根據(jù)選定的設(shè)計階段文件夾,利用批處理命令“dir*.*/b/a:d->listDir.dat”獲得子文件夾的名稱,再由“dir*.dwg/b/s->listdwg.dat”、“dir*.doc/b/s->listDoc.dat”、“dir*.xls/b/s->listXls.dat” 得到子文件夾(不同專業(yè))下三類文件的名稱?;蛘哂蒁ir(MyPath,vbDirectory)與(GetAttr(MyPath&MyName)And vbDirectory)=vbDirectory來找到某個文件夾下面子文件夾的名稱列表,再由 Dir(MyPath,vbNormal)與 (GetAttr (MyPath&MyName)And vbNormal)=vbNormal,(InStr(MyName,".dwg")>0)來找到子文件夾下AutoCAD文件的列表。用VB分別控制AutoCAD、Word與Excel,將圖紙文件的有關(guān)信息提取出來,如圖紙代號、名稱、張數(shù)、面積、密級等,從而為圖樣和技術(shù)文件目錄的匯總提供基礎(chǔ)。同時還可獲得每份圖紙的編制、校對、審核、標檢與審定人員的名字,以及圖紙會簽的信息。
程序自動將每個專業(yè)的圖紙文件信息形成一個數(shù)據(jù)文件,并且將其中有問題的圖紙文件以備注方式標出錯誤種類,如頁數(shù)、面積有誤等。在Excel中打開該文件,對圖紙代號所在的列進行“有標題行”的升序排序,即可得到滿足打印條件的“全船圖樣及技術(shù)文件目錄”文件。
七○八所軍船中心在圖紙設(shè)繪中采用了統(tǒng)一的圖框格式,每份圖紙文件信息(如文件名、圖號、頁數(shù)、面積、密級等)均作為Block的Attributes包含其中。本文仔細分析了圖框的格式及組成,利用VB編程操控AutoCAD將每份圖紙的信息自動提取出來,并輸出到文件中加以匯總[3]。同時可自動驗證原圖紙中的反向圖號、總面積、總頁數(shù)等信息是否有誤。對于產(chǎn)品名稱 (PRODUCT-NAME)、圖紙名稱(DRAW-NAME)、密級(STANDBY4)等信息,有時由于特殊字符的存在或字數(shù)太多太長,并不是作為Attribute的屬性值而存在,則利用圖框中該位置處(區(qū)位框四周打×者)與當前Pixel_Unit獲得相關(guān)信息,用CP方式進行選擇。若該區(qū)域存在格式Block以外的對象,則自動提取出來,并作為相應(yīng)tag的value輸出到文件內(nèi)。將frame_title_c/ce的組成部分插入到文件中時,先后關(guān)系不變,但以insert為基點,用塊信息 Xscale、Yscale、Zscale 進行縮放,見圖2。產(chǎn)品名、文件名、密級的選取定位,需要Line0、Line2、Line3中的有關(guān)信息。 frame_title_c與frame_title_ce略有不同,Block中的成員編號70相應(yīng)于71號,其后依次相應(yīng)減1。
圖2 七○八所統(tǒng)一圖框的圖紙信息欄
用VB控制AutoCAD提取dwg文件有關(guān)信息的流程,參見圖3。提取出每份dwg文件的信息后,程序中可檢查各頁圖紙的面積之和與總面積是否一致,若有誤,則給出錯誤提示標識。同時可獲得dwg文件所標出的重量信息,用于重量重心計算書的校對。
Word文件主要包括計算書、說明書、明細表等,分為豎式與橫式兩種,其中豎式封面見圖4。
圖3 使用統(tǒng)一圖框的圖紙信息提取流程
圖4 七○八所統(tǒng)一圖框的豎式Word文件封面首頁
利用VB編程,經(jīng)Active OCX CreateObject方式創(chuàng)建Word應(yīng)用,打開相應(yīng)的word文件,盡可能將首頁內(nèi)容選中并copy至剪貼板上,然后paste至記事本文件內(nèi)或者Excel文件內(nèi)進行下一步的信息處理。自動提取出有關(guān)信息,如文件名、圖號、總頁數(shù)與面積等。
當Word文件由兩個及多個Section組成時,封面首頁為第一個Section,利用其相關(guān)信息,可選中整個封面頁,將該頁內(nèi)容copy至剪切板,paste并保存到temp.dat中,再對此文本文件進行處理,提取出有關(guān)信息來,不過需要Delay合適的時間間隔。
若Word文件僅由一個Section組成,可通過翻轉(zhuǎn)到文件最后一頁最后一行,由插入numPages域的方式來獲取頁數(shù),由此得到封面首頁的近似wdStory end值,將包含封面首頁在內(nèi)盡可能少的內(nèi)容copy至剪切板[4]。
用VB控制Word提取doc文件有關(guān)信息的流程,參見圖5。
圖5 使用統(tǒng)一圖框的Word文件信息提取流程
Excel文件主要包括重量重心計算書、電纜冊、設(shè)備明細表等,其中“封面”sheet見圖6。
利用VB編程,經(jīng)CreateObject方式創(chuàng)建Excel應(yīng)用,打開*.xls文件。判斷sheet Name中是否有“封面”。 若有,則經(jīng) xls.Application.Sheets("封面").Select,激活“封面”sheet,由 ActiveSheet.UsedRange.Rows.Count來獲得已經(jīng)應(yīng)用的范圍,取得iRowBegin與iColBegin。利用Set foundCell=ExcelSheet.Application.ActiveSheet.UsedRange.Find (What: ="Area",After: =ExcelSheet.Application.ActiveCell,LookIn:=xlFormulas,LookAt: =xlPart,SearchOrder: =xlByRows,Search Direction: =xlNext,MatchCase: =False,MatchByte: =False,SearchFormat:=False)得到各感興趣 cell的位置,再將所需信息提取出來。
用VB控制Excel提取xls文件有關(guān)信息的流程,參見圖7。
圖7 使用統(tǒng)一圖框的Excel文件信息提取流程
下面談一下Excel打印時在頁面上的任意位置處自動插入頁碼的實現(xiàn)方法。
船舶設(shè)計中的“全船電纜冊”,少則十幾頁、多則幾百頁,此Excel格式的文件要求打印出的每頁具有相同的表頭,且在表頭的同一位置處需插入頁碼。Excel文件可利用“Print title”功能,使得打印出的每頁文件具有相同格式的表頭;分頁由Excel自動完成,可方便添加或刪除任意行,而不像Word中必須重新手動調(diào)整分頁位置;當然也可在分頁預(yù)覽狀態(tài),按需手工調(diào)整分頁符的位置。相對于Word文件中的頁碼“所見即所得”,Excel文件中的頁碼只有在打印預(yù)覽或輸出時才顯示出來,這使得調(diào)整其位置較為不便。
在打印區(qū)域之內(nèi)的任意位置,設(shè)定頁碼可用兩種方式:利用頁面設(shè)置中的頁碼按鈕,以自定義方式將頁碼插入;利用VBA中的HPageBreaks與VPageBreaks屬性,將取得的頁碼插入到Excel文件的相應(yīng)cell中。
2.3.1 自定義頁碼方式
在Print Preview中,頁碼垂向的位置調(diào)整,可通過按下“頁邊距”按鈕,然后拖曳頁眉的頁邊距(為頁眉頂端到頁面頂端的距離)控制柄到所需的位置,調(diào)整頁眉頂端到頁面頂端的距離。頁碼的默認位置,在頁面的水平方向是固定的,如LeftHeader左邊距左邊界為 0.75 inch (54 pt),CenterHeader處于頁面水平方向的正中間,RightHeader右邊距右邊界為0.75 inch(54 pt)。水平方向的位置調(diào)整,可通過“頁眉/頁腳”中的“自定義頁眉”選項中的左、中、右三個文本框內(nèi)設(shè)置相應(yīng)的頁碼。其中右邊的設(shè)置頁碼框內(nèi)頁碼位置不能調(diào)整,而左、中兩個文本框內(nèi)頁碼的位置可添加空格鍵的方式調(diào)整(即向右側(cè)移動),這樣可在生成的打印輸出頁面的任意位置處設(shè)置頁碼。Excel中行高的尺寸由長度單位磅(pt)給出,(1 pt=1/72 inch或0.035 cm),而列寬是單元格中0~9號標準字體(工作表的默認文本字體,標準字體決定了“常規(guī)”單元格樣式的默認字體)平均數(shù)的倍數(shù) (the average number of digits 0 through 9 of the standard font that fit in a cell)。如標準字體為“宋體”,字形為“常規(guī)”時,0-9號標準字體的平均數(shù)中的1相當于6磅。在“頁面設(shè)置”中設(shè)定起始頁碼,通過增減空格或換行來調(diào)整頁碼在頁面上的位置,此外可經(jīng)設(shè)定空行相應(yīng)的字體大小來微調(diào)頁碼的位置。
2.3.2 給指定的單元格賦值方式
相對于只能在輸出頁面上的某一位置設(shè)定頁碼“&P”的限制,可以將通過其他途徑獲得的頁碼值直接賦值給Excel中的cell,從而實現(xiàn)頁碼的自動設(shè)置。正常情況下可由ActiveSheet的(1+HPageBreaks.Count)與(1+VPageBreaks.Count)相乘得到總頁碼,其余情形下總頁碼的獲取詳見程序中。根據(jù)PageSetup的Order值 (xlDownThenOver或xlOver ThenDown),得到預(yù)覽(或輸出)時的先后順序,從而確定以HPageBreaks或VPageBreaks為內(nèi)循環(huán)設(shè)置頁碼數(shù)?!?P”僅在預(yù)覽或打印輸出時才能轉(zhuǎn)換成具體的數(shù)值,在程序中不能參加運算。而由此方式獲得的頁碼與“&P”不同,它僅僅是一個循環(huán)計數(shù),故可參加程序的運算,如將頁碼設(shè)置為羅馬數(shù)字的“I、II、III…”及其他的個性化頁碼(將“頁碼”設(shè)置為僅有偶數(shù)值)。而頁碼字符的大小及頁碼之間的對齊方式,可由其所依附的Cell的單元格格式中的“字體(Font)”與“文本對齊”(Text Alignment)選項來設(shè)置,因而也更為靈活。
程序中的具體實現(xiàn)方式,由InputBox選擇頁碼相應(yīng)的指定Cell,并由另一InputBox輸入需打印的總頁數(shù)及首頁頁碼數(shù)值,其余由程序自動完成。不過由于本文假設(shè)的Excel文件在預(yù)覽或輸出時具有相同的表頭,程序是對每一頁進行循環(huán)得到頁碼數(shù),進而將其值賦給指定的Cell。(對于非相同的標題行,最好由第一種方式設(shè)置頁碼)。效果可由Adobe Acrobat(完全版)安裝后自帶的Acrobat Distiller虛擬打印機生成pdf格式文件加以檢驗,不過需給定多個文件名(每頁一個文件);直接打印到物理打印機則無此問題。
2.3.3 設(shè)置頁碼兩種方法的比較
自定義頁碼方式保證了打印輸出時頁碼的一致性,并對整個WorkSheet或打印區(qū)域起作用;但位置及對齊方式可能會影響到文件的美觀,且有時調(diào)整會較費時。利用本文程序中第二種方法插入頁碼,對具有統(tǒng)一標題頭的文件,操作較為方便,且可設(shè)置個性化頁碼(如甲、乙、丙、丁等);但當生成的Excel文件橫向有較多頁時,需以(1+VpageBreaks.Count)為外循環(huán)數(shù),對橫向的每一頁列都需指定標題行中插入頁碼的Cell位置。
整船的重量重心計算書由各專業(yè)提交的分項重量重心匯總而成,而各專業(yè)提交的分項方式不盡相同。如結(jié)構(gòu)分項為船體、艙棚、駕駛室、主機基座、支架等;舾裝分項為錨及系泊設(shè)備布置圖、方向舵系布置圖、門/窗/蓋/梯/欄桿布置圖、消防救生設(shè)備布置圖、艙室布置圖、油漆、供應(yīng)品等;輪機分項為發(fā)動機、軸系、油箱、水箱等;電氣分項為主配電板、充放電板、駕控臺、燈具、蓄電池、電纜及附件等。相對而言,舾裝專業(yè)各布置圖相應(yīng)的重量可按圖索驥,由程序直接從圖紙信息欄中提取出來。
如何判斷驗證各專業(yè)的分項重量分布是否有誤,是一項費力的工作。將各重量位置直接在總圖上表示出來,不失為直觀的輔助手段,合理與否盡可一目了然。本文利用VB編程,直接將重量重心計算書中不同sheet(專業(yè))的重量分項名稱及其坐標表示在總布置圖上,其中每個sheet放在一Layer內(nèi)(Layer名為 sheet之 name),這樣便于操作[5]。 此外,某項重量在俯視圖與側(cè)視圖上的標識各有一個,以對應(yīng)三維坐標。為方便對照,程序中將該對標識自動加以編組,形成一個Group。另,為便于調(diào)整某一重量Layer中字體大小,編寫了LISP輔助程序,只要任選一個標識text,即可對該標識所在Layer內(nèi)的所有標識更改文字大小。
本文編程在AutoCAD中進行二次開發(fā),輔助實現(xiàn)CAD圖紙中有關(guān)文件信息的自動提取,對Word與Excel文件信息提取亦開發(fā)出相應(yīng)程序,可減少人工統(tǒng)計的工作量,為總體專業(yè)省出寶貴的時間,以完成快速性、續(xù)航力、完整穩(wěn)性、破艙穩(wěn)性等有關(guān)圖紙的計算編制。編程自動提取不僅可避免人工統(tǒng)計時出現(xiàn)失誤,同時可對原文件信息加以驗證,糾正原圖紙中的一些基本失誤。此外,對重量重心分布位置的判讀校驗提供了有效的輔助手段。
[1]錢浩.AutoCAD圖紙批量打印程序的開發(fā)與應(yīng)用[J].船舶,2006,17(1):61-63.
[2]徐天曉.利用VB二次開發(fā)AutoCAD提升打印功能[J].船舶,2009,20(3):61-64.
[3]張晉西.Visual Basic與AutoCAD二次開發(fā)[M].清華大學出版社,2002.2.
[4]顧經(jīng)宇.其實你還沒懂Word[M].上海科學技術(shù)出版社,2002.
[5]二代龍震工作室.AutoCAD VBA函數(shù)庫查詢詞典[M].中國鐵道出版社,2003.