[英]Complex transpose exceeding run time in Google Apps Script
我在單列中接收數據,必須將其轉換為單獨的記錄。 一些記錄的長度為 12 個字符,其他的為 10 個,其余為 9 個。此外,10 個和 9 個字符長的記錄中的后 2 個值必須分別向右移動 1 個和 2 個字段。 給定記錄中的第一個值始終是日期。 我創建了以下代碼運行良好,除了它在大約 6 分鍾和 77 條記錄后超時。 我需要能夠處理 15 倍甚至更多。
我在每個 if 語句的 else 部分嵌入了日期對象的計算,並嵌套了后續的 if 語句,以減少不必要的計算。 這讓我從大約 48 條記錄增加到 77 條。
非常感謝任何聰明的見解🙂
function transposeNew(){
let ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
let lr = ss.getRange("A13").getDataRegion().getLastRow();
let sr = 13
// get the data column
let data = ss.getRange(sr,1,lr-sr,1).getValues();
// set up the rows loop
let pasteRow = 2;
let arrayField = 0;
while (arrayField < data.length){
//use the new Date() constructor to create a date object with the date value passed
let isDate12 = new Date(data[arrayField+12]).getFullYear(); //processed; size input;record should include 12 rows & 13th should be a date to begin the next row
if (isDate12 === 2020) {
let record = data.slice(arrayField, arrayField+12);
let recordTr = transposeSub(record);
ss.getRange(pasteRow, 5, 1, 12).setValues(recordTr);
arrayField = arrayField + 12;
}
else {
let isDate10 = new Date(data[arrayField+10]).getFullYear(); //unprocessed;size input
if (isDate10 === 2020) {
let record = data.slice(arrayField, arrayField+10);
let record1 = record.slice(0,8);
let record1Tr = transposeSub(record1);
let record2 = record.slice(8,10);
let record2Tr = transposeSub(record2);
ss.getRange(pasteRow, 5, 1, 8).setValues(record1Tr);
ss.getRange(pasteRow, 14, 1, 2).setValues(record2Tr);
arrayField = arrayField + 10;
}
else {
let isDate9 = new Date(data[arrayField+9]).getFullYear(); //unprocessed;no size
input
if (isDate9 === 2020) {
let record = data.slice(arrayField, arrayField+10);
let record1 = record.slice(0,7);
let record1Tr = transposeSub(record1);
let record2 = record.slice(7,9);
let record2Tr = transposeSub(record2);
ss.getRange(pasteRow, 5, 1, 7).setValues(record1Tr);
ss.getRange(pasteRow, 14, 1, 2).setValues(record2Tr);
arrayField = arrayField + 9;
}
}
}
pasteRow ++;
}
}
function transposeSub(a)
{
return Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
}
我看到您創建了一個循環,並在此while
語句中多次調用 SpreadsheetApp 函數。 這會創建與電子表格的連接,讀取/更改其數據並多次關閉連接,這就是您的代碼運行時間過長的原因。 請查看GAS 最佳實踐批處理操作部分。
你應該考慮放逐任何get/setValue()
內while
相反,調用getValues()
之前保持在JavaScript數組的所有值while
再使用setValues()
后while
在一次寫入所有輸出。 本答案探討了所描述的概念。
所以事實證明問題是循環標准中的一個缺陷; 菜鳥錯誤。 存在數據異常,以至於一條記錄不符合任何 if 語句中的標准,因此循環一直在繼續。 我通過在工作表上的每條記錄旁邊插入 pasteRow 和 arrayField 的值來發現這一點,以便我可以看到它在哪里中斷。 有趣的是,記錄停止了,但 pasteRow 和 arrayField 值在應用程序退出之前持續到了 20,000 秒。
我確實注意到@Bruno Polo 和@Cooper 提供的反饋是正確的。 發布后不久,我對其進行了修改,將記錄推送到一個新數組中,並在完成后粘貼該數組。 由於上述相同的原因,這失敗了。 我想現在我明白了這個問題,我會回到那個版本。
謝謝你和我一起看這個。 這是一個非凡的專家社區,我從中學到了很多! 😁
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.