2017-06-12 90 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最佳做法。他們在解釋如何執行讀寫操作方面做得很好 –