本演练演示如何从工作簿中的 Visual Basic for Applications (VBA) 代码调用 Microsoft Office Excel 文档级自定义中的方法。 该过程涉及三个基本步骤:将方法添加到 Sheet1 主机项类,向工作簿中的 VBA 代码公开该方法,然后从工作簿中的 VBA 代码调用该方法。
适用于: 本主题中的信息适用于 Excel 和 Word 的文档级项目。 有关详细信息,请参阅 Office 应用程序和项目类型提供的功能。
尽管本演练专门使用 Excel,但本演练演示的概念也适用于 Word 的文档级项目。
本演练阐释了以下任务:
创建包含 VBA 代码的工作簿。
使用 Excel 中的信任中心信任工作簿的位置。
将方法添加到
Sheet1宿主项类。为
Sheet1主机项类提取接口。向 VBA 代码公开该方法。
从 VBA 代码调用方法。
注释
以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅个性化设置 Visual Studio IDE。
先决条件
你需要满足以下条件才能完成本演练:
包含 Microsoft Office 开发人员工具的 Visual Studio 版本。 有关详细信息,请参阅 配置计算机以开发 Office 解决方案。
Microsoft Excel
创建包含 VBA 代码的工作簿
第一步是创建一个启用了宏的工作簿,其中包含一个简单的 VBA 宏。 在自定义 VBA 中公开代码之前,工作簿必须已包含 VBA 代码。 否则,Visual Studio 无法修改 VBA 项目,使 VBA 代码能够调用自定义程序集。
如果已有包含要使用的 VBA 代码的工作簿,则可以跳过此步骤。
创建包含 VBA 代码的工作簿
启动 Excel。
将活动文档另存为 Excel 宏启用工作簿 (*.xlsm),名称为 WorkbookWithVBA。 将其保存到方便的位置,例如桌面。
在功能区上,单击“ 开发人员 ”选项卡。
注释
如果 “开发人员 ”选项卡不可见,必须先显示它。 有关详细信息,请参阅 “如何:在功能区上显示开发人员”选项卡。
在 “代码 ”组中,单击 “Visual Basic”。
此时会打开 Visual Basic 编辑器。
在 “项目” 窗口中,双击 “ThisWorkbook”。
此时会打开对象的
ThisWorkbook代码文件。将以下 VBA 代码添加到代码文件。 此代码定义一个不执行任何作的简单函数。 此函数的唯一用途是确保工作簿中存在 VBA 项目。 这对于本演练的后续步骤是必需的。
Sub EmptySub() End Sub保存文档并退出 Excel。
创建项目
现在,你可以为 Excel 创建一个文档级项目,该项目使用前面创建的启用了宏的工作簿。
创建新项目
启动 Visual Studio。
在“ 文件 ”菜单上,指向“ 新建”,然后单击“ 项目”。
在模板窗格中,展开 Visual C#,然后展开 Office/SharePoint。
选择 Office 加载项 节点。
在项目模板列表中,选择 Excel 2010 工作簿 或 Excel 2013 工作簿 项目。
在 “名称 ”框中,键入 CallingCodeFromVBA。
单击 “确定” 。
此时会打开 Visual Studio Tools for Office 项目向导 。
选择 “复制现有文档”,并在 现有文档框的完整路径 中指定之前创建的 WorkbookWithVBA 工作簿的位置。 如果使用自己的启用了宏的工作簿,则请指定该工作簿的位置。
单击“完成”。
Visual Studio 在设计器中打开 WorkbookWithVBA 工作簿,并将 CallingCodeFromVBA 项目添加到 解决方案资源管理器。
信任工作簿的位置
在解决方案中向工作簿中的 VBA 代码公开代码之前,必须信任工作簿中的 VBA 才能运行。 有多种方法可以实现这一点。 在本演练中,您将通过信任 Excel 信任中心中的工作簿位置来完成此任务。
信任工作簿的位置
启动 Excel。
单击“ 文件 ”选项卡。
单击 “Excel 选项” 按钮。
在“类别”窗格中,单击“ 信任中心”。
在详细信息窗格中,单击“ 信任中心设置”。
在“类别”窗格中,单击“ 受信任的位置”。
在详细信息窗格中,单击“ 添加新位置”。
在 “Microsoft Office 受信任位置 ”对话框中,浏览到包含 CallingCodeFromVBA 项目的文件夹。
选择也信任此位置的子文件夹。
在 “Microsoft Office 受信任位置 ”对话框中,单击“ 确定”。
在 “信任中心 ”对话框中,单击“ 确定”。
在 “Excel 选项 ”对话框中,单击“ 确定”。
退出 Excel。
向 Sheet1 类添加方法
设置 VBA 项目后,请将公共方法添加到可从 VBA 代码调用的 Sheet1 主机项类。
向 Sheet1 类添加方法
在 解决方案资源管理器中,右键单击 Sheet1.cs,然后单击“ 查看代码”。
Sheet1.cs文件将在代码编辑器中打开。
将以下代码添加到
Sheet1类。 该方法CreateVstoNamedRange在指定范围内创建新 NamedRange 对象。 此方法还会为 Selected 的 NamedRange 事件创建事件处理程序。 在本演练的后面部分,你将从文档中的 VBA 代码调用CreateVstoNamedRange该方法。private Microsoft.Office.Tools.Excel.NamedRange namedRange1; public void CreateVstoNamedRange(Excel.Range range, string name) { if (!this.Controls.Contains(name)) { namedRange1 = this.Controls.AddNamedRange(range, name); namedRange1.Selected += new Excel.DocEvents_SelectionChangeEventHandler( namedRange1_Selected); } else { MessageBox.Show("A named range with this specific name " + "already exists on the worksheet."); } } private void namedRange1_Selected(Microsoft.Office.Interop.Excel.Range Target) { MessageBox.Show("This named range was created by Visual Studio " + "Tools for Office."); }将以下方法添加到
Sheet1类。 此方法重写 GetAutomationObject 方法以返回Sheet1类的当前实例。protected override object GetAutomationObject() { return this; }在类声明的第一行
Sheet1之前应用以下属性。 这些属性使类对 COM 可见,但不生成类接口。[System.Runtime.InteropServices.ComVisible(true)] [System.Runtime.InteropServices.ClassInterface( System.Runtime.InteropServices.ClassInterfaceType.None)]
提取 Sheet1 类的接口
在向 VBA 代码公开 CreateVstoNamedRange 该方法之前,必须创建定义此方法的公共接口,并且必须将此接口公开给 COM。
提取 Sheet1 类的接口
在 Sheet1.cs 代码文件中,单击类中的
Sheet1任意位置。在 “重构 ”菜单上,单击“ 提取接口”。
在 “提取接口 ”对话框中的 “选择公共成员以形成接口 ”框中,单击该方法的
CreateVstoNamedRange条目。单击 “确定” 。
Visual Studio 将生成一个名为
ISheet1的新接口,并修改类的定义Sheet1,以便实现ISheet1该接口。 Visual Studio 还会在代码编辑器中打开 ISheet1.cs 文件。在 ISheet1.cs 文件中,将
ISheet1接口声明替换为以下代码。 此代码使ISheet1接口公开,并应用 ComVisibleAttribute 属性以使接口对 COM 可见。[System.Runtime.InteropServices.ComVisible(true)] public interface ISheet1 { void CreateVstoNamedRange(Microsoft.Office.Interop.Excel.Range range, string name); }构建项目。
向 VBA 代码公开方法
若要向CreateVstoNamedRange工作簿中的 VBA 代码公开该方法,请将主机项的 ReferenceAssemblyFromVbaProject 属性设置为 Sheet1。
将方法暴露给 VBA 代码
在 解决方案资源管理器中,双击 Sheet1.cs。
WorkbookWithVBA 文件在设计器中打开,Sheet1 可见。
在 “属性” 窗口中,选择 ReferenceAssemblyFromVbaProject 属性,并将值更改为 True。
在显示的消息中单击 “确定 ”。
构建项目。
从 VBA 代码调用方法
现在可以从工作簿中的 VBA 代码调用 CreateVstoNamedRange 该方法。
注释
在本演练中,将在调试项目时向工作簿添加 VBA 代码。 每次生成项目时,您添加到此文档的 VBA 代码都会被覆盖,因为 Visual Studio 会用主项目文件夹中的文档副本替换生成输出文件夹中的文档。 如果要保存 VBA 代码,可以将它复制到项目文件夹中的文档。 有关详细信息,请参阅 合并 VBA 和文档级自定义。
从 VBA 代码调用方法
按 F5 运行项目。
在 “开发人员 ”选项卡上的 “代码 ”组中,单击 “Visual Basic”。
此时会打开 Visual Basic 编辑器。
在 “插入 ”菜单上,单击“ 模块”。
将以下代码添加到新模块。
此代码调用
CreateTable自定义程序集中的方法。 宏通过使用全局GetManagedClass方法访问向 VBA 代码公开的Sheet1主机项类来访问此方法。 当您在本演示中先前设置 ReferenceAssemblyFromVbaProject 属性时,GetManagedClass方法已自动生成。Sub CallVSTOMethod() Dim VSTOSheet1 As CallingCodeFromVBA.Sheet1 Set VSTOSheet1 = GetManagedClass(Sheet1) Call VSTOSheet1.CreateVstoNamedRange(Sheet1.Range("A1"), "VstoNamedRange") End Sub按 F5。
在打开的工作簿中,单击 Sheet1 上的单元格 A1。 验证是否显示消息框。
无需保存更改即可退出 Excel。
后续步骤
可以在以下主题中了解有关从 VBA 调用 Office 解决方案中的代码的详细信息:
从 VBA 调用 Visual Basic 自定义项中的主机项中的代码。 此过程不同于 Visual C# 进程。 有关详细信息,请参阅 演练:在 Visual Basic 项目中从 VBA 调用代码。
从 VBA 调用 VSTO 外接程序中的代码。 有关详细信息,请参阅 演练:从 VBA 调用 VSTO 外接程序中的代码。