VSTO加载xlam和调用vba的方法

  • 发布时间:2017年5月2日 11:02
  • 作者:杨仕航
  • 分类标签: VSTO
  • 阅读(1946)
  • 评论(0)

在用VSTO开发Excel插件时,可能有些旧的vba代码无法转化成VSTO代码(C#或VB.net);可能有些代码用vba执行更好或者某些功能需要;也可能是一些自定义函数提高Excel使用。

通常可以将包含vba代码的Excel文件,另存为xlam格式或xla格式。在VSTO插件执行过程中调用xlam文件中的vba代码即可。


假设我们已经有个xlam文件,名为test.xlam。该文件放在VSTO项目的根目录下。该文件中有个公共函数如下:

Public Function msg_test()
    MsgBox "弹窗测试"
End Function


1、通过插件直接打开xlam

xlam也是Excel文件,可以直接被打开。只不过打开在后台,可以在vba代码界面看到。

20170502/20170502095827081.png


打开VSTO项目,找到插件开始加载事件ThisAddIn_Startup。在插件中打开xlam文件,如下代码:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    //获取插件dll的所在位置
    string strPath = System.AppDomain.CurrentDomain.BaseDirectory;
    
    //根据xlam文件的路径(存放在VSTO项目发布之后的根目录下)
    string strXlam = System.IO.Path.Combine(strPath, "test.xlam");
    
    //加载宏
    Globals.ThisAddIn.Application.Workbooks.Open(strXlam);
}


该方法虽然比较简单,不过有个问题:安全提示。

20170502/20170502100728152.png


通常做法是引导用户设置安全性级别。信任中心设置启用所有宏:

20170502/20170502100907902.png


当然,控制安全级别可以通过注册表控制。在打开xlam之前,先记录当前的安全级别。若不是最低的,则修改为最低的安全基本。打开xlam之后,再调整安全级别为原先的级别。

设置安全级别的路径为 :

HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Excel\Security

其中,14.0是当前Office的版本。Office2003是11.0;2007是12.0;2010是14.0;2013是15.0。没有数字13,西方也是有些迷信,不喜欢这个数字。


注册表键名为VBAWarngins,值类型是dword。

若该键值不存在或为2,则安全级别默认为禁用并通知。最低安全级别的值为1。

原理已经奉上,这里就不介绍怎么操作注册表。搜索一下有大把注册表操作的代码。


2、写注册表加载xlam文件

可能大家会留意到菜单:选项 --> 加载项 --> Excel加载项。可看到Excel的加载宏。

20170502/20170502104412226.png


该窗口可让我们自行添加xlam文件。

同样,添加的文件信息记录在注册表中。可以直接写注册表,写入该xlam文件。注册表位置如下:

HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Excel\Add-in Manager

往该位置添加一个字符串注册表键。键名为xlam文件完整路径,键值为空字符串。


不过,不推荐在VSTO中写代码添加。还需考虑用户有可能卸载插件。若卸载插件,xlam文件也被删除。该注册表项还存在,打开Excel还会继续加载。由于文件不存在了,会报错提示。

所以,建议在安装包安装程序中写入该注册表项。卸载时也同时删掉该注册表项。


3、VSTO调用vba的方法

加载了xlam文件,可能需要在VSTO中执行vba的函数。顺便把这个知识点也讲了。

vba中有个Application.Run方法,可以使用字符串的函数名调用vba函数。

VSTO同样可以通过Application对象执行Run方法。代码如下:

Globals.ThisAddIn.Application.Run("msg_test")


上一篇:Django初步使用Celery

下一篇:用装饰器优化Redis缓存代码

评论列表

智慧如你,不想发表一下意见吗?

新的评论

清空

猜你喜欢

  • 猜测中,请稍等...