office 脚本中 while 循环的奇怪行为

Weird behaviour of while loop in office script

我使用以下代码更新单元格 A1,但它不起作用:

function main(workbook: ExcelScript.Workbook) { 

    let worksheet = workbook.getWorksheet("Sheet1");
    var i: number = 0; 

    while (true) {
        worksheet.getRange("A1").setValue(i);
        i = i + 1;
    }
}

代码为 运行 时没有任何反应。

但是,如果我添加一个不相关的行

console.log("abc")

在循环结束时,如下所示:

function main(workbook: ExcelScript.Workbook) { 

    let worksheet = workbook.getWorksheet("Sheet1");
    var i: number = 0; 

    while (true) {
        worksheet.getRange("A1").setValue(i);
        i = i + 1;
        console.log("abc");
    }
}

一切都会顺利进行。

那么,这里到底发生了什么?

为了提高性能,Office 脚本仅在您与脚本“同步”后才发布脚本的结果。 console.log() 是强制执行此操作的方法之一,但还有其他方法。


来自 Office Scripts in Excel > Troubleshooting > Improve script performance(强调我的):

Remove unnecessary console.log statements

Console logging is a vital tool for debugging your scripts. However, it does force the script to synchronize with the workbook to ensure the logged information is up-to-date. Consider removing unnecessary logging statements (such as those used for testing) before sharing your script. This typically won't cause a noticeable performance issue, unless the console.log() statement is in a loop.

同样,来自文章Avoid using the context.sync method in loops

It's generally a good practice to put have a final context.sync just before the closing "}" character of the application run method (such as Excel.run, Word.run, etc.). This is because the run method makes a hidden call of context.sync as the last thing it does if, and only if, there are queued commands that have not yet been synchronized. The fact that this call is hidden can be confusing, so we generally recommend that you add the explicit context.sync. However, given that this article is about minimizing calls of context.sync, it is actually more confusing to add an entirely unnecessary final context.sync. So, in this article, we leave it out when there are no unsynchronized commands at the end of the run.

您的 Office 文档只有在工作簿同步时才会明显更新。当 context.sync 为 运行 时会发生这种情况,这会隐式发生在脚本的末尾;当你像 console.log 这样的 同步命令 时也会发生这种情况。如果您要使循环有限而不是无限,那么您的脚本将在达到循环限制时自动同步,并且您的工作簿将适当地更新一次。

如果您想看到部分进展,您也可以使用 console.logcontext.sync 在脚本中间强制更新,但您应该知道这些调用很昂贵并且您可能希望尽可能少地使用它们,就像在链接的文章中那样。

上面的答案是正确的,尽管我想对 context.sync 进行一些澄清。 Office 脚本提供了一个同步 API,它不需要用户显式执行同步操作(并且不公开上下文对象)。连续写入确实都是批处理一次发送。在您的初始样本中,您只是永远添加到批次中。对工作簿的任何 console.log 或读取操作都将强制进行同步,您将看到到那时为止已批处理的写入操作。