ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
123
返回列表 发新帖
楼主: c001q

XLL文档翻译

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-6-27 16:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:插件开发
本帖最后由 c001q 于 2016-6-27 16:40 编辑

----------------------------
仅允许在 DLL 中使用的函数和命令
----------------------------
Excel 有一部分函数只能在 DLL/XLL 中使用。它们在头文件中定义为 (n | xlSpecial)n 是一个大于或等于零的十进制数,前面的 xlSpecial 定义为十六进制的 0x4000。下表列举出了这些函数,关于它们的更多介绍,大家可以参考 API 函数参考一节。
xlFree   0 | xlSpecial  释放 Excel 分配的内存资源

xlStack  1 | xlSpecial  返回 Excel堆栈 中释放的空间

xlCoerce  2 | xlSpecial  转换 XLOPER/XLOPER12 类型
xlSet  3 | xlSpecial    一种可以快速设置单元格值的方法。
xlSheetId  4 | xlSpecial  一种可以快速设置单元格值的方法。

xlSheetNm  5 | xlSpecial  从表格的名称获取表格的ID

xlAbort  6 | xlSpecial  检查用户是否已经按下 CANCEL 按键(ESC键)

xlGetInst  7 | xlSpecial  获取 Excel 实例句柄

xlGetHwnd  8 | xlSpecial  获取 Excel 实例句柄

xlGetName  9 | xlSpecial  获取 Excel 实例句柄

xlEnableXLMsgs  10 | xlSpecial 函数已经过期,不建议使用

xlDisableXLMsgs  11 | xlSpecial 函数已经过期,不建议使用
xlDefineBinaryName  12 | xlSpecial 定义一个使用位存储的名称。

xlGetBinaryName  13 | xlSpecial  获取位存储的名称。



--------------------------------------------------------
operRes参数:保存 XLOPER/XLOPER12 返回值
--------------------------------------------------------
operRes 是回调函数中的第二个参数,它是一个指向 XLOPER 或 XLOPER12 的指针。函数调用成功后,它包括函数和命令的返回值。 如果函数没有返回值,operRes 可以设置为 zero(NULL 指针)。如果要覆盖 operRes参数 的前一个内容,一定要先释放它的内存,以避免内泄漏。
--------------------------------------------------------
count 参数:后面参数的数量
--------------------------------------------------------
count 参数是函数中的第三个参数,它是一个 32位 的带符号整数类型,它应该被设置为后面参数的数量,从1开始。如果 函数或命令没有带任何参数,它需要被设置为 0. 在Excel 2003中,它的最大值为30,也就是说,函数最多只能带30个参数,尽管大多函数的参数数量都小于这个数。在 Excel2007 中,它的最大值为 255,函数最多可以带255个参数。
Excel4 和 Excel12 count 表示指针数量,并随着 Excel4 和 Excel12 一起传送。你需要注意参数的数字不能少于实际的参数数量。否则将导致堆栈读取错误,XLOPER / XLOPER12s 处理无效。还有可能会导致应用程序的崩溃。
Excel4v 或 Excel12v 中,count 表示 XLOPER/XLOPER12s 指针数组大小,并会传送到下一个或最后一个参数。同样的,你需要小心不可以传递小于元素大小的数组,它将导致数组越界。
--------------------------------
传递参数到 C-API 函数
--------------------------------
Excel4 和 Excel12 都带有可带长度的参数列表,计算参数数量后将分别作为 XLOPERs 指针 和 XLOPER12s 指针。Excel4v 和 Excel12v 带有一个参数,计算参数数量后,在Excel4v 将是一个 XLOPERs 数组指针。在 Excel12v中,将是一个 XLOPER12s 指针。
void Excel12v_example(double *dbl_array, int size, double &sum, double &average, double &min, double &max)
{
// 30 is the limit in Excel 2003. 255 is the limit in Excel 2007.
// Use the lower limit to be safe, although it is better to make
// the function version-aware and use the correct limit.
    if(size < 1 || size > 30)
        return;
// Create an array of XLOPER12s
    XLOPER12 *xOpArray = (XLOPER12 *)malloc(size * sizeof(XLOPER12));
// Create an array of pointers to XLOPER12s
    LPXLOPER12 *xPtrArray =
        (LPXLOPER12 *)malloc(size * sizeof(LPXLOPER12));
// Initialise and populate the array of XLOPER12s
// and set up the pointers in the pointer array
    for(int i = 0; i < size; i++)
    {
        xOpArray.xltype = xltypeNum;
        xOpArray.val.num = dbl_array;
        xPtrArray = xOpArray + i;
    }
    XLOPER12 xResult;
    int retval;
    int fn[4] = {xlfSum, xlfAverage, xlfMin, xlfMax};
    double *result_ptr[4] = {&sum, &average, &min, &max};
    for(i = 0; i < 4; i++)
    {
        retval = Excel12v(fn, &xResult, size, xPtrArray);
        if(retval == xlretSuccess && xResult.xltype == xltypeNum)
            *result_ptr = xResult.val.num;
    }
    free(xPtrArray);
    free(xOpArray);
}

使用 XLOPER 替换 XLOPER12s,Excel4v 替换 Excel12v, 在这个代码中可以让函数被所有版本的Excel支持。替换后Excel函数 SUM、AVERAGE、MIN、和MAX 是很简单的,在C语言中使用它们会更有效率,从而避免调用到Excel时的,准备参数时的额外系统开销。然而很多Exceo函数包含的参数更复杂,使得这种方法在很多情况下都很管用。
在 xlfRegister 一节,提供了一些 Excel4v 和  Excel12v 实例。注册 XLL 工作表函数时,你可以为每个参数提供一个描述性的字符,这些字符可以显示在 粘贴函数 对话框中。因此,提供给 xlfRegister 的参数数目这个参数,依赖于你的 XLL函数 中的参数总数,函数与函数之间的参数有着很大的不同。
你总是使用相同的参数数量调用 C-API 函数和命令。你想要减少重复创建这些参数指针时的工作量。既然这然,选择使用 Excel4 和  Excel12 将会更为简单和方便。例如,注册XLL 函数 和命令,你需要为DLL/XLL提供路径和文件名。你可以调用 xlfGetName 获取,调用 xlFree 释放。如果这儿所展示的 Excel4 和  Excel12
XLOPER xDllName;
if(Excel4(xlfGetName, &xDllName, 0) == xlretSuccess)
{
    // Use the name....
    // Then free the memory that Excel allocated for the string
    Excel4(xlFree, 0, 1, &xDllName);
}
XLOPER12 xDllName;
if(Excel12(xlfGetName, &xDllName, 0) == xlretSuccess)
{
    // Use the name....
    // Then free the memory that Excel allocated for the string
    Excel12(xlFree, 0, 1, &xDllName);
}
在实践中函数 Excel12v_example 创建 单个 xltypeMulti XLOPER12 参数,使用 Excel12 调用 C-API,程序的运行效率会更高。例如:
void Excel12_example(double *dbl_array, int size, double &sum, double &average, double &min, double &max)
{
// In this implementation the upper limit is the largest
// single column array = 2^20 = 1048576 rows in Excel 2007
    if(size < 1 || size > 1048576)
        return;
// Create an array of XLOPER12s
    XLOPER12 *xOpArray = (XLOPER12 *)malloc(size * sizeof(XLOPER12));
// Create and initialize an xltypeMulti array
// representing a one-column array.
    XLOPER12 xOpMulti;
    xOpMulti.xltype = xltypeMulti;
    xOpMulti.val.array.lparray = xOpArray;
    xOpMulti.val.array.columns = 1;
    xOpMulti.val.array.rows = size;
// Initialize and populate the array of XLOPER12s.
    for(int i = 0; i < size; i++)
    {
        xOpArray.xltype = xltypeNum;
        xOpArray.val.num = dbl_array;
    }
    XLOPER12 xResult;
    int fn[4] = {xlfSum, xlfAverage, xlfMin, xlfMax};
    double *result_ptr[4] = {&sum, &average, &min, &max};
    for(i = 0; i < 4; i++)
    {
        Excel12(fn, &xResult, 1, &xOpMulti);
        if(xResult.xltype == xltypeNum)
            *result_ptr = xResult.val.num;
    }
    free(xOpArray);
}

--------------------------------
XLCallVer
--------------------------------

除了回调函数 Excel4,Excel4v,Excel12 和 Excel12v,Excel 输出函数 XLCallVer 返回 正在运行的C-API 版。
函数原型:
int pascal XLCallVer(void);
你可以从任何 XLL 命令 和 函数调用它,而且也是线程安全的。
在 Excel97 到 Excel2003,XLCallVer 返回 1280=0x0500 hex = 5x256,表明 Excel版本是5。Excel 2007 返回 3072=0x0c00 hex =12x256,同理,它表示Excel 版本是12.
虽然你可以使用这个函数 确定 C-API 函数运行时是否有效,你可能更喜欢使用 Excel(xlfGetWorkspace, &version, 1, &agr) 获取 Excel 的版本。arg 是一个数值,被XLOPER设置 2  。函数返回一个字符 XLOPER 版本号,然后强制转换为一个 integer。这么作的理由在于,你的 add-in 需要识别 不同Excel版本,而不是C-API 版本。例如,改变了一些统计函数的精确度。

TA的精华主题

TA的得分主题

 楼主| 发表于 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 函数的第一个参数。这种调用方式 比每次都查找函数名要快得多,

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-7-3 16:01 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
=============================
Evaluating Names and Other Worksheet Formula Expressions
计算名称以及其它的工作表公式表达式。
=============================

One of the most important features that Excel exposes through the C API is the ability to convert any string formula that can legally be entered into a worksheet to a value, or array of values.

Excel 暴露给 C-APi 的一个最重要的特性,是能转换任意字符串公式,并被合法的登记为一个工作表值或数组值。

This is essential for XLL functions and commands that must read the contents of defined names, for example. This ability is exposed through the xlfEvaluate function, as shown in this example.

XLL 函数和命令必需要有定义的名称。例如,实例中,通过 xlfEvaluate 函数输出。

int WINAPI evaluate_name_example(void)
{
  wchar_t *expression = L"\016!MyDefinedName";
  XLOPER12 xNameText, xNameValue;
  xNameText.xltype = xltypeStr;
  xNameText.val.str = expression;

// Try to evaluate the name. Will fail with a #NAME? error
// if MyDefinedName is not defined in the active workbook.
  Excel12(xlfEvaluate, &xNameValue, 1, &xNameText);

// Attempt to convert the value to a string and display it in
// an alert dialog. This fails if xNameValue is an error value.
  Excel12(xlcAlert, 0, 1, &xNameValue);

// Must free xNameValue in case MyDefinedName evaluated to a string
  Excel12(xlFree, 0, 1, &xNameValue);
  return 1;
}

Note that when you are evaluating a worksheet name, either on its own or in a formula, you must prefix the name with ‘!’, at least. Otherwise, Excel tries to find the name in a hidden namespace reserved for DLLs. You can create and delete hidden DLL names using the xlfSetName function. You can get the definition of any defined name, whether it is a hidden DLL name or a worksheet name, using the xlfGetDef function.

当你在计算一个工作表名称时,在其自身或公式中,你必需以 !为作前缀,否则,Excel会试着在为DLL保留的隐藏命名空间中查找。你可以使用 xlSetName 函数创建和删除 隐藏的DLL名字。你可以使用 xlfGetDef 函数获取任意的名称定义,无论是否隐藏 DLL 名称 或 工作表名称。

The full specification for a worksheet name takes the following form:

工作表命名规范如下面格式。

='C:\example folder\[Book1.xls]Sheet1'!Name

Note that Office Excel 2007 introduces a number of new file extensions. You can omit the path, the workbook name, and the sheet name where there is no ambiguity among the open workbooks in this Excel session.

注意 2007 中引入了一些新的文件扩展,你在当前打开的工作簿中 Excel 会话可以省略路径工作表。

The next example evaluates the formula COUNT(A1:IV65536) for the active worksheet and displays the result. Note the need to prefix the range address with ‘!’, which is consistent with the range reference convention on XLM macro sheets. The C API XLM follows this convention:

下一个实例,在当前激活工作表中计算公式 COUNT(A1:IV65536)并显示结果。注意 引用地址前需要加上 '!'。它符合 XLM 宏表的引用约定。 C-API XLM 遵守以下约定:

=A1 A reference to cell A1 on the current macro sheet. (Not defined for XLLs).

在当前宏表中引用一个单元格 A1. (不是定义在 XLL中).

=!A1 A reference to cell A1 on the active sheet (which could be a worksheet or macro sheet)

在激活的表格中引用单元格 A1 (可以是工作表或宏表)

=Sheet1!A1 A reference to cell A1 on the specified sheet, Sheet1 in this case.

在批定的表格中引用单元格 A1 ,本列中引用的是 Sheet1 表格。

=[Book1.xls]Sheet1!A1 A reference to cell A1 on the specified sheet in the specified workbook

引用 Book1.xls 工作薄中的 Sheet1 工作表中的 A1 单元格。

In an XLL, a reference without a leading exclamation point (!) cannot be converted to a value. It has no meaning because there is no current macro sheet. Note that a leading equals sign (=) is optional and is omitted in the next example.

在 XLL 中,引用范围前没有感叹号,它们就不能被转换成值。因为在没有当前宏表的情况下,引用是没有意义的。注意前面的等号是可选择的。在下面的实例中, 等号被省略了。

int WINAPI evaluate_expression_example(void)
{
    wchar_t *expression = L"\022COUNT(!A1:IV65536)";
    XLOPER12 xExprText, xExprValue;
    xExprText.xltype = xltypeStr;
    xExprText.val.str = expression;

// Try to evaluate the formula.
    Excel12(xlfEvaluate, &xExprValue, 1, &xExprText);

// Attempt to convert the value to a string and display it in
// an alert dialog. Will fail if xExprValue is an error.
    Excel12(xlcAlert, 0, 1, &xExprValue);

// Not strictly necessary, as COUNT never returns a string
// but does no harm.
    Excel12(xlFree, 0, 1, &xExprValue);
    return 1;
}


You can also use the xlfEvaluate function to retrieve the registration ID of an XLL function from its registered name, which can then be used to call that function using the xlUDF function.

你还可以使用 xlfEvaluate 函数检索 XLL函数在自己名称中登记的ID。它可以被用在 xlUDF 函数中调用函数。

TA的精华主题

TA的得分主题

发表于 2018-1-29 22:02 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-22 05:11 , Processed in 0.037099 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表