执行失败:超过最长执行时间

时间:2017-06-12 11:40:57

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

我收到的消息超过了最长执行时间,并且无法修复它。

如果我遗漏了检查单元格是否为空的部分以及修改后的日期列是否有效。

知道如何解决这个问题吗?

function autoUpdateFields(triggerField, valueField, updateValue, event) {
  var timezone = "GMT+1";
  var timestamp_format = "dd-MM-yyyy HH:mm:ss"; // Timestamp Format. 
  var sheet = event.source.getSheetByName('data'); //Name of the sheet where you want to run this script.


  var sheet = event.source.getSheetByName('data');

  var actRng = event.source.getActiveRange();
  var editColumn = actRng.getColumn();
  var index = actRng.getRowIndex();
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();

  var valueCol = headers[0].indexOf(valueField);
  var triggerCol = headers[0].indexOf(triggerField); triggerCol = triggerCol+1;

  if (valueCol > -1 && index > 1 && editColumn == triggerCol) { 
    var cell = sheet.getRange(index, valueCol + 1);
    updateValue = updateValue.replace(/%/g,index);
    var date = Utilities.formatDate(new Date(), timezone, timestamp_format);

    // do not overwrite CreatedDt

    var checkIfModifiedDt = headers[0][headers[0].indexOf(valueField)] == 'ModifiedDt';
    var checkIfCellEmpty = cell.getValue() == '';

    Logger.log(checkIfModifiedDt);
    Logger.log(checkIfCellEmpty);
    Logger.log(updateValue);

    // only update when cell is empty
    if (updateValue == 'timestamp' && checkIfCellEmpty) {
      cell.setValue(date)
    }

    if (updateValue != 'timestamp' && checkIfCellEmpty){
      cell.setFormula(updateValue);
    };

    if (checkIfModifiedDt && !checkIfCellEmpty) {
      cell.setValue(date)
    }

  }
}

function onEdit(event)
{ 
  autoUpdateFields('Task', 'DueDt', '=TODAY()', event)
  autoUpdateFields('Task', 'Dleft', '=A%-TODAY()', event)
  autoUpdateFields('Task', 'Priority', '=(if(isblank(F%);5;if(F%=0;1;F22))+if(isblank(E%);5;if(E%=0;1;E%)))*if(B%=0;1;B%+1)', event)
  autoUpdateFields('Task', 'CreatedDt', 'timestamp', event)
  autoUpdateFields('Task', 'ModifiedDt', 'timestamp', event)
  autoUpdateFields('Status', 'CompletedDt', 'timestamp', event)


}

我使用Anton的以下代码和指南来完成它。读取和处理是隔离的。我没有隔离写入过程,因为它只使用if函数设置这些值一次。

如果有额外的修改可以帮助我,请告诉我。

function autoUpdateFields(params, triggerField, valueField, updateValue) {

  var valueCol = params.headers[0].indexOf(valueField);
  var triggerCol = params.headers[0].indexOf(triggerField); triggerCol = triggerCol+1;

  if (valueCol > -1 && params.index > 1 && params.editColumn == triggerCol) { 
    var cell = params.sheet.getRange(params.index, valueCol + 1);
    updateValue = updateValue.replace(/%/g,params.index);

    // do not overwrite CreatedDt

    var checkIfModifiedDt = params.headers[0][params.headers[0].indexOf(valueField)] == 'ModifiedDt';
    var checkIfCellEmpty = cell.getValue() == '';


    // only update when field is empty unless ModfiedDt
    if (checkIfCellEmpty && updateValue == 'timestamp') {
      cell.setValue(params.date)
    }

    if (checkIfCellEmpty && updateValue != 'timestamp') {
      cell.setFormula(updateValue);
    };

    if (!checkIfCellEmpty && checkIfModifiedDt) {
      cell.setValue(params.date)
    }

  }
}

function onEdit(event)
{ 

  var timezone = "GMT+1";
  var timestamp_format = "dd-MM-yyyy HH:mm:ss"; // Timestamp Format. 
  var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
  var sheet = event.source.getSheetByName('data'); //Name of the sheet where you want to run this script.
  var actRng = event.source.getActiveRange();
  var editColumn = actRng.getColumn();
  var index = actRng.getRowIndex();
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();

  var params = { 'timezone': timezone, 'timestamp_format': timestamp_format, 'date': date, 'sheet': sheet, 'actRng': actRng, 'editColumn': editColumn, 'index': index, 'headers': headers };

  autoUpdateFields(params, 'Task', 'DueDt', '=TODAY()')
  autoUpdateFields(params, 'Task', 'Dleft', '=A%-TODAY()')
  autoUpdateFields(params, 'Task', 'Priority', '=(if(isblank(F%);5;if(F%=0;1;F22))+if(isblank(E%);5;if(E%=0;1;E%)))*if(B%=0;1;B%+1)')
  autoUpdateFields(params, 'Task', 'CreatedDt', 'timestamp')
  autoUpdateFields(params, 'Task', 'ModifiedDt', 'timestamp')
  autoUpdateFields(params, 'Status', 'CompletedDt', 'timestamp')


}

1 个答案:

答案 0 :(得分:0)

问题源于同时调用太多服务。每次调用autoUpdateFields()都会在执行堆栈之上再添加一个块。某些操作(例如获取Sheet和Range对象的变量)应该只执行一次。

在函数内部挤压这些操作会使代码重复,效率低下且非常慢。

最后,不要在读写操作之间交替。相反,请遵循read-process-write例程。

1)将所有服务调用移至onEdit()函数。您应该在哪里创建工作表,范围,标题变量等。不要将事件对象作为参数传递给另一个函数。从中获取所需数据并使用它来确定目标范围。

2)修改你的autoUpdateFields()函数,使它返回一个准备好被range.setValue()使用的2d值数组。从中删除所有服务电话。

3)使用if()或switch()运算符来确定必须将哪些参数传递给函数。如果你这样做,那么召唤一次就足够了。