筆者在實際應用中發現,報表的內容一般很少變動,但其字體格式及版式是經常變動的,而且有時用戶為了某種需要,不想修改資料庫的真實內容而又要改變報表內容。如果用ReportSmith可以解決前者問題,但對於後者則無能為力了,且其介面是英文的,不合使用者習慣。如果用3.0中的TQReport的報表零件,則兩者都無法即時解決,必須修改原程式碼後重新編譯才能使用。而使用Word及Excel則完全可以克服以上不足。具體實作如下(以Word實作為例):
先用Word編輯報表格式,並排好版,把將要輸出的資料項目用表單域代替,取名。這裡我們暫時假設有表單域Item1及Item2(均為文字型),將這個文件存為模板檔Example.dot,然後如下步驟進行:
1)運行Delphi3,在Form1裡加入一個System部件集裡的TDdeClientCov部件,取名為DdeExample,將其ConnectMode設為ddeManual(手動方式);將DdeService設為'(WinWord)';將Serviceapplication設為'WinWord '。
2)編寫一個自訂過程,以啟動Word,如下:
PRocedure Tform1.WordActive(Cmds: TStrings);
var
WordPath: String;
begin
if(not DdeExample.OpenLink) then {判斷是否巳動態連結}
begin
if(FindWindow('OpusApp', nil)=0) then
begin
WordPath := 'C:msofficewinword';
if(WordPath=') then
ShowMessage('中文Word未安裝或未設定路徑,請安裝設定Word中文版。')
else begin
DdeExample.ServiceApplication := WordPath+'Winword.exe';
if(DdeExample.OpenLink) then {如果巳動態連結執行巨集指令}
DdeExample.ExecuteMacroLines(Cmds,False)
else
ShowMessage('無法啟動Word中文版!');
DdeExample.ServiceApplication := 'WinWord.exe';
end;
end
else begin{如果巳動態連結執行巨集指令}
DdeExample.ExecuteMacroLines(Cmds,False);
end;
end
else
DdeExample.ExecuteMacroLines(Cmds,false);
end;
在private聲明區加入如下:
procedure ActiveWord(Cmds: TStrings);
3)在Form1中加入一個按鈕Button1,在其onclick事件裡寫如下程式碼:
procedure TForm1.Button1Click(Sender: TObject);
var
Cmds:TStringList;{建立Cmds}
TempItem1,TempItem2:String;
begin
cmds:=TStringList.Create;
cmds.Clear;
TempItem1:='資料項目一';
TempItem2:='資料項目二';
with Cmds do
begin
Clear;
Add('[FileNew.Template ="Example.Dot″]');{開啟範本檔案Example.Dot}
Add('[AppMaximize]');{文件最大化}
Add('[SetFormResult"Item1″,″'+TempItem1+'″]');{將資料TempItem1傳給表單域Item1}
Add('[SetFormResult"Item2″,″'+TempItem2+'″]);{將資料TempItem2傳給表單域Item2}
end;
WordActive(DdeExample,Cmds);{呼叫自訂過程}
Cmds.Free;{釋放Cmds}
end;
執行這個程序,點選Button1,大家可以發現Word被啟動了,螢幕上出現了:資料項一;資料項二、兩個資料項。最後,大家可以任意修改本報表的格式及數據,因為這時這個報表與具體的應用程式巳沒有關係了。
本例中用的是中文Word6或中文Word7。由於Word97的巨集指令巳變成Visual Basic語句,如大家想用Word97實現,請將其巨集指令改變為對應的程式碼。
這是個簡單的範例,大家可以利用Word的巨集錄製功能,錄取更多的巨集(如自動產生表格、填充文字、變動字體等巨集指令),並與資料庫的各種資料表連結起來,依序加入Cmds中即可實現您所要求的更複雜的功能。