1.关于EXCEL的运行目录
EXCEL 打开一个XLS或XLA文件时,其缺省的运行目录是 C:\Program Files\Microsoft Office\Office10,因此加载DLL的时候会报找不到DLL文件,需要将相关的DLL(注意DLL可能会调用其他的非操作系统DLL)全部拷贝到 SYSTEM32或者设置运行环境变量中的PATH,把放DLL的目录加入PATH。
2.关于DLL中的函数名及调用格式
为了VBA能够调用C++写的DLL,在定义DLL函数时一定要加上__stdcall.及 EXTERN "C"
如:
extern "C" __declspec( dllexport ) int __stdcall ExcelInterface_GetQueryData(int row, int column, LPTSTR retStr);
函数体为:
int __stdcall ExcelInterface_GetQueryData(int row, int column, LPTSTR retStr)
编译完成后用 Dependecy walker一类的工具看DLL输出的函数名可能会有变化,比如:
_ExcelInterface_GetQueryData@12
在VBA中定义的时候这样写:
Declare Function ExcelInterface_GetQueryData Lib "MOinterface" Alias "_ExcelInterface_GetQueryData@12" (ByVal row As Long, ByVal col As Long, ByVal retStr As String) As Long
3.关于函数中传回的字符串
DLL函数中如需返回字符串比较有讲究,
首先要在参数中回传字符串(C函数直接返回字符串好像不行)。
另外说明参数时一定要用ByVal不能用ByRef ,因为VBA的字符串传递的时候用的是指针。在传递以前,要给字符串分配足够的空间,在C函数中用strcpy copy进去。另外传入的参数不能用局部变量一定要用全局量(这个绕了我半天,不知道原因)。例子:
注意变量bb的定义,是全局的。
Dim bb As String
Sub abc()
Dim aa
Dim cc As String
Call ExcelInterface_Initialize
aa = ExcelInterface_ConnectDB()
aa = ExcelInterface_QueryData("select * from abc")
bb = String(256, vbNullChar)
aa = ExcelInterface_GetQueryData(0, 0, bb)
cc = Left(bb, _
InStr(1, bb, vbNullChar) - 1)
aa = ExcelInterface_GetQueryDataRowCount()
Call ExcelInterface_CloseDB
End Sub
参考http://www.microsoft.com/china/msdn/Archives/voices/office03082001.asp