|
本帖最后由 灰袍法师 于 2011-12-10 20:36 编辑
强烈推荐论坛置顶帖 VBA收藏贴 http://club.excelhome.net/thread-721260-1-1.html
更新第10楼,靠VSTO的开发方法,直接在VB开发Excel工作簿,全自动把一切代码打包入DLL,连注册都不需要!
需要VS2007, office2007 .NET 3.5以上才可以用
很多筒子也许希望用VB的强大功能制作DLL,从而使VBA的速度加快,功能增多,或者保护代码,简单搜索一下论坛,你会找到许多封装DLL的例子。
以下介绍一个直接在 VBA引用VB 编译的DLL类库(class library)的方法,不是封装自定义函数哦,而是封装VBA直接使用的对象。
本方法编译出来的DLL可以放在任意目录,使用前无须人手点击VBA菜单的引用,也无需regsvr32.exe
不过需要.NET framework 2.0或以上,office2007或以上的支持,office 2003需要打补丁(附件压缩包有此补丁)
本方案用Visual studio 2010, 编译 32位DLL for anyCPU,附件有工程源码,熟练的筒子可以自行重新编译自己喜欢的版本。
重点有2个:
1 VB的类库必须要能够被regasm.exe注册,也就是说要有COM的注册信息,微软的官方网页有介绍
Walkthrough: Creating COM Objects with Visual Basic
http://msdn.microsoft.com/en-us/library/x66s8zcd.aspx
这里简单介绍步骤:
步骤一: VB2010里面新建项目,选择VisualBasic,类库
步骤二 :在解决方案资源管理器点击你的项目ClassLibrary1 (或者你刚才新建项目时候采用的项目名称),选择添加-新建项-COM类
这时候你将会看到出现一个ComClass1,这就是你要写你的自定义对象代码的地方,里面应该已经自动生成了以下代码
这些代码是注册COM类必需要用到的,GUID可以换成其他你喜欢的值,只要跟系统已经注册的其他项目没冲突就行(一般乱写一个也不会有冲突)
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1
#Region "COM GUID"
' 这些 GUID 提供此类的 COM 标识
' 及其 COM 接口。若更改它们,则现有的
' 客户端将不再能访问此类。
Public Const ClassId As String = "4061126d-7488-4dcd-a4f1-40d632e03a15"
Public Const InterfaceId As String = "65aab5a1-a56b-4418-a8bf-35d247166e49"
Public Const EventsId As String = "ae811cd9-1c21-4a89-99a5-ff4ef3edb396"
#End Region
' 可创建的 COM 类必须具有一个不带参数的 Public Sub New()
' 否则, 将不会在
' COM 注册表中注册此类,且无法通过
' CreateObject 创建此类。
Public Sub New()
MyBase.New()
End Sub
End Class
步骤三: 写好你的对象代码,属性方法等等,编译即可得到一个DLL。
如果你只需要在自己的电脑用这个DLL,那么可以让编译器帮你自动注册
双击 My Project ,点击编译类别,勾选“为COM互操作注册”即可
但是这个做法并不能让你的DLL在其他操作系统,其他电脑运行,所以实际上没什么用。
2 要在VBA使用这个DLL,需要先注册这个DLL,注册方法是采用.NET framework 目录的regasm.exe
本附件的VBA已经做成靠Shell命令在运行时自动注册,自动注销。
详细的命令可以看VBA源码,或者自己搜索这个regasm.exe的用法。
要注意的是:这个注册方法要求安装了.NET framwork 2.0或以上,并且需要是office 2007或以上
office2003则需要打一个补丁(附件已提供此补丁简体中文版,也可去微软网站下载 http://www.microsoft.com/download/en/details.aspx?id=10624)
按上述做法,现在应该可以在VBA用createobject来引用这个DLL了。
附件的qsort.dll是编译好的类库
附件的.xls将引用这个类库,对数组排序,可以看出这个排序速度非常快,100万行也就0.3秒!
不过这个版本只能处理数值型的排序。。。。。。
因为VB没有 Variant 变体类型,只有Object类型,这种类型简直是龟速吖!!!
而且不能在一个数组里面混合处理数值和字符串,也不会自动识别数值型和字符串吖。太残了。。。。。。
所以我又编译了另外一个qsortstr.dll,这个dll把所有输入数据当作字符串来排序,除了文件名不同,其余用法跟qsort.dll一样。
100万行4字符长度排序,耗时1.3秒左右,看来排序的速度跟数值大小,和字符串长度都有很大关系吖。
打算封装VBA代码的筒子要知道的是:有好多不同的封装方法,互相不通用的!!! 详情看第10楼。
这个关于VB6.0封装DLL的链接不错,图文并茂而且很详细,强烈推荐:VB封装DLL实例讲解 by 江羽
http://www.accessoft.com/blog/ar ... userid=3967&Id=4563
如果是VS2010要封装自定义函数的话,参考:
chentx的VSTO4.0类库制作EXCEL自定义函数
http://club.excelhome.net/thread-674732-1-1.html
VB6.0参考:
Zamyi的封装自定义工作表函数为DLL
http://club.excelhome.net/viewth ... B7%E2%D7%B0%2Bzamyi
本帖附件补充一个跟Zamyi的帖一样但更详细更安全的封装方法,也就是用VB6制作excel的自定义函数DLL,可以在单元格直接使用
而且本帖附件的DLL可以放在任意目录,由VBA自动注册,引用,注销,VBA源码和VB工程全部公开,VB6做这个太简单了
关键是:
1 VB6的工程选择ActiveX DLL
2 VBA用regsvr32 去注册这个DLL,注意执行命令 regsvr32 的 /s 参数必需在最前面,否则无法静默注册,必须先自动取消之前的注册,否则目录一旦更改就无法新增最新的目录到注册表。
3 VBA用addins.add方法去引用这个DLL为加载宏,比较保险的方法是加上on error resume next,并且先取消之前的引用,然后再加。
[ 本帖最后由 灰袍法师 于 2011-8-10 20:36 编辑 ]
|
评分
-
10
查看全部评分
-
|