Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 执行失败:超过了最大执行时间_Javascript_Google Apps Script_Google Sheets - Fatal编程技术网

Javascript 执行失败:超过了最大执行时间

Javascript 执行失败:超过了最大执行时间,javascript,google-apps-script,google-sheets,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. va

我收到的消息超过了最大执行时间,不知道如何修复它

如果我省略了检查单元格是否为空以及是否是修改的日期列的部分,那么它就工作了

你知道怎么解决这个问题吗

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')


}

问题源于同时调用过多的服务。对autoUpdateFields()的每次调用都会在执行堆栈的顶部再添加一个块。某些操作,例如获取工作表和范围对象的变量,应该只执行一次

将这些操作压缩到函数中会使代码重复、效率低下且非常缓慢

最后,不要在读操作和写操作之间交替。相反,请遵循读取过程写入例程

1) 将所有服务调用移动到onEdit()函数。这是您应该创建工作表、范围、标题变量等的地方。不要将事件对象作为参数传递给其他函数。从中获取所需数据,并用于确定目标范围

2) 修改autoUpdateFields()函数,使其返回一个2d值数组,该数组可供range.setValue()使用。从中删除任何服务调用


3) 使用if()或switch()运算符可以确定必须传递给函数的参数。如果您这样做了,只需打一次电话就足够了。

谢谢,我正在尝试它,它会让您知道它是否解决了问题(可能会)。我不知道读进程写结构。这听起来确实合乎逻辑。你能推荐一些关于编程结构的好资源吗?事实上,我对编程还比较陌生,所以请恕我直言:)也就是说,Anthony Alicea关于Udemy的JavaScript课程非常有助于我理解JS是如何“在幕后”工作的。值得一提的是,这门课的理论性很强,而且他的演讲非常缓慢和深思熟虑,这让许多想快速解决实际问题的人感到恼火。然而,带回家的信息是非常值得的。仅供参考,我与作者没有任何关系。另外,处理这个问题的最佳来源之一是谷歌自己的天然气最佳实践。他们在解释如何执行读写操作方面做得很好。感谢您的跟进,将其添加到书签中,我相信这将在将来有所帮助。我一直在为表现而挣扎。