演练:从 VBA 中调用应用程序级外接程序中的代码

更新:2007 年 11 月

适用对象

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

项目类型

  • 应用程序级项目

Microsoft Office 版本

  • 2007 Microsoft Office system

  • Microsoft Office 2003

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

此演练演示如何向其他 Microsoft Office 解决方案(包括 Visual Basic for Applications (VBA) 和 COM 外接程序)公开某个应用程序级外接程序中的对象。

尽管此演练专门使用 Excel,但该演练演示的概念适用于 Visual Studio Tools for Office 提供的任何外接程序项目。

本演练阐释以下任务:

  • 定义可向其他 Office 解决方案公开的类。

  • 向其他 Office 解决方案公开该类。

  • 从 VBA 代码中调用该类的方法。

Bb608614.alert_note(zh-cn,VS.90).gif说明:

对于在以下说明中使用的某些 Visual Studio 用户界面元素,您的计算机可能会显示不同的名称或位置。这些元素取决于您使用的 Visual Studio 版本及设置。有关更多信息,请参见Visual Studio 设置

先决条件

您需要以下组件来完成本演练:

  • Visual Studio Tools for Office(Visual Studio 2008 专业版 和 Visual Studio Team System 的可选组件)。

  • Microsoft Office Excel 2007。

    Bb608614.alert_note(zh-cn,VS.90).gif说明:

    您也可以使用 Microsoft Office Excel 2003 执行此演练。但是,部分说明假定您在使用 Excel 2007 中的功能区。

默认情况下,Visual Studio Tools for Office 随列出的 Visual Studio 版本一起安装。若要检查它是否已安装,请参见安装 Visual Studio Tools for Office

链接到视频有关视频演示,请参见 Video How to: Calling Code in an Application-Level Add-in from VBA(视频帮助:从 VBA 中调用应用程序级外接程序中的代码)。

创建外接程序项目

第一步是针对 Excel 创建一个外接程序项目。

创建新项目

  • 使用适用于 2007 Microsoft Office system 的 Excel 外接程序项目模板,创建一个名为“ExcelImportData”的 Excel 外接程序项目。有关更多信息,请参见如何:创建 Visual Studio Tools for Office 项目

    Visual Studio 将打开 ThisAddIn.cs 或 ThisAddIn.vb 代码文件,并将“ExcelImportData”项目添加到“解决方案资源管理器”中。

定义可向其他 Office 解决方案公开的类

此演练的目的是从 VBA 代码中调入外接程序中名为 AddInUtilities 的类的 ImportData 方法。此方法将数据导入活动工作簿中的一个新工作表,并创建一个简单的 DataSet 以包含数据。

若要向其他 Office 解决方案公开 AddInUtilities 类,您必须使该类成为公共类并对于 COM 可见。您还必须提供一种方式来公开该类中的 IDispatch 接口。下面过程中的代码演示了一种可满足这些要求的方式。有关更多信息,请参见从其他 Office 解决方案调用应用程序级外接程序中的代码

定义可向其他 Office 解决方案公开的类

  1. 在“项目”菜单上单击“添加类”。

  2. 在“添加新项”对话框中,将新类的名称改为 AddInUtilities,然后单击“添加”。

    AddInUtilities.cs 或 AddInUtilities.vb 文件将在代码编辑器中打开。

  3. 将下面的语句添加到文件的顶部。

    Imports System.Data
    Imports System.Runtime.InteropServices
    Imports Excel = Microsoft.Office.Interop.Excel
    
    using System.Data;
    using System.Runtime.InteropServices;
    using Excel = Microsoft.Office.Interop.Excel;
    
  4. 用下列代码替换空的 AddInUtilities 类声明。

    此代码使 AddInUtilities 类对于 COM 可见,并且它向类中添加 ImportData 方法。为了公开 IDispatch 接口,AddInUtilities 类还会实现一个具有 InterfaceIsIDispatch 属性的接口。

    <System.Runtime.InteropServices.ComVisibleAttribute(True)> _
    <System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
    Public Interface IAddInUtilities
        Sub ImportData()
    End Interface
    
    <System.Runtime.InteropServices.ComVisibleAttribute(True)> _
    <System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)> _
    Public Class AddInUtilities
        Implements IAddInUtilities
    
        Public Sub ImportData() Implements IAddInUtilities.ImportData
    
            ' Create a new DataTable.
            Dim ds As New DataSet()
            Dim dt As DataTable = ds.Tables.Add("Customers")
            dt.Columns.Add(New DataColumn("LastName"))
            dt.Columns.Add(New DataColumn("FirstName"))
    
            ' Add a new row to the DataTable.
            Dim dr As DataRow = dt.NewRow()
            dr("LastName") = "Chan"
            dr("FirstName") = "Gareth"
            dt.Rows.Add(dr)
    
            ' Add a new XML map to the collection.
            Dim activeWorkbook As Excel.Workbook = Globals.ThisAddIn.Application.ActiveWorkbook
            Dim xmlMap1 As Excel.XmlMap = activeWorkbook.XmlMaps.Add(ds.GetXmlSchema(), _
                "NewDataSet")
    
            ' Import the data.
            If Not (xmlMap1 Is Nothing) Then
                Dim lastSheet As Object = activeWorkbook.Sheets(activeWorkbook.Sheets.Count)
                Dim newSheet As Excel.Worksheet = CType(activeWorkbook.Sheets.Add( _
                    After:=lastSheet), Excel.Worksheet)
                newSheet.Name = "Imported Data"
                activeWorkbook.XmlImportXml(ds.GetXml(), xmlMap1, True, _
                    newSheet.Range("A1"))
            End If
        End Sub
    End Class
    
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    [System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IAddInUtilities
    {
        void ImportData();
    }
    
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    [System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)]
    public class AddInUtilities : IAddInUtilities
    {
        public void ImportData()
        {
            // Create a new DataTable.
            DataSet ds = new DataSet();
            DataTable dt = ds.Tables.Add("Customers");
            dt.Columns.Add(new DataColumn("LastName"));
            dt.Columns.Add(new DataColumn("FirstName"));
    
            // Add a new row to the DataTable.
            DataRow dr = dt.NewRow();
            dr["LastName"] = "Chan";
            dr["FirstName"] = "Gareth";
            dt.Rows.Add(dr);
    
            // Add a new XML map to the collection.
            Excel.Workbook activeWorkbook = Globals.ThisAddIn.Application.ActiveWorkbook;
            Excel.XmlMap xmlMap1 = activeWorkbook.XmlMaps.Add(ds.GetXmlSchema(), 
                "NewDataSet");
    
            // Import the data.
            if (xmlMap1 != null)
            {
                object lastSheet = activeWorkbook.Sheets[activeWorkbook.Sheets.Count];
                Excel.Worksheet newSheet = (Excel.Worksheet)activeWorkbook.Sheets.Add(
                    System.Type.Missing, lastSheet, 1, System.Type.Missing);
                newSheet.Name = "Imported Data";
    
                activeWorkbook.XmlImportXml(ds.GetXml(), out xmlMap1, true,
                    newSheet.get_Range("A1", System.Type.Missing));
            }
        }
    }
    

向其他 Office 解决方案公开该类

若要向其他 Office 解决方案公开 AddInUtilities 类,请重写 ThisAddIn 类中的 RequestComAddInAutomationService 方法。在重写中,返回 AddInUtilities 类的实例。

向其他 Office 解决方案公开 AddInUtilities 类

  1. 在“解决方案资源管理器”中展开“Excel”。

  2. 右击“ThisAddIn.cs”或“ThisAddIn.vb”,然后单击“查看代码”。

  3. 向 ThisAddIn 类中添加下面的代码。

    Private utilities As AddInUtilities
    
    Protected Overrides Function RequestComAddInAutomationService() As Object
        If utilities Is Nothing Then
            utilities = New AddInUtilities()
        End If
        Return utilities
    End Function
    
    private AddInUtilities utilities;
    
    protected override object RequestComAddInAutomationService()
    {
        if (utilities == null)
            utilities = new AddInUtilities();
    
        return utilities;
    }
    
  4. 在“生成”菜单上,单击“生成解决方案”。

    验证解决方案已生成且未发生错误。

测试外接程序

您可以从若干不同类型的 Office 解决方案中调入 AddInUtilities 类。在此演练中,您将在 Excel 工作簿中使用 VBA 代码。有关同样可以使用的其他类型 Office 解决方案的更多信息,请参见从其他 Office 解决方案调用应用程序级外接程序中的代码

测试外接程序

  1. 按 F5 运行项目。

  2. 在 Excel 中,将活动工作簿另存为启用宏的 Excel 工作簿 (*.xlsm)。将它保存在一个方便的位置,比如桌面。

  3. 在功能区上,单击“开发人员”选项卡。

    Bb608614.alert_note(zh-cn,VS.90).gif说明:

    如果看不到“开发人员”选项卡,您必须首先显示该选项卡。有关更多信息,请参见如何:在功能区上显示“开发人员”选项卡

  4. 在“代码”组中,单击“Visual Basic”。

    将打开 Visual Basic 编辑器。

  5. 在“项目”窗口中,双击“ThisWorkbook”。

    将打开 ThisWorkbook 对象的代码文件。

  6. 向代码文件中添加以下 VBA 代码。此代码首先获取一个 COMAddIn 对象,该对象表示 ExcelImportData 外接程序。然后,代码使用 COMAddIn 对象的 Object 属性来调用 ImportData 方法。

    Sub CallVSTOMethod()
        Dim addIn As COMAddIn
        Dim automationbject As Object
        Set addIn = Application.COMAddIns("ExcelImportData")
        Set automationObject = addIn.Object
        automationObject.ImportData
    End Sub
    
  7. 按 F5。

  8. 验证是否已将新的“导入的数据”工作表添加到工作簿。同时,验证单元格 A1 是否包含字符串 Chan,以及单元格 B1 是否包含字符串 Gareth。

  9. 退出 Excel。

后续步骤

可以从以下主题中了解有关外接程序编程的更多信息:

请参见

任务

如何:创建 Visual Studio Tools for Office 项目

概念

应用程序级外接程序编程

从其他 Office 解决方案调用应用程序级外接程序中的代码

开发 Office 解决方案

AddIn 宿主项

使用扩展性接口自定义 UI 功能

应用程序级外接程序的体系结构