À 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"
.
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"]];
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.
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();
}
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.
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);