摘 要: 在軟件中填充和擴展Word表格的實現(xiàn)原理及方法,并給出了VB程序示例。
關(guān)鍵詞: Word RTF 表格 填充 Visual Basic
在一些軟件的使用過程中,用戶需要把計算結(jié)果生成一定格式的Word環(huán)境下的數(shù)據(jù)表格,以便直接插入到工作報告中。本文將介紹一種Word表格的自動填充方法。該方法利用Word文件的RTF(Rich Text Format)存儲格式的特點,可滿足用戶的要求,并能進一步實現(xiàn)行列數(shù)可變的表格的生成。本方法簡單有效,且無需Word軟件的支持。
1 RTF格式簡介
Word文件有多種存儲格式,除常用的“.doc”外,還有一種“.rtf”。本文將借助RTF格式實現(xiàn)對表格的操作。RTF是一種純文本描述性的格式。文件內(nèi)容全部為ASCII碼,可用記事本打開,從而可以看到其全部的描述內(nèi)容,也可以在應(yīng)用軟件中打開該文件并進行修改。表格的自動填充及擴展就是通過這種方式實現(xiàn)的。
在一個RTF格式的Word文件中,可以看到用“\”隔開的表示各種格式的字符串和數(shù)字,且Word版本越高其格式越復(fù)雜。但是只需知道幾個有針對性的關(guān)鍵的格式字符串及其規(guī)律即可。
任何編程語言對文本文件和字符串的操作都比較簡單,故用任何一種語言實現(xiàn)對表格的操作都將是簡單可行的。
2 創(chuàng)建表格模板
先要根據(jù)用戶的需要,借助于Word軟件創(chuàng)建表格模板文件,步驟如下。
(1)運行Word軟件,按照用戶的要求插入表格,設(shè)置格式,并根據(jù)操作的需要預(yù)填單元格。表格模板示例如表1所示。
(2)單擊菜單的“文件/另存為”,文件類型選為“.rtf”,保存即可。此文件即為表格模板文件。
(3)在程序中打開此文件,進行相應(yīng)操作后,另存為新的目標(biāo)文件。這就是用戶需要的數(shù)據(jù)表格。
(4)用戶用Word軟件打開該新文件,可看到填充后的表格,將該表格復(fù)制、粘貼到用戶的Word文檔中即可。
下面以Visual Basic為例介紹如何實現(xiàn)對模板文件的操作。
3 表格的填充
在RTF格式的模板文件的ASCII碼中,可以看到類似“……\hich\af0\dbch\af15\loch\f0 AA22\cell……”的字符串。其中,“\cell”表示這是在描述一個單元格的格式及內(nèi)容,“AA22”是單元格內(nèi)容,前邊的字符串是關(guān)于其字體、字號等格式的描述。
RTF在格式描述符中極少用大寫字母,且不會連續(xù)使用大寫字母,例如有可能出現(xiàn)“Width”但不會出現(xiàn)“WIDTH”、“WI”及“A2”等字樣。所以,如果每個單元格的內(nèi)容都是大寫字母或數(shù)字且互不相同(如表1),則它們在整個文件的描述字符串中就是惟一的。在軟件中找到該惟一的特征字符串并用相應(yīng)的字符串替換,就實現(xiàn)了表格的自動填充。由于這種填充方式只涉及單元格內(nèi)容而與格式無關(guān),所以預(yù)先創(chuàng)建的模板表格可以是任意復(fù)雜的,且每個單元格的字體、字號等格式也是任意的。
在替換時如果有漢字,則應(yīng)先將其轉(zhuǎn)換成用ASCII碼,如“日”要轉(zhuǎn)換成“\′c8\′d5”(“日”的十六進制編碼為“C8D5”)。
實現(xiàn)表格自動填充的VB源代碼如下:
Private Sub FillGrid(MaxDimension As Integer,
StrSourceFile As String,StrTargetFile As String,
StrSource( ) As String,StrTarget( ) As String)
'功能:替換RTF格式的模板源文件中的單元格內(nèi)容,
′并生成新的RTF格式的目標(biāo)文件
′MaxDimension為內(nèi)容數(shù)組的維數(shù),可以大于表格單元的總個數(shù)
′StrSourceFile和StrTargetFile分別為RTF格式的模板文件名和目標(biāo)文件名
′StrSource( )和StrTarget( )分別為被替換單元的原始容內(nèi)和新內(nèi)容的字符串?dāng)?shù)組
Dim i As Integer,S1 As String,P As Long
LoadFileToStr StrSourceFile,S1′把模板文件讀入到字符串S1中,源代碼略
For i=0 To MaxDimension-1
P=InStr(S1,StrSource(i))′在源文件字符串中搜索將被替換的字符串的位置
If P>0 Then ′如果找到則進行字符串替換在字符串替換時,因為新串可能比舊串長,
′所以不能使用串替換命令,而應(yīng)把整個字符串分成3段,并重新組合
S1=Left(S1,P-1)+StrTarget(i)+Mid(S1,P+Len
(StrSource(i)))
End If
Next i
WriteStringToFile StrTargetFile,S1′寫入目標(biāo)文件,源代碼略
End Sub
該程序的特點是參數(shù)表中數(shù)據(jù)字符串StrTarget( )的維數(shù)與當(dāng)前表格單元格的個數(shù)無關(guān)。這是因為,一個軟件一般支持多種數(shù)據(jù)類型,通常希望生成含有不同種類數(shù)據(jù)的多種表格。如果將每種數(shù)據(jù)均與某個互不相同的特征字符串綁定,所有特征字符串和數(shù)據(jù)均放在StrSource( )和StrTarget( )中,則不論表格有多大,該程序均完全適用。
4 增加表格的列數(shù)
在有些應(yīng)用軟件中,要處理數(shù)據(jù)的種類(表格的列項)很多,但用戶希望表格的列數(shù)可以任意變化。這時可采用對最少列數(shù)的標(biāo)準(zhǔn)表格模板任意增加列的方法,得到與模板表格的行數(shù)相同但列數(shù)任意多的表格。新列的格式與所選定的被復(fù)制列相同。
下面介紹簡單表格(整行整列)的增列方法。對于特殊表格的加列,則需根據(jù)具體情況編程,雖然程序復(fù)雜一些,但方法大同小異。
一個有表格的RTF文件中,在該表格的描述字符串的前、后和中間都會有對該表格的坐標(biāo)等很多參數(shù)的描述。其中最容易理解的是表格豎線的坐標(biāo)描述,例如對于“cellx2732”,修改其數(shù)值會改變豎線的位置,而如果將2個“cellx***”間的描述串(不必知其具體含義)原地復(fù)制一遍(坐標(biāo)值當(dāng)然要做相應(yīng)的修改),同時將描述相應(yīng)單元格的以“ABC\cell”(“ABC”為單元格內(nèi)容)為標(biāo)志的描述串也原地復(fù)制一遍,則再次打開Word時,就會發(fā)現(xiàn)增加了一列。
在下面的源代碼中,為了簡化程序,要求表格模板的單元格內(nèi)容完全相同,并且擴充后的表格的單元格內(nèi)容也完全相同,且等列寬。其實,要想使新表格中單元格內(nèi)容各不相同并能任意設(shè)置列寬是很容易實現(xiàn)的。
在表格中增加列的VB源代碼如下:
Private Sub ExpandVolumes(OldVols As Integer,
CopiedVol As Integer,NewVols As Integer,
MaxWidth As Integer,StrSourceFile As String,
StrTargetFile As String,StrCell As String)
′功能:把表格的指定列(不能是第1列)進行復(fù)制,形成均勻列寬的多列表格
′說明:原始模板的單元格內(nèi)容必須全部相同(為 Str
′Cell,如“ABC”),新單元格也按此填充
′OldVols、CopiedVol和NewVols分別為原始模板的列數(shù)、被復(fù)制列的序號和擴展后的列數(shù)
′MaxWidth為擴展后表格的寬度,此處只考慮4位數(shù)的情況
Dim i As Integer,j As Integer,P1 As Long,StartP As Long
Dim S1 As String,S2 As String
Dim CellPos As Integer,StrTemp As String,ITemp As Integer
LoadFileToStr StrSourceFile,S1′把模板文件讀入到字符串S1中
S2=″″′S2用于臨時保存處理過的字符串
Do′增加表格的列描述
For i=1 To OldVols ′原始模板為3列
P1=InStr(S1,″cellx″)′在余下的字符串中從起始查找
If P1=0 Then′搜索完畢
S1=S2+S1′轉(zhuǎn)換完成的字符串仍賦給S1
Exit Do
End If
If i=CopiedVol Then′復(fù)制指定列參數(shù)串并修改坐標(biāo)值
For j=CopiedVol To CopiedVol+NewVols-
OldVols ′2 To NewVols-1
S2=S2+Left(S1,P1+4)+Trim(Str(Int(MaxWidth/NewVols)*j))
Next j
ElseIf i<CopiedVol Then ′修改坐標(biāo)值
S2=S2+Left(S1,P1+4)+Trim(Str(Int(MaxWidth/ NewVols*i)))
Else ′i>CopiedVol,修改坐標(biāo)值
S2=S2+Left(S1,P1+4)+Trim(Str(Int(MaxWidth/ NewVols*(i+NewVols-OldVols))))
End If
S1=Mid(S1,P1+9) ′剩余字符串
Next i
Loop
S2=″″
ITemp=Len(StrCell)
Do ′增加表格單元格
For i=1 To OldVols
P1=InStr(S1,StrCell) ′搜索″ABC″
If P1=0 Then ′搜索完畢
S1=S2+S1 ′轉(zhuǎn)換完成的字符串仍賦給S1
Exit Do
End If
If i=CopiedVol Then′復(fù)制單元格
For j=CopiedVol To CopiedVol+NewVols-OldVols
S2=S2+Left(S1,P1+ITemp-1)
Next j
Else
S2=S2+Left(S1,P1+ITemp-1)
End If
S1=Mid(S1,P1+ITemp) ′剩余字符串
Next i
Loop
WriteStringToFile StrTargetFile,S1′保存成新的模板文件
End Sub
生成的新的模板文件的單元格內(nèi)容是完全相同的,可以用各不相同的特征字符串逐一替換,形成如表1所示的表格模板后,就可以調(diào)用FillGrid進行自動填充了。
5 為表格增加行
在RTF文件中,表格的描述是以行為單位的,所以增加行比增加列要容易得多。其描述符中,有一個出現(xiàn)頻率不是很高的字符串“}\pard”,其中“}”是對一段完整描述內(nèi)容的分隔(與“{”對應(yīng)),而“\par”或“\pard”是一段描述內(nèi)容的結(jié)束符。在只有一個表格的文件中,“}\pard”只在文件頭結(jié)束(其后即為文件的全部內(nèi)容的描述)及每行表格的描述結(jié)束時才出現(xiàn)。據(jù)此,就可以很容易地找到某行表格的完整的描述字符串,將其復(fù)制就可為表格增加一行,其實現(xiàn)非常簡單。
6 結(jié) 論
以上介紹了對任意固定表格的填充方法和對簡單表格增加行列的方法。該方法的最大優(yōu)點在于,只要編程者對RTF格式的文件進行簡單分析并熟悉字符串的編程,就可以完成表格的操作。如果進一步對復(fù)雜表格的RTF文件進行分析,還可以繼續(xù)編程實現(xiàn)對其行或列的添加,但如果其行列變化不多,建議多制幾個標(biāo)準(zhǔn)表格模板則會更方便。
當(dāng)然,利用OLE編程也可以實現(xiàn)上述功能,但要求編程者必須熟悉OLE編程,且運行時必須有Word軟件環(huán)境。在某些特殊場合(如用于工業(yè)實時控制的工控機上),為了避免感染病毒,是不允許安裝Office等軟件的,這時該種方法就顯得更為實用。
參考文獻(xiàn)
1 劉廣孚.以讀解的方式實現(xiàn)RTF文件的打印和預(yù)覽.計算機應(yīng)用研究(精擴本),2001
2 Microsoft Corporation著,希望圖書創(chuàng)作室譯.Microsoft Visual Basic 6.0組件工具指南.北京:北京希望電子出版社,1999
3 Halvorson M著,希望圖書創(chuàng)作室譯.Microsoft Visual Basic 6.0專業(yè)版循序漸進教程.北京:北京希望電子出版社,1999