Excel 2010与Excel 2003中的整数表示法(C++插件)
Representation of integers in Excel 2010 vs Excel 2003 (C++ plugin)
简介
我继承了一个使用VS2008、xlw2.0和Excel2003开发的遗留插件项目(C++)。
我已经设法将它移植到xlw 4.0头中(当添加对Excel2007的支持时,一些方法更改了名称,诸如此类)。我还没有生成任何东西,因为旧代码是手工编写的,我不会改变正在工作的东西,并且只有为了它才有合理的结构和代码逻辑。
该代码在Excel2003下可以正常工作。我今天试用了excel 2010,发现了一个最令人费解(也最可怕)的错误。
困惑行为
我(从VBA宏)接收一列(n行,1列)数字(通过构造的小正整数)作为XlfOper&我想把它转换成一个(老式)数组。代码基本上是遍历每一行,然后在对应于给定行的XlfOper上调用AsInt()方法。类似于:
for (long iy = 0; iy < numcols; ++iy)
{
for (long ix = 0; ix < numrows; ++ix)
convertXflOper( x(ix, iy), a1D[iy*numrows + ix] );
}
其中a1D是该特定项目中使用的一维数组类型,convertXflOper是一个模板函数,用于以下类型:
void convertXflOper (const XlfOper &x, long & y)
{
y = x.AsInt();
}
在给定的一行,我在excel工作簿中有数字10。
在Excel 2003下,这将转换为10。在Excel 2010下,这将转换为9。
我已经调试过了,问题是它的读数不是10,而是它的两倍近似值
x.lpxloper4_->val.num
9.9999999999999982 // wrong: I am not asking for 10.0, I am asking for 10
Excel 2010和
x.lpxloper4_->val.num
10.000000000000000 // right: an integer is an integer
在Excel 2003中。因此,C++代码,尽管很漂亮(或不漂亮),似乎没有错。AsInt()方法的行为类似于强制转换,static_cast<long>(9.9999999999999982)
是9,而不是10。
问题
这件事会让我非常痛苦,主要是因为它很容易被忽视:对于许多其他整数值,它在Excel2003和2010中都能正确工作。
我在excel接口中做错了什么,因为它认为整数必须被视为双精度?谁知道何时何地,我怎么能确定这不会发生?解决这个问题的最佳方法是什么?
Excel内部不保存整数-所有数字(整数、日期、时间、货币等)都是双精度的。所以Oper val.num总是一个double,xltypeNum的操作符总是一个duble
(运算器可以保存val.w中的整数,但只能作为XLM宏流量控制等功能的一部分,这些功能已经过时了几十年,在实践中不太可能实现)
我不知道为什么你在Excel 2007中得到9.9999999-你是如何将值传递给Oper的?
- 在传递 com 变体时运行 excel 宏崩溃
- 使用来自 Excel VBA 的 C++ dll 时"Bad DLL calling convention" - 如何解决?
- Excel 不愉快地显示大型 2D 范围公式数组
- 如何从excel文件中读取数据并存储到变量中?
- 错误写入Excel文件-C++
- 如何使用ActiveQt在excel中将工作表附加到工作簿末尾
- 如何更改 Excel DSN 的默认工作簿?
- 随机字符,从强制转换 Arduino 字符串到 Excel BSTR 通过 c++ DLL
- 将带有时区的纪元时间转换为Excel格式的时间?
- 从Excel VBA调用C++DLL只能从Visual Studio中的调试实例工作
- 如何使用 Win32 API 从 Excel VBA 中的非"Single-Threaded Apartment"线程调用 InternetGetProxyInfo
- 如何连接C++和Excel(从C++程序输出到Excel电子表格)
- 我想使用 C++ 从 excel 获取记录,并希望使用特定的列数据(例如书籍 ID)控制输出
- C++使用 adodb 在 64 位 Windows 7 中读取 Excel 文件?
- 使用 XLNT Excel 库时出现问题
- 调试通过 LoadLibrary() 加载到 Excel 中的C++ DLL
- 如何在 VBA/Excel 中创建字符串数组并将其发送到C++ DLL,以便可以在 DLL 中循环访问它
- #VALUE!在 64 位 Excel 中调用 DLL 函数 (C++) 时
- 在C J2ME中读取Excel文件,并从ITQ获取数据
- 从Excel/CSV值创建静态数组