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是如何“在幕后”工作的。值得一提的是,这门课的理论性很强,而且他的演讲非常缓慢和深思熟虑,这让许多想快速解决实际问题的人感到恼火。然而,带回家的信息是非常值得的。仅供参考,我与作者没有任何关系。另外,处理这个问题的最佳来源之一是谷歌自己的天然气最佳实践。他们在解释如何执行读写操作方面做得很好。感谢您的跟进,将其添加到书签中,我相信这将在将来有所帮助。我一直在为表现而挣扎。