Ken Getz
MCW Technologies, LLC
適用于:
Microsoft Visual Basic 2005
Microsoft Visual Basic for Applications
Microsoft Visual C# 2005
Microsoft Visual Studio 2005
Microsoft Visual Studio 2005 Tools for Microsoft Office System
Microsoft Office Excel 2003
Microsoft Office Word 2003
摘要:了解 C# 開發(fā)人員在使用 Visual Studio 2005 Tools for Office 創(chuàng)建 Word 和 Excel 應(yīng)用程序時必須知曉的問題,包括如何使用以 VBA 為核心的方法和屬性。參閱示例 — 比較 Visual Basic 與 C# 的代碼。
注 本文是預(yù)發(fā)布版本的文檔,在將來的版本中可能會有所更改。 Microsoft Visual Studio 2005 Tools for Microsoft Office System 測試版包含 Microsoft Visual Studio 2005 測試版。
本頁內(nèi)容
簡介
向 Word 傳遞參數(shù)
使用 Excel 處理可選參數(shù)
使用 Word 處理可選參數(shù)
使用 Excel 處理參數(shù)化屬性
在 Word 中使用訪問器方法
Word 中的晚期綁定
小結(jié)
其他資源
關(guān)于作者
簡介
Microsoft Visual Studio 2005 Tools for Microsoft Office System (Visual Studio 2005 Tools for Office) 使您能夠在 Microsoft Visual Studio 2005 中利用 Microsoft Office Word 2003 和 Microsoft Office Excel 2003 的強大功能來創(chuàng)建豐富的、基于 Microsoft Office 2003 的應(yīng)用程序。您可以在 Microsoft Visual Basic 2005 或 Microsoft Visual C# 中利用 Word 和 Excel 對象模型提供的所有功能。盡管 Visual Basic 開發(fā)人員可以輕松使用由對象模型公開的對象,但 C# 開發(fā)人員還是可能會遇到困難。由于 Office 對象模型的歷史和原始設(shè)計,創(chuàng)建其對象成員的意圖在于,它們將由 Microsoft Visual Basic for Applications (VBA) 代碼調(diào)用。因此,不同的屬性和方法利用由 VBA 提供但不響應(yīng) C# 功能的功能。本文討論的問題包括使用 Word 和 Excel 的以 VBA 為核心的方法和屬性,并提供比較 Visual Basic 代碼和相應(yīng)的 Visual C# 代碼的示例。
使用 Visual Studio 2005 Tools for Office 時,C# 開發(fā)人員必須了解 VBA 或 Visual Basic 開發(fā)人員無需考慮的問題。下表詳細描述了本文中討論的問題:
-
傳遞參數(shù)。默認情況下,VBA 希望通過引用傳遞參數(shù)。默認情況下,Visual Basic 和 C# 均通過值傳遞參數(shù)。VBA 和 Visual Basic 對這一區(qū)別不作具體要求,Excel 的主 interop 程序集接受通過值傳遞的參數(shù),盡管它最初接受通過引用從 VBA 代碼傳遞的所有值。Word 的主 interop 程序集要求比較高;其參數(shù)(有幾個例外)必須通過引用傳遞。Visual Basic 無需額外的工作即可處理此情況,但 C# 不能。
-
可選參數(shù)。VBA 和 Visual Basic 支持方法調(diào)用的可選參數(shù),但 C# 不支持。許多 Office 方法允許 20、30 或更多個可選參數(shù),因此,C# 開發(fā)人員必須比 Visual Basic 開發(fā)人員編寫更多的代碼才能獲得相同的效果。
-
參數(shù)化屬性。VBA 和 Visual Basic 支持接受參數(shù)作為只讀功能的屬性。由于 C# 不支持該種屬性,因此必須使用訪問器方法設(shè)置并檢索接受參數(shù)的屬性值。當使用接受 Variant 參數(shù)的方法時,Word 也存在這樣的問題。
-
晚期綁定。VBA 可以在運行時確定對象的屬性,從而有效地提供代碼與對象本身之間的晚期綁定。Word 在 Dialog 類中利用了該行為。Visual Basic 只能使用 Option Strict Off 指令處理晚期綁定。使用 Option Strict On 的 C# 開發(fā)人員和 Visual Basic 開發(fā)人員不能利用晚期綁定,并且必須使用替代的方法以編程方式與 Word Dialog 類交互。
要為 Visual Basic 和 C# 開發(fā)人員公開 Office 對象模型功能,Microsoft 創(chuàng)建了一組主 interop 程序集。Visual Studio 2005 Tools for Office 使用 Word 和 Excel 的單獨主 interop 程序集,并且每個程序集都有其針對 Visual Basic 和 C# 開發(fā)人員的專門行為。本文下面的部分將討論以上每一問題,說明 Word 和 Excel 主 interop 程序集如何處理每種情況,并提供代碼示例以演示 C# 開發(fā)人員如何處理這里描述的每一種情況。
向 Word 傳遞參數(shù)
Word 對象模型提供的對象希望通過引用傳遞參數(shù)。盡管這對 Visual Basic 開發(fā)人員而言不是問題,但作為 C# 開發(fā)人員,當您向 Word 方法傳遞參數(shù)時必須格外小心。每個由 Word 提供的方法都希望它的每個方法通過 ref 關(guān)鍵字進行傳遞,并且您只能通過引用傳遞 lvalues(即,在布局左側(cè)出現(xiàn)的元素)。您不可以用 C# 代碼向 Word 方法傳遞文字值。
作為一個簡單的示例,以下過程從現(xiàn)有窗口創(chuàng)建一個新窗口,然后平鋪這兩個窗口。以下代碼片段演示該代碼的 Visual Basic 和 C# 版本。
' Visual Basic Friend Sub CreateNewWindowAndTile() ' Create a new window from the active document. Dim wnd As Word.Window = _ Application.ActiveWindow.NewWindow ' Tile the two windows. Application.Windows.Arrange( _ Word.WdArrangeStyle.wdTiled) End Sub // C# public void CreateNewWindowAndTile() { // Create a new window from the active document. Word.Window wnd = Application.ActiveWindow.NewWindow(); // Tile the two windows. Object value = Word.WdArrangeStyle.wdTiled; Application.Windows.Arrange(ref value); }
在該示例中,代碼創(chuàng)建了一個 Object 變量,并為其分配了一個值。然后,代碼使用 ref 關(guān)鍵字向 Arrange 方法傳遞該變量。您必須以相同的方式調(diào)用 Word 中的每個方法;每個參數(shù)必須使用 ref 關(guān)鍵字傳遞,并且必須傳遞包含實際值的變量。
注 面向 Excel 的 C# 開發(fā)人員不需要采取這些特殊的步驟。 Excel 的主 interop 程序集已經(jīng)創(chuàng)建了,這樣就可以正確地處理按值傳遞給不同成員的文字值。
使用 Excel 處理可選參數(shù)
在其他支持可選參數(shù)的語言中,VBA 中的可選參數(shù)必須出現(xiàn)在方法調(diào)用列表的結(jié)尾,并且在參數(shù)標記為可選后,參數(shù)的其余部分也必須為可選。Excel 提供的許多方法都接受可選參數(shù);Visual Basic 開發(fā)人員可以忽略這些參數(shù)并接受它們的默認值。
例如,Workbooks.Add 方法允許您指定可選參數(shù)來表示要使用的模版??梢灾付0嫖募拿Q或 XlWBATemplate 常數(shù)的成員,來表示您希望新工作簿包含的表單類型;也可以不提供值(創(chuàng)建一個具有空表單的工作簿)。如果選擇不提供值(接受默認行為),您可以編寫以下代碼。
' Visual Basic Dim wb As Excel.Workbook = Application.Workbooks.Add()
但是,由于缺???的參數(shù),C# 中的代碼不進行編譯。要解決該問題,需要傳遞可選參數(shù)的 System.Type.Missing 字段。如果使用 Visual Studio 2005 Tools for Office 創(chuàng)建一個項目,那么您可以使用名為 missing 的預(yù)定義變量,該變量包含 System.Type.Missing 值以保存某些類型。
// C# Excel.Workbook wb = Application.Workbooks.Add(System.Type.Missing); // or Excel.Workbook wb = Application.Workbooks.Add(missing);
當 Visual Basic 開發(fā)人員使用反射動態(tài)創(chuàng)建對接受可選參數(shù)的方法進行的方法調(diào)用時,System.Type.Missing 很有用。它表示您希望使用指定參數(shù)的默認值。當然,您可以自己閱讀 Excel 文檔,找到默認值并顯式傳遞該值。
如果 Excel 方法需要多個可選參數(shù),您會發(fā)現(xiàn),用 C# 編寫代碼比編寫相應(yīng)的 Visual Basic 代碼更耗費精力。例如,以下代碼片段比較了 Visual Basic 代碼與 C# 代碼。Workbooks.Open 方法允許您指定幾個可選參數(shù),表示您要打開的工作簿的行為。
' Visual Basic Dim wb As Excel.Workbook = _ Application.Workbooks.Open("C:\YourPath\YourWorkbook.xls") // C# Excel.Workbook wb = Application.Workbooks.Open( "C:\YourPath\YourWorkbook.xls", missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
您只可以傳遞接受引用類型的參數(shù)的 System.Type.Missing 值。對于值類型參數(shù),需要確定并傳遞實際的默認值。例如 Range.Sort 方法,它接受許多枚舉值作為參數(shù)。作為值類型參數(shù),它們要求您明確指定要傳遞的值。
' Visual Basic ' rng is a variable of type Excel.Range. rng.Sort(rng, _ Orientation:=Excel.XlSortOrientation.xlSortColumns) // C# // rng is a variable of type Excel.Range. rng.Sort(rng, Excel.XlSortOrder.xlAscending, missing, missing, Excel.XlSortOrder.xlAscending, missing, Excel.XlSortOrder.xlAscending, Excel.XlYesNoGuess.xlNo, missing,missing, Excel.XlSortOrientation.xlSortColumns, Excel.XlSortMethod.xlPinYin, Excel.XlSortDataOption.xlSortNormal, Excel.XlSortDataOption.xlSortNormal, Excel.XlSortDataOption.xlSortNormal);
您可能會覺得奇怪,為什么 C# 不支持可選參數(shù)。相反,C# 和 Visual Basic 都支持方法重載,這樣您可以創(chuàng)建單一過程的多個“版本”,傳遞不同的參數(shù)集。重載方法的主要局限在于:每個單獨方法的參數(shù)符號必須是不同的;編譯器必須能夠根據(jù)您所調(diào)用的參數(shù),確定您調(diào)用的是哪個版本的過程。該功能比 VBA 對可選參數(shù)的支持更加強大和靈活。
Visual Basic 包含可選參數(shù),因為 Visual Basic 和 VBA 已經(jīng)在若干版本中包含了此功能。但是,對于您現(xiàn)在編寫的代碼而言,使用重載比使用可選參數(shù)更有益。為了提高成為最佳代碼的可能性,C# 設(shè)計人員使用了重載,而不是支持可選參數(shù)。在一般的編碼中,您可能不會注意到 C# 并不具備該功能。只有在針對對象模型(如 Office 所提供的對象模型)編程時,您才會注意到 C# 中缺少可選參數(shù),原因是在該模型中,許多成員會利用可選參數(shù)并使用大量可選參數(shù)。
在一些情況下,您可能會發(fā)現(xiàn)創(chuàng)建內(nèi)置方法的包裝方法很有用。例如,Excel WorksheetFunction 類公開了一大組函數(shù)(其初衷是在工作表上使用),它們提供對統(tǒng)計、財務(wù)以及其他類型與工作表相關(guān)的功能的支持。WorksheetFunction 類的多數(shù)方法可以接受 30 個參數(shù),其中有一兩個是所需的參數(shù)。從 C# 調(diào)用這些方法很復雜,如下示例,它調(diào)用指定的 Excel Range 對象的 WorksheetFunction.Min 方法。
' Visual Basic MessageBox.Show(Application.WorksheetFunction.Min(rng)) MessageBox.Show(Application.WorksheetFunction.Max(rng)) // C# MessageBox.Show(Application.WorksheetFunction.Min(rng, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing).ToString()); MessageBox.Show(Application.WorksheetFunction.Max(rng, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing).ToString());
對于上述情況,您可以考慮創(chuàng)建一種能調(diào)用現(xiàn)有方法的包裝方法,從而免于計算和跟蹤所有的可選參數(shù)。
// C# private delegate double WorksheetFunctionDelegate( object value1, object value2, object value3, object value4, object value5, object value6, object value7, object value8, object value9, object value10, object value11, object value12, object value13, object value14, object value15, object value16, object value17, object value18, object value19, object value20, object value21, object value22, object value23, object value24, object value25, object value26, object value27, object value28, object value29, object value30); private double CallWorksheetFunction( WorksheetFunctionDelegate func, Object value, params object[] values) { // All the values except the first one. object[] overflowParameters = new object[29]; values.CopyTo(overflowParameters, 0); for (int i = values.Length; i < overflowParameters.Length; i++) { overflowParameters[i] = missing; } return func ( value, overflowParameters[0], overflowParameters[1], overflowParameters[2], overflowParameters[3], overflowParameters[4], overflowParameters[5], overflowParameters[6], overflowParameters[7], overflowParameters[8], overflowParameters[9], overflowParameters[10], overflowParameters[11], overflowParameters[12], overflowParameters[13], overflowParameters[14], overflowParameters[15], overflowParameters[16], overflowParameters[17], overflowParameters[18], overflowParameters[19], overflowParameters[20], overflowParameters[21], overflowParameters[22], overflowParameters[23], overflowParameters[24], overflowParameters[25], overflowParameters[26], overflowParameters[27], overflowParameters[28]); }
然后,要調(diào)用接受一個所需參數(shù)的工作表函數(shù),您可以編寫以下代碼。
WorksheetFunctionDelegate func = new WorksheetFunctionDelegate( Application.WorksheetFunction.Min); MessageBox.Show( CallWorksheetFunction(func, rng, missing).ToString());
您即可以擴展該功能以支持多個所需參數(shù),也可以使用 C# params 關(guān)鍵字。
提示 Visual Studio 2005 Tools for Office 文檔包含的示例包括一些常用成員的幫助器方法。在這些示例中,找到標題中帶有單詞 “helper” 的區(qū)域或類。您可以使用這些方法作為自己的方法集的開始,這樣就可以更容易地調(diào)用 Word 和 Excel 提供的方法。
使用 Word 處理可選參數(shù)
如果在 Word 中使用可選參數(shù),那么需要您考慮的問題與在 Excel 中使用可選參數(shù)時需要考慮的問題一樣。您可能會發(fā)現(xiàn)自己編寫的代碼與以下代碼片類似,這段代碼將在 Visual Basic 中打開的 Word 文檔與在 C# 中打開 Word 文檔進行比較。
' Visual Basic Application.Documents.Open("C:\Test\MyNewDocument.doc") // C# Object filename = @"C:\Test\MyNewDocument.doc"; Application.Documents.Open(ref filename, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
通常,從 C# 調(diào)用 Word 方法比調(diào)用相似的 Excel 方法更復雜,因為您必須按引用傳遞大多數(shù)參數(shù)。如果需要頻繁地調(diào)用這樣的方法,您會發(fā)現(xiàn)使用由 Visual Studio 2005 Tools for Office 項目模版創(chuàng)建的 missing 變量很有用。
您經(jīng)常需要引用 Word 中的范圍。在 Visual Basic 中,指定不帶任何參數(shù)的 Range 屬性會返回整個范圍;如果要使用文檔的整個內(nèi)容,無需指定起始和結(jié)束值。當然,對 C# 開發(fā)人員而言并非如此,因為在 C# 中,必須經(jīng)常為所有可選參數(shù)傳遞值。在 C# 中,您可以為所有可選參數(shù)傳遞 System.Type.Missing 以設(shè)定默認值,如以下代碼片段所示。
' Visual Basic Dim rng As Word.Range = ThisDocument.Range() rng.Select() // C# Word.Range rng = ThisDocument.Range(ref missing, ref missing); rng.Select();
使用 Excel 處理參數(shù)化屬性
Excel 中的許多屬性允許您傳遞參數(shù),指示您希望與之交互的屬性的特定實例。例如,您可以通過將命名范圍作為字符串傳遞來指定一個 Range 對象。您也可以通過傳遞左上角單元格名稱和右下角單元格名稱指定一個范圍。您必須至少指定一個參數(shù)(一個命名范圍),也可以指定兩個(兩個單元格名稱)。在每種情況中,屬性都返回一個與指定范圍相對應(yīng)的 Excel.Range 對象。
在 Visual Basic 中,您可以編寫如下所示的代碼,指定并檢索對 Range 對象的引用。
' Visual Basic Dim rng1 As Excel.Range = Application.Range("TotalSales") ' or Application.Range("A1", "B2").Font.Bold = True
C# 不支持此類屬性引用 — 在 C# 中,只有參數(shù)指定了一個索引,屬性引用才可以擁有參數(shù)。為了突破這一限制,Excel 主 interop 程序集為每個參數(shù)化屬性提供了訪問器 get/set 方法。例如,要使用 C# 檢索對 Excel Range 對象的引用,可以重寫前面的代碼,如以下示例所示。
// C# Excel.Range rng1 = Application.get_Range("TotalSales", missing); // or Application.get_Range("A1", "B2").Font.Bold = true;
請注意,您必須向 get_Range 方法傳遞兩個參數(shù),因為 Excel 中的 Application.Range 屬性需要一個參數(shù)以及另一個可選參數(shù)。
相同的問題也適用于 Range 對象的 Offset 屬性;該參數(shù)化屬性允許您檢索指定數(shù)目的行和/或列(從左上角開始的一個范圍)。以下代碼片段演示如何在 Visual Basic 和 C# 中檢索屬性。
' Visual Basic Private Sub ListRecentFiles() Dim i As Integer Dim rng As Excel.Range = DirectCast( _ Application.Range("RecentFiles"). _ Cells(1, 1), Excel.Range) For i = 1 To Application.RecentFiles.Count rng.Offset(i - 1, 0).Formula = _ Application.RecentFiles(i).Name Next End Sub // C# private void ListRecentFiles() { Excel.Range rng = (Excel.Range)Application. get_Range("RecentFiles", missing).Cells[1, 1]; for (int i = 1; i <= Application.RecentFiles.Count; i++) { rng.get_Offset(i - 1, 0).Formula = Application.RecentFiles[i].Name; } }
提示 Range.Cells 屬性看起來像是一個參數(shù)化屬性,但其實不是。Cells 屬性返回一個數(shù)組,您可以通過傳遞行列號的值來檢索數(shù)組。
如果要使用 Excel 提供的多種文件處理對話框,您需要再次使用 get_FileDialog 訪問器方法。因為 Application.FileDialog 屬性有一個參數(shù),所以它在 C# 中不直接可用。要突破該限制,可以調(diào)用 get_FileDialog,如以下代碼片段所示。
' Visual Basic With Application.FileDialog( _ Office.MsoFileDialogType.msoFileDialogFolderPicker) If .Show <> 0 Then Application.Range("FolderPickerResults"). _ Formula = .SelectedItems.Item(1) End If End With // C# dlg = Application.get_FileDialog( Office.MsoFileDialogType.msoFileDialogFolderPicker); if (dlg.Show() != 0) { Application.get_Range("FolderPickerResults", missing). Formula = dlg.SelectedItems.Item(1); }
Excel Range.Value 屬性還需要特殊的處理。該屬性接受一個參數(shù),但當 C# 設(shè)置或檢索屬性值時不接受參數(shù)。在本例中,您必須使用 Value2 屬性,這是不需要參數(shù)的原始屬性的一種變體。例如,以下代碼片段顯示相同作用的 Visual Basic 和 C# 代碼。
' Visual Basic Dim rng As Excel.Range = Application.Range("A1") rng.Value = "Some Value" // C# Excel.Range rng = Application.get_Range("A1", missing); rng.Value2 = "Some Value";
本文顯示使用 Range、Offset、Value 和 FileDialog 屬性的一些示例;您還可以使用其他許多屬性。如果不能直接檢索或設(shè)置屬性值,那么您要查看一下屬性是否需要一個參數(shù),如果是,則尋找相應(yīng)的訪問器方法或替換的屬性。
在 Word 中使用訪問器方法
盡管 Word 通常不使用參數(shù)化屬性(像 Excel 一樣),但在 Word 中編程時,還有一些情況需要使用 get_ 和 set_ 訪問器方法。Word 處理這些方法的情況與 Excel 稍有不同;但在本示例中,訪問器方法是隱藏的。當您鍵入時,不能在可用方法列表中找到它們,也不能在對象瀏覽器窗口中找到它們。您必須知道它們的確定位置并使用它們。
例如,Word 中的 Style 屬性返回并接受 Variant 值,而不是將其轉(zhuǎn)換為 Object 類型以便在 C# 中使用,您必須調(diào)用 get_Style 和 set_Style 方法以解決該問題。需要編寫以下代碼,從而為特定段落設(shè)定樣式。
' Visual Basic Dim rng As Word.Range = _ ThisDocument.Paragraphs(1).Range rng.Style = "Normal Indent" // C# Word.Range rng = ThisDocument.Paragraphs[1].Range; Object style = "Normal Indent"; rng.set_Style(ref style);
對于 Word 中的其他方法,您必須按引用傳遞樣式名稱(或 Style 對象),這需要使用包含所需值的變量。您可以使用相似的代碼檢索一個范圍的 Style 屬性,從而調(diào)用 get_Style 方法。
Word 中的 Item 方法存在相同的問題。Word 主 interop 程序集公開一個按引用接受 Object 參數(shù)的 get_Item 方法,而不是讓您向該方法傳遞一個 Variant 參數(shù)。如果要在當前的 Documents 集合內(nèi)保存特定文檔,您可以編寫以下代碼。
' Visual Basic Application.Documents("MyNewDocument.doc").Save() // C# Object file = "MyNewDocument.doc"; Application.Documents.get_Item(ref file).Save();
規(guī)則很簡單:對于任何接受 Variant 參數(shù)的方法或任何參數(shù)化屬性而言,需要假定有一個訪問器方法(或一對方法)可用。
Word 中的晚期綁定
由于 Word 編程模型已經(jīng)有一段較長的歷史,因此其中某些技術(shù)不適用于面向?qū)ο蟮膹婎愋途幊?。其中之一就?Dialog 類。該類提供了一組基本的屬性和方法,以及一個包含 Word 用戶界面中所有可用對話框的數(shù)組。您可以顯示任何對話框,或者只需使用由對話框公開的不同屬性來影響 Word 的行為。例如,您使用 Page Setup 對話框來配置當前文檔的頁面寬度和高度。
問題在于,Word 對象實際上不包含有關(guān)每個指定對話框的信息。對話框有許多屬性,對話框模型在您加載每個對話框時“動態(tài)”創(chuàng)建這些屬性,而不是在類型庫(現(xiàn)在為主 interop 程序集)中為 Word 硬編碼這些屬性。基本上,每個對話框中的每個控件都有一個對應(yīng)的屬性,您可以以編程方式設(shè)置或檢索每個控件的值。在 VBA 中,這不是問題。盡管您不能使用 Microsoft 智能感知提示來幫助您輸入代碼,但是您仍可以引用不同的屬性并且代碼仍可以編譯。
在 Visual Basic(啟用 Option Strict)或 C# 中并非如此。在強類型語言中,如果要在編寫代碼時使用標準 Object.Property 語法,那您就別指望編譯器會放棄可用的屬性(一直到編譯時)。例如,Visual Basic 利用 Option Strict Off 可對代碼進行編譯,但相應(yīng)的 C# 代碼卻不能編譯。
' Visual Basic with Option Strict Off Dim dlg As Word.Dialog dlg = Application.Dialogs( _ Word.WdWordDialog.wdDialogFilePageSetup) dlg.PageWidth = 3.3 dlg.PageHeight = 6 // C# (This does not compile.) dlg = Application.Dialogs [Word.WdWordDialog.wdDialogFilePageSetup]; dlg.PageWidth = 3.3; dlg.PageHeight = 6;
使用這些屬性有兩種選擇??梢詣?chuàng)建一個在頂部包含 Option Strict Off 設(shè)置的 Visual Basic 文件,并將代碼放在該文件中;也可以采取一種方法執(zhí)行晚期綁定。C# 和 Visual Basic 開發(fā)人員可以使用 System.Reflection 命名空間,這樣就允許運行的代碼確定指定類型的可用成員,并執(zhí)行某一類型的晚期綁定。有了成員信息,代碼就可以使用 System.Reflection 命名空間來調(diào)用屬性設(shè)置過程,例如,設(shè)置一個屬性值。
要在 Visual Basic 或 C# 中處理晚期綁定對象,可以針對 System.Reflection 命名空間的功能添加一個簡單的包裝,以設(shè)置對象(只有在運行時才能知道該對象的功能)的屬性。
' Visual Basic Private Sub InvokeHelper(ByVal dlg As Word.Dialog, _ ByVal member As String, ByVal dlgValue As Object) Dim dlgType As Type = GetType(Word.Dialog) dlgType.InvokeMember(member, _ BindingFlags.SetProperty Or _ BindingFlags.Public Or BindingFlags.Instance, _ Nothing, dlg, New Object() {dlgValue}) End Sub // C# private void invokeHelper(Word.Dialog dlg, string member, Object dlgValue) { // Assumes a using statement in the file: // using System.Reflection; Type dlgType = typeof(Word.Dialog); dlgType.InvokeMember(member, BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null, dlg, new object[] {dlgValue.ToString()}); }
要使用 InvokeHelper 方法,可以傳遞 Dialog 對象、要設(shè)置的屬性,以及該屬性的值。
' Visual Basic Public Sub HiddenPageSetupDialog() Dim dlg As Word.Dialog dlg = Application.Dialogs( _ Word.WdWordDialog.wdDialogFilePageSetup) InvokeHelper(dlg, "PageWidth", 3.3) InvokeHelper(dlg, "PageHeight", 6) dlg.Execute() End Sub // C# public void HiddenPageSetupDialog() { Word.Dialog dlg; dlg = Application.Dialogs[ Word.WdWordDialog.wdDialogFilePageSetup]; invokeHelper(dlg, "PageWidth", 3.3); invokeHelper(dlg, "PageHeight", 6); dlg.Execute(); }
小結(jié)
Word 和 Excel 公開了豐富的編程模型,但這些對象模型最初都是為了供 VBA 用戶使用而編寫的。Visual Basic(即使 Option Strict On)可以處理大多數(shù) Office 對象模型的要求。在 C# 中使用這些對象模型需要格外小心。使用 Visual Studio 2005 Tools for Office 和 C# 編寫應(yīng)用程序時需要記住,您經(jīng)常需要對不同語言間的差異作出讓步,注意可選參數(shù)、參數(shù)化屬性、Variant 參數(shù),以及晚期綁定。在了解了可能遇到的問題類型之后,您會覺得編寫與 Office 交互的 C# 代碼和編寫 Visual Basic 代碼的難度相差無幾。