(Excel 外接程序) 将大数设置为Range.value 时,电子表格中得到的数字不同

(Excel add-in) When setting a large number to Range.value, the resulting number in the spreadsheet is different

将一个大数字设置为范围(单元格)的值时,写入电子表格的数字与原始数字不同。例如。

如果我设置42300000000,excel中的数字就变成了-649672960。较小的数字不会发生这种情况

我用 Visual Studio 中的基本项目示例对其进行了测试。只需将原来的 loadSampleData 函数替换为:

function loadSampleData() {

     var values = [
                    [4230, 42300, 423000],
                    [4230000, 42300000, 423000000],
                    [4230000000, 42300000000, 423000000000]
    ];

    // Run a batch operation against the Excel object model
    Excel.run(function (ctx) {
        // Create a proxy object for the active sheet
        var sheet = ctx.workbook.worksheets.getActiveWorksheet();
        // Queue a command to write the sample data to the worksheet
        sheet.getRange("B3:D5").values = values;

        // Run the queued-up commands, and return a promise to indicate task completion
        return ctx.sync();
    })
    .catch(errorHandler);
}

当我 运行 加载项时,我在 Excel 中得到这个:

4230         42300      423000
4230000      42300000   423000000
-64967296   -649672960  2093204992

这是某种溢出吗?我做错了什么吗?

谢谢!

感谢您报告此错误。

问题似乎出在我们用来反序列化传入请求的 JSON 解析器中。它错误地假定任何整数都适合 int32_t。正确的行为是解析像 double 这样大的值,尽管它们是整数。

由于这不是 Excel 代码,修复可能需要很长时间。

不幸的是,在这些文字的末尾附加 .0E0 不会驱动解析器将这些文字解析为 double。正如 Charles Williams 指出的那样,用单引号或双引号括起文字可以满足您的目的 [出于某种未知原因]。

我无法找到更具确定性的解决方法。欢迎提出其他建议。

兹拉特科

当我探索这个错误时,我得到以下结果

  • 9876543210 和 9876543210.0 给出 1286608618 - 失败
  • 9876543210.9 给出 9876543210.9 - 有效
  • '9876543210' 和 "9876543210" - 不会产生字符串(我会认为这是一个错误,但也许这只是一个令人讨厌的 JS 类型混淆)但给出 9876543210 作为数字(因此可能绕过原始错误)
  • "'9876543210" 给出 '9876543210,excel 将其识别为字符串 - 正确

对 1704.8017.1000 使用以下代码

async function setValue() {
    try {
        await Excel.run(async (context) => {
            let sheet = context.workbook.worksheets.getActiveWorksheet();

            let range = sheet.getRange("C3");
            range.values = [[ 9876543210.0 ]];
            range.format.autofitColumns();

            await context.sync();
        });

        console.log("Done!");
    }
    catch (error) {
        OfficeHelpers.Utilities.log(error);
    }
}