从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个参数,文本和字符数)