簡體   English   中英

第三方可用的函數和方法.xll 添加

[英]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 都應對應一個入口點(除非它像xlOilExcelDNA那樣動態工作)。 不能保證在 Excel 中注冊的 function 的名稱將與入口點名稱匹配,但您可能能夠找出一個鏈接。

涉及方法

我們可以偽裝成 Excel 並捕獲對xlfRegister方法的調用。 下面我在 C++ 中為使用較新版本的 C-API 的插件執行此操作。 如果它使用舊的 API,我們需要以類似的方式欺騙xlcall32.dll ,定義Excel4入口點。 如果SetExcel12EntryPtGetProcAddress失敗,我們就會知道我們處於這種情況。

#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM