Aufrufen von benutzerdefinierten Funktionen aus DLLs
Gilt für: Excel 2013 | Office 2013 | Visual Studio
Das Aufrufen von benutzerdefinierten Funktionen (USER-Defined Functions, UDFs) aus einem Arbeitsblatt ist so einfach wie das Aufrufen integrierter Funktionen: Sie geben die Funktion über eine Zellformel ein. In der C-API gibt es jedoch keine vordefinierten Funktionscodes, die mit den Rückrufen verwendet werden können. Damit Sie UDFs aufrufen können, exportiert die C-API eine reine XLL-Funktion, die xlUDF-Funktion . Das erste Argument der Funktion ist der Funktionsname als Zeichenfolge, und nachfolgende Argumente sind die Argumente, die die UDF normalerweise erwarten würde.
Sie können eine Liste der derzeit registrierten XLL-Add-In-Funktionen und -Befehle abrufen, indem Sie die xlfGetWorkspace-Funktion mit dem Argument 44 verwenden. Dadurch wird ein dreispaltiges Array zurückgegeben, bei dem die Spalten Folgendes darstellen:
Der vollständige Pfad und Name der XLL
Der Name der aus der XLL exportierten UDF oder des Befehls.
Die Rückgabe- und Argumentcodezeichenfolge
Hinweis
Der Aus der XLL exportierte Name ist möglicherweise nicht mit dem registrierten Namen identisch, unter dem Excel die UDF oder den Befehl kennt.
Ab Excel 2007 sind die ATP-Funktionen (Analysis Toolpak) vollständig integriert, und die C-API verfügt über eigene Enumerationen für Funktionen wie PRICE, xlfPrice. In früheren Versionen mussten Sie xlUDF verwenden, um diese Funktionen aufzurufen. Wenn Ihr Add-In mit Excel 2003 und Excel 2007 oder höheren Versionen arbeiten muss und diese Funktionen verwendet, sollten Sie die aktuelle Version erkennen und die Funktion auf die entsprechende Weise aufrufen.
Beispiele
Das folgende Beispiel zeigt die xlUDF-Funktion , die zum Aufrufen der ATP-Funktion PRICE verwendet wird, wenn die ausgeführte Version von Excel 2003 oder früher ist. Informationen zur Einstellung einer globalen Versionsvariablen, z. B. gExcelVersion12plus in diesem Beispiel, finden Sie unter Abwärtskompatibilität.
Hinweis
In diesem Beispiel werden die Frameworkfunktionen TempNum, TempStrConst zum Einrichten der Argumente und Excel zum Aufrufen der C-API verwendet.
LPXLOPER TempNum(double d);
LPXLOPER TempStrConst(const LPSTR lpstr);
int cdecl Excel(int xlfn, LPXLOPER pxResult, int count, ...);
double call_ATP_example(void)
{
XLOPER xPrice;
int xl_ret_val;
if(gExcelVersion12plus) // Starting in Excel 2007
{
xl_ret_val = Excel(xlfPrice, &xPrice, 7,
TempNum(39084.0), // settlement date 2-Jan-2007
TempNum(46706.0), // maturity date 15-Nov-2027
TempNum(0.04), // Coupon
TempNum(0.05), // Yield
TempNum(1.0), // redemption value: 100% of face
TempNum(1.0), // Annual coupons
TempNum(1.0)); // Rate basis Act/Act
}
else // Excel 2003-
{
xl_ret_val = Excel(xlUDF, &xPrice, 8,
TempStrConst("PRICE"),
TempNum(39084.0), // settlement date 2-Jan-2007
TempNum(46706.0), // maturity date 15-Nov-2027
TempNum(0.04), // Coupon
TempNum(0.05), // Yield
TempNum(1.0), // redepmtion value: 100% of face
TempNum(1.0), // Annual coupons
TempNum(1.0)); // Rate basis Act/Act
}
if(xl_ret_val != xlretSuccess || xPrice.xltype != xltypeNum)
{
// Even though PRICE is not expected to return a string, there
// is no harm in freeing the XLOPER to be safe
Excel(xlFree, 0, 1, &xPrice);
return -1.0; // an error value
}
return xPrice.val.num;
}
Wenn Sie eine XLL-Funktion aufrufen, die einen Wert zurückgibt, indem Sie ein Argument direkt ändern, gibt die xlUDF-Funktion den Wert weiterhin über die Adresse des Ergebnisses XLOPER/XLOPER12 zurück. Anders ausgedrückt: Das Ergebnis wird wie durch eine normale return-Anweisung zurückgegeben. Die XLOPER/XLOPER12 , die dem Argument entspricht, das für den Rückgabewert verwendet wird, ist unverändert. Betrachten Sie beispielsweise die folgenden beiden UDFs.
// Registered as "1E". Returns its argument incremented by 1.
void WINAPI UDF_1(double *pArg)
{
*pArg += 1.0;
}
// Registered as "QQ". Returns its argument unmodified
// unless it is a number, in which case it increments it
// by calling UDF_1.
LPXLOPER12 WINAPI UDF_2(LPXLOPER12 pxArg)
{
static XLOPER12 xRetVal; // Not thread-safe
XLOPER12 xFn;
xFn.xltype = xltypeStr;
xFn.val.str = L"\005UDF_1";
Excel12(xlUDF, &xRetVal, 2, &xFn, pxArg);
xRetVal.xltype |= xlbitXLFree;
return &xRetVal;
}
Wenn UDF_2UDF_1 aufruft, bleibt der Wert von pxArg nach dem Aufruf von Excel12 unverändert, und der von UDF_1 zurückgegebene Wert ist in xRetVal enthalten.
Wenn Sie auf diese Weise eine große Anzahl von Aufrufen einer UDF ausführen, können Sie den Funktionsnamen zuerst mit der xlfEvaluate-Funktion auswerten. Die resultierende Zahl, die mit der Registrierungs-ID identisch ist, die von der xlfRegister-Funktion zurückgegeben wird, kann anstelle des Funktionsnamens als erstes Argument an die xlUDF-Funktion übergeben werden. Dadurch kann Excel die Funktion schneller finden und aufrufen, als wenn der Funktionsname jedes Mal nachschlagen muss.