我首先想說明的是這篇文章算是我以前寫的“使用Delphi 7控制Word 2000生成文檔的方法”http://blog.csdn.net/neowang/archive/2004/10/08/127522.aspx的續篇(到目前爲止,該文章已經被瀏覽了214+11次)。
因爲用戶的需求發生了改變,我不得不在複習備考自然辯證法的幾天裏擠出時間來改寫源程序來滿足新的需求(看在是老同學的面子上,另一方面也不想佔用自己過聖誕節的寶貴時間)。
原來的值班日誌是直接一行接一行的輸出到一個空白文檔中的(也可以看做是輸出到以Normal.dot爲模板創建的新文檔中),這次老同學給我發來了一個他用Word畫的表格,要求程序的輸出要插入到表格對應的空白處。這個表格並不是一個規整的m×n的表格,而是經過合併單元格處理的,這樣就提高了難度。
我本來是打算操縱VBA中的對象來畫出一個相同的表格的,可是試過以後才發現這個方法十分複雜,工作量較大,就中途放棄了。這時想到將同學發過來的文檔轉換爲了一個模板(文件>新建>模板,然後把表格複製過來,保存爲“值班日誌表.dot”即可),這樣一個一模一樣的表格就有了,接下來就是用程序插入相應的內容了。當然了,程序中也必須做一些相應的修改:
1)在調用Documents集合的Add方法時,Template參數不再使用EmptyParam值,而是指定爲“值班日誌表.dot”,這樣添加的文檔將以“值班日誌表.dot”爲模板;
2)在插入相應的內容時,我使用的是一個比較笨的方法,但是對於這個不規則的表格來說卻可能是最有效的方法:計算出該表格中共有多個個段落,然後通過語句在所有應插入內容的段落中插入內容。也懶得自己數了,定義了一個整型變量paraCount,將其賦值爲WordDoc.Paragraphs.Count,最後用一個消息框顯示出來,得到該表格有38個段落,最後註釋掉以上代碼:)
3)接下來的工作就是數數了,數到一個該插入內容的段落,就寫一段代碼插入相應的內容。比如:“值班時間”(表頭)是第6段,接在後面該填入內容的空白段落就是第7段,於是寫代碼在第7段中插入實際內容。
最後,想說的是一個在操作Word 2000時很有用的幫助文件,VBAWRD9.CHM,裏面詳細介紹了Word 2000中使用的VBA,裏面介紹了很多有用的對象、屬性和方法,還有一些VB代碼作爲示例,很容易可以想到對應的Delphi代碼。這個文件在Office 2000的安裝盤裏面可以找到,具體路徑忘記了,煩請搜索:)
//單擊“導出到Word文檔”按鈕事件處理程序
procedure TfrmDetails.btnExportClick(Sender: TObject);
var
V: Variant; //代表Word的變體類型變量
Template, NewTemplate, DocumentType, Visible: OleVariant; //Documents.Add()方法使用的參數
itemIndex: OleVariant;
fileName: Olevariant;
NoPrompt, OriginalFormat: OleVariant;
RouteDocument, SaveChanges: OleVariant;
//paraCount: Integer;
begin
//指定文檔的路徑和文件名
fileName := 'C:/LogAdmin/doc/' + '值班日誌' + Trim(DBTextDate.Caption) + '.doc';
//如果該日誌的對應Word文檔已經存在則提示是否覆蓋
if FileExists(fileName) = true then
begin
Beep;
if Application.MessageBox('文檔已經存在,是否覆蓋?','警告',MB_OKCANCEL)=IDCANCEL then
Abort;
end;
//測試當前是否運行了Word 2000
try
V := GetActiveOleObject('Word.Application');
except
//未運行則運行之
V := CreateOleObject('Word.Basic');
end;
try
//連接到Word 2000
WordApp.Connect;
except
Beep;
MessageDlg('不能生成文檔,請確認是否安裝了Word 2000!', mtError, [mbOK], 0);
Abort;
end;
//顯示Word 2000
WordApp.Visible:=true;
//給調用Add函數使用的實參賦值
//Template := EmptyParam; //使用空白文檔,即“Normal.dot”模板
Template := '值班日誌表.dot'; //使用“值班日誌表.dot”模板
NewTemplate := False;
DocumentType := wdNewBlankDocument;
Visible := true;
//調用Add函數添加一個文檔
WordApp.Documents.Add(Template, NewTemplate, DocumentType, Visible);
//連接到新建的文檔
itemIndex := 1;
WordDoc.ConnectTo(WordApp.Documents.Item(itemIndex));
//文檔另存爲
WordDoc.SaveAs(fileName);
//向Word文檔中寫入內容
//paraCount := WordDoc.Paragraphs.Count; //求得模板中的段落總數爲38
//MessageDlg(IntToStr(paraCount), mtInformation, [mbOK], 0);
//在第3段中插入值班日期
WordDoc.Paragraphs.Item(3).Range.InsertAfter(DBTextDate.Caption);
//在第5段中插入值班人姓名
WordDoc.Paragraphs.Item(5).Range.InsertAfter(DBTextName.Caption);
//在第7段中插入值班時間
WordDoc.Paragraphs.Item(7).Range.InsertAfter(DBTextTime.Caption);
//在第10段中插入溫度
WordDoc.Paragraphs.Item(10).Range.InsertAfter(DBTextT.Caption);
//在第12段中插入溼度
WordDoc.Paragraphs.Item(12).Range.InsertAfter(DBTextH.Caption);
//在第14段中插入天氣
WordDoc.Paragraphs.Item(14).Range.InsertAfter(DBTextWeather.Caption);
//在第17段中插入工具
WordDoc.Paragraphs.Item(17).Range.InsertAfter(DBMemoTool.Text);
//在第19段中插入現場
WordDoc.Paragraphs.Item(19).Range.InsertAfter(DBMemoEnv.Text);
//在第21段中插入有無異常
WordDoc.Paragraphs.Item(21).Range.InsertAfter(lbException.Caption);
//在第26段中插入記錄一
WordDoc.Paragraphs.Item(26).Range.InsertAfter(DBMemoR1.Text);
//在第29段中插入記錄二
WordDoc.Paragraphs.Item(29).Range.InsertAfter(DBMemoR2.Text);
//在第33段中插入記錄三
WordDoc.Paragraphs.Item(32).Range.InsertAfter(DBMemoR3.Text);
//在第36段中插入備註
WordDoc.Paragraphs.Item(36).Range.InsertAfter(DBMemoMemo.Text);
//保存文檔
NoPrompt := false;
OriginalFormat := wdOriginalDocumentFormat;
WordApp.Documents.Save(NoPrompt, OriginalFormat);
//關閉文檔
SaveChanges := wdSaveChanges;
OriginalFormat := wdOriginalDocumentFormat;
RouteDocument := false;
WordApp.Documents.Close(SaveChanges, OriginalFormat, RouteDocument);
//斷開和Word 2000的連接
WordApp.Disconnect;
MessageDlg('日誌內容導出成功!保存爲' + fileName, mtInformation, [mbOK], 0);
frmDetails.Close;
end;
終於在1個小時之前完成程序的更新,我也可以安心的考試和過節了,祝我自己聖誕節快樂先,也祝各位Delphi Fans聖誕快樂!