Cours Apps Script : les boucles (suite)

Bien que la boucle for soit probablement celle que vous utiliserez dans la majorité des cas, il en existe d'autres (et nous en verrons certaines plus complexes un peu plus loin dans le cours)


While

La boucle while est exécutée tant que la condition entre () est vraie.

Dans cet exemple, la boucle est exécutée tant que le nombre de valeurs du tableau est inférieur à 10 :

function boucles() {

  const tableau = [];

  while (tableau.length < 10) {
    tableau.push(0);
  }

  console.log(tableau); // Affiche : [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
}

Do while

La boucle do while est l'équivalent de la boucle while à la différence que la condition est testée après l'exécution des instructions, ce qui signifie que les instructions sont dans tous les cas exécutées au moins une fois :

function boucles() {

  const tableau = [];

  do {
    tableau.push(0);
  } while (tableau.length < 10);

  console.log(tableau); // Affiche : [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
}

ForEach

La boucle forEach permet de parcourir chaque valeur d'un tableau (mais nous y reviendrons plus tard dans ce cours)

Exercice

Dans une nouvelle feuille, entrez plusieurs fois le nombre 55 dans la colonne A (entre la ligne 1 et 1000).

Utilisez ensuite une boucle for pour parcourir toutes les valeurs des cellules de la colonne A et colorer toutes celles qui contiennent le nombre 55. Complétez cette fonction avant de passer à la solution un peu plus bas :

function colorer55() {

  const feuille = SpreadsheetApp.getActiveSheet();

  // A compléter ...

}

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Voici une solution commentée :

function colorer55() {

  const feuille = SpreadsheetApp.getActiveSheet();

  // Boucle de la ligne 1 à 1000
  for (let i = 1; i <= 1000; i++) {

    // Cellule à tester
    const cellule = feuille.getRange(i, 1);

    // Si la valeur de la cellule est 55
    if (cellule.getValue() == 55) {
      cellule.setBackground('#e6f6f2');
    }
  }
}

Ce code fonctionne bien et vous semble peut-être très juste mais c'est pourtant ce qu'il faut éviter de faire ...

Son exécution est terriblement lente (environ 6 secondes) et c'est simplement dû au fait que les méthodes getRange et getValue sont exécutées 1000 fois (au lieu de 1), ce sont autant de requêtes à traiter pour Google !

Voici une solution plus optimisée qui ne va récupérer les valeurs qu'une seule fois :

function colorer55() {

  const feuille = SpreadsheetApp.getActiveSheet();
  const tabValeurs = feuille.getRange('A:A').getValues().flat();

  // Boucle de la ligne 1 à 1000
  for (let i = 1; i < 1000; i++) {

    // Si la valeur testée du tableau est 55
    if (tabValeurs[i - 1] == 55) {
      feuille.getRange(i, 1).setBackground('#e6f6f2');
    }
  }
}

Pour corser un peu l'exercice, ajoutez maintenant des 55 dans quelques cellules des autres colonnes puis, en vous inspirant de la dernière solution, faites le nécessaire pour qu'elle prenne en compte la plage de la feuille qui contient des données (avec getDataRange) et pas uniquement la première colonne.

Avec une difficulté supplémentaire : vous ne connaissez cette fois pas d'avance le nombre de lignes et de colonnes de la feuille.

function colorer55() {

  const feuille = SpreadsheetApp.getActiveSheet();
  const tabValeurs = feuille.getDataRange().getValues(); // getDataRange = plage de la feuille contenant des données
  
  // A compléter ...
  
}

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Avez-vous réussi ?

Si non, cela vous aidera peut-être :

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Voici une solution commentée :

function colorer55() {

  const feuille = SpreadsheetApp.getActiveSheet();
  const tabValeurs = feuille.getDataRange().getValues(); // getDataRange = plage de la feuille contenant des données

  // Boucle de la colonne 1 à tabValeurs[0].length (tabValeurs[0] correspond au tableau de la première ligne)
  for (let j = 0; j < tabValeurs[0].length; j++) {

    // Boucle de la ligne 1 à tabValeurs.length
    for (let i = 0; i < tabValeurs.length; i++) {

      // Si la valeur testée du tableau est 55
      if (tabValeurs[i][j] == 55) {
        feuille.getRange(i + 1, j + 1).setBackground('#e6f6f2');
      }
    }
  }
}