web-dev-qa-db-fra.com

Itérer sur la plage, ajouter une chaîne à chaque

J'ai une série de cellules sélectionnées dans une feuille de calcul Google (activerange).

Je veux parcourir toutes les cellules de cette plage et ajouter une chaîne à la fin. La chaîne est toujours la même et peut être codée en dur dans la fonction.

Cela semble être une chose très simple, mais cela fait maintenant une heure que je manipule le code et je ne peux rien obtenir d’utile, et les documents ne nous aident vraiment pas. 

Voici ce que j'ai maintenant. Je ne code pas JS (je connais VBA, pour tout ce qui aide ..).

function appendString() {
  var range = SpreadsheetApp.getActiveSheet().getActiveRange();
  for (var i = 0; i < range.length; i++) {
    var currentValue = range[i].getValue();
    var withString = currentValue + " string";
    range[i].setValue(withString);
  }
}

Toute aide serait appréciée.

36
ezuk

Vous pouvez essayer quelque chose comme ça:

function appendString() {
  var range = SpreadsheetApp.getActiveSheet().getActiveRange();
  var numRows = range.getNumRows();
  var numCols = range.getNumColumns();
  for (var i = 1; i <= numRows; i++) {
    for (var j = 1; j <= numCols; j++) {
      var currentValue = range.getCell(i,j).getValue();
      var withString = currentValue + " string";
      range.getCell(i,j).setValue(withString);
    }
  }
}
75
flyingjamus

Ou bien utilisez setValues ​​() qui écrit toutes les valeurs en même temps. Semble exécuter plus vite aussi.

var range = SpreadsheetApp.getActiveSheet().getActiveRange();
var numRows = range.getNumRows();
var numCols = range.getNumColumns();
var writeValues = []
for (var i = 1; i <= numRows; i++) {
  var row = []
  for (var j = 1; j <= numCols; j++) {
    var currentValue = range.getCell(i,j).getValue();
    var withString = currentValue + " string";
    row.Push(withString)
  }
  writeValues.Push(row)
}
range.setValues(writeValues)
19
Voy

voici la mise à jour de Voy's post , utilise range.getValues ​​() pour obtenir toutes les valeurs et omettre le tableau temporaire. devrait être encore plus rapide car range.getCell().getValue() est omis dans la boucle bidimensionnelle. Notez que les index commencent à partir de 0 dans cet extrait. Je trouve aussi cela plus lisible.

  var cells = range.getValues();
  var numRows = range.getNumRows();
  var numCols = range.getNumColumns();
  for (var i = 0; i < numRows; i++) {
    for (var j = 0; j < numCols; j++) {
      cells[i][j] += " string";
    }
  }

  range.setValues(cells);
3
Elan Ruusamäe

Voici une fonction très générale qui itère sur les valeurs d'une plage. Il peut également être utilisé pour effectuer une fonction reduce sur celle-ci (ce qui est utile dans votre cas). Il peut également sortir de la boucle si vous ne voulez jamais que trouver le premier d'un élément.

Il est très facile de changer pour accepter une instance Range réelle au lieu du tableau de valeurs.

function range_reduce(rangeValues,fn,collection) {
  collection = collection || [];
  var debug_rr = "<<";
  for(var rowIndex = 0, row=undefined; rowIndex<rangeValues.length && (row = rangeValues[rowIndex]); rowIndex++) { 
    for(var colIndex = 0, value=undefined; colIndex<row.length && (value = row[colIndex]); colIndex++) {
      try {
        collection = fn(collection, value, rowIndex, colIndex);
      } catch (e) {
        if(! e instanceof BreakException) {
          throw e;
        } else {
          return collection;
        }
      }
    }
  }
  return collection;
}

// this is a created, arbitrary function to serve as a way
// to break out of the reduce function. Your callback would
// `throw new BreakException()` and `rang_reduce` would stop
// there and not continue iterating over "rangeValues".
function BreakException();

Dans ton cas:

var range = SpreadsheetApp.getActiveSheet().getActiveRange()
var writeValues = range_reduce(range.getValues(), function(collection, value, row, col) {
    collection[row] || collection.Push([]);
    collection[row].Push(value + " string");
});
range.setValues(writeValues)
2
Alexander Bird

Je préfère la méthode Javascript 1.6 forEach à la boucle old school for. Vous pouvez:

function appendString() {
    var range = SpreadsheetApp.getActiveSheet().getActiveRange();
    var values = range.getValues();

    values.forEach(function(row, rowId) {
        row.forEach(function(col, colId) {
            values[rowId][colId] += " string";
            // Or: range.getCell(rowId + 1, colId + 1).setValue(col + " string");
            // Note: - '+1' to hit the cells, when using getCell
            //       - 'col' holds the current value of range.getCell(rowId + 1, colId + 1)
        });
    });

    range.setValues(values); // needless if using range.getCell(...).setValue(...);
}

Javascript 1.6 offre également map, que je préfère encore plus:

function appendString() {
  var range = SpreadsheetApp.getActiveSheet().getActiveRange();
  var values = range.getValues();

  var modified = values.map(function (row) {
    return row.map(function (val) { 
      return val + " string"; 
    }); 
  })

  range.setValues(modified);
}

J'aimerais utiliser les fonctions de flèche dans les deux cas, mais elles ne sont pas encore prises en charge dans google-apps-script.

1
Stephan Stamm

google-sheets
Vous pouvez facilement le faire avec Trouver et remplacer.

  • Sélectionnez votre gamme

  • Trouver:

    ^(.*)$
    
  • Remplacer: 

    $1AppendString
    
  • Marquer utiliser des expressions régulières 

  • Cliquez sur Remplacer tout

Je ne vois aucun avantage à utiliser un script ici, mais, si vous devez le faire, vous pouvez également émettre une API Rechercher remplacer demande via les feuilles.

0
TheMaster