向后兼容性
适用于:Excel 2013 | Office 2013 | Visual Studio
本主题解决不同版本的 Microsoft Excel 中的 XLL 兼容性问题。
有用的常量定义
请考虑在 XLL 项目代码中包含与这些定义类似的定义,并替换此上下文中使用的文本数字的所有实例。 这将阐明特定于版本的代码,并降低以无害数字形式出现版本相关 bug 的可能性。
#define MAX_XL11_ROWS 65536
#define MAX_XL11_COLS 256
#define MAX_XL12_ROWS 1048576
#define MAX_XL12_COLS 16384
#define MAX_XL11_UDF_ARGS 30
#define MAX_XL12_UDF_ARGS 255
#define MAX_XL4_STR_LEN 255u
#define MAX_XL12_STR_LEN 32767u
获取正在运行的版本
应使用 Excel4(xlfGetWorkspace, &version, 1, &arg)
检测哪个版本正在运行,其中 arg
数字 XLOPER 设置为 2,version 是字符串 XLOPER ,然后可强制转换为整数。 对于Microsoft Excel 2013,这是 15.0。 应在 xlAutoOpen 函数中或从中执行此操作。 然后,可以设置一个全局变量,通知项目中正在运行哪个版本的 Excel 的所有模块。 然后,代码可以决定是使用 Excel12 和 XLOPER12调用 C API,还是使用 XLOPER调用 Excel4。
可以调用 XLCallVer 来发现 C API 版本,但这并不指示你运行的是哪个 Excel 2007 之前的版本。
创建导出双接口的加载项
请考虑一个 XLL 函数,该函数采用字符串并返回可以是任何工作表数据类型的值。 可以导出注册为类型“PD”的函数,并按如下方式创建原型,其中字符串作为长度计数字节字符串传递。
LPXLOPER WINAPI my_xll_fn(unsigned char *arg);
虽然这非常有效,但有几个原因导致从 Excel 2007 开始,这不是代码的理想界面:
- 它受 C API 字节字符串的限制,并且无法访问从 Excel 2007 开始支持的长 Unicode 字符串。
- 尽管从 Excel 2007 开始,Excel 可以传递并接受 XLOPER,但在内部会将它们转换为 XLOPER12,因此,从 Excel 2007 开始,当代码在早期版本的 Excel 中运行时,存在隐式转换开销。
- 此函数可能使线程安全,但如果类型字符串更改为
PD$
,则注册在 Excel 2007 之前启动失败。
出于这些原因,理想情况下,从 Excel 2007 开始,你应该为注册为 QD%$
的用户导出一个函数,前提是你的代码是线程安全的,并且按如下所示进行了原型制作。
LPXLOPER12 WINAPI my_xll_fn_v12(wchar_t *arg);
从 Excel 2007 开始注册其他函数的另一个原因是,它允许 XLL 函数最多使用 255 个参数,而不是早期版本的 30 个限制。
幸运的是,通过从项目导出这两个版本,可以获得这两个版本的优点。 然后,可以检测正在运行的 Excel 版本,并有条件地注册最合适的函数。 有关详细信息和示例实现,请参阅 在 Excel 2007 中开发外接程序 (XL) 。
此方法可能会导致在 Excel 2003 中运行的工作表显示的结果可能与从 Excel 2007 开始运行的同一工作表不同。 例如,Excel 2003 会将 Excel 2003 工作表单元格中的 Unicode 字符串映射到 ASCII 字节字符串,并在将其传递给 XLL 函数之前将其截断。 从 Excel 2007 开始,Excel 会将未转换的 Unicode 字符串传递给以正确方式注册的 XLL 函数。 这可能会导致不同的结果。 你应该意识到这种可能性及其对用户的影响,而不仅仅是在升级中。 例如,Excel 2000 和 Excel 2003 之间改进了某些内置数值函数。
新建工作表函数和分析工具库函数
分析工具库 (ATP) 函数从 Excel 2007 开始属于 Excel。 以前,XLL 只能使用 xlUDF 调用 ATP 函数。 从 Excel 2007 开始,应使用 xlcall.h 中定义的函数枚举调用 ATP 函数。 从 DLL 调用用户定义函数中的示例演示了两种不同的方法。