【XLL 文档翻译】【第2部分】C API 回调函数 Excel4, Excel12
Excel4 和 Excel12 函数使得 DLL 可以调用 Excel 工作表函数、宏表函数、命令、XLL特定函数或命令。最近的一些 Excel 版本都支持 Excel12 函数。这两个函数支持下面两种形式。
- 来自于 Excel4/Excel12 可变长度参数列表
- 来自于Excel4v/Excel12v 数组参数
除了将参数传递给这两个函数方法不同以外,这两种形式的功能是相同的。两二种形式的完整描述在 Excel4/Excle12 中。Excel4v/Excel12v 包含了关于这种形式的其它问题。
Excel4/Excel12
从 DLL/XLL 或 代码资源中调用 Excel 内部的 工作表函数、宏表函数、 XLL 特定函数 或 命令。
最近版本的 Excel版本都支持 Excel4。只有 Excel 2007 及其后继续版本支持 Excel12.
这两个回调函数只能通过由 Excel 通过 DLL/XLL 调用。他们也可以间接的通过 VBA 调用。除上面两种情况以外,它们不能在其它任何时间进行调用。例如,当操作系统调用 DLL 时,不能在调用 DllMain 时或其它时刻调用这两个回调函数,或是在DLL创建的其它线程调用。
Excel4v 和 Excel12v 其参数是数组形式,因这些它们的参数,使用的是堆栈中的可变长度列表。在其它方面,Excel4 与 Excel4v,Excel12 与 Excel12v 表现出来的行为都是一样的。
函数原型
int Excel4(int iFunction, LPXLOPER pxRes, int iCount, LPXLOPER argument1, ...);
int Excel12(int iFunction, LPXLOPER12 pxRes, int iCount, LPXLOPER12 argument1, ...);
参数
iFunction ( int )
表示你想调用的 命令、函数或特定的函数,有效的 iFunction 值,参考 “备注” 一节中的内容。
pxRes ( LPXLOPER or LPXLOPER12 )
一个指向 XLOPER(用于Excel4) 或 XLOPER12 (用于Excel12),用于保存评估计算结果。
iCount ( int )
表示后面将传送到函数中的参数的数量。到 Excel 2003 版本为止,此数值可以设置为 0 到 30。在 Excel 2007 中,可以设置为 0 到 255。
argument1, ... (LPXLOPER or LPXLOPER12)
作为函数的可选参数。所有参数必需是 XLOPER 或 XLOPER12 指针。
属性值 / 返回值
必需返回下表中的任意一个值(int)
值 | 返回代码 | 描述 |
---|---|---|
0 | xlretSuccess | 函数成功调用返回这个值。但并不意味着,函数没有返回 Excel 错误值。 为了确认错误值,你必需观察 *pxRes* 值类型。 |
1 | xlretAbort | 命令或函数异常结束(内部中断)。当 XLM 宏表调用 CLOSE 函数自我关闭或是 Excel 内存不足就会发生这种情况。如果 你接收到此错误,你必需立即退出。DLL 只允许在退出以前调用 xlFree。其它任何的 C API 调用都是不被允许的。 用户可以使用 文件菜单中的 Save 命令保存之前的任何操作。 |
2 | xlretInvXlfn | 提供了一个无效的函数成员。如果你使用来自 XLCALL.H 中的常量,这种情况不会发生, 除非你正在调用一些你当前 Excel版本 不支持的常量。 |
4 | xlretInvCount | 输入了一个无效的参数数量,到 Excel 2003 ,最大的参数数量是 30,而到了 Excel 2007 ,最大的参数数量达到了 255 个。一些函数需要一个固定的或最小数量的参数数。 |
8 | xlretInvXloper | 一个无效的 XLOPER 或 XLOPER12 被传递给函数,或参数中使用了一个错误的数据类型。 |
16 | xlretStackOvfl | 发生堆栈溢出。使用 xlStack 监视栈上的空间数量,尽可能的避免在堆栈上分配一个很大的局部(自动)数组和结构,把它们设置为静态的。(注意有可能会发生一个没有被探测到的内在溢出)。 |
32 | xlretFailed | 命令等效函数失败,它等效于 宏命令显示宏错误警告对话框。 |
64 | xlretUncalced | 调用一个还没有完成计算的一个单元格。这种情况下,DLL 将立即将控制权返还给Excel。在退出函数前,DLL 只允许调用 C-API 函数 xlFree。其它的 C API 是不可以调用的。 |
128 | xlretNotThreadSafe | 只会在 Excel 2007 运行时,并且 XLL 工作表函数被声明为线程安全的,才能返回这个值。 多线程重计算期间,尝试调用的函数不是线程安全的, |
备注
有效的 iFunction 值
有效的 iFunction 值都是 xlf 或 xlc 开头的常量,它们定义在 XLCALL.H 中或是以下的特定函数。
xlAbort | xlEnableXLMsgs | xlGetInst | xlSheetNm |
xlCoerce | xlFree | xlGetName | xlStack |
xlDefineBinaryName | xlGetBinaryName | xlSet | xlUDF |
xlDisableXLMsgs | xlGetHwnd | xlSheetId |
不同的函数类型
Excel4 和 Excel12 在三个函数类型上有区别。函数依据 Excel 调用 DLL 的三种情况进行分类。
- 类型1 来自于工作表的调用,作为重计算的结果。
- 类型2 从函数宏,或工作表调用,其文本类型被注册为数字符号
- 类型3 从对象、宏、菜单、工具栏 、快捷捷、执行Excel4宏,或 工具/宏/运行 命令调用。
下表展示了,每个类型可使用的函数。
Class 1 | Class 2 | Class 3 |
---|---|---|
任何工作表函数 任何 以xl...开头的 XLL 函数,除了 xlSet. xlfCaller |
任意工作表函数 任何 以xl...开头的 XLL 函数,除了 xlSet. 宏表函数,包括xlfCaller, 但执行在工作空间和打开的工作簿中无任何效果 |
任意工作表函数,包含 xlSet and 命令等效函数. |
命令等效函数显示对话框
如果命令等效函数关联了对话框,你可以在 iFuntcion 函数中设置 xlPrompt 位。这样,Excel 就会在执行命令前显示相应的对话框。
DLL的国际性支持
如果你在 iFunction 中设置了 xlIntl 位,函数或命令命令将和 美版的 Excel 表现是一至的,即使它是运行在国际版本的 Excel 中。
clretUncalced 或 xlretAbort
如果返回值为这二种类型中的一种,你的 DLL 必需清除,并将控制权返还给 Excel。 C API 回调 操作,会在 接到到这种返回值后失效,除了 xlFree 函数。
实例
这个实例使用 Excel12 函数选择调用的单元格
\SAMPLES\EXAMPLE\EXAMPLE.C.
注意 这个函数调用一个命令宏 xlcSelect 因此只会在 XLM 宏表中调用时有效。
short WINAPI Excel12Example(void)
{
XLOPER12 xRes;
Excel12(xlfCaller, &xRes, 0);
Excel12(xlcSelect, 0, 1, (LPXLOPER12)&xRes);
Excel12(xlFree, 0, 1, (LPXLOPER12)&xRes);
return 1;
}
Excel4v/Excel12v
从 DLL/XLL 或代码资源中调用 Excel 内部的工作表函数、宏表函数或命令、或 XLL-only 特定函数或命令
所有最新版本的 Excel4v 都支持 Excel4v 函数。只有 Excel 2007 及其后续版本支持 Excel12v。
这些函数只在 DLL/XLL 回调 Excel 功能可以使用。它们还可以间接的通过 VBA 来调用。除此以外,其它的任何时间都不可以调用这两个函数。例如,它们不能在 操作系统调用 DLL时调用 DllMain 时直接调用这个函数。 DLL 创建的线程也不能调用这个函数。
Excel4 和 Excel12 接收堆栈上的可变长度参数列表,然而 上面的两个函数只接收数组形式的参数。在其它方面,这两组函数是等效的。
函数原型
int _cdecl Excel4v(int iFunction, LPXLOPER pxRes, int iCount,LPXLOPER rgx[]);
int _cdecl Excel12v(int iFunction, LPXLOPER12 pxRes, int iCount,LPXLOPER12 rgx[]);
参数
iFunction (int)
一个数字类型,表明你要调用的 命令、函数 或 特殊函数。有效的 iFunction 值,参考 “Remarks” 一节。
pxRes (LPXLOPER or LPXLOPER12)
XLOPER 或 XLOPER12 类型的指针,用于保留函数的结果值。
iCount (int)
要传送给函数的参数数量。到 Excel 2003 版本,这里的数值最大为30。但是在 Excel 2007 版本,最大数值是 255。
rgx (LPXLOPER[] 或 LPXLOPER12[])
包含要传送给函数的参数数组。数组中的所有参数必需指向 XLOPERs 或 XLOPER12s 类型。
属性值 / 返回值
这些函数的返回值 与 Excel4 和 Excel12 是相同的。
备注
当参数的数量是不是固定,使用这些函数更好。例如,当使用 xlfRegister 注册函数时,参数数量依赖于注册的函数的参数数量。这种情况下就可以使用这些函数。或者当你为 Excel4 或 Excel12 建一个包装函数时,你需要转换变量参数列表才能提供给 Excel4 或 Excel12 。而使用 Excel 4v 或 Excel12v 只需要调用一个包含了所有函数的参数数组就可以了。
实例
在 SAMPLES\FRAMEWRK\FRAMEWRK.C 包含了 Excel 和 Excel12f 函数的实例代码。