脚本非常慢。确保每行只选中一个复选框

Script is very slow. Making sure only one checkbox is selected per row

提问人:DetroitJimBurke 提问时间:12/23/2022 最后编辑:RubénDetroitJimBurke 更新时间:12/25/2022 访问量:75

问:

我有一个谷歌工作表工作簿,里面有四张带有调查表的工作表。每个调查每行都有一个问题,可以选择两到四个选项。每个选项都有相应的复选框。我需要确保如果用户更改了连续中的选择,则之前选中的复选框未选中。这工作正常,但取消选中旧选择的速度很慢。在它最快的时候,需要几秒钟,但有时可能需要 7 或 8 秒。在我看来,这应该只需要几分之一秒,没有做太多事情。也许我走错了路。

这是我的 onEdit 函数和它调用的函数之一。所有被调用的函数基本上都是相同的,只是行数不同,就速度而言,它们的行为都大致相同。

function onEdit(e) {
   
  // get event object data: sheet name, row number and column number
  const sheet = e.range.getSheet();
  const row = e.range.rowStart;
  const col = e.range.columnStart;
  const currentsheet = sheet.getSheetName()
   
  switch(currentsheet) {
    case "Adaptive Behavior":
      onEditADaptive(sheet, row, col)
    case "Social Communication":
      onEditSocComm(sheet, row, col)
    case "Behavior 6-18":
      onEditBehavior618(sheet, row, col)
    case "BRIEF-2 Parent Report":
      onEditBRIEF2(sheet, row, col)

  }
}



function onEditBehavior618(mySheet, myRow, myCol) {
  
  switch(myCol) {
    
        // case when column C is checked   C-E-G
        case 3:
          mySheet.getRangeList(["E" + myRow,"G" + myRow]).uncheck();
          break;
    
        // case when column E is checked
        case 5:
          mySheet.getRangeList(["C" + myRow,"G" + myRow]).uncheck();
          break;
    
        // case when column G is checked
        case 7:
          mySheet.getRangeList(["C" + myRow,"E" + myRow]).uncheck();
          break;
        
        // cell is outside of columns C, E or G
        default:
          return;
    
      }
}

这是我通过搜索找到的技术,除了速度慢之外,它工作正常。

google-apps-script google-sheets 复选框 触发器

评论

0赞 Waxim Corp 12/24/2022
我对编辑的看法很慢,你不能做太多事情来优化它......您可能应该使用 Web App developers.google.com/apps-script/guides/web
0赞 DetroitJimBurke 12/24/2022
不确定这是否适用于我想要完成的任务。在尝试走这条路之前,我会尽我所能先上班,但感谢您的提示。

答:

0赞 TheWizEd 12/23/2022 #1

尝试更改代码的这一部分

var timer = null;
switch(currentsheet) {
  case "Adaptive Behavior":
    timer = new Timer("onEditADaptive")
    onEditADaptive(sheet, row, col);
    timer.stop();
    break;
  case "Social Communication":
    timer = new Timer("onEditSocComm")
    onEditSocComm(sheet, row, col);
    timer.stop();
    break;
  case "Behavior 6-18":
    timer = new Timer("onEditBehavior618")
    onEditBehavior618(sheet, row, col);
    timer.stop();
    break;
  case "BRIEF-2 Parent Report":
    timer = new Timer("onEditBRIEF2")
    onEditBRIEF2(sheet, row, col);
    timer.stop();
    break;
 }

将计时器添加到您的 Code.gs

class Timer {
  constructor(label) {
    if( label === undefined ) label = "Timer";
    this.label = label;
    this.start = new Date();
  }
  stop() {
    let end = new Date();
    end = (end.valueOf()-this.start.valueOf())/1000;
    Logger.log(this.label+": elapsed time: "+end.toFixed(3)+" sec" );
  }
}

以下是查看 onEdit 执行日志的示例

function onEdit(e) {
  try {
    Logger.log("Hello from onEdit");
  }
  catch(err) {
    SpreadsheetApp.getActiveSpreadsheet().toast(err);
  }
}

我只需编辑一个单元格,然后从脚本编辑器转到左侧的执行

enter image description here

评论

0赞 DetroitJimBurke 12/23/2022
我将如何改变它以使其更有效率?每个工作表都必须以不同的方式处理,因为它们都有不同数量的复选框和/或它们的复选框位于不同的列中。我做这件事的方式是什么让它变慢了速度,什么会让它更快?
0赞 TheWizEd 12/23/2022
在声明中,如果您在相关案例之后没有休息,它将执行下一个案例。例如,如果工作表是“自适应行为”,它将执行,后跟switch caseonEditADaptiveonEditSocCommonEditBehavior618onEditBRIEF2
0赞 DetroitJimBurke 12/23/2022
我想我错过了一些东西——在每一个之后我都会休息一下。
0赞 DetroitJimBurke 12/23/2022
哎呀 - 我没有意识到你在那里添加了这些,我的错误。谢谢。
0赞 DetroitJimBurke 12/23/2022
正如您所示,我在每种情况之后都添加了中断,但仍然很慢。