向后兼容性

适用于: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 的所有模块。 然后,代码可以决定是使用 Excel12XLOPER12调用 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 调用用户定义函数中的示例演示了两种不同的方法。

另请参阅