How to reduce execution time of this script (Google app script timeout)

1.2k views Asked by At

I have this piece of script. It filter a range by a criteria, then It copy values that respect criteria in a specific sheet then It deletes all the row in the original sheet that respect the criteria. So that If my range contains more than 1000 rows, It's said to me error: Google app script timeout.

I put my code here, can You help me to get a better performance about execution time of this script?

function trasferisciDati() {
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Inserisci il mese dei dati da esportare', '(Esempio: agosto (tutto minuscolo))', ui.ButtonSet.OK_CANCEL);
var inizioTRASFERISCIVALORI = Utilities.formatDate(new Date(), "CET", "HH:mm:ss.SSS");
 if (response.getSelectedButton() == ui.Button.OK) {
//get filtered range and set values to the new range
var description = ui.prompt('Inserisci una descrizione per questa esportazione', 'apparirà come tag dell\'esportrazione', ui.ButtonSet.OK_CANCEL);
var sourceData = SpreadsheetApp.openById("1XkYhjdQfgU7mVCR7E8mfZsf292I-cJ16PnpCimnd1v8").getSheetByName("Prova");
var destinationData = SpreadsheetApp.openById("1cdXMqqBwgWK5nCQUtAP_TyIIDOHksS7wWvSG4jRu658").getSheetByName("Prova");
var lastRow = sourceData.getLastRow();
var data = sourceData.getRange(1, 1, lastRow, 1).getValues();
var chiave = response.getResponseText();
  for(var i=0;i<data.length;i++)
{
 if (data[i][0] == chiave) {
   var filteredRow = sourceData.getRange(i+1,1,1,5).getValues();
destinationData.appendRow(filteredRow[0]);
 } 
}

//number of records of the filtered range
 var lastRow = destinationData.getLastRow();
var data = destinationData.getRange(1, 6, lastRow, 1).getValues();
var loop = 0  
  for(var i=0;i<data.length;i++)
{
  if(!data[i][0])
  {
   var loop = loop + 1
  }
}
Logger.log(Utilities.formatString('%1.0f', Math.floor(loop)))
 //appendi timestamp al rigo ed eventuale descrizione aggiuntiva inserita dall'utente
 var lastRow = destinationData.getLastRow();
 var data = destinationData.getRange(1, 6, lastRow, 1).getValues();
 var timestamp = Utilities.formatDate(new Date(), "CET", "dd/MM/YYYY HH.mm.ss") 
 for(var i=0;i<data.length;i++)
{
  if(!data[i][0])
  {
destinationData.getRange(i+1,6).setValue(timestamp)
destinationData.getRange(i+1,7).setValue(description.getResponseText())
  }
}
 //cancella l'intervallo originale
var maxRows = sourceData.getMaxRows();
var data = sourceData.getRange(1, 1, maxRows, 1).getValues();
  for(var i=data.length; i>=0;i--) 
{
 if (data[i] == chiave) {
sourceData.deleteRow(i+1)
  } 
  }
   var fineTRASFERISCIVALORI = Utilities.formatDate(new Date(), "CET", "HH:mm:ss.SSS");
   var inTime=inizioTRASFERISCIVALORI.split(":");
   var outTime= fineTRASFERISCIVALORI.split(":");
   var hr = outTime[0] - inTime[0]; 
   var min = ((outTime[1] - inTime[1])+hr*60)%60;
   var sec = ((outTime[2] - inTime[2])+min*60)%60;
   var duration = Utilities.formatString('%2.0f', Math.floor(hr)) + 'h ' + Utilities.formatString('%2.0f', Math.floor(min)) + 'm ' + Utilities.formatString('%2.0f', sec) + 's';  
   ui.alert('Trasferite '+ Utilities.formatString('%1.0f', Math.floor(loop)) +' righe in '+ duration, ui.ButtonSet.OK)
 } else if (response.getSelectedButton() == ui.Button.CANCEL) {
   SpreadsheetApp.getUi().alert('L\'utente ha annullato l\'operazione');
 }  else {
   SpreadsheetApp.getUi().alert('L\'utente ha chiuso la finestra di dialogo');
   }
}
1

There are 1 answers

2
Cooper On BEST ANSWER

You might try this:

  var data = sourceData.getRange(1, 1, lastRow, 5).getValues();
  var chiave = response.getResponseText();
  for(var i=0;i<data.length;i++)
  {
     if (data[i][0] == chiave) 
     {
       //var filteredRow = sourceData.getRange(i+1,1,1,5).getValues();
       destinationData.appendRow(data[i]);
     } 
  }

And you might consider the same thing on your destination data.