摘要:Office Automation Using Delphi 2006
作者:蔡煥麟
日期:Dec-11-2005
摘要
本文說明如何使用 Delphi 2006 控制 Office .NET 互動組件(Interop Assembly),並以範例說明如何利用這項技術來製作 Excel 報表。
1. 簡介
本文件使用的軟體版本如下:
- Microsoft Office Professional Edition 2003 
- Delphi 2006 Architect with Update 1 
2. 安裝 Office Primary Interop Assemly
你可以先用檔案總管檢視 Windows 資料夾底下的 assembly 目錄,看看有沒有「Microsoft.Office.Interop.*」的組件,如果有,表示你在安裝 Office 時已經連同相關的的 .NET 組件都安裝進去了;如果沒有,請依照下列步驟安裝 Office 基礎互動組件(Primary Interop Assembly, PIA):
- 開啟控制台的「新增/移除程式」,找到並點選 Microsoft Office,然後點「變更」。 
- 接著會開啟 Office 安裝程式的畫面,選擇「新增或移除功能」,按「下一步」。 
- 將「選擇應用程式的進階自訂」項目打勾,按「下一步」。 
- 將你需要的安裝的 Office 應用程式項目底下,尋找「.NET 程式設計支援」,並選擇「從我的電腦執行」。 
- 展開「Office 工具」,點選「Microsoft Forms 2.0 .NET 程式設計支援」,並選擇「從我的電腦執行」。 
- 在「Office 工具」底下,展開「Microsoft Graph」,點選「.NET 程式設計支援」,並選擇「從我的電腦執行」。 
- 按「更新」 
完成後,Office 互動組件就會安裝到 GAC 裡面。
以上步驟亦可參考 MSDN 網站上的英文說明: How to- Install Office Primary Interop Assemblies。
3. 加入 Primary Interop Assembly 參考
在你的專案中加入 Office PIA 參考,如果是 Visual Studio .NET,需切換到「COM」頁夾;如果是 Delphi 2005,則切換到「COM Imports」頁夾,參考下圖:
在清單裡面找到你需要的組件,例如:Excel 2003 的組件名稱是「Microsoft Excel 11.0 Object Library」。下表列出所有 Office 2003 的 PIA 名稱及其對應的組件檔名:
| Office Application or Component | Primary Interop Assembly Name | 
|---|---|
| Microsoft Access 11.0 Object Library | microsoft.office.interop.access.dll | 
| Microsoft Excel 11.0 Object Library | microsoft.office.interop.excel.dll | 
| Microsoft FrontPage 6.0 Web Object Reference Library | microsoft.office.interop.frontpage.dll | 
| Microsoft FrontPage 6.0 Page Object Reference Library | microsoft.office.interop.frontpageeditor.dll | 
| Microsoft Graph 11.0 Object Library (used by PowerPoint, Access, and Word for graphs) | microsoft.office.interop.graph.dll | 
| Microsoft Outlook 11.0 Object Library | microsoft.office.interop.outlook.dll | 
| Microsoft Outlook View Control (can be used in Web pages and applications to access your inbox) | microsoft.office.interop.outlookviewctl.dll | 
| Microsoft Office Web Components 11.0 (spreadsheet, graph, and pivot table for Web pages) | microsoft.office.interop.owc11.dll | 
| Microsoft PowerPoint 11.0 Object Library | microsoft.office.interop.powerpoint.dll | 
| Microsoft Publisher 11.0 Object Library | microsoft.office.interop.publisher.dll | 
| Microsoft Smart Tags 2.0 Type Library | microsoft.office.interop.smarttag.dll | 
| Microsoft Word 11.0 Object Library | microsoft.office.interop.word.dll | 
| Microsoft Visual Basic for Applications Extensibility 5.3 | microsoft.vbe.interop.dll | 
| Microsoft Forms 2.0 Object Library (programmable controls that can be used in applications) | microsoft.vbe.interop.forms.dll | 
| Microsoft Office 11.0 Object Library (Office shared functionality) | office.dll | 
(表格內容取自 MSDN 網站:http://msdn.microsoft.com/library/en-us/dv_wrcore/html/wrrefOfficePrimaryInteropAssemblies.asp)
要在程式中控制 Office 應用程式,你的專案必須加入以下基本的組件參考:
- 「COM Imports」頁夾的 Microsoft Office 11.0 Object Library (OFFICE.DLL) 
- 「COM Imports」頁夾的 Microsoft Visual Basic for Applications Extensibility 5.3 (Microsoft.vbe.Interop.dll) 
- 「.NET Assemblies」頁夾的 stdole (stdole.dll) 
如果你是要控制 Excel,則還要加入「COM Imports」頁夾的 Microsoft Excel 11.0 Object Library (Microsoft.Office.Interop.Excel.dll);如果是要控制 Word,則要加入 Microsoft Word 11.0 Object Library (Microsoft.Office.Interop.Word.dll)。
4. 建立報表模板
這裡我們示範如何控制 Excel,並且將 Excel 當作是一個報表工具。基本的作法是:
- 製作一個 Excel 報表模板,例如:MyRpt.xls,在此模板中,先把報表的輪廓、格式先設定好,並且將一些會由程式動態填入的儲存格定義名稱(主選單 > 插入 > 名稱 > 定義),以便在程式中丟資料到儲存格時,可以使用易記的名稱,而不用將儲存格的位置寫死(例如:C4)。 
- 在程式中建立 Excel 應用程式物件,並且將資料輸出。 
- 資料輸出完畢之後,進入預覽或者直接印出。 
5. 撰寫程式
5.1. 命名空間
Excel 互動組件的命名空間是 Microsoft.Office.Interop.Excel,此命名空間必須加入程式的 uses 敘述裡,例如:
uses Microsoft.Office.Interop.Excel;
5.2. 建立 Excel 物件
以下程式片段會建立 Excel 物件,並且顯示 Excel 視窗。
var
  ExcelApp: ApplicationClass;
begin
  ExcelApp := ApplicationClass.Create;
  try  
    ExcelApp.Visible := True;
    // 根據報表模板開啟新的檔案
    // .... 餵資料給 Excel。
  finally
    ExcelApp.Quit;  
    ExcelApp.Free;
  end;
end;5.3 從報表模板建立新的檔案
var
  ExcelApp: Microsoft.Office.Interop.Excel.ApplicationClass;
  fname: string;
  i: integer;
begin
  ExcelApp := ApplicationClass.Create;
  try
    ExcelApp.Visible := True;
    ExcelApp.DisplayAlerts := False;  // 關閉提示訊息
    ExcelApp.Interactive := False;    // 關閉使用者互動(鍵盤與滑鼠)
    // 根據報表模板開啟新的檔案
    fname := ExtractFilePath(Forms.Application.ExeName) + 'Quot.xls';
    ExcelApp.Workbooks.Add(fname);
    ExcelApp.ActiveWindow.View := XlWindowView.xlNormalView;
    // .... 餵資料給 Excel。
  finally
    ExcelApp.Quit;  
    ExcelApp.Free;
  end;
end;5.4 輸出資料到 Excel
輸出資料至 Excel 文件必須了解 Excel 應用程式的物件模型,這方面的資料請參考 Excel VBA 相關的文件說明。
5.5 完整程式碼
procedure TForm1.btnPrintClick(Sender: TObject);
var
  ExcelApp: Microsoft.Office.Interop.Excel.ApplicationClass;
  fname: string;
  i: integer;
begin
  ExcelApp := ApplicationClass.Create;
  try
    ExcelApp.Visible := True;
    ExcelApp.DisplayAlerts := False;  // 關閉提示訊息
    ExcelApp.Interactive := False;    // 關閉使用者互動(鍵盤與滑鼠)
    // 根據報表模板開啟新的檔案
    fname := ExtractFilePath(Forms.Application.ExeName) + 'Quot.xls';
    ExcelApp.Workbooks.Add(fname);
    ExcelApp.ActiveWindow.View := XlWindowView.xlNormalView;
    
    // 餵資料給 Excel。
    ExcelApp.Range['CoName', System.Type.Missing].Select;
    ExcelApp.ActiveCell.Value2 := edCoName.Text;
    ExcelApp.Range['CustName', System.Type.Missing].Select;
    ExcelApp.ActiveCell.Value2 := edCustName.Text;
    Randomize;
    for i := 0 to Memo1.Lines.Count-1 do
    begin
      ExcelApp.&Goto('SerNo', &Type.Missing);
      ExcelApp.ActiveCell.EntireRow.Select;
      ExcelApp.ActiveCell.EntireRow.Copy(&Type.Missing);
      ExcelApp.ActiveCell.EntireRow.Insert(Microsoft.Office.Interop.Excel.XlDirection.xlDown, &Type.Missing);
      ExcelApp.ActiveCell.Value2 := IntToStr(i+1);
      ExcelApp.ActiveCell.Offset[TObject(0), TObject(1)].Select;
      ExcelApp.ActiveCell.Value2 := Memo1.Lines.Strings[i];
      ExcelApp.ActiveCell.Offset[TObject(0), TObject(1)].Value2 := TObject(Random(10) + 1);
      ExcelApp.ActiveCell.Offset[TObject(0), TObject(2)].Value2 := TObject(Random(1000) * 100 + 10);
    end;
    ExcelApp.&Goto('SerNo', &Type.Missing);
    ExcelApp.ActiveCell.EntireRow.Delete(Microsoft.Office.Interop.Excel.XlDirection.xlDown);
    ExcelApp.ActiveWorkbook.Saved := True;
    ExcelApp.ActiveWorkbook.PrintPreview(nil);  // 預覽列印
  finally
    ExcelApp.Interactive := True;
    ExcelApp.Quit;
    ExcelApp.Free;
  end;
end;5.6. 一些常用技巧
- 關閉互動模式:Interactive 屬性。若此屬性為 False,則當程式忙著丟資料給 Excel 時,使用者無法操作 Excel,亦即避免使用者的誤動作而破壞了程式輸出的動作。 
- 關閉提示訊息:DisplayAlerts。若此屬性為 False,則 Excel 不會顯示任何確認的訊息視窗,例如:當 Excel 關閉時,若文件尚未儲存,也不會問使用者(常用於報表製作)。 
- Workbook.Saved 屬性。設定為 True 時,會讓 Excel 以為該檔案已經儲存過了。 
- ScreenUpdating 屬性。設為 False 可以讓 Excel 不更新畫面顯示。 
參考文獻
- MSDN: Office Primary Interop Assemblies 
 http://msdn.microsoft.com/library/en-us/dv_wrcore/html/wrrefOfficePrimaryInteropAssemblies.asp
- Microsoft Excel 2003 Language Reference 
 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbaxl11/html/xlobjRange1_HV05204333.asp