[英]Functions and Methods available in third party .xll Add in
我們有一個第 3 方 excel 插件,我們在 excel 中注冊。 現在,我們如何查看 that.xll 中可用的所有函數和方法列表。 另外,我們可以在.xll 文件中看到 vba 代碼嗎? 我正在使用 64 位 2016 Excel。 下面是我嘗試過的代碼,但它沒有顯示.xll 文件中可用的任何函數和子程序。
Public Sub ListRegisteredXLLFunctions()
Dim RegisteredFunctions As Variant
Dim i As Integer
RegisteredFunctions = Application.RegisteredFunctions
If IsNull(RegisteredFunctions) Then
Exit Sub
Else
Dim rng As Range
Set rng = SignalLogs.Range("A1")
Set rng = rng.Resize(UBound(RegisteredFunctions, 1), UBound(RegisteredFunctions, 2))
rng.Value = RegisteredFunctions
End If
End Sub
在 VBA 中使用Application.RegisteredFunctions
但由於某種原因,這不適用於 OP。
您可以運行依賴項並將 XLL 放入其主 window。 右側窗格將顯示 XLL 的入口點,它實際上只是一個重命名的 DLL。 XLL 加載項注冊的每個 function 都應對應一個入口點(除非它像xlOil或ExcelDNA那樣動態工作)。 不能保證在 Excel 中注冊的 function 的名稱將與入口點名稱匹配,但您可能能夠找出一個鏈接。
我們可以偽裝成 Excel 並捕獲對xlfRegister
方法的調用。 下面我在 C++ 中為使用較新版本的 C-API 的插件執行此操作。 如果它使用舊的 API,我們需要以類似的方式欺騙xlcall32.dll
,定義Excel4
入口點。 如果SetExcel12EntryPt
的GetProcAddress
失敗,我們就會知道我們處於這種情況。
#include <iostream>
#include <windows.h>
// You need this header from the Excel C-API SDK
#include <Excel2013SDK/include/XLCALL.H>
#include <string>
using namespace std;
// Full path to the target XLL
static wstring TARGET = L"example.xll";
wstring to_wstring(LPXLOPER12 xloper)
{
if (!xloper) return L"(null)";
switch (xloper->xltype)
{
case xltypeNum: return to_wstring(xloper->val.num);
case xltypeBool: return to_wstring(xloper->val.xbool == 0);
case xltypeErr: return L"ERR:#" + to_wstring(xloper->val.err);
case xltypeMissing: return L"#MISSING";
case xltypeNil: return L"#NIL";
case xltypeInt: return to_wstring(xloper->val.w);
case xltypeStr: return wstring(xloper->val.str + 1, xloper->val.str[0]);
default:
return L"#UNKNOWN?";
}
}
int __stdcall MdCallBack12(int xlfn, int coper, LPXLOPER12* rgpxloper12, LPXLOPER12 result)
{
// It's possible an XLL may call other functions and except a valid return,
// so this switch may need expansion to other cases.
switch (xlfn)
{
case xlfRegister:
{
wcout << "xlfRegister: " << to_wstring(rgpxloper12[3])
<< L", argtypes=" << to_wstring(rgpxloper12[2]) << L" : ";
// We simply dump the parameters to the register call:
// Refer to the Excel SDK documentation for their meanings
for (auto i = 0; i < coper; ++i)
wcout << to_wstring(rgpxloper12[i]) << L", ";
cout << endl;
static int iFunc = 0;
if (result)
{
result->xltype = xltypeNum;
result->val.num = ++iFunc;
}
return xlretSuccess;
}
case xlGetInstPtr:
{
result->val.bigdata.h.hdata = GetModuleHandle(NULL);
result->xltype = xltypeBigData;
return xlretSuccess;
}
case xlGetInst:
{
result->val.w = (int)GetModuleHandle(NULL);
result->xltype = xltypeInt;
return xlretSuccess;
}
case xlGetHwnd:
{
result->val.w = (int)HWND_DESKTOP;
result->xltype = xltypeInt;
return xlretSuccess;
}
case xlEventRegister:
{
if (result)
{
result->val.xbool = 1;
result->xltype = xltypeBool;
}
return xlretSuccess;
}
case xlGetName:
{
auto len = TARGET.size() + 1;
auto s = new wchar_t[len];
s[0] = len;
wcsncpy_s(s + 1, len, TARGET.c_str(), len);
result->val.str = s;
result->xltype = xltypeStr;
return xlretSuccess;
}
default:
cout << "Called: " << xlfn << endl;
}
return xlretSuccess;
}
int main()
{
auto handle = LoadLibrary(TARGET.c_str());
if (handle == 0)
{
// If this load fails, ensure that xlcall32.dll is on the path.
// You can find this DLL in any Excel installation. Also ensure
// that any other dependencies the XLL needs can be found on the path.
cout << "Load failed" << endl;
return -1;
}
auto autoOpen = (int(*__stdcall)())GetProcAddress(handle, "xlAutoOpen");
if (autoOpen == 0)
{
cout << "Cannot find xlAutoOpen. Not a valid XLL." << endl;
return -1;
}
auto setExcel12EntryPt = (void(*__stdcall)(void*))GetProcAddress(handle, "SetExcel12EntryPt");
if (setExcel12EntryPt == 0)
{
cout << "Cannot find SetExcel12EntryPt. Probably uses older C-API." << endl;
return -1;
}
setExcel12EntryPt(&MdCallBack12);
autoOpen();
return 0;
}
確保您使用正確的位數構建以匹配加載項! 您將需要Excel XLL SDK 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.