如何为使用 appendRow 写入数据的多个复选框制作更好的 Google Sheets 循环脚本

How to make a better Google Sheets looping script for multiple checkboxes that write data using appendRow

我想看看是否有比我从其他 S.O 拼凑出来的更有效的编码选项。职位。我对 Sheets 编码非常缺乏经验,所以我确定我已经找到了效率最低的解决方案。我不太了解缓存的使用或其他实践。

我有一页数据搜索结果(下面称为 GammaPage),这些结果是根据用户搜索填充的。当用户找到他们想要合并到单独报告中的一行数据时,他们按下一个复选框,然后该复选框触发一个 onEdit(e) 命令,该命令将所选数据行(并且仅该行)附加到用于数据收集和处理的单独页面(下面的 EpsilonPage)。

什么有效:脚本 运行正确,在复选框提示时导出用户选择的数据。

令我疑惑的是:脚本需要很长时间才能运行(大约8秒)。我觉得在执行相同任务时必须有一种更有效的方法来编写它。需要说明的是,我并不是要全新的剧本。我只是问是否应该以某种方式重写我拥有的那个,以便更干净地循环。

为什么会这样:

代码(为清楚起见进行了压缩): 我在下面附加了函数,或者至少附加了它的前四个循环,以演示它是如何工作的。整个函数目前 341 行长 。我觉得我好像错过了一个明显的通配符。

function onEdit(e) {
if (e.source.getActiveSheet().getName() != 'AlphaSheet' && != 'BetaSheet' && e.source.getActiveSheet().getName() != 'EpsilonSheet') {
  var spreadsheet = SpreadsheetApp.getActive();
  var rr = e.range;
  var ss = e.range.getSheet();
  var headerRows = 5;  // # header rows to ignore
  if (rr.getRow() <= headerRows) return;
  var checkBoxLocation6 = "A6";
  const values6 = spreadsheet.getRange('GammaSheet!B6:D6').getValues().flat();
  var checkBoxLocation7 = "A7";
  const values7 = spreadsheet.getRange('GammaSheet!B7:D7').getValues().flat();
  var checkBoxLocation8 = "A8";
  const values8 = spreadsheet.getRange('GammaSheet!B8:D8').getValues().flat();
  var checkBoxLocation9 = "A9";
  const values9 = spreadsheet.getRange('GammaSheet!B9:D9').getValues().flat();
  var checkBoxCondition = true;
  var result = SpreadsheetApp.getUi().alert("Do you wish to extract this data?", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('GammaSheet'), true);
  if (e.range.getA1Notation() == checkBoxLocation6) {
    if (e.range.getValue() == checkBoxCondition) {
    if(result === SpreadsheetApp.getUi().Button.OK) {
    spreadsheet.getSheetByName('EpsilonSheet').appendRow(values6);
    SpreadsheetApp.getActive().toast("Request initiated.");
    spreadsheet.getRange('B3').clearContent();
    } else {
    SpreadsheetApp.getActive().toast("Request canceled.");}
    spreadsheet.getRange('A6').setValue('FALSE');}}
  if (e.range.getA1Notation() == checkBoxLocation7) {
    if (e.range.getValue() == checkBoxCondition) {
    if(result === SpreadsheetApp.getUi().Button.OK) {
    spreadsheet.getSheetByName('EpsilonSheet').appendRow(values7);
    SpreadsheetApp.getActive().toast("Request initiated.");
    spreadsheet.getRange('B3').clearContent();
    } else {
    SpreadsheetApp.getActive().toast("Request canceled.");}
    spreadsheet.getRange('A7').setValue('FALSE');}}
  if (e.range.getA1Notation() == checkBoxLocation8) {
    if (e.range.getValue() == checkBoxCondition) {
    if(result === SpreadsheetApp.getUi().Button.OK) {
    spreadsheet.getSheetByName('EpsilonSheet').appendRow(values8);
    SpreadsheetApp.getActive().toast("Request initiated.");
    spreadsheet.getRange('B3').clearContent();
    } else {
    SpreadsheetApp.getActive().toast("Request canceled.");}
    spreadsheet.getRange('A8').setValue('FALSE');}}
  if (e.range.getA1Notation() == checkBoxLocation9) {
    if (e.range.getValue() == checkBoxCondition) {
    if(result === SpreadsheetApp.getUi().Button.OK) {
    spreadsheet.getSheetByName('EpsilonSheet').appendRow(values9);
    SpreadsheetApp.getActive().toast("Request initiated.");
    spreadsheet.getRange('B3').clearContent();
    } else {
    SpreadsheetApp.getActive().toast("Request canceled.");}
    spreadsheet.getRange('A9').setValue('FALSE');}}
}};

以此类推另外26个循环

截图供参考:

那么,考虑到我想要它做的事情,我的编码可以不那么笨拙吗?还是说它已经很好了?

抱歉,实在是忍不住想把314行改成25行(无注释)。那么,我们开始吧:

function onEdit(e) {
  // check if it's first column
  if (e.range.columnStart != 1) return;

  // check if checkbox is true
  if (e.value != 'TRUE') return;

  // check if the sheet is the right sheet
  var sheet = SpreadsheetApp.getActive();
  var ignored_sheets = ['BetaSheet', 'EpsilonSheet', 'Imported master list'];
  if (ignored_sheets.includes(sheet.getName())) return;

  // get data from current row
  var row_index = e.range.rowStart;
  var row = sheet.getRange('B' + row_index + ':D' + row_index).getDisplayValues().flat();
 
  // check if cell 'C' of current row is not empty, just to be sure
  if (row[1] == '') return; 
  
  // show the prompt message
  var result = SpreadsheetApp.getUi()
    .alert("Do you wish to request this student?", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
  if (result != SpreadsheetApp.getUi().Button.OK) {
    sheet.toast("Request canceled.");
    return;
  }

  // do stuff
  sheet.toast("Request initiated.");
  sheet.getActiveCell().setValue(false);
  sheet.getRange('B3').clearContent();
  sheet.getSheetByName('EpsilonSheet').appendRow(row);
}