Reputation: 35
we have a 3rd party excel Add-in which we registered in excel. Now, how can we see what are all the list of functions and methods available in that .xll. Also, can we see the vba code inside .xll file? I am using 64bit 2016 Excel. Below is the code I tried but its not showing any functions and subs available in .xll file.
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
Upvotes: 3
Views: 735
Reputation: 506
Use Application.RegisteredFunctions
in VBA but for some reason this doesn't work for the OP.
You can run Dependencies and drop the XLL into its main window. The right hand pane will show the entry points to the XLL, which is really just a renamed DLL. Each function registered by the XLL add-in should correspond to an entry point (unless it works dynamically like xlOil or ExcelDNA). There's no guarantee that the name of the registered function in Excel will match the entry point name, but you may be able to figure out a link.
We can pretend to be Excel and capture calls to the xlfRegister
method. Below I do this in C++ for add-ins using the newer version of the C-API. If it uses the older API we'd instead need to spoof xlcall32.dll
in a similar way, defining an Excel4
entry point. We'd know we were in this case if the GetProcAddress
for SetExcel12EntryPt
fails.
#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;
}
Make sure you build with the right bitness to match the add-in! Youll need the Excel XLL SDK.
Upvotes: 2