提高 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”标记你的问题,以便专家可以找到它并提供帮助。