将VBA代码编译封装成为DLL动态链接库的方法

   一、为什么要编译成为DLL

  我们知道,Visual C++、Visual Basic和C++ Builder以及Delphi等编译器所编译出来的程序不容易被人破解(相对来说),这是因为代码被编译成了可执行文件或者动态链接库文件。那么,我们是否可以将VBA代码封装到动态链接库文件中,然后用Word调用呢?回答是肯定的。而且这样做还有一个好处,即可以加快代码的运行速度。

  二、将VBA代码封装成动态链接库

  假如我们已经写好了一个VBA工程,而且运行无误。

  ①建立VB工程及一般性操作

  首先,我们需要两种工具,其中当然包括Microsoft Word,另外一种是Microsoft Basic 6.0。

  打开Microsoft Basic 6.0,在“新建工程”中选取“ActiveX DLL”,新建一个工程。在属性窗口中将工程名改为VBAPrj,类模块名改为VBACls。然后在“工程”菜单下打开“引用”,选取“Microsoft Office 11.0 Object Library”——这一步很是关键,切不可遗漏,然后保存工程。下面我们所做的是向工程内添加代码。

  将VBA工程中的一个名为Test过程的代码选定后复制,然后切换到VB编辑器,选中VB的工程管理器中的类模块VBACls,将代码粘贴至代码编辑窗口中,于是这段代码便成了类模块VBACls一个方法,然后将工程编译生成dll文件(如果编译成功的话)。在Word中,我们就可以通过类模块VBACls建立的对象来调用此方法(具体怎么调用,我们将后面介绍)。当然,我们可以继续向工程里添加代码。

  ②修改代码

  虽然VBA源于VB,但是两者毕竟存在着一些差异。因此,需要对转移到VB中的VBA代码做一些必要的修改。

  A、修改VBA代码中所特有类型的对象

  如果我们所添加的代码里有VBA所特有类型——如Document、Rang、BookMark等所建立的对象,编译时会提示错误,因为VB不能够识别这些对象。此时修改的方法是,将这些对象作为过程或函数的参数进行传递。需要注意的是,这些参数的类型都一律设为Object。

  例如,我们在过程Test中要访问对象ThisDocument,但是VB无法识别ThisDocument,于是我们就为过程test添加一个参数Doc来传递ThisDocument,即Test可定义为Test(Doc As Object)。

  B、修改VBA所特有一般变量

  VB也无法识别VBA特有的一般变量,如ProtectType,同样,我们也将其作为过程后函数的参数进行传递,不过其类型名都一律设为Variant。

  C、修改VBA所特有常量

  如果在VBA代码中出现了这样的语句:

  ProtectionType = wdNoProtection

  很明显,wdNoProtection是Word所独有的常量,不为VB所能识别,因而无法通过编译。怎样解决这个问题呢?当然,我们可以用修改变量的方法予以修改。但是聪明的读者会想到:如果我们知道了wdNoProtection的值,就可以直接将值赋给ProtectionType。但是接下来的一个问题是:我们怎样才能获得wdNoProtection的值呢?方法很简单,就是让Word“开口”告诉我们。

  在Word一个事件中添加以下语句:

  MsgBox CStr (wdNoProtection)

  其中CStr是类型转换函数,返回参数相应的字符串。只要在Word中触发此事件,会弹出一个对话窗,显示“-1”,这就是Word所告诉我们的:wdNoProtection 的值是-1。于是我们就可以将语句 ProtectionType = wdNoProtection 改为 ProtectionType = -1,问题到此就迎刃而解了。

  三、封装用户窗体

  我们也可以将用户窗体封装到动态链接库文件里。首先打开Word的VBA编辑器,选中工程资源管理器中的用户窗体,点击右键,选择“导出文件”,选定路径后,将窗体文件保存。然后切换到VB编辑器,在“工程”菜单中选择“添加文件”命令,添加保存的窗体文件。添加结束后,我们会发现VB编辑器中的工程资源管理器中的设计器出现了刚添加的窗体名,选中后双击,在窗体编辑器中就会显现所添加的用户窗体。

  到了这里,读者会问:窗体还有代码呢,怎么办?先别急,试一试下面的操作,你就会明白,问题早已不再是问题了。选中工程资源管理器中的用户窗体,点击右键,选择“查看代码”,你就会高兴发现,在代码编辑框中出现了窗体所对应的代码。原来,在我们导入窗体文件的同时也导入了窗体的代码!当然高兴之余,不要忘了还要对这些代码按照我们上述的方法进行必要修改,以保证代码顺利地通过编译。这样Word就可以通过类模块VBACls间接地调用窗体。

  四、在Word中引用动态链接库

  假如经过我们编译已生成了一个动态链接库文件VBAPrj.dll,其中有一类模块VBACls,此类模块有一个方法Test(Doc As Object)。

  接下来我们所要做的是用Word调用Test,有三种方法可供选择:

  1.打开Word的VBA编辑器中ThisDocument代码窗口,点"工具"菜单下的"引用"命令,在引用对话框中引用该动态链接库。

  调用代码如下:

  Dim VBACls As New VBAPrj.VBACls

  VBACls.Test(ThisDocument)

  2.如果知道该动态链接库文件的位置,可以在ThisDocument代码窗口以代码形式引用, 代码如下:

  Private Sub Document_Open()

  On Error Resume Next

  Me.VBProject.References.AddFromFile "D:VBAPrj.dll"

  End Sub

  3.将动态链接库文件拷贝到Word文档同一目录下,可在ThisDocument代码窗口中建立如下引用函数:

  Private Function GetProjectDoc() As Object

  On Error Resume Next

  Dim VBACls As Object

  Set VBACls = CreateObject("VBAPrj.VBACls")

  If VBACls Is Nothing Then

  MsgBox "VBAPrj.dll必须和文档在同一目录下!"

  Exit Function

  End If

  Set GetProjectDoc = VBACls

  End Function

  然后以以下代码形式调用Test:

  Dim objPrjDoc As Object

  Set objPrjDoc = GetProjectDoc

  Call objPrjDoc.Test(ThisDocument)

  Set objPrjDoc = Nothing

  推荐您使用第三种方法,虽然这种方法相对麻烦,但是只要动态链接库与Word文档处于同一目录下,可保证程序的可移植性。

  到目前为止,我们已完成了我们所要达的目的。此时,即便我们不对VBA工程设置密码保护,别人也将很难窥视到我们的代码。

时间: 2024-09-09 20:32:18

将VBA代码编译封装成为DLL动态链接库的方法的相关文章

Lua5.1中加载dll动态链接库的方法

  这篇文章主要介绍了Lua5.1中加载dll动态链接库的方法,本文讲解了加载专门为lua写的扩展dll的方法和加载不是专为lua写的扩展dll的方法,需要的朋友可以参考下 一.加载专门为lua写的扩展dll 使用require或package.loadlib方法,在此不做过多解释. 二.加载不是专为lua写的扩展dll "不是专为lua写的扩展dll"是指:dll中并没有以lua注册函数的方式导出接口,而是以__declspec(dllexport)形式导出的接口.这样就不能使用&q

Lua5.1中加载dll动态链接库的方法_Lua

一.加载专门为lua写的扩展dll     使用require或package.loadlib方法,在此不做过多解释. 二.加载不是专为lua写的扩展dll     "不是专为lua写的扩展dll"是指:dll中并没有以lua注册函数的方式导出接口,而是以__declspec(dllexport)形式导出的接口.这样就不能使用"package.loadlib"方法调用,而要使用lua5.1封装过的"alien.load()"方法.(Lua\5.1

Win7恢复dll动态链接库的方法

  1.一般来说,如果电脑中的dll动态链接库有问题,便会出现相关的警示窗口,这个时候,便需要从电脑中出现的警示窗口中得知该动态链接的文件名,例如SHELL30.dll这种以dll后缀的文件,而它的路径则是C:WINDOWSsystem32SHELL30.dll,这是需要记录下来的信息. 2.之后,同时按下键盘上的win+R快捷键打开电脑的运行窗口,然后在窗口中输入REGSVR32 /n /i:u shell30,之后单击回车,这样电脑便会自动的开始修复这个SHELL30.dll文件了,等待系统

通过VB6将ASP编译封装成DLL组件最简教程 附全部工程源文件_应用技巧

1.新建DLL打开VB6-->文件-->新建工程-->选择ActiveX DLL-->确定 2.将默认工程.类重命名工程重命名:工程-->工程1 属性(此名称对应窗体内工程项目名称)-->在打开对话框中将"工程名称"重命名为ASP2DLL(当DLL组件在系统中注册后,在asp中默认的调用方法是"工程名.类名")-->确定 类重命名在属性窗口中将名称重命名为Demo 3.定义ASP基本对象添加模块:工程-->添加模块--

Java代码编译出现illegal character:5279解决方法

今天编译代码的时候,意外遇到如下错误: illegal character: 5279 文件是UTF-8编码,按理说不应该会出错. 于是去网上查阅资料,发现UTF-8编码有2种: UTF-8-BOM编码和UTF-8无BOM编码 初步怀疑可能2种编码有关. 由于错误提示发生文件的第一个字符位置,怀疑可能是文件带有BOM标记. 具体原因如下: 某些编辑器会往utf8文件中添加utf8标记(editplus称其为签名),它会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)

Python调用C/C++动态链接库的方法详解_python

本文以实例讲解了Python调用C/C++ DLL动态链接库的方法,具体示例如下: 示例一: 首先,在创建一个DLL工程(本例创建环境为VS 2005),头文件: //hello.h #ifdef EXPORT_HELLO_DLL #define HELLO_API __declspec(dllexport) #else #define HELLO_API __declspec(dllimport) #endif extern "C" { HELLO_API int IntAdd(in

托管C++调用DLL中的方法时遇到yield时该如何? [问题点数:40分]

问题描述 假设className,methodName是参数被传入我用下面的代码调用了某个DLL中的方法Assembly^dllAssembly=Assembly::LoadFrom(dllPath);array<System::Type^>^selectType=dllAssembly->GetTypes(className);MethodInfo^selectedMethod=selectType->GetMethod(methodName);System::Object^in

一个网站程序是由asp.net写的,里面的代码大多数封装到了dll里面,dll能在被编译么!?又办法没?

问题描述 一个网站程序是由asp.net写的,里面的代码大多数封装到了dll里面,dll能在被编译么!?有办法没?

用VB将ASP代码封装成DLL

封装|封装 摘 要 主要介绍用VB将ASP代码封装成DLL以保护 ASP代码和加快ASP代码的执行速度.节省服务器的资源关键词 ASP,DLL,编程一.引言Server端的脚本运行环境,它简单易用,不需要编译和连接,脚本可以在 Server端直接运行,并且它支持多用户.多线程,在 Web开发中得到了广泛的应用.服务器端的组件有别于客户端的组件.客户端的组件是通过网络传输,依靠HTML来起作用,而且只能在IE上有用.但是服务器端的组件是运行在服务器端,它在服务器上执行各种操作.因此,所有的浏览器都