excel|visual|word|編程
樣本 3:開啟現有的 Word 文檔
同
Documents.SaveAs 方法一樣,
Documents.Open 方法簽名在 Office 2000 和 OfficeXP 之間也存在差別,因此新名稱封裝在
#if 聲明中。
Open 方法和
SaveAs 方法一樣簡單,如下所示:
object fileName = Environment.CurrentDirectory+"\\example3"; object optional=Missing.Value;#if OFFICEXP _Document doc = app.Documents.Open2000( ref fileName,#else _Document doc = app.Documents.Open( ref fileName,#endif ref optional, ref optional, ref optional, ref optional, ref optional, ref optional, ref optional, ref optional, ref optional, ref optional, ref optional);
協助中的 Word 2002 Visual Basic 參考以及 MSDN(英文)中有關
Documents.Open 方法的說明記錄了這些選擇性參數。
本樣本中比較讓人感興趣的代碼是,開啟的文檔中的文本先被反白,然後被剪下:
object first=0; object last=doc.Characters.Count; Range r = doc.Range(ref first, ref last); r.Select(); Thread.Sleep (2000); r.Cut();
第一個字元和最後一個字元位置的整數值被封裝到第一個和最後一個對象,然後傳遞給 Document.Range() 函數,該函數返回 Select() 函數調用的
Range 對象。這種顯式封裝是必需的,因為
Range 對象期待引用其參數,並且任何隱式或顯式的轉換都會將參數改為右值,而右值是不能按引用傳遞的。本樣本使文本反白持續兩秒鐘,而後對文本進行剪下。剪下操作也可以通過以下代碼實現:
object first=0; object units = WdUnits.wdCharacter; object last=doc.Characters.Count; doc.Range(ref first, ref last).Delete(ref units, ref last);
如何產生和運行 example3.cs
要產生 example3.cs,可以在
Visual Studio .NET Command Prompt(Visual Studio .NET 命令提示)視窗中執行以下操作:
- 開啟儲存 example3.cs 源檔案的目錄(例如 C:\CSOfficeSamples),並在命令提示後鍵入 csc /r:"C:\Office XP PIAs\Microsoft.Office.Interop.Word.dll" /d:OFFICEXP example3.cs。
(如果 Office XP PIA 儲存在其他位置,則需要使用相應值替換下面的“磁碟機”和“安裝路徑”:csc /r:磁碟機:\<安裝路徑>\Microsoft.Office.Interop.Word.dll /d:OFFICEXP example3.cs。)
- 要運行 example3.exe(與 example3.cs 源檔案位於同一檔案夾中),雙擊該程式即可。
樣本 4:使用 Word 公開的事件
本樣本涉及的內容要比其他幾個多一些,但實際上並不複雜。看起來複雜的主要原因在於標識事件及其處理常式類型的名稱長一些。看一看 Office XP 版本的
DocumentOpen 和
DocumentChange 事件處理常式的設定代碼:
...#if OFFICEXP ApplicationEvents3_DocumentOpenEventHandler myOpenDoc = new ApplicationEvents3_DocumentOpenEventHandler (MyOpenEventHandler); ApplicationEvents3_DocumentChangeEventHandler myChangeDoc = new ApplicationEvents3_DocumentChangeEventHandler(DocChange);#else...
這兩條語句僅僅是聲明事件的事件處理常式。隨後的幾行代碼中,這些處理常式將指定給
Application 對象 app 中的事件:
app.DocumentOpen += myOpenDoc; app.DocumentChange += myChangeDoc;
現在就可以使用這兩個事件了。調用
Open 方法時,這兩個事件將同時引發。依次開啟超連結閱讀有關 DocumentOpen(英文)和 DocumentChange(英文)方法的文檔。
那麼,如何知道哪些事件可用及其處理常式的調用方法呢?如果使用 ILDASM 檢查 Word 2002 PIA (Microsoft.Office.Interop.Word.dll),會發現在有些類型前面標有綠色倒三角標誌。該標誌表示成員是一個事件。圖 4 顯示了 ILDASM 樹視圖表徵圖的協助。
圖 4:ILDASM 的樹視圖表徵圖協助
圖 5:使用 ILDASM 查看 Application 對象的事件(單擊圖片查看大映像)
圖 5 顯示了 Application 對象的事件的部分螢幕快照。每一行最左邊的標識符是事件名稱。冒號右邊是事件處理常式的完整限定類型名。例如,DocumentBeforeSave 事件要求有如下類型的處理常式:
Microsoft.Office.Interop.Word .ApplicationEvents3_DocumentBeforeSaveEventHandler
請注意,事件並未告訴我們任何有關事件處理常式簽名的資訊。因此,需要看一下事件處理常式聲明。在 ILDASM 中,如果雙擊
ApplicationEvents3_DocumentBeforeSaveEventHandler 類型,就會看到類似
圖 6 顯示的內容。
圖 6:在 ILDASM 中查看事件處理常式聲明
讓我們感興趣的是
Invoke 方法。為事件處理常式編寫的函數必須具有此簽名。但是如何知道參數的含義及其使用的值呢?這就是 Word 2002 Visual Basic 文檔的重要性所在。對於
DocumentBeforeSave 事件,文檔(英文)敘述如下:
Private Sub object_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
該文檔接下來描述了每個參數的含義。請記住,C# 在預設情況下按值傳遞參數,而 Visual Basic 在預設情況下按引用傳遞參數。這就是為什麼兩個
Boolean 參數在用 ILDASM 顯示時後面要跟 & 符號,而在 C# 中使用時則用關鍵字
ref 標記的原因了。同樣,Visual Basic 中的
Subs 在 C# 中被看作返回 void 的方法。因此,
DocumentSave 事件的處理常式應類似於如下所示:
public static void SaveHandler (Document doc, ref bool b1, ref bool b2) { MessageBox.Show ("Saving document", "DocumentSave event", MessageBoxButtons.OK, MessageBoxIcon.Information);}
當通過調用
SaveAs 方法儲存文檔時,
DocumentBeforeSave 事件將在儲存文檔前引發。
在
SaveAs 方法調用的後面幾行代碼中,您將看到如下程式碼片段:
app.DocumentChange -= myChangeDoc;
此程式碼解除了
DocumentChange 事件的掛鈎,這樣該事件就不會在調用
Quit 期間引發了。
如何產生和運行 example4.cs
要產生 example4.cs,可以在
Visual Studio .NET Command Prompt(Visual Studio .NET 命令提示)視窗中執行以下操作:
- 開啟儲存 example4.cs 源檔案的目錄(例如 C:\CSOfficeSamples),並在命令提示後鍵入 csc /r:"C:\Office XP PIAs\Microsoft.Office.Interop.Word.dll" /d:OFFICEXP example4.cs。
(如果 Office XP PIA 儲存在其他位置,則需要使用相應值替換下面的“磁碟機”和“安裝路徑”:csc /r:磁碟機:\<安裝路徑>\Microsoft.Office.Interop.Word.dll /d:OFFICEXP example4.cs。)
- 要運行 example4.exe(與 example4.cs 源檔案位於同一檔案夾中),雙擊該程式即可。
樣本 5:動畫顯示 Office 助手
有些使用者喜歡 Office 助手,有些人則討厭它們。無論如何,example5.cs 在此處都僅僅是為了增添一點樂趣。本樣本程式還使用位於 mso.dll 中的助手類型資訊。該程式使用兩個 PIA:
- Microsoft.Office.Interop.Word.dll
- Office.dll
example5.cs 源檔案中的每個重要步驟都作了詳細注釋。由於易於理解,此處不準備對此代碼加以介紹。
如何產生和運行 example5.cs
要產生 example5.cs,可以在
Visual Studio .NET Command Prompt(Visual Studio .NET 命令提示)視窗中執行以下操作:
- 開啟儲存 example5.cs 源檔案的目錄(例如 C:\CSOfficeSamples 目錄),並在命令提示後鍵入 csc /r:"C:\Office XP PIAs\Microsoft.Office.Interop.Word.dll" /r:"C:\Office XP PIAs\Office.dll" example5.cs。
(如果 Office XP PIA 儲存在其他位置,則需要使用相應值替換下面的“磁碟機”和“安裝路徑”:csc /r:磁碟機:\<安裝路徑>\Microsoft.Office.Interop.Word.dll /r:Drive:\<安裝路徑>\Office.dll example5.cs。)
- 要運行 example5.exe(與 example5.cs 源檔案位於同一檔案夾中),雙擊該程式即可。
樣本 6:預設屬性和索引屬性
Word 2002 很少用到預設屬性和索引屬性,而 Excel 2002 卻經常用到它們,因此本樣本 (excel1.cs) 利用了這一事實。
同所有 Office XP 互作業碼一樣,本樣本程式從執行個體化 Application 對象開始。建立活頁簿和工作表後,建立了一個用於儲存欄位標題的字串數組。建立完該數組後,您將看到如下程式碼片段:
wksRange = wks.get_Range("A2", "D2");
此代碼擷取儲存格 A2 到 D2 的 Range 對象。但既然工作表有一個 Range 屬性,為什麼還需要直接調用訪問函數呢?並且這樣做為何不象通常那樣會產生語法錯誤?
與 Visual Basic 和 Visual C++ 不同,C# 沒有適用於索引屬性的文法結構。要在 C# 中使用索引屬性,就必須直接調用訪問函數。
_Worksheet.Range 屬性便是一個很好的例子。要在 Visual C++ 中擷取
Range 屬性的值,代碼應如下所示:
myRange = myWorksheet->Range["A2", "D2"];
要在 C# 中執行相同的操作,代碼則應如下所示:
myRange = myWorksheet.get_Range("A2", "D2");
設定
Range 屬性,而不是向其賦值,是對 set 訪問函數的調用:
myWorksheet.set_Range("A2", "D2", myRange);
Microsoft Excel 2000 中的
Range.Value 屬性是一個常規屬性,但在 Excel 2002 中,則變成了一個索引屬性。這就是為什麼在本樣本程式中使用該屬性時要將其括在 #if OFFICEXP 語句中的原因。
_Workbook.Worksheets 具有所謂的預設屬性。預設屬性在Interop 組件中被看作是名稱為 Item 的屬性。通常必須指定 Item 成員才能從 C# 使用預設屬性,但是在 Excel 庫中,TLBIMP 只需少量代碼就可以建立稱為
get__Default 或
set__Default 的訪問函數。如果這兩個訪問函數存在,C# 就可以使用索引產生器文法而不是直接調用訪問函數。本樣本中的這兩行代碼如下所示:
_Worksheet wks2 = (_Worksheet)wkb.Worksheets["Market Share!"];((_Worksheet)wkb.Worksheets["Market Share!"]).Name = "Fred";
如何產生和運行 excel1.cs
要產生 excel1.cs,可以在
Visual Studio .NET Command Prompt(Visual Studio .NET 命令提示)視窗中執行以下操作:
- 開啟儲存 excel1.cs 源檔案的目錄(例如 C:\CSOfficeSamples 目錄),在命令提示後鍵入 csc /r:"C:\Office XP PIAs\Microsoft.Office.Interop.Excel.dll" /d:OFFICEXP excel1.cs。
(如果 Office XP PIA 儲存在其他位置,則需要使用相應值替換下面的“磁碟機”和“安裝路徑”:csc /r:磁碟機:\<安裝路徑>\Microsoft.Office.Interop.Excel.dll /d:OFFICEXP excel1.cs。)
- 要運行 excel1.exe(與 excel1.cs 源檔案位於同一檔案夾中),雙擊該程式即可。
小結
C# 的 COM Interop是一種非常有用的工具,因為利用它可以直接使用現有對象而無需為那些對象重寫代碼。本文可協助您利用現有 COM 物件代碼。
下面是一些有關 PIA、.NET 安全性、.NET 和 COM Interop等內容的文章連結,從中可以獲得更詳細的資訊。
- Introduction to COM Interop(英文)
- Primary Interop Assemblies (PIAs)(英文)
- Microsoft .NET Framework FAQ(英文)
- Microsoft .NET/COM Migration and Interoperability(英文)
- .NET Interop: Get Ready for Microsoft .NET by Using Wrappers to Interact with COM-based Applications(英文)
- Exposing .NET Framework Components to COM(英文)
- Calling a .NET Component from a COM Component(英文)
- Calling COM Components from .NET Clients(英文)