|
楼主 |
发表于 2016-6-30 16:22
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
=============================
用DLL中调用用户定义函数
=============================
Calling user-defined functions (UDFs) from a worksheet is as simple as calling built-in functions: You enter the function via a cell formula. However, from the C API, there are no pre-defined function codes to use with the call-backs. To enable you to call UDFs, the C API exports an XLL-only function, the xlUDF function. The function’s first argument is the function name as a string, and subsequent arguments are those that the UDF would normally expect.
从工作表中调用用户定义函数(UDFs)和调用Excel内置函数一样容易:可以以单元格公式方法输入函数。然而在 C-API 中没有任何以回调方式使用的预定义函数。为了让你可以调用 UDFs ,C-API 提供了一个 xlUDF 函数。此函数的第一个参数是字符串形式的函数名。随后的参数由 UDF 本身参数决定。
You can obtain a list of the currently registered XLL add-in functions and commands by using the xlfGetWorkspace function with the argument 44. This returns a three-column array where the columns represent the following:
* The full path and name of the XLL
* The name of the UDF or command as exported from the XLL
* The return and argument code string
你可以使用 拥有44个参数的 xlfGetWorkspace 函数 获取 当前注册的 XLL add-in 函数和命令列表。它将三维数据用于表示了以下信息:
* XLL 的完整路径和名称。
* XLL 输出 的UDF 或 命令 名称
* 返回和参数字符串
The name as exported from the XLL might not be the same as the registered name by which Excel knows the UDF or command.
XLL 输出的名称,可能和 Excel中已知的 UDF和命令的注册名称不一样。
In Excel 2007, the Analysis Toolpak (ATP) functions are fully integrated, and the C API has its own enumerations for functions such as PRICE, xlfPrice. In earlier versions, you had to use xlUDF to call these functions. If your add-in needs to work with Excel 2003 and Excel 2007, and it uses these functions, you should detect the current version and call the function in the appropriate way.
在 Excel 2007 中, Analysis Toolpak (ATP)函数是完全整合的,C-API 拥有自身的函数枚举,例如 PRICE、xlfPrice。在早期的Excel版本中,你必需使用 xlUDF 调用这些函数。如果你的 add-in 需要工作在 Excel 2003 和 Excel 2007 中,并使用这些函数,你需要检查当前的 Excel 版本,并使用适当的方法调用这些函数。
例如
The following example shows the xlUDF function being used to call the ATP function PRICE when the running version of Excel is 2003 or earlier. For information about the setting of a global version variable, such as gExcelVersion12plus in this example, see Backward Compatibility.
接下来的实例,展示了运行Excel2003或更早期的版本时, xlUDF 函数被用来调用 ATP 函数 PRICE。全球版本变量的设置信息,例如 实例中的 gExcelVersionl2plus ,更多兼容性问题请查看,向后兼容性一节。
注意
This example uses the Framework functions TempNum, TempStrConst to set up the arguments and Excel to call the C API.
这个实例使用框架函数 TempNum,TempStrConst 设置参数 和 Exel 去调用 C-API。
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) // 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;
}
Where you are calling an XLL function that returns a value by modifying an argument in place, the xlUDF function still returns the value via the address of the result XLOPER/XLOPER12. In other words, the result is returned as if through a normal return statement. The XLOPER/XLOPER12 that corresponds to the argument that is used for the return value is unmodified. For example, consider the following two UDFs.
你正在调用的 XLL 函数,通过编辑一个参数返回值,xlUDF 函数 通过XLOPER/XLOPER12 的结果返回值。换句话说,如果通过正常的返回语句返回的结果是。 XLOPER/XLOPER12 相当于,参数用于返回未更改过的值。例如,下一个实例中的 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;
}
When UDF_2 calls UDF_1, the value of pxArg is unchanged after the call to Excel12, and the value returned by UDF_1 is contained in xRetVal.
当 UDF_2 调用 UDF_1 ,pxArg 值,在调用 Excel 12 的不会更改变,UDF_1 返回值 包含在 xRetVal。
When you are making a large number of calls to a UDF in this way, you can evaluate the function name first by using the xlfEvaluate function. The resulting number, which is the same as the registration ID that is returned by the xlfRegister function, can be passed in place of the function name as the first argument to the xlUDF function. This enables Excel to find and call the function more quickly than if it has to look up the function name every time.
当你使用这个方法将一个 单元格大数 发送给 UDF,你可以首先使用 xlfEvaluate 函数获取函数的名称。作为结果的数字,类同于 xlfRegister函数返回的登记ID,它可以被传送到函数名的位置,如 xlUDF 函数的第一个参数。这种调用方式 比每次都查找函数名要快得多,
|
|