禁用自动转换为日期

时间:2016-07-06 13:18:40

标签: ms-office office-js

在我需要分析的一个工作簿(来自其他人)中,他们使用公式来构建字符串列表:04-09-0104-09-0204-09-03等等general格式。在我的部分代码中,我需要将这些值复制到其他地方。但是,因为这些值非常特殊,所以它们会自动被视为Date(而它们显然不是用户的日期)并转换为09/04/200109/04/200209/04/2003,结果,这些值完全改变了,基于这些粘贴值的计算会导致错误。

这是一个测试代码:

function test () {
    Excel.run(function (ctx) {
        var r0 = ctx.workbook.worksheets.getItem("Sheet1").getRange("A2:A10");
        var r1 = ctx.workbook.worksheets.getItem("Sheet1").getRange("F2:F10");
        r0.load(["values"]);
        return ctx.sync()
            .then(function () { console.log(r0.values.toString()); r1.values = r0.values; })
            .then(ctx.sync)
            .then(function () { r1.load(["values"]); })
            .then(ctx.sync)
            .then(function () { console.log(r1.values.toString()); })
    });
}

控制台中的结果显示值已完全更改:

enter image description here

在Excel中,它显示:

enter image description here

请注意,Excel本身并不会系统地将这些值转换为日期。例如,如果我们仅将值04-09-01复制到另一个单元格。 Excel会发出警告并建议将其转换为日期,但用户可以忽略此警告并保持04-09-01原样:

enter image description here

所以我的问题是,是否有一种方法或解决方法可以在JavaScript API中禁用此自动转换,以便我们可以忠实地复制值?

修改1:

我尝试使用numberFormat来保留范围的初始格式。首先,我将A2:A0如下General格式化。

enter image description here

然后,我运行以下代码:

function test () {
    Excel.run(function (ctx) {
        var r0 = ctx.workbook.worksheets.getItem("Sheet1").getRange("A2:A10");
        var saveValues, saveNumberFormat;
        r0.load(["values", "numberFormat"]);
        return ctx.sync().then(function () {
            saveNumberFormat = r0.numberFormat;
            saveValues = r0.values;
            r0.numberFormat = saveNumberFormat;
            r0.values = saveValues;
        });
    });
}

结果如下所示,格式为Date

enter image description here

因此恢复numberFormat无济于事?

编辑2:我做了一个将范围复制到另一个范围的示例。我希望r1具有与r0完全相同的数字格式和值。但结果显示,04-09-01中的general r004/09/2001中生成Dater1。基本上,问题与上一个示例相同:numberFormat无法忠实地复制或恢复。

function test () {
    Excel.run(function (ctx) {
        var r0 = ctx.workbook.worksheets.getItem("Sheet1").getRange("A2:A10");
        var r1 = ctx.workbook.worksheets.getItem("Sheet1").getRange("K2:K10");
        r0.load(["values", "numberFormat"]);
        return ctx.sync()
            .then(function () { r1.numberFormat = r0.numberFormat; })
            .then(ctx.sync)
            .then(function () { r1.values = r0.values; })
        });
}

2 个答案:

答案 0 :(得分:5)

您应该可以做以下两件事之一:

1)如果将范围的数字格式设置为文本(“@”),则在应用值之前,值应保持不变。

2)您还可以在文本的开头添加撇号('),以强制Excel将其视为纯文本,无论内部引擎通常将其视为什么。

<强>更新

这里实际上有两件事是危险的。显示的文本与基础值有关。

要获取文本,请访问range.text属性(2D数组)。这将是UI中显示的文本。 要获取基础值,请访问range.values属性(也是2D数组)

如果要将值从一个地方复制到另一个地方,或者存储它们然后进行恢复,请务必同时存储range.numberFormatrange.values。然后使用.numberFormat 首先恢复它们。

更新2

请参阅下面的屏幕截图。代码按预期工作。

enter image description here

~Michael Zlatkovsky,Office可扩展性平台开发人员,MSFT

答案 1 :(得分:0)

你可以复制数字格式,所以可能会这样:

function test () {
    Excel.run(function (ctx) {
        var ws = ctx.workbook.worksheets.getItem("Sheet1");
        var r0 = ws.getRange("A2:A10");
        var r1 = ws.getRange("K2:K10");

        r0.load(["values", "numberFormat"]);
        return ctx.sync().then(function () { 
            r1.numberFormat = "@"; 
            r1.values = r0.values; 
            r1.numberFormat = r0.numberFormat; 
        })
    });
}