2017-06-12 22 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) 


} 

私はそれが次のコードとアントンからのガイドラインを使用して作業しました。読み取りとプロセスは分離されています。私はwrite関数を分離しませんでした。なぜなら、これらの値は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()を呼び出すたびに、実行スタックの上にもう1つのブロックが追加されます。 SheetやRangeオブジェクトの変数を取得するなどのアクションは、一度しか実行してはいけません。

関数内でこれらのアクションを絞り込むと、コードが繰り返し、効率が悪く、非常に遅くなります。

最後に、読み取りと書き込みの操作を交互に行わないでください。代わりに、read-process-writeルーチンに従います。

1)すべてのサービスコールをonEdit()関数に移動します。これで、シート、範囲、ヘッダー変数などを作成する必要があります。イベントオブジェクトをパラメータとして別の関数に渡さないでください。必要なデータを取得し、それを使用してターゲット範囲を決定します。

2)autoUpdateFields()関数を変更して、range.setValue()によって消費される準備のできた値の2次元配列を返すようにします。サービスコールをすべて削除します。

3)if()またはswitch()演算子を使用して、関数に渡す必要のあるパラメータを特定します。そうしたら、一度呼び出すだけで十分です。

+0

ありがとう、私はそれが問題を解決するかどうかを知らせようとしています(おそらくそうです)。私は、読み取りプロセス書き込み構造については気づいていませんでした。これはそれについての論理的思考を聞いています。あなたが推薦するかもしれないプログラミング構造上の良いリソース? – Christoph

+0

実際、私はプログラミングに比較的新しいので、塩の塊で私の助言を取ってください:)アンソニー・アリスチアのUdemyに関するJavaScriptコースは、JSがどのように「フードの下で」動作するかを理解するために、 。コースは理論上重く、彼のプレゼンテーションは非常に遅く、意図的で、実際の作業をすばやく解決したい多くの人を悩ませるものです。テイク・ホームのメッセージはそれ以上の価値があります。参考までに、私は著者と何ら関係していません。 –

+0

また、この問題に対処するための最良の情報源の1つは、GoogleのGASベストプラクティス(https://developers.google.com/apps-script/guides/support/best-practices)です。彼らは読み書き操作がどのように実行されなければならないかを説明する良い仕事をします –

関連する問題