VB DLL实例分步讲解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VB封装DLL实例讲解(一)
一、DLL基本概念
(一)概念
DLL即动态链接库(Dynamic Link Library),是由可被其它程序调用的函数集合组成的可执行文件模块。
DLL不是应用程序的组成部分,而是运行时链接到应用程序中。
(二)主要优点:
1、多个应用程序可以共享一个DLL,而且当多个应用程序调用库的同一个函数时,可执行文件中装入的只是该函数的内存地址,从而节省内存和磁盘空间;
2、使用动态链接库易于我们维护用户程序,即使对动态链接库进行修改也不会影响用户程序;
3、从ACCESS角度而言,还可以更好的确保核心代码的安全。
二、用VB封装VBA代码,构建自定义的DLL动态链接库
(一)ACCESS中实例代码
下面是一个“快速提取字符串中数字.mdb”实例(该实例在文件包中),单击“提取结果”按钮,将文本框中的数字在弹出消息显示出来。
我将就这个实例演示如何将该实例VBA代码封装成为DLL。
按钮单击事件代码如下:
Private Sub CmdFindnumber_Click()
Dim strM As String '初始字符串
Dim strOut As String '输出字符串变量
Dim I
strM = Me.Text1
'从第一个字符向最后一个字符循环,以提取每个字符
For I = 1 To Len(strM)
'判断是否为0到9字符,是则赋值输出
If Mid(strM, I, 1) Like "[0-9]" Then
strOut = strOut & Mid(strM, I, 1)
End If
Next I
'用MsgBox函数进行输出测试
End Sub
以上代码还不能直接用于封装,须将其修改成为公用函数(过程)
(二)VB 封装实例中VBA 代码
步骤一:在VB 编辑窗中,点菜单【文件】-【新建工程】,打开新建工程窗口
步骤二:修改工程名,这即生成的DLL 库名
步骤三:修改类名
步骤四:在代码窗口输入如下代码。
将ACCESS 中的单击事件代码,略做修改成为一个公用函数,然后复制到VB 代码编辑窗口
代码如下
'将这前的ACCESS代码改成一个公用函数
'输入:strPutString 字符串变量,需分离数字的字符串
'输出:fFindNumber字符串变量,得到的数字字符
Public Function fFindNumber(strPutString As String) As String
Dim strOut As String '输出字符串变量
Dim I
'从第一个字符向最后一个字符循环,以提取每个字符
For I = 1 To Len(strPutString)
'判断是否为0到9字符,是则赋值输出
If Mid(strPutString, I, 1) Like "[0-9]" Then
strOut = strOut & Mid(strPutString, I, 1)
End If
Next I
'数字输出
fFindNumber = strOut
End Function
步骤五:编译DLL,点菜单【文件】-【生成我的动态库.dll】,VBA代码封装DLL就完成了。
三、在mdb中调用自定义DLL动态链接库
(一)新建数据库及窗体
新【快速提取数字(DLL)实例.mdb】数据库,新建一个窗体【frmMain】,在窗体添文本框【text0】,按钮【CmdFindNum】,Caption属性:“提取数字”(见下图)
(二)引用【我的动态库.dll】库
按【Alt+F11】打开VBE窗口,点菜单【工具】-【引用】,打开引用对话框,完成对我们自己编译的DLL的引用。
(三)在【CmdFindNum 】按钮单击事件中加入如下代码。
Private Sub CmdFindNum_Click() '申明自定义类
Dim MyFindNum As 提取数字 Dim strOut As String
'实例化"提取数字类"对象
Set MyFindNum = New 提取数字
'将函数输出结果赋值给自定义字符串变量 strOut = MyFindNum.fFindNumber(Text0)
'在消息框中显示
MsgBox "你提取的数字为:" & strOut, vbInformation, "江羽提示:" End Sub
点击保存后,你就可以运行一下窗体测试你的成果了
本文实例见实例包,下载测试如果提示错误,请重新对自定义类库进行引用。
本文只是通过一个简单的实例演示了,如何通过VB 封装一般的VBA 中代码,因为该代码中并未涉及到ACCESS 应用程序对象,所以在VB 中没有对ACCESS 对象类库进行引用,另外实例中只是简单演示了,如何手动实现对DLL 的注册引用,在后续文章中我将就如何实现DLL 与ACCESS
应用程序对接及DLL 的自动注册及引用结合实例进行讲解。
2、选择引用的DLL
3、点打开
VB 封装DLL 实例讲解(二)
上文中我们已经就DLL 的基本概念,以及如何将VBA 代码封装为DLL ,如何引用该生成的DLL 动态链接库,进行了初步的讲解,我想大家对于VB 封装DLL 应该有了一个初步的了解。
下面主要就DLL 如何实现对ACCESS 对象进行封装方法进行探讨。
一、如何在VB 中实现对ACCESS 对象编程
(一)在VB 中引用ACCESS 对象类库
我们要通过编译DLL 来实现对ACCESS 对象的封装,首先必须在VB 中引用ACCESS 对象类库,这样我们就可以在VB 中,实现对ACCESS 应用程序中的对象进行编程。
打开VB 编辑窗口,点菜单【工程】-【引用】,打开【引用对话框】,点选“Microsoft Access 11.0 Object Library ”完成对当前版本ACCESS 应用程序对象的引用。
(实例演示版本为ACCESS 2003
)
对ACCESS 对象库的引用很关键,否则我们无法实现对ACCESS 对象的编程
(二)了解ACCESS 对象模型
在VB 中要对ACCESS 对象进行编程,还必需对ACCESS 所提供的各项对象有一定了解,因为VB 就是通过ACCESS 对象的方法与属性,来完成各项操作与设置,下图为ACCESS 2003 的对象部分模型图例。
上图为ACCESS 2003对象模型,因为篇幅的问题,文中只显示模型中部分对象,要了解全部对象模型,请大家参阅帮助。
(三)VB编程中ACCESS VBA与VB对象表述区别
1、ACCESS VBA与VB的顶层对象都为Application,但在编程中ACCESS VBA顶层对象表述为:Application,而在VB编程中顶层对象用简写:App表述(到又改回了Application)。
✍例程:在VB编程中获得VB及ACCESS VBA获取当前路径实例:
'在VB中获得当前路径:
App.Path
'在VB中获得ACCESS的当前路径:
Application.CurrentProject.Path
在office各应用程序之间调用各组件时,通常在对象前加上库名,如:Access.Application 来表述,但因为VB与ACCESS顶层对象原本表述就存在区别,在VB中可以直接用Application表述ACCESS
2、ACCESS VBA和VB中部分预定义类对象(如:窗体、控件等)表述基本相同,以“标签控件”为例,VB与ACCESS VBA均为Label,在VB编程中为了与ACCESS预定义类对象加以区别,ACCESS 标签对象通常用bel表述。
✍例程:在VB编程中定义VB及ACCESS标签控件对象实例:
'在VB中定义VB标签对象:
Dim m_Label As Label
'在VB中定义ACCESS标签对象:
Dim m_Label As bel
在进行DLL编程时,特别需注意对象表述区别的问题,否则无法编译或是编译后在ACCESS 调用中报错。
(四)VB编程中关于ACCESS VBA专属常量
ACCESS VBA专属常量以“ac”开头,如:控件类(AcControlType)中的文本控件常量为acTextBox,这些常量不一定能被VB所识别,解决办法通常不使用“常量名”,而直接使用“常量值”,或以输入参数方式传递的方法来解决。
✍例程:实现隐藏所有文本控件。
acTextBox常量值为109。
Dim ctl As Access.Control '申明ACCESS控件对象
Dim frmClt As Access.Controls '申明ACCESS控件集合
'遍历所有ACCESS控件集合,如为文本控件,则不显示该控件
For Each ctl In frmClt.Controls
'文本控件类常量值为109,以常量值替代acTextBox常量名
If ctl.ControlType = 109 Then ctl.Visible = False
Next
你可以通过帮助查阅ACCESS专属常量值,也可以在ACCESS VBA中通过程序方式获取,如:在立即窗口输入:?acTextBox回车,就可以acTextBox常量值为:109。
二、DLL封装ACCESS对象实例演示
(一)ACCESS的MDB实例
MDB实例演示获得ACCESS版本信息,并在标签Label0中显示(见下图),具体参看实例中frmVer6窗体中的代码,及类模块ClsVeresion中代码。
mdb实例中frmVer1-frmVer6各窗体中具体演示了,代码按DLL封装需要整理的思路。
✍例程:frmVer6窗体加载事件代码
Private Sub Form_Load()
'申明自定义类的实例
Dim m_Ver As New ClsVeresion
m_Ver.objAddItem Label0 '调用自定义类的objAddItem方法End Sub
✍例程:ClsVeresion类模块代码
'程序功能:定义类接口,将版本信息输出并在标签中显示Public Sub objAddItem(m_label As Label)
m_label.Caption = AppVersion
End Sub
'函数功能:输出ACCESS版本信息
Private Function AppVersion() As String
Dim strVer As String '定义字符串变量
'将版本号赋值给字符串变量
strVer = Application.Version
'根据版号输出对应版本信息
Select Case strVer
Case "8.0"
AppVersion = "Access 97"
Case "9.0"
AppVersion = "Access 2000"
Case "10.0"
AppVersion = "Access 2002"
Case "11.0"
AppVersion = "Access 2003"
Case "12.0"
AppVersion = "Access 2007"
End Select
End Function
(二)DLL的封装ACCESS对象实现
1、打开VB6.0编辑器,点菜单【新建工程】,在【新建工程】对话框中,点选【ActiveX DLL】,点【确定】。
2、修改工程名及类名,实例中我定义的工程名:GetAccVer ,类名:ClsAccVer ,修改完成以后点选菜单【保存】工程(见下图)。
工程名就是我们后面将引用的DLL库名,类模块名为代码中我们申明的类名。
3、点菜单【工程】-【引用】,打开【引用对话框】,点选“Microsoft Access 11.0 Object Library”完成对当前版本ACCESS应用程序对象的引用。
4、将MDB中类模块ClsVeresion代码复制到VB中ClsAccVer类模块中,按前面我们所述的VB中实现ACCESS对象编程的注意要点略做修改。
(见下图划红线部分)
1、因为VB与ACCESS VBA 中标签类对象都为Label,因此加上库名(bel)加以区别;
2、因为VB与ACCESS VBA顶层应用程序对象,表述原本就有区别,所以无需特别区分。
例程:ClsAccVer类模块代码
'程序功能:定义DLL接口,将版本信息输出并在标签实例中显示
Public Sub objAddItem(m_label As bel)
m_label.Caption = AppVersion
End Sub
'函数功能:输出ACCESS版本信息
Private Function AppVersion() As String
Dim strVer As String '定义字符串变量
'将版本号赋值给字符串变量
strVer = Application.Version
'根据版号输出对应版本信息
Select Case strVer
Case "8.0"
AppVersion = "Access 97"
Case "9.0"
AppVersion = "Access 2000"
Case "10.0"
AppVersion = "Access 2002"
Case "11.0"
AppVersion = "Access 2003"
Case "12.0"
AppVersion = "Access 2007"
End Select
End Function
4、编译DLL,点菜单【文件】-【GetAccVer.dll】动态链接库,封装DLL就完成了。
你现在可以在ACCESS中引用该DLL测试一下看看成果了。
参看实例中frmVer7窗体,如实例引用报错,请重新引用GetAccVer.dll即可。
因为本人认知及文字水平所限,不免有错漏之处,还请大家斧正。
本文的Word文稿、VB源码、MDB 实例均在实例包中。
在后文中我们主要就动态链接库引用的方法和技巧结合实例进行探讨。
VB 封装DLL 实例讲解(三)
一、手动注册及引用
(一)手动注册及引用方法(参看实例:手动引用.mdb ) 进入VBA 编辑窗口,点菜单【工具】—【引用】,打开【引用】对话框,点【浏览】按钮,打开【添加引用】对话框,点选要引用的DLL (测试实例为:ClsFindString .dll ),点【打开】—点【确定】,我们完成动态链接库的手动注册及引用。
(二)手动注册及引用方法不足及问题
手动注册引用优点是不言而喻的,方便简捷,易于操作。
但在实际运用中,当我们在其他电脑上发布应用程序,或运行我们测试好的应用程序时,却会出现错误提示,程序无法正常运行。
错误(一):找不到工程或库(见下图)
错误的主要原因:DLL 在当前运行的电脑系统中没有注册信息,而且引用不正确。
错误(二):引用的动态链接库(DLL )丢失(见下图) 进入到VBA 编辑窗口,点菜单【工具】—【引用】
,打开【引用】对话框,我们会看到之前引用的
2 点选DLL
3 点打开按钮
DLL动态链接库丢失。
错误的主要原因:系统无法找到原路径引用DLL。
错误(三):自动化错误(见下图)
错误的主要原因:我们在发布应用程序的电脑或系统中,虽然重新完成DLL手动注册和引用,但如果DLL路径再次改变,运行程序时就会出现“自动化错误”提示。
错误(四):ActiveX部件不能创建对象(见下图)
错误的主要原因:应用程序已正常引用DLL动态链接库,但其册注信息丢失或者没有正常注册,就会出现以下问题。
(三)解决上述错误方法
1、解决错误方法,当然是重新进行DLL 的手动注册及引用,具体步骤参下图。
但这只是治标不治本的办法,不利于对外发布我们的应用程序,最好的办法还是通过VBA 自动完成DLL 的注册及引用。
二、自动注册及引用DLL 方法
在探讨如何实现DLL 自动注册及引用之前,我们必须清楚一点,那就是DLL 的注册与引用并不是同一事件或行为的两种不同表述,而是两种不同的动作。
3 点选DLL
4 点打开按钮
✧DLL注册
是指将DLL的相关信息,如:DLL唯一识标号(GUID),版本号(Version)及路径(Path)信息写入注册表中,以供系统对DLL进行识别调用。
我们通过VB编译生成DLL时,VB一般会自动完成对该DLL的注册,但如果要在其它电脑上运行程序时,我们就必须重新对该DLL进行注册。
✧DLL引用
是指将DLL类库对象集成到代码编辑环境中,以便编程时调用类库中的对象、属性及方法。
我们通过手动方式完成DLL的引用时,系统会自动完成对该DLL的注册,所以我们无需另行对DLL 进行注册,但如果我们在其它电脑上运行程序时,还会出现我们在之前章节中所述的错误。
(一)DLL自动注册方法
我们可以通过Regsvr32.exe来进行DLL注册或反注册,具体的语法及参数:
语法:
Regsvr32 [/u] [/n] [/i[:cmdline]] dllname
说明:其中dllname为DLL文件名,建议在发布时将DLL复制到system文件夹下。
1.1 示例通过Shell运行Regsvr32程序完成DLL注册
Shell "Regsvr32 /S " & Chr(34) & CurrentProject.Path & "\ClsFindString.dll" & Chr(34)
Shell 函数用以运行Regsver32程序
Regsver32 注册程序
/S 注册程序参数,书写时记得参数前后必须留空
Chr(34) Chr函数,获指定代码字符,Chr(34)为引号
CurrentProject.Path DLL当前路径
ClsFindString.dll演示实例DLL名
1.2 示例通过Shell运行Regsvr32程序反注册
Shell "Regsvr32 /U /S " & Chr(34) & CurrentProject.Path & "\ClsFindString.dll" & Chr(34)
我们可以将注册语句放在窗体的加载事件,自动完成DLL的注册,具体可以参看实例。
但如果我们有多个DLL需要批量注册时,可以考虑通过软件打包发布工具来完成DLL的注册工作;也可以事先编写BA T文件,让打包发布时将该BA T文件一并打包发布,安装时运行该BAT文件,来完成N个DLL的批量注册,在些就不多着笔墨,大家可以参看实例包中的BA T文件实例。
(二)DLL自动引用方法
2.1 通过References对象的AddFromFile方法实现自动引用
Dim ref As Reference '申明引用类对象
On Error Resume Next '避免因重复引用造成的错误提示
'实例化引用对象,完成DLL的引用
Set ref = References.AddFromFile(CurrentProject.Path & "\ClsFindString.dll")
为了避免因重复引用出现的错误,我们可以如上代码中加入Error语句,我们还可以在应用程序退出时,通过对References对象的Remove方法释放DLL或反引用。
Dim ref As Reference '申明引用类对象
'实例化反引用对象
Set ref = References("ClsFindString")
'移除引用指定类库
References.Remove ref
说明:根据本人实践,我个人倾向于使用Error语句,因为如果应用程序非正常退出,引用对象没有反引用成功,启动时就难免出现重复引用的错误问题。
2.2 通过DLL唯一标识号实现自动引用
Dim ref As Reference'申明引用类对象
On Error Resume Next '避免因重复引用造成的错误提示
'唯一标识号完成注册,需要DLL标识号,主版本号,次版本
Set ref = References.AddFromGuid("{C5E340E2-C557-4852-AE83-5A0578B6863B}", 1, 0)
DLL的标识号是编译生成时就确定了的,这个标识号就是DLL的终生制身份证号,我们可以通过这个唯一标识号来完成DLL自动引用。
但此种方法必须具备两个条件,一是DLL已经成功注册,二是我们知道了该DLL的标识号、主版本号、次版本号。
2.2.1获取DLL标识号、主版本号、次版本号方法
Dim ref As Reference '申明引用类对象
'实例化引用类库对象
Set ref = References.AddFromFile(CurrentProject.Path & "\ClsFindString.dll")
Debug.Print ref.GUID '获得DLL唯一标识号
Debug.Print ref.Major '获得主版本号
Debug.Print ref.Minor '获得次版本号
2.3通过CreateObject方法实现自动引用
Dim DllFindStr As Object '申明对象
'实例化对象为创建的DLL类库对象
'ClsFindstring为DLL库名,clsFindStr为DLL类名
Set DllFindStr = CreateObject("ClsFindstring.clsFindStr")
DllFindStr.sFindStr Text2, Me.Text0 '调用DLL类库方法,运行程序
Set DllFindStr = Nothing'释放对象
根据我本人实践经验,CreateObject方法自动引用是最为便捷高效的方法,仅供参考。
关于DLL相关自动注册及引用方法就探讨这里,以上文字仅是本人实践的一点总结,希望对大家有所帮助,如有错漏之处还请大家斧正。
本文的Word文稿、DLL源码(含DLL)、mdb演示实例及BAT 注册文件实例均在实例包中。