web-dev-qa-db-fra.com

Comment puis-je résoudre l'erreur "Temps d'exécution maximal dépassé" dans Google Sheets?

J'ai trouvé un script dont j'ai vraiment besoin ( lien ):

function getTotalSum(cell) {
    var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
    var sum = 0;
    for (var i = 0; i < sheets.length ; i++ ) {
        var sheet = sheets[i];
        var val = sheet.getRange(cell).getValue();

        if (typeof(val) == 'number') {
            sum += val;   
        }       
    }

    return sum;
}

mais cela donne généralement une erreur (temps d'exécution maximum dépassé).

Comment puis-je résoudre cette erreur?

3
user66322

J'ai essayé avec succès la fonction personnalisée suivante avec 170 feuilles maximum:

function getTotalSum(startrow, startcol) {
  var ss = SpreadsheetApp.getActive();
  var start = new Date();   
  var numSheets = ss.getNumSheets(), sum=0;
  for(var k=1; k<numSheets; k++) {
    var data = ss.getSheets()[k].getDataRange().getValues();
    var value = data[startrow-1][startcol-1];
    if(typeof(value) == 'number') {
      sum += value;   
    }       
  }
  return sum;
}

Au-delà des 170 problèmes ariase: enter image description here

Par conséquent, j'ai créé le code ci-dessous qui peut être utilisé pour au moins 750 feuilles (mais ne doit pas être utilisé en tant que fonction personnalisée).

Code

// global 
var ss = SpreadsheetApp.getActive();

function onOpen() {
  ss.addMenu("Sum", [{name: "Go !!", functionName: "getSum"}]);
}

function getSum() {
  // get user input
  var cell = Browser.inputBox('Enter A1 notation', 'like B21',
    Browser.Buttons.OK_CANCEL);

  // retrieve cell reference from a sheet and get row and col index
  var aCell = ss.getActiveSheet().getRange(cell.toString());
  var row = aCell.getRow()-1, col = aCell.getColumn()-1;

  // get number of sheets and set sum to zero
  var numSheets = ss.getNumSheets(), sum=0;

  // iterate through sheets, starting from second sheet
  for(var k=1; k<numSheets; k++) {
    // bulk load sheet at once 
    var data = ss.getSheets()[k].getDataRange().getValues();

    // get value from array
    var value = data[row][col];

    // valid value
    if(typeof(value) == 'number') {
      sum += value;   
    }       
  }

  // return value to active cell   
  ss.getActiveCell().setValue(sum);
}

A expliqué

La fonction personnalisée n'est pas vraiment destinée à être utilisée de manière aussi intensive. Bizarrement, la fonction personnalisée s’exécute bien dans les 5 minutes du temps d’exécution pour les 170 feuilles (30). L'utilisation de .getDataRange().getValues() est légèrement avantageuse par rapport à .getValue() (environ 30 secondes pour 750 feuilles).

Exemple

J'ai créé un exemple de fichier pour vous: 750 feuilles
Créez une copie et recherchez les morceaux de code supplémentaires que j'ai ajoutés.

1
Jacob Jan Tuinstra