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