【问题标题】:Speeding up an onEdit() function in Google Apps Script [duplicate]在 Google Apps 脚本中加速 onEdit() 函数 [重复]
【发布时间】:2020-12-25 03:23:21
【问题描述】:

我们正在管理来自多个工作表(29 个不同位置中的每个工作表)的所有更改,以反映在一个 main_db 中。然后将 main_db 连接到 Data Studio for Analytics。

我们为所做的更改实施了“updates_to_db”记录表,然后每 10 分钟运行一次触发服务,在 main_db 中实际获取和设置数据。

当 getLastRow() 为连续快速触发的 onEdit() 返回相同的值时,我遇到了 onEdit() 函数相互写入数据的问题。我已经实现了一个 PropertyKey 来保存这个值。 onEdit() 首先更新这个值,然后继续。这样所有后续的 onEdits() 都会正确写入更新的 lastRow。

onOpen() 函数 这会准确设置更新记录表中实际最后一行的 PropertyKey 值。

function onOpen() {
  
  // Welcome message
  var message = 'The current time is ' + new Date().toString();
  var title = 'Welcome to xxxxxx DASHBOARD';
  SpreadsheetApp.getActiveSpreadsheet().toast(message, title);

  var last_row = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(push_to_db_sheet).getLastRow();
  PropertiesService.getScriptProperties().setProperty('last_row_updates_sheet', last_row + 1);

}

onEdit() 函数

function onEdit(e){

  var activeSheet = e.source.getActiveSheet();
  var date_stamp = new Date();
  var tabs = ["Customer Requests","Indent Status","Tracking Acknowledgements","Actual Costs","Balance Payments","Payment Updates"];
  
  if(tabs.indexOf(activeSheet.getName()) !== -1){

    var row_to_edit = PropertiesService.getScriptProperties().getProperty('last_row_updates_sheet');
    row_to_edit= +row_to_edit; // converting string to int
    PropertiesService.getScriptProperties().setProperty('last_row_updates_sheet', row_to_edit + 1);

    var cell = e.range;
    var col = cell.getColumn();
    var changes_sheet = e.source.getSheetByName(push_to_db_sheet);
  //  var last_row = changes_sheet.getLastRow() + 1;
    
    changes_sheet.getRange(row_to_edit, 1).setValue(date_stamp);
    changes_sheet.getRange(row_to_edit, 2).setValue(activeSheet.getName());
    changes_sheet.getRange(row_to_edit, 3).setValue(activeSheet.getRange(cell.getRow(),3,1,1).getValue());
    changes_sheet.getRange(row_to_edit, 4).setValue(cell.getColumn())
    changes_sheet.getRange(row_to_edit, 5).setValue(e.value);
      
    cell.setNote('Last modified: ' + date_stamp); // helps the user know when the last edit was made
    cell.setBackground("#FBF7EC"); // helps the user visually see when the update has been captured. I can move this up to make it "seem" faster...
  } // IF tab name matches

}

关于如何加快 onEdit() 的任何想法?目前运行需要 4 - 13 秒。最终,我将根据已编辑的特定单元格调用电子邮件和 SMS 触发功能。我想要一个显示电子邮件/短信的弹出窗口,然后确认按钮将触发电子邮件/短信。

我担心在显示电子邮件/短信弹出对话框时,如果 onEdit() 时间长,用户会领先几列。

【问题讨论】:

  • 我有什么理由不应该将其作为stackoverflow.com/a/29800759stackoverflow.com/a/57836700 的副本关闭?
  • @TheMaster 感谢您提供参考链接。一旦我完成了整个功能改进,包括电子邮件/短信对话触发器,我会回到这里并发布我实际有效的改进方法,以及一些性能结果。
  • 我正在关闭它。如果您想添加通用答案,您可以将其添加到上面链接的任何重复问题中,这样就会有一个数据线程而不是拆分数据。或者,如果您想要一个特定的答案,您可以编辑您现有的答案。还阅读了 DRY 原则。避免重复整个全局调用:PropertiesService.getScriptProperties()activeSheet.getName() .. 最好将它们存储在一个变量中。
  • 好的 - 明白了!这是我在网站上的第一个 Q,感谢您向我展示了绳索!下次@TheMaster 会记住这一点

标签: javascript performance google-apps-script google-sheets triggers


【解决方案1】:

我已经更新了这个读/写列表:

changes_sheet.getRange(row_to_edit, 1).setValue(date_stamp);
    changes_sheet.getRange(row_to_edit, 2).setValue(activeSheet.getName());
    changes_sheet.getRange(row_to_edit, 3).setValue(activeSheet.getRange(cell.getRow(),3,1,1).getValue());
    changes_sheet.getRange(row_to_edit, 4).setValue(cell.getColumn())
    changes_sheet.getRange(row_to_edit, 5).setValue(e.value);

到这里:

    changes_sheet.getRange(row_to_edit, 1, 1, 5).setValues([[date_stamp , activeSheet.getName() , activeSheet.getRange(cell.getRow(),3,1,1).getValue() , cell.getColumn() , e.value]]);

注意事项:

  • setValues() 需要一个二维数组。当像我一样设置数据时,请确保将数据包含在适当的 [] 括号中以实现此目的。
  • 之前的方法平均 onEdit 完成时间为 7.6988 秒
  • 更新后的方法平均 onEdit 完成时间为 3.6741 秒 -> 减少 52%

对于 onEdit() 函数来说,这是一个合理的执行时间吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多