问题
I have a google sheet with some data and I am trying to combine all cell data in a JSON variable so I can pass it on to API to do something.
I have this javascript function that takes all data and combine everything in JSON variable like this:
function combine_val() {
var startRow = 2; // First row of data to process. Starting with 2 to ignore headers
var startColumn = 1; //First Column to process, in case that changes.
var numRows = mysheet.getLastRow(); // Number of rows to process
var numCols = mysheet.getLastColumn(); //Also the number of columns to process, again in case that changes.
var dataRange = mysheet.getRange(startRow, startColumn, numRows, numCols);//Get the full range of data in the sheet dynamically.
var data = JSON.stringify(dataRange.getValues());//Get the value of the range, AND convert it to a JSON string in one line.
// DO something HERE with "data" to push the JSON string in a controlled batch to API
SpreadsheetApp.getUi().alert(data);
}
The API where I am passing this data takes JSON with 200 rows only. So I need help in creating a batch of 200.
This is what I have done so far and need help.
var mybatch = 200;
function combine_val_increment() {
var startRow = 2; // First row of data to process. Starting with 2 to ignore headers
var startColumn = 1; //First Column to process, in case that changes.
var numRows = mysheet.getLastRow(); // Number of rows to process
var numCols = mysheet.getLastColumn(); //Also the number of columns to process, again in case that changes.
for (var i = 0; i < numRows/mybatch; ++i) {
var dataRange = mysheet.getRange(startRow, startColumn, startRow+mybatch, numCols);//Get the full range of data in the sheet dynamically.
var data = JSON.stringify(dataRange.getValues());//Get the value of the range, AND convert it to a JSON string in one line.
// DO something HERE with "data" to push the JSON string in a controlled batch to API
SpreadsheetApp.getUi().alert(data);
startRow = startRow + mybatch;
}
}
Approach# 2 based on suggestions / comments
function rowsForAPI2(){
var batchsize = 2;
//var batchsize = 200;
//var ss = SpreadsheetApp.getActiveSheet();
var ss = SpreadsheetApp.getActive().getSheetByName('Sheet5'); //SHEET NAME
// var data = ss.getDataRange().getValues(); // 2D array with all of the data in the sheet.
var startRow = 2; // First row of data to process. Skip 1st row of column headers for this test.
var startColumn = 1; //First Column to process, in case that changes.
var numRows = ss.getLastRow(); // Number of rows to process
//var numCols = mysheet.getLastColumn(); //Also the number of columns to process, again in case that changes.
var numCols = 4; //Hardcode for this test
var dataRange = ss.getRange(startRow, startColumn, numRows, numCols);//Get the full range of data in the sheet dynamically.
var data = dataRange.getValues();//Get the value of the range, AND convert it to a JSON string in one line.
var rowCount = ss.getLastRow() - 1; // To know how many rows have data (-1 will ignore the column header)
var obj = [];
var temp = 0;
var results = [];
Logger.log(rowCount/batchsize)
for (var i = 0; i < (rowCount/batchsize); i++){
for (var j = temp; j < batchsize*(i+1); j++){
obj.push(data[j]); // Push row into object.
temp = j;
if (temp == rowCount-1) // Got to the end of the data.
break;
}
temp++;
results.push(JSON.stringify(obj)); // Adds the JSON object to an array
obj = []; // Clear the array of the 200 rows stored
}
return results;
}
function doSomething(){
var objects = rowsForAPI2();
var curr;
for ( var i = 0; i < objects.length; i++){
curr = objects[i];
// Do the API thing with curr...
Logger.log(curr);
}
}
New requirement for approach 3 -
In this new use-case, instead of passing data in JSON.stringify array of 200 rows batch. I have an API endpoint that takes rows in this format:
{
"recipient": {
"emailAddress": "email_1@domain.com",
"listName": {
"path": "testfolder"
}
}
},
{
"recipient": {
"emailAddress": "email_2@domain.com",
"listName": {
"path": "testfolder"
}
}
},
{
"recipient": {
"emailAddress": "email_3@domain.com",
"listName": {
"path": "testfolder"
}
}
}
How can I use same solution discussed below with batching technique but for building the above^ formatted records where email list is coming from values in rows in google sheet? Any help?
回答1:
Try this:
function rowsForAPI(){
var ss = SpreadsheetApp.getActiveSheet();
var data = ss.getDataRange().getValues(); // 2D array with all of the data in the sheet.
var rowCount = ss.getLastRow(); // To know how many rows have data
var obj = []; // Array where the row objects will be stored
var temp = 0; // A counter of how many rows have been processed.
var results = []; // Array where the resulting JSON objects will be stored and returned.
Logger.log(rowCount/200)
for (var i = 0; i < (rowCount/200); i++){
for (var j = temp; j < 200*(i+1); j++){
obj.push(data[j]); // Push row into object.
temp = j;
if (temp == rowCount-1) // Got to the end of the data (if there are less than 200 rows in this batch).
break;
}
temp++; // Update row count.
results.push(JSON.stringify(obj)); // Adds the JSON object to an array
obj = []; // Clear the array of the 200 rows stored before the next loop starts.
}
return results;
}
function doSomething(){
var objects = rowsForAPI();
var curr;
for ( var i = 0; i < objects.length; i++){ // Go through each batch
curr = objects[i]; // Current batch.
// Do the API thing with curr...
}
}
This method will return an array of JSON objects that holds batches of 200 rows from the Sheet, it will also stop if it reaches the end of the data in the sheet.
来源:https://stackoverflow.com/questions/57822236/how-can-i-create-batch-in-javascript-loop-to-select-x-rows-then-next-x-rows-unti