web-dev-qa-db-fra.com

Tableur de script Google Apps - Écrire un tableau dans des cellules

À l'aide de Google Apps Script, existe-t-il un moyen d'écrire les valeurs d'un tableau Google Spreadsheet sur une plage sans effectuer de boucle? 

Je pense quelque chose comme ceci pour mettre un nom chacun dans les cellules A1:A3

function demoWriteFromArray() {

   var employees=["Adam","Barb","Chris"];

   ssActive = SpreadsheetApp.getActiveSheet();

   rgMyRange = ssActive.getRange("A1:A3");

   rgMyRange.setValue(employees)
} 

Le problème avec ce qui précède est qu’après l’exécution, A1:A3 contient tous ={"Adam","Barb","Chris"} and display "Adam".

15
Playing with GAS

Range.setValue () est utilisé pour définir la même valeur dans chaque cellule de la plage, tandis que setValues ​​ permet de définir un tableau de valeurs dans les cellules correspondantes de la plage. Sachez que cette méthode attend un tableau multi-dimensionnel, le tableau externe étant des lignes et le tableau interne étant des colonnes. Donc, dans votre cas, les données devraient ressembler à:

var employees=[["Adam"],["Barb"],["Chris"]];
23
Eric Koleda

Même s'il est un peu tard, quelqu'un pourrait trouver cette réponse à un moment donné. J'ai écrit une fonction qui convertit un tableau 1-d en un tableau 2-d (matrice), ce qui est attendu comme paramètre pour Range.setValues():

// Morphs a 1-d array into a 2-d array for use with Range.setValues([][])
function morphIntoMatrix(array) {

  // Create a new array and set the first row of that array to be the original array
  // This is a sloppy workaround to "morphing" a 1-d array into a 2-d array
  var matrix = new Array();
  matrix[0] = array;

  // "Sanitize" the array by erasing null/"null" values with an empty string ""
  for (var i = 0; i < matrix.length; i ++) {
    for (var j = 0; j < matrix[i].length; j ++) {
      if (matrix[i][j] == null || matrix[i][j] == "null") {
        matrix[i][j] = "";
      }
    }
  }
  return matrix;
}

Je ne peux pas garantir que toutes les valeurs, sauf les types de données de base, seront préservées. Le paramètre sanitization est nécessaire, car JavaScript semble remplacer en interne les valeurs vides du tableau d'origine par null ou "null" lorsqu'il est affecté à l'élément d'un autre tableau. Au moins, c'est mon expérience. Cela fonctionne bien, quelqu'un peut le trouver utile.

7
Chris Cirefice

J'ai amélioré le temps d'exécution du script d'un facteur 10 × . Cela fonctionne pour moi comme ceci:

function xabo_api() { 
var sskey = 'KEY-CODE';
var doc = SpreadsheetApp.openById(sskey);    
var conn = Jdbc.getConnection("jdbc:mysql://Host:PORT/DB", "USER", "PWD");
var stmt = conn.createStatement();

//stmt.setMaxRows(5000);

var rs = stmt.executeQuery("select * from xabo;");
var sheet = doc.setActiveSheet(doc.getSheetByName("xabo laboratories"));

//var cell = doc.getRange('A2');

var row = 0;
var data = [];

while (rs.next()) {
    var rowData = [];
    for (var col = 0; col < rs.getMetaData().getColumnCount(); col++) {
    rowData[col] = (rs.getString(col + 1));
}
data[row] = rowData;
row++;
}

 // My script writes from the second row, as first I use for headers only

 var range = sheet.getRange(2,1,row, col); // check edges or uses a1 notation
 range.setValues(data);

 //   This is what google api doc suggests: It takes 10x more row by row
 //   while (rs.next())
 //   {
 //       for (var col = 0; col < rs.getMetaData().getColumnCount(); col++){
 //         cell.offset(row, col).setValue(rs.getString(col + 1));
 //        }
 //     row++;
 //   } 

 rs.close();
 stmt.close();
 conn.close();
 }
4
user2890988

J'ai vu cette question lors de la recherche d'une réponse pour ma propre application. Une autre solution consiste à utiliser une fonction custom qui renvoie un tableau 2D.

Voici un exemple. Supposons que "Adam, Barb, Chris; Aaron, Bill, Cindy" soit un texte en A1. Si vous faites référence à une fonction personnalisée dans B1, vous pouvez remplir la plage B1: D2 avec des noms individuels.

Fonction personnalisée écrite dans le script d'applications:

function splitNames(names) {
  // you could do any other work necessary here
  var arr = names.split("; ");
  arr[0] = arr[0].split(", ");
  arr[1] = arr[1].split(", ");

  // output should be 2D array where each element of the
  // main array is a range spanning 1 or more columns and
  // one row and each sub array are cells within that range
  return arr;
}

La formule dans B1 faisant référence à la fonction personnalisée: =splitNames(A1)

Notez que cette fonction lève une exception si les cellules adjacentes à B1 ne sont pas vides. Cela pourrait être géré avec la formule IFERROR ou éventuellement essayer/attraper dans la formule personnalisée.

0
mjblay

La réponse principale fournit un moyen simple et agréable d’écrire un tableau sur une ligne, mais écrire sur une colonne est un peu plus difficile, mais comme c’est la question que nous avons ici, voici une fonction rapide pour le faire:

function addArrayToSheetColumn(sheet, column, values) {
  const range = [column, "1:", column, values.length].join("");
  const fn = function(v) {
    return [ v ];
  };
  sheet.getRange(range).setValues(values.map(fn));
}

Où vous appelez alors la fonction dans votre code comme suit:

const ss = SpreadsheetApp.getActiveSpreadsheet();
const cache = ss.getSheetByName("_cache_");
const results = ["Adam","Barb","Chris"];
addArrayToSheetColumn(cache, "A", results);
0
ken