2017-06-12 63 views
0

我收到的消息超过最大执行时间,并且无法解决它。执行失败:超出最大执行时间

如果我忽略它检查单元格是否为空的部分,以及它是否为修改日期列而不是它的工作。

任何想法如何解决这个问题?

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


} 

回答

0

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

在一个函数内部挤压这些动作会让你的代码重复,效率低下并且非常慢。

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

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

2)修改你的autoUpdateFields()函数,使它返回一个准备被range.setValue()使用的二维数组值。删除任何服务电话。

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

+0

谢谢,我试着它会让你知道它是否修复了这个问题(它可能会)。我不知道读取过程写入结构。这听起来很合逻辑。你可能会推荐任何有关编程结构的优秀资源? – Christoph

+0

实际上,我对编程相对来说比较陌生,所以我的建议是用一点盐:)这就是说,Anthony Alicea关于Udemy的JavaScript课程对于让我理解JS如何在“引擎盖下”工作非常有帮助, 。需要注意的是,这门课程在理论上是头重脚轻的,而且他的介绍非常缓慢而且刻意,这让很多想要快速解决实际任务的人感到烦恼。回家的信息不仅值得。仅供参考,我不以任何方式隶属于作者。 –

+0

此外,处理此问题的最佳来源之一是Google自己的GAS https://developers.google.com/apps-script/guides/support/best-practices最佳做法。他们在解释如何执行读写操作方面做得很好 –