在运行时在应用程序级外接程序中扩展 Word 文档和 Excel 工作簿

更新: 2008 年 7 月

适用于

本主题中的信息仅适用于指定的 Visual Studio Tools for Office 项目和 Microsoft Office 版本。

项目类型

  • 应用程序级项目

Microsoft Office 版本

  • Excel 2007

  • Word 2007

有关更多信息,请参见按应用程序和项目类型提供的功能

从 Visual Studio 2008 Service Pack 1 (SP1) 开始,可以使用应用程序级外接程序以如下方式自定义文档和工作簿:

  • 将托管控件添加到任何打开的文档或工作表。

  • 创建在特定文档或工作簿中识别的智能标记。

  • 将 Excel 工作表中的现有列表对象转换为 Visual Studio Tools for Office 列表对象,后者公开事件,且可通过使用 Windows 窗体数据绑定模型绑定到数据。

  • 访问由 Word 和 Excel 公开的有关特定文档、工作簿和工作表的应用程序级事件。

为使用此功能,您在运行时生成一个 Visual Studio Tools for Office 对象来扩展文档或工作簿。

在外接程序中生成扩展对象

“扩展对象”是 Visual Studio Tools for Office 对象,用于将功能添加到 Word 或 Excel 对象模型中固有的对象(称为“本机 Office 对象”)。若要在外接程序中生成扩展对象,请在 Excel 和 Word 主互操作程序集中使用以下其中一种类型实例的 GetVstoObject 方法:

第一次调用本机 Office 对象的 GetVstoObject 方法时,它会返回一个新的 Visual Studio Tools for Office 对象来扩展此对象。每次在同一本机 Office 对象上调用该方法时,它都会返回同一扩展对象。

该扩展对象的类型名称与此本机 Office 对象的类型名称相同,但扩展对象的类型是在 Microsoft.Office.Tools.ExcelMicrosoft.Office.Tools.Word 命名空间中定义的。例如,Microsoft.Office.Interop.Word.Document 对象的 GetVstoObject 方法返回一个 Microsoft.Office.Tools.Word.Document

若要确定是否已为某个特定本机 Office 对象生成了一个 Visual Studio Tools for Office 对象,请使用该 Office 对象的 HasVstoObject 方法。有关更多信息,请参见确定 Office 对象是否已扩展。

GetVstoObject 方法主要用在应用程序级项目中。也可以在文档级项目中使用这些方法,但此时它们的行为将不同于在应用程序级项目中时的行为,且用处较少。有关更多信息,请参见从文档级自定义项中的本机 Office 对象获取扩展对象

说明:

若要在除 ThisAddIn.cs 或 ThisAddIn.vb 以外的代码文件中或在安装 SP1 之前创建的项目中使用 GetVstoObject 和 HasVstoObject 方法,必须修改您的项目。有关更多信息,请参见配置项目以使用 GetVstoObject 和 HasVstoObject 方法。

生成宿主项

使用文档级对象(即 Microsoft.Office.Interop.Excel.WorkbookMicrosoft.Office.Interop.Excel.WorksheetMicrosoft.Office.Interop.Word.Document)的 GetVstoObject 方法时,返回的对象称为“宿主项”。宿主项是一种可以包含其他对象的类型,这些对象包括其他扩展对象和控件。宿主项类似于 Word 或 Excel 主互操作程序集中的相应类型,但还具有其他功能。有关宿主项的更多信息,请参见宿主项和宿主控件概述

生成宿主项后,可用它将智能标记或托管控件添加到文档、工作簿或工作表中。有关更多信息,请参见向文档和工作簿中添加智能标记和向文档和工作表中添加托管控件。

为 Word 文档生成宿主项

  • 使用 Microsoft.Office.Interop.Word.Document 的 GetVstoObject 方法。下面的代码示例为活动文档生成一个宿主项。

    If Globals.ThisAddIn.Application.Documents.Count > 0 Then
        Dim NativeDocument As Microsoft.Office.Interop.Word.Document = _
            Globals.ThisAddIn.Application.ActiveDocument
        Dim VstoDocument As Microsoft.Office.Tools.Word.Document = _
            NativeDocument.GetVstoObject()
    End If
    
    if (Globals.ThisAddIn.Application.Documents.Count > 0)
    {
        Microsoft.Office.Interop.Word.Document nativeDocument =
            Globals.ThisAddIn.Application.ActiveDocument;
        Microsoft.Office.Tools.Word.Document vstoDocument =
            nativeDocument.GetVstoObject();
    }
    

为 Excel 工作簿生成宿主项

  • 使用 Microsoft.Office.Interop.Excel.Workbook 的 GetVstoObject 方法。下面的代码示例为活动工作簿生成一个宿主项。

    Dim NativeWorkbook As Microsoft.Office.Interop.Excel.Workbook = _
        Globals.ThisAddIn.Application.ActiveWorkbook
    
    If NativeWorkbook IsNot Nothing Then
        Dim VstoWorkbook As Microsoft.Office.Tools.Excel.Workbook = _
            NativeWorkbook.GetVstoObject()
    End If
    
    Microsoft.Office.Interop.Excel.Workbook nativeWorkbook =
        Globals.ThisAddIn.Application.ActiveWorkbook;
    
    if (nativeWorkbook != null)
    {
        Microsoft.Office.Tools.Excel.Workbook vstoWorkbook =
            nativeWorkbook.GetVstoObject();
    }
    

为 Excel 工作表生成宿主项

  • 使用 Microsoft.Office.Interop.Excel.Worksheet 的 GetVstoObject 方法。下面的代码示例为活动工作表生成一个宿主项。

    Dim NativeSheet As Microsoft.Office.Interop.Excel.Worksheet = _
        TryCast(Globals.ThisAddIn.Application.ActiveSheet,  _
        Microsoft.Office.Interop.Excel.Worksheet)
    
    If NativeSheet IsNot Nothing Then
        Dim VstoSheet As Microsoft.Office.Tools.Excel.Worksheet = _
            NativeSheet.GetVstoObject()
    End If
    
    Microsoft.Office.Interop.Excel.Worksheet nativeSheet =
        Globals.ThisAddIn.Application.ActiveSheet as
        Microsoft.Office.Interop.Excel.Worksheet;
    
    if (nativeSheet != null)
    {
        Microsoft.Office.Tools.Excel.Worksheet vstoSheet =
            nativeSheet.GetVstoObject();
    }
    

生成 ListObject 宿主控件

使用 Microsoft.Office.Interop.Excel.ListObject 的 GetVstoObject 方法时,该方法返回一个 Microsoft.Office.Tools.Excel.ListObject。所生成的 Microsoft.Office.Tools.Excel.ListObject 不但具有原始 Microsoft.Office.Interop.Excel.ListObject 的所有功能,而且还具有其他功能,例如能够通过使用 Windows 窗体数据绑定模型绑定到数据。有关更多信息,请参见 ListObject 控件

为 ListObject 生成宿主控件

  • 使用 Microsoft.Office.Interop.Excel.ListObject 的 GetVstoObject 方法。下面的代码示例为活动工作表中的第一个 Microsoft.Office.Interop.Excel.ListObject 生成一个 Microsoft.Office.Tools.Excel.ListObject

    Dim sheet As Excel.Worksheet = Globals.ThisAddIn.Application.ActiveSheet
    
    If sheet.ListObjects.Count > 0 Then
        Dim listObject As Excel.ListObject = sheet.ListObjects(1)
        Dim vstoListObject As Microsoft.Office.Tools.Excel.ListObject = _
            listObject.GetVstoObject()
    End If
    
    Microsoft.Office.Interop.Excel.Worksheet sheet =
        Globals.ThisAddIn.Application.ActiveSheet as
        Microsoft.Office.Interop.Excel.Worksheet;
    
    if (sheet.ListObjects.Count > 0)
    {
        Excel.ListObject listObject = sheet.ListObjects[1];
        Microsoft.Office.Tools.Excel.ListObject vstoListObject =
            listObject.GetVstoObject();
    }
    

向文档和工作簿中添加智能标记

生成 Microsoft.Office.Tools.Word.DocumentMicrosoft.Office.Tools.Excel.Workbook 后,可以创建在这些对象所表示的文档或工作簿的上下文中识别的智能标记。实现方式是:使用 Microsoft.Office.Tools.Word.DocumentMicrosoft.Office.Tools.Excel.Workbook 的 VstoSmartTags 属性。有关更多信息,请参见下列主题:

向文档和工作表中添加托管控件

生成 Microsoft.Office.Tools.Word.DocumentMicrosoft.Office.Tools.Excel.Worksheet 后,可以向这些扩展对象表示的文档或工作表中添加控件。实现方式是:使用 Microsoft.Office.Tools.Word.DocumentMicrosoft.Office.Tools.Excel.Worksheet 的 Controls 属性。有关更多信息,请参见在运行时向 Office 文档添加控件

可以添加 Windows 窗体控件或宿主控件。宿主控件是 Visual Studio Tools for Office 控件,用于封装 Word 或 Excel 主互操作程序集中的相应控件。宿主控件公开基础本机 Office 对象的所有行为,除此之外还引发事件,并可通过使用 Windows 窗体数据绑定模型绑定到数据。有关更多信息,请参见宿主项和宿主控件概述

说明:

不能使用外接程序向工作表中添加 XmlMappedRange 控件,或向文档中添加 XMLNodeXMLNodes 控件。这些宿主控件不能以编程方式添加。有关更多信息,请参见宿主项和宿主控件的编程限制

保留和删除控件

向文档或工作表中添加托管控件后,保存然后关闭文档时并不保留这些控件。所有宿主控件都被删除,这样只有基础本机 Office 对象保留下来(例如,Microsoft.Office.Tools.Excel.ListObject 成为 Microsoft.Office.Interop.Excel.ListObject)。此外还移除所有 Windows 窗体控件,但将这些控件的 ActiveX 包装留在文档中。必须在外接程序中包括代码,以清理这些控件,或者下次打开文档时重新创建它们。有关更多信息,请参见在 Office 文档中保存动态控件

访问关于文档和工作簿的应用程序级事件

本机 Word 和 Excel 对象模型中的某些文档、工作簿和工作表事件仅在应用程序级别引发。例如,在 Word 中打开某个文档时引发 Microsoft.Office.Interop.Word.Application 事件,但该事件是在 Microsoft.Office.Interop.Word.Document 类中而不是 DocumentBeforeSave 类中定义的。

如果在外接程序中仅使用本机 Office 对象,则必须处理这些应用程序级事件,然后编写额外的代码,以确定引发了这些事件的文档是否是您自定义过的文档。宿主项在文档级别提供这些事件,这样更便于处理特定文档的事件。可以生成一个宿主项,然后处理该宿主项提供的事件。

使用本机 Word 对象的示例

下面的代码示例演示如何处理 Word 文档的应用程序级事件。此示例中的 CreateDocument1 方法新建一个文档,然后定义一个使该文档无法保存的 DocumentBeforeSave 事件处理程序。由于这是一个针对 Microsoft.Office.Interop.Word.Application 对象引发的应用程序级事件,因此该事件处理程序必须将 Doc 参数与 document1 对象相比较,以确定 document1 对象是否表示已保存的文档。

Private document1 As Word.Document = Nothing

Private Sub CreateDocument1()
    document1 = Me.Application.Documents.Add()
End Sub

Private Sub Application_DocumentBeforeSave(ByVal Doc As Word.Document, _
    ByRef SaveAsUI As Boolean, ByRef Cancel As Boolean) _
    Handles Application.DocumentBeforeSave
    If Type.ReferenceEquals(Doc, document1) Then
        Cancel = True
    End If
End Sub
private Word.Document document1 = null;

private void CreateDocument1()
{
    document1 = this.Application.Documents.Add(ref missing,
        ref missing, ref missing, ref missing);
    this.Application.DocumentBeforeSave += 
        new Word.ApplicationEvents4_DocumentBeforeSaveEventHandler(
        Application_DocumentBeforeSave);
}

private void Application_DocumentBeforeSave(Word.Document Doc, 
    ref bool SaveAsUI, ref bool Cancel)
{
    if (Type.ReferenceEquals(Doc, document1)) 
    {
        Cancel = true;
    }
}

使用宿主项的示例

下面的代码示例通过处理 Microsoft.Office.Tools.Word.Document 宿主项的 BeforeSave 事件来简化该过程。此示例中的 CreateDocument2 方法生成一个扩展 document2 对象的 Microsoft.Office.Tools.Word.Document,然后定义一个使文档无法保存的 BeforeSave 事件处理程序。由于仅在保存 document2 时调用该事件处理程序,因此该事件处理程序无需进行任何额外的工作来验证保存了哪个文件,即可取消保存操作。

Private document2 As Word.Document = Nothing
Private WithEvents vstoDocument As Microsoft.Office.Tools.Word.Document = Nothing

Private Sub CreateDocument2()
    document2 = Me.Application.Documents.Add()
    vstoDocument = document2.GetVstoObject()
End Sub

Private Sub vstoDocument_BeforeSave(ByVal sender As Object, _
    ByVal e As SaveEventArgs) Handles vstoDocument.BeforeSave
    e.Cancel = True
End Sub
private Word.Document document2 = null;
private Microsoft.Office.Tools.Word.Document vstoDocument = null;

private void CreateDocument2()
{
    document2 = this.Application.Documents.Add(ref missing,
        ref missing, ref missing, ref missing);
    vstoDocument = document2.GetVstoObject();
    vstoDocument.BeforeSave += new SaveEventHandler(vstoDocument_BeforeSave);
}

private void vstoDocument_BeforeSave(object sender, SaveEventArgs e)
{
    e.Cancel = true;
}

确定 Office 对象是否已扩展

若要确定是否已为某个特定本机 Office 对象生成了一个 Visual Studio Tools for Office 对象,请使用该 Office 对象的 HasVstoObject 方法。如果已生成扩展对象,则该方法返回 true,否则返回 false。

如果希望仅在指定的 Office 对象具有扩展对象时运行代码,这会很有帮助。例如,如果您有一个 Word 外接程序,用于处理 DocumentBeforeSave 事件,以在文档保存之前从中移除托管控件,则可以使用 HasVstoObject 方法来确定该文档是否已扩展。如果该文档还未扩展,则它不能包含托管控件,因此事件处理程序只能返回,而不尝试清理该文档中的控件。

配置项目以使用 GetVstoObject 和 HasVstoObject 方法

在安装 Visual Studio 2008 SP1 后创建一个应用程序级项目时,该项目自动进行配置,以便您在 ThisAddIn.cs 或 ThisAddIn.vb 代码文件中使用 GetVstoObject 和 HasVstoObject 方法。

若要在除 ThisAddIn.cs 和 ThisAddIn.vb 以外的代码文件中使用这些方法,则必须对该代码文件做如下更改。

修改 Excel 项目中的代码文件以创建扩展对象

  • 将下面的 using(对于 C#)或 Imports(对于 Visual Basic)语句添加到代码文件的开头处,以便可以在其中使用 GetVstoObject 和 HasVstoObject 方法。

    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Microsoft.Office.Tools.Excel.Extensions;
    

修改 Word 项目中的代码文件以创建扩展对象

  • 将下面的 using(对于 C#)或 Imports(对于 Visual Basic)语句添加到代码文件的开头处,以便可以在其中使用 GetVstoObject 和 HasVstoObject 方法。

    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Microsoft.Office.Tools.Excel.Extensions;
    

若要将这些方法用于在安装 SP1 之前创建的应用程序级项目,则必须对该项目做如下更改。

修改现有 Excel 外接程序以创建扩展对象

  1. 添加对 Microsoft.Office.Tools.Excel.v9.0.dll 程序集的引用。

  2. 将下面的 using(对于 C#)或 Imports(对于 Visual Basic)语句添加到代码文件的开头处,以便可以在其中使用 GetVstoObject 和 HasVstoObject 方法。

    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Microsoft.Office.Tools.Excel.Extensions;
    

修改现有 Word 外接程序以创建扩展对象

  1. 添加对 Microsoft.Office.Tools.Word.v9.0.dll 程序集的引用。

  2. 将下面的 using(对于 C#)或 Imports(对于 Visual Basic)语句添加到代码文件的开头处,以便可以在其中使用 GetVstoObject 和 HasVstoObject 方法。

    Imports Microsoft.Office.Tools.Word.Extensions
    
    using Microsoft.Office.Tools.Word.Extensions;
    

需要进行这些更改的原因在于 GetVstoObject 和 HasVstoObject 方法是作为扩展方法实现的。尽管您使用 GetVstoObject 和 HasVstoObject 方法就好像它们是在 Excel 或 Word 主互操作程序集中的类型中定义的,但实际上它们是在 Visual Studio Tools for Office 运行时的 Microsoft.Office.Tools.Excel.ExtensionsMicrosoft.Office.Tools.Word.Extensions 命名空间中的类型中定义的。有关扩展方法的更多信息,请参见扩展方法(C# 编程指南)扩展方法 (Visual Basic)

请参见

任务

Excel 外接程序动态控件示例

Word 外接程序动态控件示例

概念

应用程序级外接程序编程

在运行时向 Office 文档添加控件

宿主项和宿主控件概述

智能标记概述

从文档级自定义项中的本机 Office 对象获取扩展对象

修订记录

日期

修订历史记录

原因

2008 年 7 月

新增主题。

SP1 功能更改。