从VBA调用一个xll UDF
我想从VBA中调用我的一个用户自定义函数。
我的用户定义函数在C ++中声明:
XLOPER12*WINAPI HelloWorld()noexcept{ THROWS(); static XLOPER12 res=[](){ static std::array<wchar_t,13>str={ 11,'H','e','l','l','o',' ','W','o','r','l','d','\0'}; XLOPER12 tmp; tmp.xltype=xltypeStr; tmp.val.str=str.data(); return tmp;}(); return &res;}
这是一个真正的函数的简化版本,可以返回一个string或者一个双精度数组。 当然这里我只返回一个string,但是这限制了我的UDF的返回types到LPXLOPER12
。
我可以成功注册我的函数与xlfRegister
指定一个pxTypeText
"U$"
。 然后我可以从Excel中调用我的UDF:
=HelloWorld()
它的工作原理!
如果我尝试从VBA调用我的function,如下所示:
Sub macro_test() Dim hw As Variant hw = Application.Run("D:\Path\MyAddIn.xll!HelloWorld") End Sub
我从Application.run得到一个错误信息:
运行时错误“1004”:应用程序定义或对象定义的错误
如果我尝试从VBA调用我的function,如下所示:
Private Declare PtrSafe Function HelloWorld Lib "C:\Path\MyAddIn.xll" () As Variant Sub macro_test() Dim hw As Variant hw = HelloWorld() End Sub
我得到一个空的结果,而不是"Hello World"
。
我究竟做错了什么 ?
杂项信息:
- 使用Excel 2013
- 使用VS 2017 15.5
- 使用第一种方法(
Application.Run
),VBA不会调用我的函数(我不能用debugging器进入我的函数)。 - 使用第二种方法,VBA调用我的函数(我可以使用debugging器进入我的函数)。
- 使用第二种方法,当我将
xlbitDLLFree
添加到我的xltype
,函数xlAutoFree12
不会被调用,这让我觉得VBA不能正确理解返回值。
如果你的XLL被加载并且它的UDF被注册了,所以在一个单元格中的= HelloWord()可以工作,那么你应该可以像这样从VBA中调用它(除非无参数string函数有问题)
var=Application.run("HelloWorld")
您也可以使用评估
var=Application.Evaluate("=HelloWorld()")
我testing了我的REVERSE.TEXT XLL函数,并且它工作正常。
Sub testing() Dim var As Variant var = Application.Run("REVERSE.TEXT", "Charles") var = Application.Evaluate("=REVERSE.TEXT(""Charles"")") End Sub
Reverse.Text使用UQQ $注册(有2个参数,文本和字符数)