在Excel VBA中可以引用Excel工作表函数,也可以引用Excel VBA函数,还可以引用用户自己定义的函数或过程。除此以外,还可以调用Windows API。
Windows API包括几千个可调用的函数,这些函数是Windows提供给应用程序与操作系统的接口,他们犹如“积木块”一样,可以搭建出各种界面丰富,功能灵活的应用程序。它们大致可以分为以下几个大类:
基本服务;
组件服务;
用户界面服务;
图形多媒体服务;
消息和协作;
网络;
Web服务。
Windows API使用 .lib 文件。.lib 文件也就是库文件,分为静态库文件和动态库文件(DLL)
静态链接就是把静态链接库中的函数直接复制到程序中,成为程序的一部分。
动态链接是指在程序运行时将已驻留在内存中的动态链接库中的函数在需要时链接起来一起运行。
API 的 dll 在 windows 系统的 system32 目录下, 图形界面相关的 API 在 USER32.dll 里,进程、文件之类的操作在 kernel32.dll 里。MSDN 的每个函数都会说明它在哪个头文件, 哪个 lib, 哪个 dll 里的。
动态链接库中的函数可以被VBA调用,下面就以一个实例来说明。
在kernel32.dll中有一个 GetSystemDirectory()函数,可以到到Windows的系统路径。以下就是通过一个过程来调用这个函数的实例:
Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" _
(ByVal lpBuffer As String, ByVal nSize As Long) As Long
Sub info()
Dim sPath As String * 260, lLen As Long
lLen = GetSystemDirectory(sPath, 260)
Text3 = Left(sPath, lLen)
VBA.MsgBox (Text3)
End Sub
效果如下:
1.1查询如何传递参数到DLL函数的Declare语句格式
为了调用Windows API中的函数,需要描述这些可用的函数的文档规范,如何在VBA中声明这些函数,以及如何调用它们。下面是两个有用的资源:
I 可以使用API Viewer加载宏查找和复制需要的Declare语句。可以在下面的站点下载API声明查看器:
/rubriken/apiviewer/index-apiviewereng.html
登录以下页面后在以下点击下载:
安装后打开需要的文件:
即可查看可以使用的API及声明:
II Microsoft Platform SDK,包含复杂的Windows API文档。可以在下面的地址中查看:/t/api/index.html?apihelp.htm
可以使用的API函数类别:
1.2 使用Declare语句
在从VBA中调用DLL里的函数之前,必须为VBA提供在哪里找到函数以及如何调用该函数的信息:
Declare语句是一个定义,告诉VBA在哪里找到特定的DLL函数以及如何调用该函数。在代码中添加Declare语句最简单的办法是使用API Viewer加载宏,其中包含Windows API中大多数函数的Declare语句,也包含一些函数所需要的常量和类型定义。
Declare语句声明的形式如下:
[Public|Private]Declare Sub name Lib "libname" [Alias "aliasname"][([arglist])]
[Public|Private]Declare Function name Lib "libname" [Alias "aliasname"] [([arglist])] [As type]
下面是GetTempPath函数的Declare语句的示例,该函数返回Windows临时文件夹的路径(默认为C:WindowsTemp):
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
I 关键字Declare告诉VBA在工程中要包含的DLL函数的定义。在标准模块中的Declare语句可以是公共的或私有的,取决于你希望API函数仅用于单个模块还是整个工程。在类模块中,Declare语句必须是私有的。
II 在关键字Function之后是函数的名字,具体地说,是从VBA中调用该函数时使用的名字。这个名字可以与API函数本身的名字相同,也可以在Declare语句中使用关键字Alias指定打算在VBA中通过不同的名字(别名)调用该函数。
III 在上面的示例中,在DLL中API函数的名字是GetTempPathA,从VBA中调用该函数时使用的名字是GetTempPath。注意,DLL函数的实际名字出现在关键字Alias之后,同时也注意到GetTempPath是Win32API.txt文件用于该函数的别名(有充分必要使用别名),但你可以将其改变为任何你想要的名字。
IV 关键字Lib指定包含函数的DLL。
1.3 在过程中调用API函数。
有如下任务:判断一个文件框如果内容为空,则显示一个提示文本框进行提示,并在3秒后自动消息。
我们知道,VBA提供以下代码的提示对话框,但它需要用户自己点击关闭按钮才可以关闭,不能满足我们的需要。
MsgBox ("提示:编号不能为空!")
2.1 插入用户窗体,并添加两个文本框,如下:
2.2 在VBE中插入模块,并添加以下代码:
Private Declare Function MsgBoxTimeout Lib "user32" _
Alias "MessageBoxTimeoutA" ( _
ByVal hwnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal wType As VbMsgBoxStyle, _
ByVal wlange As Long, _
ByVal dwTimeout As Long) _
As Long
Sub PopupMsgbox(Optional prompt As String = "OK", Optional title As String = "友情提示", Optional seconds As Long = 300)
MsgBoxTimeOut 0, prompt, title, 64, 0, seconds
End Sub
2.3 为文本框添加事件代码:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If TextBox1.Value = "" Then
'MsgBox ("提示:编号不能为空!")
PopupMsgbox "编号不能为空!", "提示", 1500 '1.5秒后提示窗口自动关闭
End If
End Sub
2.4 当文本框为空,鼠标光标点击到文本框以外的其它位置时,就会弹出提示对话框,并在1.5秒后自动关闭,如下:
MsgBoxTimeout()是一个未公开的 API 函数。
此函数的参数如下:
hwnd:消息框拥有者窗口的句柄,可以设为 0
lpText:消息框显示内容,类似于 MsgBox 函数的第一个参数 Prompt
lpCaption:消息框标题,类似于 MsgBox 函数的第三个参数 Caption
wType:消息框类型,类似于 MsgBox 函数的第二个参数 Buttons
wlange:函数扩展,一般取 0
dwTimeout:消息框延迟关闭时间,单位为毫秒
总结上例使用API的流程:
I Declare MsgBoxTimeOut
II 定义PopupMsgbox过程,在此过程中调用了MsgBoxTimeOut
III 在其他过程中调用PopupMsgbox()
也可以声明后直接调用:
Dim i As Long
i = MsgBoxTimeout(0, "编号不能为空!", "提示", vbYesNo, 0, 1500)
-End-
有话要说...