ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 13034|回复: 10

VBA与C#的交互----在VBA中调用VSTO的函数

[复制链接]

TA的精华主题

TA的得分主题

发表于 2012-11-19 13:49 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:VSTO开发
本帖最后由 liucqa 于 2012-11-19 15:09 编辑

http://msdn.microsoft.com/zh-cn/library/bb608613%28v=vs.100%29.aspx
参考上贴,抄袭了一个通过VBA调用VSTO(C#)函数的示例

Sheet1.cs中的代码
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows.Forms;
  7. using System.Xml.Linq;
  8. using Microsoft.Office.Tools.Excel;
  9. using Microsoft.VisualStudio.Tools.Applications.Runtime;
  10. using Excel = Microsoft.Office.Interop.Excel;
  11. using Office = Microsoft.Office.Core;

  12. namespace CallingCodeFromVBA
  13. {
  14.     //在 Sheet1 类声明的第一行前面应用下列特性。这些特性使类对于 COM 可见,但不生成类接口。
  15.     [System.Runtime.InteropServices.ComVisible(true)]
  16.     [System.Runtime.InteropServices.ClassInterface(
  17.         System.Runtime.InteropServices.ClassInterfaceType.None)]
  18.     public partial class Sheet1 : CallingCodeFromVBA.ISheet1
  19.     {
  20.         
  21.          //下面是准备从文档的 VBA 代码中调用 的MyMsg函数。
  22.         public void MyMsg(string msg)
  23.         {
  24.              MessageBox.Show(msg);         
  25.         }

  26.         //此方法将重写 GetAutomationObject() 方法,以返回 Sheet1 类的当前实例。
  27.         protected override object GetAutomationObject()
  28.         {
  29.             return this;
  30.         }

  31.         private void Sheet1_Startup(object sender, System.EventArgs e)
  32.         {
  33.         }

  34.         private void Sheet1_Shutdown(object sender, System.EventArgs e)
  35.         {
  36.         }

  37.         #region VSTO 设计器生成的代码

  38.         /// <summary>
  39.         /// 设计器支持所需的方法 - 不要
  40.         /// 使用代码编辑器修改此方法的内容。
  41.         /// </summary>
  42.         private void InternalStartup()
  43.         {
  44.             this.Startup += new System.EventHandler(Sheet1_Startup);
  45.             this.Shutdown += new System.EventHandler(Sheet1_Shutdown);
  46.         }

  47.         #endregion

  48.     }
  49. }
复制代码

ISheet1.cs中的代码

  1. using System;
  2. namespace CallingCodeFromVBA
  3. {
  4.     //添加
  5.     [System.Runtime.InteropServices.ComVisible(true)]
  6.     //此代码使 ISheet1 接口成为公共接口,并且应用 ComVisibleAttribute 特性以使该接口对于 COM 可见。
  7.     public interface ISheet1
  8.     {
  9.         void MyMsg(string msg);
  10.     }
  11. }
复制代码

将 Sheet1 宿主项的“ReferenceAssemblyFromVbaProject”属性设置为“True”。
该设置会在Excel文件中增加对VSTO函数所在文件的引用

在模块1中使用VSTO函数
Sub CallVSTOMethod()
    Dim VSTOSheet1 As CallingCodeFromVBA.Sheet1
    Set VSTOSheet1 = GetManagedClass(Sheet1)
    Call VSTOSheet1.MyMsg("hello")
End Sub

工程文件
CallingCodeFromVBA.rar (861.34 KB, 下载次数: 207)


发布的文件
publish.rar (379.36 KB, 下载次数: 137)




TA的精华主题

TA的得分主题

 楼主| 发表于 2012-11-19 14:57 | 显示全部楼层
本帖最后由 liucqa 于 2012-11-20 11:22 编辑

使用发布的setup安装之后,你可以在机器的任何位置运行.xlsm文件,引用中的信息是在注册表中记录的。
引用的文件在C:\Users\Charltsing\AppData\Local\Apps\2.0\目录里面可以找到

安装之后的文件位置
捕获.JPG


HKEY_USERS\S-1-5-21-1772528870-2292866102-2639753598-1000\Software\Classes\SOFTWARE\Microsoft\Windows\CurrentVersion\Deployment\SideBySide\2.0\Components
注册表.JPG


HKEY_CURRENT_USER\Software\Microsoft\VSTA\Solutions\ffe865c9-a8a2-4a9b-adf0-51e1eb68dca1
捕获.JPG

安装之后的注册表信息,注意那个PublicKeyToken=800ce568bcd031d1,与安装在C:\Users\Charltsing\AppData\Local\Apps\2.0\A1Z0ZEYE.Q41\L7V3NW7P.NDR里面的文件是对应的
捕获.JPG




用Total Uninstall监控得到的。



TA的精华主题

TA的得分主题

 楼主| 发表于 2012-11-19 15:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
1.JPG

如果你的机器没有安装.Net 4.0和VSTO运行库,执行发布文件安装的时候,会自动下载上图的内容






总体来看,用VSTO4.0做出来的东东,发布还是很方便的

TA的精华主题

TA的得分主题

发表于 2012-11-19 15:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
这个注册表不全

点评

就截图了一部分,下面还有  发表于 2012-11-19 15:59

TA的精华主题

TA的得分主题

发表于 2012-11-20 09:12 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
嗯 这个和发布dll在VBA中使用非常相似...
对了 在VBA中引用是自动引用吗? 改引用在其他EXCEL文件中是否可以被引用 还有就是 比如
Call VSTOSheet1.MyMsg("hello")
在代码编写的时候 打出 '点' 的时候会自动列出成员吗?

.....目前在公司 无法试验 麻烦楼主下
我对这个比较感兴趣
另外感谢分享检测安装时注册表变化的软件

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-11-20 10:01 | 显示全部楼层
本帖最后由 liucqa 于 2012-11-20 11:30 编辑
doryan 发表于 2012-11-20 09:12
嗯 这个和发布dll在VBA中使用非常相似...
对了 在VBA中引用是自动引用吗? 改引用在其他EXCEL文件中是否可以 ...

在VBA中引用是自动引用吗? 改引用在其他EXCEL文件中是否可以被引用
答:引用是由VSTO的ReferenceAssemblyFromVbaProject在属性发生变化时,自动写入到XLSM里面的。
捕获.JPG
D:\Test Code\CallingCodeFromVBA\CallingCodeFromVBA\{1BF669DD-3D96-409D-BD16-1AD130D907E7}
引用地址格式如上,谁能解释一下呢?

这个CLSID在AssemblyInfo.cs文件中定义
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("1bf669dd-3d96-409d-bd16-1ad130d907e7")]

         
  1. private void ThisWorkbook_Startup(object sender, System.EventArgs e)
  2.         {
  3.             System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
  4.             //得到当前这个Assembly

  5.             Guid id = ass.ManifestModule.ModuleVersionId;
  6.             //得到一个Guid的版本号,但好像不是AssemblyInfo里写的那个

  7.             object[] attrs = ass.GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false);
  8.             Guid AssemblyInfoid = new Guid(((System.Runtime.InteropServices.GuidAttribute)attrs[0]).Value);
  9.             //这个得到的就是AssemblyInfo里的那个了

  10.             MessageBox.Show(id.ToString());
  11.             MessageBox.Show(AssemblyInfoid.ToString());
  12.         }
复制代码


Call VSTOSheet1.MyMsg("hello"),在代码编写的时候 打出 '点' 的时候会自动列出成员吗?
答:如果引用正确的话,会自动列出成员。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-11-20 10:15 | 显示全部楼层
本帖最后由 liucqa 于 2012-11-20 10:15 编辑

ReferenceAssemblyFromVbaProject

当所有宿主项 ReferenceAssemblyFromVbaProject 属性在 Visual Basic 或 Visual C# 项目中设置为 True时, Visual Studio 将执行下列任务:

    它在程序集生成自定义项程序集的类型库并嵌入类型库。

    它引用添加到 VBA 项目的以下类型库文档中:

        您的自定义项程序集的类型库。

        for Office execution engine 9.0 的 Microsoft Visual Studio 工具类型库。 此类型库。 Visual Studio Tools for Office Runtime中。

当 ReferenceAssemblyFromVbaProject 属性重新设置为 False时, Visual Studio 将执行下列任务:

    它移除类型库文档中的 VBA 项目引用。

    它从程序集中移除嵌入的类型库。

TA的精华主题

TA的得分主题

发表于 2012-11-20 19:53 | 显示全部楼层
本帖最后由 doryan 于 2012-11-20 19:54 编辑
liucqa 发表于 2012-11-20 10:15
ReferenceAssemblyFromVbaProject

当所有宿主项 ReferenceAssemblyFromVbaProject 属性在 Visual Basic  ...

奶奶的 学门新技术真有难度啊
搞不定啊 明天卸了VS08和Office2003 两个Office真的很容易出问题

未命名.jpg

我这没有那个属性的设置...03中有 但是03的不能修改...

TA的精华主题

TA的得分主题

发表于 2015-3-30 21:00 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
打包成msi安装包后,安装的时候提示,    不能注册模块 XXX.TLB   请问是什么问题?

TA的精华主题

TA的得分主题

发表于 2015-10-22 16:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
Mark......
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-17 04:15 , Processed in 0.052420 second(s), 14 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表