提高 Office 脚本的性能

Office 脚本的用途是自动执行一系列常见任务,以节省时间。 慢速脚本可能感觉不会加快工作流速度。 大多数情况下,脚本将完全正常并按预期运行。 但是,有一些可避免的方案可能会影响性能。

减少读取或写入调用数

脚本速度缓慢的最常见原因是与工作簿的通信过多。 使用 Excel web 版 时,这一点尤其明显。 在某些情况下,脚本会将其本地数据与工作簿的本地数据同步。 这意味着,任何写入操作 ((如 workbook.addWorksheet()) )仅在发生此幕后同步时应用于工作簿。 同样,任何读取操作 ((例如 myRange.getValues()) 在这些时间仅从脚本的工作簿中获取数据。 在任一情况下,脚本在对数据执行操作之前提取信息。 例如,以下代码将准确记录所用区域中的行数。

let usedRange = workbook.getActiveWorksheet().getUsedRange();
let rowCount = usedRange.getRowCount();
// The script will read the range and row count from
// the workbook before logging the information.
console.log(rowCount);

Office 脚本 API 可确保工作簿或脚本中的任何数据在必要时准确且最新。 无需担心这些同步,脚本就可以正确运行。 但是,了解此脚本到云通信有助于避免不必要的网络调用。

读取循环外部的工作簿数据

从工作簿获取数据的任何方法都可以触发网络调用。 应尽可能在本地保存数据,而不是重复进行相同的调用。 处理循环时尤其如此。

请考虑使用脚本来获取工作表所用区域中负数的计数。 脚本需要循环访问所用区域中的每个单元格。 为此,它需要范围、行数和列数。 在启动循环之前,应将这些变量存储为局部变量。 否则,循环的每次迭代将强制返回到工作簿。

/**
 * This script provides the count of negative numbers that are present
 * in the used range of the current worksheet.
 */
function main(workbook: ExcelScript.Workbook) {
  // Get the working range.
  let usedRange = workbook.getActiveWorksheet().getUsedRange();

  // Save the values locally to avoid repeatedly asking the workbook.
  let usedRangeValues = usedRange.getValues();

  // Start the negative number counter.
  let negativeCount = 0;

  // Iterate over the entire range looking for negative numbers.
  for (let i = 0; i < usedRangeValues.length; i++) {
    for (let j = 0; j < usedRangeValues[i].length; j++) {
      if (usedRangeValues[i][j] < 0) {
        negativeCount++;
      }
    }
  }

  // Log the negative number count to the console.
  console.log(negativeCount);
}

注意

作为试验,请尝试将 循环usedRange.getValues()中的 替换为 usedRangeValues 。 你可能会注意到,在处理大范围时,脚本的运行时间要长得多。

避免在循环或周围循环中使用 try...catch

我们不建议在循环或周围循环中使用 try...catch 语句。 这与应避免在循环中读取数据的原因相同:每次迭代都会强制脚本与工作簿同步,以确保未引发任何错误。 通过检查从工作簿返回的对象,可以避免大多数错误。 例如,以下脚本在尝试添加行之前检查工作簿返回的表是否存在。

/**
 * This script adds a row to "MyTable", if that table is present.
 */
function main(workbook: ExcelScript.Workbook) {
  let table = workbook.getTable("MyTable");

  // Check if the table exists.
  if (table) {
    // Add the row.
    table.addRow(-1, ["2012", "Yes", "Maybe"]);
  } else {
    // Report the missing table.
    console.log("MyTable not found.");
  }
}

删除不必要的 console.log 语句

控制台日志记录是 调试脚本的重要工具。 但是,它会强制脚本与工作簿同步,以确保记录的信息是最新的。 在共享脚本之前,请考虑删除不必要的日志记录语句 (,例如用于测试) 的日志记录语句。 这通常不会导致明显的性能问题,除非 console.log() 语句处于循环中。

脚本运行时暂停计算

如果脚本更改了大量值,则可能会触发过多的重新计算。 通过在脚本运行时将计算模式设置为“手动”来控制 Excel 计算引擎。 使用 Application.setCalculation 切换 Excel 以手动重新计算公式。 完成后,请务必将工作簿返回到原始计算模式。

以下示例演示如何更改计算模式。 它还演示了如何使用 手动重新计算工作簿 Application.calculate

/**
 * This script adjusts the calculation mode of the workbook and makes a manual recalculation.
 * Wrap the CalculationMode changes around code that repeatedly updates values.
 */
function main(workbook: ExcelScript.Workbook) {
  const application = workbook.getApplication();

  // Turn off automatic calculations during the script.
  application.setCalculationMode(ExcelScript.CalculationMode.manual);

  // ... 

  // Perform a manual recalculation of the workbook.
  application.calculate(ExcelScript.CalculationType.fullRebuild);

  // ...

  // Resume automatic calculations after the script finishes.
  application.setCalculationMode(ExcelScript.CalculationMode.automatic);
}

逐案帮助

随着 Office 脚本平台的扩展以使用 Power Automate自适应卡片和其他跨产品功能,脚本-工作簿通信的细节变得更加复杂。 如果需要帮助加快脚本运行速度,请通过 Microsoft Q&A 联系。 请务必使用“office-scripts-dev”标记你的问题,以便专家可以找到它并提供帮助。

另请参阅