Скрипт Google Apps с медленным архивированием - PullRequest
0 голосов
/ 06 мая 2020

Я работаю над отчетом по отслеживанию финансов, завершаю вводную часть и работаю нормально. Проблема в том, что он работает очень медленно, так как в большинстве случаев идет построчно. Помимо того, что это много кода, я не могу понять, как его ускорить или объединить что-нибудь вместе. Кроме того, фигурные скобки для начала и конца рассматриваемой функции не связаны (они обе окрашены в красный цвет, когда курсор находится рядом с ними), что я не могу понять. Может ли кто-нибудь помочь немного очистить мой код, чтобы ускорить это? Вот рассматриваемая функция:

function onClickSubmit(e) {
  var wkbk = SpreadsheetApp.getActiveSpreadsheet();
  var ss = wkbk.getSheetByName("Entry");

  //Bank Details Move
    var bankDeposit = ss.getRange(3,9).getValue();
    var bankWithdrawal = ss.getRange(3,10).getValue();
    var bankDate = ss.getRange(3,12).getValue();
    var targetSheet = wkbk.getSheetByName("BANK DS");
  if(bankDate != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var bankAmt = (bankDeposit - bankWithdrawal);
    var bankDetail = [[bankDate, bankAmt]];
    targetSheet.getRange(targetRow,1,1,2).setValues(bankDetail);
    targetSheet.getRange(targetRow-1,3).copyTo(targetSheet.getRange(targetRow,3));
    ss.getRange(3,9,1,4).clearContent();
  }
  //Work Chits Move
    var work1Hours = ss.getRange(5,9).getValue();
    var work1Job = ss.getRange(5,10).getValue();
    var work1Rate = ss.getRange(5,11).getValue();
    var work1Date = ss.getRange(5,12).getValue();
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work1Date != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var work1Detail = [[work1Date,work1Job,work1Hours,work1Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work1Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(5,9,1,4).clearContent();
  }
  var work2Hours = ss.getRange(6,9).getValue();
    var work2Job = ss.getRange(6,10).getValue();
    var work2Rate = ss.getRange(6,11).getValue();
    var work2Date = ss.getRange(6,12).getValue();
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work2Date != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var work2Detail = [[work2Date,work2Job,work2Hours,work2Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work2Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(6,9,1,4).clearContent();
  }
    var work3Hours = ss.getRange(7,9).getValue();
    var work3Job = ss.getRange(7,10).getValue();
    var work3Rate = ss.getRange(7,11).getValue();
    var work3Date = ss.getRange(7,12).getValue();
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work3Date != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var work3Detail = [[work3Date,work3Job,work3Hours,work3Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work3Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(7,9,1,4).clearContent();
  }

  //Receipts Move
  var i = 9
  var reDate = ss.getRange(i,12).getValue()
  var targetSheet = wkbk.getSheetByName("RECEIPTS DS");
  if (reDate !=""){
  while (reDate !="") {
    var reAmt = ss.getRange(i,9).getValue();
    var rePlace = ss.getRange(i,10).getValue();
    var reCat = ss.getRange(i,11).getValue();
    var reDate = ss.getRange(i,12).getValue();
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var reDetail = [[reDate,rePlace,reCat,reAmt]];
    targetSheet.getRange(targetRow,1,1,4).setValues(reDetail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(i,9,1,4).clearContent();
    i++
  }
  }

  //Safe Move 3, 9, 13 (dates) 3-8, 9-12, 13-18
    var safeDate = ss.getRange(3,6).getValue();
    var targetSheet = wkbk.getSheetByName("SAFE DS");
  for (var i=3;i<9;i++){  
    var safeIn = ss.getRange(i,2).getValue();
    var safeOut = ss.getRange(i,4).getValue();
    var safeCnt = (safeIn - safeOut);
    var safeType = ss.getRange(i,3).getValue();

  if(safeCnt != 0){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();

    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
//    targetSheet.getRange(targetRow-1,3).copyTo(targetSheet.getRange(targetRow,3));
    ss.getRange(i,2).clearContent();
    ss.getRange(i,4).clearContent();
  }
}
    ss.getRange(3,6).clearContent();
  //Safe Move 9 (rolls) 3-8, 9-12, 13-18
    var safeDate = ss.getRange(9,6).getValue();
    var targetSheet = wkbk.getSheetByName("SAFE DS");
  for (var i=9;i<13;i++){  
    var safeIn = ss.getRange(i,2).getValue();
    var safeOut = ss.getRange(i,4).getValue();
    var safeCnt = (safeIn - safeOut);
    var safeType = ss.getRange(i,3).getValue();

  if(safeCnt != 0){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();

    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    ss.getRange(i,2).clearContent();
    ss.getRange(i,4).clearContent();
  }
}
    ss.getRange(9,6).clearContent();
  //Safe Move (loose) 13-18
    var safeDate = ss.getRange(13,6).getValue();
    var targetSheet = wkbk.getSheetByName("SAFE DS");
  for (var i=13;i<19;i++){  
    var safeIn = ss.getRange(i,2).getValue();
    var safeOut = ss.getRange(i,4).getValue();
    var safeCnt = (safeIn - safeOut);
    var safeType = ss.getRange(i,3).getValue();

  if(safeCnt != 0){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();

    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    ss.getRange(i,2).clearContent();
    ss.getRange(i,4).clearContent();
  }
}
    ss.getRange(13,6).clearContent();
}

Вот копия таблицы, чтобы вы могли увидеть, как она работает: https://docs.google.com/spreadsheets/d/1Ij7DPqQnVAR9cCpqZRf6QFUIKfgrvLvj-y5gyUPKJMw/edit?usp=sharing

Заранее спасибо!

ОБНОВЛЕНИЕ Я принял более подробный из двух ответов, но оба предложили отличное понимание. Хотя этот ответ содержит наиболее полезную информацию, другой ответ также добавил много. Для всех, кого это интересует, я использовал множество этих правок, а также работал над удалением вызовов методов SpreadsheetApp, вызывая их вне циклов / тестов if, а затем создавая массивы результатов. Комбинация этих двух ответов ускорила код примерно на 400%, поэтому спасибо вам обоим!

Чтобы еще больше помочь всем, кто заинтересован в ускорении кода Google Script, вот моя измененная функция. Примечание. Мне пришлось сохранить в одном экземпляре «A1: A» vs. getLastRow (), потому что в этом конкретном целевом листе есть несколько столбцов с информацией, которую нужно игнорировать:

function onClickSubmit(e) {
  var wkbk = SpreadsheetApp.getActiveSpreadsheet();
  var ss = wkbk.getSheetByName("Entry");

  //Bank Details Move
    var t=ss.getRange(3,9,1,4).getValues()[0];
    var bankDeposit = t[0];
    var bankWithdrawal = t[1];
    var bankDate = t[3];
    var targetSheet = wkbk.getSheetByName("BANK DS");
  if(bankDate != ""){
    var targetRow = targetSheet.getRange(1,1,targetSheet.getLastRow()).getValues().length + 1;
    var bankAmt = (bankDeposit - bankWithdrawal);
    var bankDetail = [[bankDate, bankAmt]];
    targetSheet.getRange(targetRow,1,1,2).setValues(bankDetail);
    targetSheet.getRange(targetRow-1,3).copyTo(targetSheet.getRange(targetRow,3));
    ss.getRange(3,9,1,4).clearContent();
  }
  //Work Chits Move
    var vals=ss.getRange(5,9,3,4).getValues();
    var work1Hours = vals[0][0];
    var work1Job = vals[0][1];
    var work1Rate = vals[0][2];
    var work1Date = vals[0][3];
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work1Date != ""){
    var targetRow = targetSheet.getRange(1,1,targetSheet.getLastRow()).getValues().length +1;
    var work1Detail = [[work1Date,work1Job,work1Hours,work1Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work1Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(5,9,1,4).clearContent();
    targetRow = targetRow + 1;
  }
    var work2Hours = vals[1][0];
    var work2Job = vals[1][1];
    var work2Rate = vals[1][2];
    var work2Date = vals[1][3];
  if(work2Date != ""){
    var work2Detail = [[work2Date,work2Job,work2Hours,work2Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work2Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(6,9,1,4).clearContent();
    targetRow = targetRow + 1;
  }
    var work3Hours = vals[2][0];
    var work3Job = vals[2][1];
    var work3Rate = vals[2][2];
    var work3Date = vals[2][3];
  if(work3Date != ""){
    var work3Detail = [[work3Date,work3Job,work3Hours,work3Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work3Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(7,9,1,4).clearContent();
    targetRow = targetRow + 1
  }

  //Receipts Move
  var i = 0
  var targetSheet = wkbk.getSheetByName("RECEIPTS DS");
  var reDetail = [];
  var reVals=ss.getRange(9,9,20,4).getValues();
  var reDate = reVals[0,3]
  var targetRow = targetSheet.getRange(1,1,targetSheet.getLastRow()).getValues().length + 1;
  if (reDate !=""){
  while (reVals[i][3] !="") {
    var reAmt = reVals[i][0];
    var rePlace = reVals[i][1];
    var reCat = reVals[i][2];
    var reDate = reVals[i][3];
    var reDetailNew = [[reDate, rePlace, reCat, reAmt]];
    var reDetail = reDetail.concat(reDetailNew);
    i=i+1
  }
    targetSheet.getRange(targetRow,1,i,4).setValues(reDetail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,i,3));
    ss.getRange(9,9,i+1,4).clearContent();


  //Safe Move (bills)

    var targetSheet = wkbk.getSheetByName("SAFE DS");
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var safeVals = ss.getRange(3,2,16,5).getValues();
    var safeDate = safeVals[0][4];
  for (var i=0;i<6;i++){
    var safeIn = safeVals[i][0];
    var safeOut = safeVals[i][2];
    var safeCnt = (safeIn - safeOut);
    var safeType = safeVals[i][1];

  if(safeCnt != 0){    
    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    targetRow = targetRow + 1;
  }
}
  //Safe Move (rolls)
    var safeDate = safeVals[6][4];
  for (var i=6;i<10;i++){  
    var safeIn = safeVals[i][0];
    var safeOut = safeVals[i][2];
    var safeCnt = (safeIn - safeOut);
    var safeType = safeVals[i][1];

  if(safeCnt != 0){
    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    targetRow = targetRow + 1;
  }
}
  //Safe Move (loose)
    var safeDate = safeVals[10][4];
  for (var i=10;i<16;i++){  
    var safeIn = safeVals[i][0];
    var safeOut = safeVals[i][2];
    var safeCnt = (safeIn - safeOut);
    var safeType = safeVals[i][1];

  if(safeCnt != 0){
    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    targetRow = targetRow + 1;
  }
}
    ss.getRange(3,2,16,1).clearContent();
    ss.getRange(3,4,16,1).clearContent();
    ss.getRange(3,6,16,1).clearContent();
}
}

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Ваш сценарий медленный, потому что он делает много вызовов методов SpreadsheetApp. Чтобы улучшить его производительность, вы должны изменить logi c, чтобы уменьшить количество этих вызовов и использовать массивы для управления данными.

IE вместо использования нескольких getValue() используйте только один getValues(), вы даже можете использовать getDatatRange(), чтобы получить «диапазон данных» (диапазон, охватывающий все ячейки, содержащие данные, включая пустую ячейку между ними ) листа, затем используйте getValues(), чтобы получить все значения листа.

Как правило, избегайте использования методов SpreadsheetApp внутри циклов (for, while, et c)

1 голос
/ 06 мая 2020

Вот несколько предложений:

Я помещаю свои предложения в виде комментариев под вашим кодом.

Как правило, избегайте использования getValue (), используйте getValues ​​() вместо этого, он возвращает 2D-массив данных . Прочтите документацию, а также просмотрите возвращаемые значения в отладчике, чтобы действительно понять, как выглядят ваши данные: [[row0], [row1], [row2] ....]

и избегайте использование обозначений A1 вида A1: A. Вместо этого используйте Sheet.getRange (1,1, Sheet.getLastRow () ....

function onClickSubmit(e) {
  var wkbk = SpreadsheetApp.getActiveSpreadsheet();
  var ss = wkbk.getSheetByName("Entry");
  //Bank Details Move
    var bankDeposit = ss.getRange(3,9).getValue();
    var bankWithdrawal = ss.getRange(3,10).getValue();
    var bankDate = ss.getRange(3,12).getValue();
    var targetSheet = wkbk.getSheetByName("BANK DS");
    //var t=ss.getRange(3,9,1,4).getValues()[0];
    //var bankDeposit = t[0];
    //var bankWithdrawal = t[1];
    //var bankDate = t[3];
    //var targetSheet = wkbk.getSheetByName("BANK DS");
  if(bankDate != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();//This often returns nulls between data last row and max rows  
    var targetRow = Avals.filter(String).length + 1;
    //var targetRow = targetSheet.getRange(1,1,targetSheet.getLastRow()).getValues().length;
    var values = ss.getRange("A:A").getValues();//Same problem as described above
    var bankAmt = (bankDeposit - bankWithdrawal);
    var bankDetail = [[bankDate, bankAmt]];
    targetSheet.getRange(targetRow,1,1,2).setValues(bankDetail);
    targetSheet.getRange(targetRow-1,3).copyTo(targetSheet.getRange(targetRow,3));
    ss.getRange(3,9,1,4).clearContent();
  }
  //Work Chits Move
    var work1Hours = ss.getRange(5,9).getValue();
    var work1Job = ss.getRange(5,10).getValue();
    var work1Rate = ss.getRange(5,11).getValue();
    var work1Date = ss.getRange(5,12).getValue();
    //try as above to get data all at once
    //var vals=ss.getRange(5,9,1,4).getValues();
    //then use vals[0]...
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work1Date != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var work1Detail = [[work1Date,work1Job,work1Hours,work1Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work1Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(5,9,1,4).clearContent();
  }
  var work2Hours = ss.getRange(6,9).getValue();
    var work2Job = ss.getRange(6,10).getValue();
    var work2Rate = ss.getRange(6,11).getValue();
    var work2Date = ss.getRange(6,12).getValue();
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work2Date != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var work2Detail = [[work2Date,work2Job,work2Hours,work2Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work2Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(6,9,1,4).clearContent();
  }
    var work3Hours = ss.getRange(7,9).getValue();
    var work3Job = ss.getRange(7,10).getValue();
    var work3Rate = ss.getRange(7,11).getValue();
    var work3Date = ss.getRange(7,12).getValue();
    var targetSheet = wkbk.getSheetByName("WORK DS");
  if(work3Date != ""){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var work3Detail = [[work3Date,work3Job,work3Hours,work3Rate]];
    targetSheet.getRange(targetRow,1,1,4).setValues(work3Detail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(7,9,1,4).clearContent();
  }

  //Receipts Move
  var i = 9
  var reDate = ss.getRange(i,12).getValue()
  var targetSheet = wkbk.getSheetByName("RECEIPTS DS");
  if (reDate !=""){
  while (reDate !="") {
    var reAmt = ss.getRange(i,9).getValue();
    var rePlace = ss.getRange(i,10).getValue();
    var reCat = ss.getRange(i,11).getValue();
    var reDate = ss.getRange(i,12).getValue();
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();
    var reDetail = [[reDate,rePlace,reCat,reAmt]];
    targetSheet.getRange(targetRow,1,1,4).setValues(reDetail);
    targetSheet.getRange(targetRow-1,5,1,3).copyTo(targetSheet.getRange(targetRow,5,1,3));
    ss.getRange(i,9,1,4).clearContent();
    i++
  }
  }

  //Safe Move 3, 9, 13 (dates) 3-8, 9-12, 13-18
    var safeDate = ss.getRange(3,6).getValue();
    var targetSheet = wkbk.getSheetByName("SAFE DS");
  for (var i=3;i<9;i++){  
    var safeIn = ss.getRange(i,2).getValue();
    var safeOut = ss.getRange(i,4).getValue();
    var safeCnt = (safeIn - safeOut);
    var safeType = ss.getRange(i,3).getValue();

  if(safeCnt != 0){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();

    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
//    targetSheet.getRange(targetRow-1,3).copyTo(targetSheet.getRange(targetRow,3));
    ss.getRange(i,2).clearContent();
    ss.getRange(i,4).clearContent();
  }
}
    ss.getRange(3,6).clearContent();
  //Safe Move 9 (rolls) 3-8, 9-12, 13-18
    var safeDate = ss.getRange(9,6).getValue();
    var targetSheet = wkbk.getSheetByName("SAFE DS");
  for (var i=9;i<13;i++){  
    var safeIn = ss.getRange(i,2).getValue();
    var safeOut = ss.getRange(i,4).getValue();
    var safeCnt = (safeIn - safeOut);
    var safeType = ss.getRange(i,3).getValue();

  if(safeCnt != 0){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();

    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    ss.getRange(i,2).clearContent();
    ss.getRange(i,4).clearContent();
  }
}
    ss.getRange(9,6).clearContent();
  //Safe Move (loose) 13-18
    var safeDate = ss.getRange(13,6).getValue();
    var targetSheet = wkbk.getSheetByName("SAFE DS");
  for (var i=13;i<19;i++){  
    var safeIn = ss.getRange(i,2).getValue();
    var safeOut = ss.getRange(i,4).getValue();
    var safeCnt = (safeIn - safeOut);
    var safeType = ss.getRange(i,3).getValue();

  if(safeCnt != 0){
    //Finds first blank cell in column A, to enter new data in:
    var Avals = targetSheet.getRange("A1:A").getValues();
    var targetRow = Avals.filter(String).length + 1;
    var values = ss.getRange("A:A").getValues();

    var safeDetail = [[safeDate, safeType,safeCnt]];
    targetSheet.getRange(targetRow,1,1,3).setValues(safeDetail);
    ss.getRange(i,2).clearContent();
    ss.getRange(i,4).clearContent();
  }
}
    ss.getRange(13,6).clearContent();
}
...