为什么 Google Sheet App Script 中的循环会在循环过程中停止,而其余代码不会 运行?

Why does the looping in Google Sheet App Script stop in middle of the looping process and the rest of the codes do not run?

我尝试了“for loop”和“do ... while ...”,它们都在循环过程中停止了,而循环之后的其余代码确实不是 运行。 当我遍历数百行时,这就成了一个问题。

我知道使用数组是更好的解决方案,因为代码执行速度更快,但我很难批量设置边框,因为没有“.setBorders(Array)” Google 表格中的功能。

这里提供的 sheet 已经过简化,只是为了显示循环问题。实际写的sheet是为了自动创建数百个具有不同值、字体粗细和水平对齐方式的表格。

我想做的事情:

  1. 选择选项“是”开始循环(循环的当前行也被跟踪并记录在“当前行”中,“状态”显示“正在处理...”)
  2. 程序将检查“SCORE”列,如果“SCORE”为空(“”),则该行的字体粗细设置为“粗体”,否则,字体粗细设置为“正常” “
  3. 如果循环直到最后一行,“STATUS”显示“完成”。

以下是Google应用程序脚本的副本:

let app = SpreadsheetApp;
let ss = app.getActiveSpreadsheet();
let activeSheet = ss.getActiveSheet();
let sheetName = activeSheet.getName();

let sheet1 = ss.getSheetByName("Sheet1");

let loopOptionRange = sheet1.getRange(4, 4);
let loopOption = loopOptionRange.getValue();
let loopStatusRange = sheet1.getRange(4, 7);

function onEdit(e) {
}

function onOpen() {
  loopOptionRange.setValue("Choose");
  sheet1.getRange(4, 5).setValue(5);
  loopStatusRange.setValue("");
}

function loopTest() {
  const startRow = 4; //table head
  const lastRow = sheet1.getLastRow();
  sheet1.getRange(4, 6).setValue(lastRow);
  const startRowLoop = startRow + 1; //first row of looping

  try {
    for (i = startRowLoop; i <= lastRow; i++) {
      const testStatus = sheet1.getRange(i, 3).getValue();
      sheet1.getRange(4, 5).setValue(i);

      if (testStatus == "") {
        sheet1.getRange(i, 1, 1, 2).setFontWeight("bold");
      } else {
        sheet1.getRange(i, 1, 1, 3).setFontWeight("normal");
      }
    }

    loopStatusRange.setValue("Done");
    loopOptionRange.setValue("Choose");

  } catch (error) {
    app.getUi().alert(`An error occured.`);
  }
}

if (sheetName === "Sheet1"){
  if (loopOption == "Yes") {
    loopStatusRange.setValue("Processing ...");
    loopTest();
  } else if (loopOption === "Cancel") {
      loopOptionRange.setValue("Choose");
  }
}

LOOP TEST - Google Sheets file

当我看到你的脚本时,getValuesetValuesetFontWeight是循环使用的。在这种情况下,工艺成本会变高。我认为这可能是您遇到问题的原因。为了降低你的脚本的进程开销,下面的修改怎么样?

发件人:

for (i = startRowLoop; i <= lastRow; i++) {
  const testStatus = sheet1.getRange(i, 3).getValue();
  sheet1.getRange(4, 5).setValue(i);

  if (testStatus == "") {
    sheet1.getRange(i, 1, 1, 2).setFontWeight("bold");
  } else {
    sheet1.getRange(i, 1, 1, 3).setFontWeight("normal");
  }
}

收件人:

const range = sheet1.getRange(startRow, 3, lastRow - startRowLoop);
const values = range.getDisplayValues().map(([c]) => [c ? null : "bold"]);
range.offset(0, -1).setFontWeights(values);

注:

  • 关于Is it really because of "the high process cost" you mentioned in your answer?,当我第一次看到你的脚本时,我认为你的问题的原因可能是由于流程成本。因为,当脚本被OnEdit触发时运行,最长执行时间为30秒。而且,当我测试你的脚本和你的电子表格时,当我在脚本停止后看到日志时,出现与最大执行时间结束相关的错误。据此,我得出您的问题的原因是脚本的处理成本。

参考文献: