使用 Microsoft Visual C# 进行 Microsoft Word 2002 和 Excel 2小结

80酷酷网    80kuku.com

  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 命令提示)窗口中执行以下操作:
  1. 打开保存 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。)
  2. 要运行 example3.exe(与 example3.cs 源文件位于同一文件夹中),双击该程序即可。

示例 4:使用 Word 公开的事件


本示例涉及的内容要比其他几个多一些,但实际上并不复杂。看起来复杂的主要原因在于标识事件及其处理程序类型的名称长一些。看一看 Office XP 版本的 DocumentOpenDocumentChange 事件处理程序的设置代码:
...#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 命令提示)窗口中执行以下操作:
  1. 打开保存 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。)
  2. 要运行 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 命令提示)窗口中执行以下操作:
  1. 打开保存 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。)
  2. 要运行 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 具有所谓的默认属性。默认属性在互操作程序集中被看作是名称为 Item 的属性。通常必须指定 Item 成员才能从 C# 使用默认属性,但是在 Excel 库中,TLBIMP 只需少量代码就可以创建称为 get__Defaultset__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 命令提示)窗口中执行以下操作:
  1. 打开保存 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。)
  2. 要运行 excel1.exe(与 excel1.cs 源文件位于同一文件夹中),双击该程序即可。

小结


C# 的 COM 互操作是一种非常有用的工具,因为利用它可以直接使用现有对象而无需为那些对象重写代码。本文可帮助您利用现有 COM 对象代码。
下面是一些有关 PIA、.NET 安全性、.NET 和 COM 互操作等内容的文章链接,从中可以获得更详细的信息。
  • 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(英文)

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: