how to add every value to data object in firebase? - google-apps-script

Im using this code to push the values from my google sheet to firebase, but i only get the first row added. how can I make this dynamic? everytime there is a new row, there is a new entry created in firebase?
here is the code:
//Add in your database secret
var secret = ''
function getFirebaseUrl(jsonPath) {
return (
'https://gradetracker-789b7-default-rtdb.firebaseio.com/' +
jsonPath +
'.json?auth=' +
secret
)
}
var sheet = SpreadsheetApp.getActiveSheet()
var [rows, columns] = [sheet.getLastRow(),
sheet.getLastColumn()]
var data = sheet.getRange(1, 1, rows, columns).getValues();
console.log(data);
var dataObject = {};
for (var i=1; i <data.length; i++) {
var dataRow = data[i];
var uid = dataRow[0];
var ET1 = dataRow[1];
var ET2 = dataRow[2];
dataObject[uid]= {
et1 : ET1,
et2 : ET2,
}
}
my sheet data is this
enter image description here
My output right now is
enter image description here
but i need this to be
enter image description here

In your situation, how about the following sample script?
Sample script:
function myFunction() {
const spreadsheetId = "###"; // Please set the Spreadsheet ID.
const sheetName = "Sheet1"; // Please set the sheet name.
// 1. Retrieve values from Spreadsheet.
const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
const [[, h1, h2], ...data] = sheet.getDataRange().getValues();
// 2. Create an object for sending to Firestore.
const obj = data.map(([a, b, c]) => ({[a]: {[h1]: b, [h2]: c}}));
console.log(obj);
// 3. Send the object to Firestore.
// const firestore = ###; // Please set your `firestore`.
// const res = obj.map(r => firestore.createDocument("###document###", r));
}
When above script is run, obj is as follows.
[
{"###uid1###":{"et1":60,"et2":80}},
{"###uid2###":{"et1":90,"et2":65}}
]
Note:
In this modification, it supposes that the header (uid, et1 and et2) of your sample spreadsheet are the cells "A1", "B1" and "C1", respectively. Please be careful this.
Reference:
map()

Related

Import Data From multiple sheet with a list of ID and specifics column

I have about many spreadsheet work with my partners and each partner use 1 spreadsheat for manage data.
I using a table to store all ID, Sheet name and column store data I need to import to my master sheet.
This is my Spreadsheet:
Link here
I using Appscript to do import data by read values in this table with 2 loop, I see it work to slow How could I speed up it?
this is my script
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Source Link');
var master = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Master') ;
const dstLr = getLastPopulatedRow(ss); //get last row of Source Link
const target_sheet_name = ss.getRange(2,6,dstLr-1,1).getValues(); //Get data in Column F input to array
const ids = ss.getRange(2,1,dstLr-1,1).getValues(); //get data in column A input to array
const ebayID = ss.getRange(2,2,dstLr - 1,1).getValues(); //get cloumn index at Column B input to array
const team = ss.getRange(2,3,dstLr-1,1).getValues(); //get column containt team name at column C input to array
const linkOrder = ss.getRange(2,4,dstLr-1,1).getValues(); //get cloumn containt Link Order at column D input to array
const tracking = ss.getRange (2,5,dstLr-1,1).getValues(); //get column containt Tracking at column E input to array
const benCO = ss.getRange(2,7,dstLr,1).getValues();
ids.forEach((id, i) => {
const srcSheet = SpreadsheetApp.openById(id).getSheetByName(target_sheet_name[i]);
const lr = getLastPopulatedRow(srcSheet);
const srcCol = [ebayID[i], team[i], linkOrder[i],tracking[i]].flat();
for(var j = 0; j < srcCol.length; j++) {
const destCol = [1,2,3,4];
const destCol2 = [5];
destCols = destCol[j]
const srcRange = srcSheet.getRange(3, srcCol[j], lr); // Origin range to copy
const values = srcRange.getValues(); // Getting values from origin column
const destRange = master.getRange(2, destCols, lr);
master.clearContents;
destRange.setValues(values);
}
})
}
function getLastPopulatedRow(sheet) {
var data = sheet.getDataRange().getValues();
for (var i = data.length-1; i > 0; i--) {
for (var j = 0; j < data[0].length; j++) {
if (data[i][j]) return i+1;
}
}
return 0;
}
I also need add value of G column for each data I import from ID and Sheet name at colum A and column F, but when I try set value for column E at Master sheet I got error that "data have 1 but destination range have 582"
Could Some one give me advise
That's what I try
ids.forEach((id, i) => {
const srcSheet = SpreadsheetApp.openById(id).getSheetByName(target_sheet_name[i]);
const lr = getLastPopulatedRow(srcSheet);
const srcCol = [ebayID[i], team[i], linkOrder[i],tracking[i]].flat();
for(var j = 0; j < srcCol.length; j++) {
const destCol = [1,2,3,4];
const destCol2 = [5];
destCols = destCol[j]
const srcRange = srcSheet.getRange(3, srcCol[j], lr); // Origin range to copy
const values = srcRange.getValues(); // Getting values from origin column
const destRange = master.getRange(2, destCols, lr);
master.clearContents;
destRange.setValues(values);
}
const coName = [];
coName.push(benCO[i]);
master.getRange(2,5,lr,1).setValues(coName);
})
and this is error:
From your question and samples, how about the following sample script?
Sample script:
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sourceLink = ss.getSheetByName('Source Link');
const master = ss.getSheetByName('Master');
const srcValues = sourceLink.getRange("A2:G" + sourceLink.getLastRow()).getValues();
const header = ["Order ID", "Team", "ID", "ID TRACKING#"];
const values = [header, ...srcValues.flatMap(r => {
const sheet = SpreadsheetApp.openById(r[0]).getSheetByName(r[5]);
const [, h, ...v] = sheet.getDataRange().getValues();
const temp = h.map(e => e.trim());
const indexes = header.map(e => temp.indexOf(e));
return v.map(r => indexes.map(i => r[i]));
})];
master.clearContents().getRange(1, 1, values.length, values[0].length).setValues(values);
}
In this sample script, first, the header is declared and the values are retrieved using the header from each sheet. And, the populated values are put into the destination sheet.
In this sample script, the header is used from your sample Spreadsheet. So, when you change the header titles, the result values might not be able to be used. Please be careful about this.
Reference:
map()
Added:
From your following reply,
I got messenger error at this line: const temp = h.map(e => e.trim()); messenger said: TypeError: e.trim is not a function
My proposed script is for your provided Spreadsheet, and when I tested my proposed script no error occurs. From your reply, I guessed that your Spreadsheet might be different from your provided Spreadsheet. If my understanding is correct, from your error message, I'm worried that the header rows might be changed. In your provided Spreadsheet, 1st 2 rows are header rows. But, if the header row is only the 1st row, the error might occur because the row values include the date object in the 2nd row. If my understanding is correct, can you test the following sample script?
Sample script:
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sourceLink = ss.getSheetByName('Source Link');
const master = ss.getSheetByName('Master');
const srcValues = sourceLink.getRange("A2:G" + sourceLink.getLastRow()).getValues();
const header = ["Order ID", "Team", "ID", "ID TRACKING#"];
const values = [header, ...srcValues.flatMap(r => {
const sheet = SpreadsheetApp.openById(r[0]).getSheetByName(r[5]);
// const [, h, ...v] = sheet.getDataRange().getValues();
let h;
let [h1, h2, ...v] = sheet.getDataRange().getValues();
if (h2.some(e => e instanceof Date)) {
h = h1;
v = [h2, ...v];
} else {
h = h2;
}
const temp = h.map(e => e.trim());
const indexes = header.map(e => temp.indexOf(e));
return v.map(r => indexes.map(i => r[i]));
})];
master.clearContents().getRange(1, 1, values.length, values[0].length).setValues(values);
}
If the same error occurs and another error occurs, can you provide the sample Spreadsheet for correctly replicating the issue? By this, I would like to confirm it.

How to get a1Notations from Row with Findall function

So I was referencing this question "https://stackoverflow.com/questions/56826834/how-to-get-a1notations-when-findall-function-returning-range-range-range-ran" and I like it and what it does but I need to go a little further and im still a beginner but this is what I have.
var searchTerm = "Changeme"; // Please set this.
var sheetName = "Sheet1"; // Please set this.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheetName = ss.getSheetByName(sheetName);
var completeSearch = dataSheetName.createTextFinder(searchTerm).findAll();
for (var i = 0; i < completeSearch.length; i++) {
var range = completeSearch[i];
var value = range.getValue();
var rowValue = dataSheetName.getRange(range.getRow(), 1, 1, dataSheetName.getLastColumn()).getValues();
Logger.log(value) // Value of the searched range
Logger.log(rowValue)
Logger.log(range.getA1Notation()
//Logger.log(rowValue) // Values of the row of searched range
}
}
This is enough to get me the row that I am looking for and the Cell of what I am searching for but what I want to do is check a column for what I am searching for and return the row then grab the value of another column in the same row and based off that answer send an email out to someone with the answer.
So Search Column H for the "SearchTerm" If I found it in the row check the cell value in column A, B, and C and if then put the values in another sheet to send them out in an email.
Any help will be appreciated.
I believe your goal is as follows.
You want to retrieve the values of columns "A" to "C" by searching the value of searchTerm at the column "H".
In this case, how about the following modified script?
Modified script 1:
When you want to use TextFinder, how about the following script?
var searchTerm = "Changeme"; // Please set this.
var sheetName = "Sheet1"; // Please set this.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheetName = ss.getSheetByName(sheetName);
var completeSearch = dataSheetName.getRange("H:H").createTextFinder(searchTerm).findAll();
for (var i = 0; i < completeSearch.length; i++) {
var range = completeSearch[i];
var rowValue = dataSheetName.getRange(range.getRow(), 1, 1, 3).getValues();
Logger.log(rowValue)
}
Modified script 2:
I thought that in your situation, at first, when the values are retrieved from the sheet and retrieve the expected values in a loop, the process cost might be a bit low. The sample script is as follows.
var searchTerm = "Changeme"; // Please set this.
var sheetName = "Sheet1"; // Please set this.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheetName = ss.getSheetByName(sheetName);
var values = dataSheetName.getRange("A1:H").getValues();
var res = values.reduce((ar, [a,b,c,,,,,h]) => {
if (h == searchTerm) ar.push([a, b, c]);
return ar;
}, []);
console.log(res);
References:
Class TextFinder
reduce()
Edit:
From your sample Spreadsheet and your replying comments,
You want to search the column "H".
You want to use the values of columns "C,D,E" of the searched row.
About the values of recipient, subject, body, options of MailApp.sendEmail(recipient, subject, body, options), you will put subject and options as the constant value. recipient is from the column "G". body is like Here is the list of your employees that are in the sheet Last Name First Name Location 123 456 Test1 1r3 1t1 Test1.
In this case, how about the following sample script?
Sample script:
function myFunction() {
var searchTerm = "Supervisor1"; // Please set this.
var sheetName = "Sheet1"; // Please set this.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheetName = ss.getSheetByName(sheetName);
var values = dataSheetName.getRange("C1:H").getValues();
var email = "";
var res = values.reduce((ar, [c,d,e,,g,h]) => {
if (h == searchTerm) {
ar.push([c, d, e]);
email = g;
}
return ar;
}, []);
if (res.length == 0 || !email) return;
var message = {
to: email,
subject: "sample subject",
body: "Here is the list of your employees that are in the sheet Last Name First Name Location\n\n" + res.map(r => r.join(",")).join("\n"), // Modified
name: "Test",
bcc: "testing",
attachments: [SpreadsheetApp.getActiveSpreadsheet().getAs(MimeType.PDF).setName("Employee Report")]
}
MailApp.sendEmail(message);
}

How to clear only "Column A" with Google Apps Script before updating with latest content in the same column

I would like to clear the contents of "column A" before "Update" function fills the latest data in the same column. The idea is remove any redundant data that is not required.
Usecase: Update all the tabs in one Index sheet, if people delete a sheet - that should not reflect in this Index sheet. Here is the code I have used after some research. I am new to this so need some help.
EDIT: Also how to exclude certain "Sheets" from the "Update" function so it doesn't show up in the Index column?
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Index Menu')
.addItem('Create Index', 'createIndex')
.addItem('Update Index', 'updateIndex')
.addToUi();
}
// function to create the index
function createIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
// check if sheet called sheet called already exists
// if no index sheet exists, create one
if (ss.getSheetByName('index') == null) {
var indexSheet = ss.insertSheet('Index',0);
}
// if sheet called index does exist, prompt user for a different name or option to cancel
else {
var indexNewName = Browser.inputBox('The name Index is already being used, please choose a different name:', 'Please choose another name', Browser.Buttons.OK_CANCEL);
if (indexNewName != 'cancel') {
var indexSheet = ss.insertSheet(indexNewName,0);
}
else {
Browser.msgBox('No index sheet created');
}
}
// add sheet title, sheet names and hyperlink formulas
if (indexSheet) {
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
}
// function to update the index, assumes index is the first sheet in the workbook
function updateIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var indexSheet = sheets[0];
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
// function to clear index
function clearContentsOnly() {
var range = SpreadsheetApp
.getActive()
.getSheetByName("Index")
.getRange(4,2,2,2);
range.clearContent();
}
// function to print out the index
function printIndex(sheet,names,formulas) {
sheet.getRange(1,1).setValue('Task Index').setFontWeight('bold');
sheet.getRange(7,1,formulas.length,1).setFormulas(formulas);
}
// function to create array of sheet names and sheet ids
function sheetNamesIds(sheets) {
var indexSheetNames = [];
var indexSheetIds = [];
// create array of sheet names and sheet gids
sheets.forEach(function(sheet){
indexSheetNames.push([sheet.getSheetName()]);
indexSheetIds.push(['=hyperlink("https://docs.google.com/spreadsheets/d/XXXX/edit#gid='
+ sheet.getSheetId()
+ '","'
+ sheet.getSheetName()
+ '")']);
});
return [indexSheetNames, indexSheetIds];
} ```
clear contents of column A
sheet.getRange(1,1,sheet.getLastRow()).clearContent();
if you have header rows and you specify the start row:
const sr = 2;
sheet.getRange( sr, 1, sheet.getLastRow() - sr + 1).clearContent();
function updateIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var indexSheet = sheets[0]; //better to use the name of the index sheet - as the sheet position may get changed easily by the user
indexSheet.GetRange("A2:A").clearContent(); //add this line
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
Make sure you create a Sheet with the name "Index" and then the following code will update column A with all Sheets and directly link to the respective sheet. It will add new sheets with the name and url below existing entries. And if a sheet has changed its name (but not its id), then it will update the sheet name.
function updateIndex(){
const ACTIVE = SpreadsheetApp.getActive()
const spreadsheetURL = ACTIVE.getUrl()
const currentIndexSheet = ACTIVE.getSheetByName("Index")
// Empty the sheet
currentIndexSheet.getRange("A1:A").clearContent()
// We will populate this with all rows
let outputRows = []
// List Sheets which should not be listed
let skipSheets = ["Index", "Another Sheet to Skip"]
// Add Header Row
outputRows.push(['="Linked Sheet"'])
// Get all Sheet and add them to the outputRows using a Hyperlink
ACTIVE.getSheets().forEach( sheet => {
// Skip certain sheets which are defined above
if( skipSheets.indexOf(sheet.getName()) != - 1) return
outputRows.push([`=HYPERLINK("${spreadsheetURL}#gid=${sheet.getSheetId()}", "${sheet.getName()}")`])
})
// Write everything to Index
currentIndexSheet.getRange(1,1, outputRows.length).setFormulas(outputRows)
}

How to iterate through a range and build a "table" based on a criteria, using Google Apps Script?

I got the following table to populate (range D6:J15) as I search the data in another sheet, based on a date criteria found in row 4:
This is where I'm to look for the data, considering Col A as the basis for the criteria:
My difficulty is to concatenate the data, as they meet the criteria.
This is the code I'm working on:
/* #OnlyCurrentDoc */
function editarPrevProd() {
const lock = LockService.getScriptLock();
lock.tryLock(3000);
if (lock.hasLock()) {
var sourceSheet = 'PrevProdDB2';
var destinationSheet = 'Previsão Entreposto';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var ActiveSheetName = ss.getActiveSheet().getName();
var LastRowSource = sheet.getLastRow();
var LastColumnSource = sheet.getLastColumn();
var values = sheet.getRange(2,1,LastRowSource,9).getValues();
var csh = ss.getSheetByName(destinationSheet);
var itens = csh.getRange("I40:J57");
var data = [];
var weekNo = csh.getRange("B4").getValue();
var weekDates = csh.getRange("D4:J4").getValues();
if (weekNo == "") {
Browser.msgBox("Escolher uma data e tente novamente!");
return;
}
//var clearRng = ["K34:K35", "N34:N35", "I40:K"];
//csh.getRangeList(clearRng).clearContent();
for (var i = 0; i < values.length; i++) {
if (values[i][7] == weekNo) {
data.push(values[i]);
//break;
}
}
var dias = 0;
var prevData = [];
for (var j = 0; j < weekDates.length; j++) {
dias = dias + 1;
Logger.log("Dias da Semana: " + dias);
for (var a = 0; a < data.length; a++) {
if (weekDates[j].valueOf() == data[a][0].valueOf()){
prevData.push(data[a][4]);
}
}
}
//map columns whose data will be set in the header.
var user = data.map(function(e){return e[5];});
var lastUpdate = data.map(function(e){return e[6];});
//Copy data array to destination sheet
csh.getRange("I1").setValue(user);
csh.getRange("I2").setValue(lastUpdate);
//csh.getRange("E6").setValue(timeStamp);
//If you wanted to set arrays in the form of
//a table, you'd use this below instead
var seg = data.map(function(e) {return [e[3]];});
var ter = data.map(function(e) {return [e[4]];});
var qua = data.map(function(e) {return [e[5]];});
var qui = data.map(function(e) {return [e[6]];});
var sex = data.map(function(e) {return [e[7]];});
var sab = data.map(function(e) {return [e[8]];});
var dom = data.map(function(e) {return [e[9]];});
//csh.getRange(6,4,data.length,1).setValues(seg);
lock.releaseLock();
}
}
Here's a sample of the file. Note that the gs file I'm working on is named SalvaPrevProducao.
https://docs.google.com/spreadsheets/d/1NOWkzQIAPPdZdxeeTR7Id2v8LR00_u06uPhHs3tzLuU/edit?usp=sharing
I believe your goal as follows.
You want to convert the above image to the bottom image using Google Apps Script.
The date header is the cells "D4:J4".
The source values are the cells "A6:M".
The column "M" of ID is Semana in the destination sheet.
In this case, I would like to propose the following flow.
Retrieve values from the source sheet.
Create an array for putting to the destination sheet.
Put the array to the destination sheet.
When this flow is reflected to the Google Apps Script, it becomes as follows.
Sample script:
Before you use this script, please set the variables of srcSheetName and dstSheetName.
function editarPrevProd() {
const srcSheetName = "Data Source"; // This is the source sheet name.
const dstSheetName = "destSheet"; // Please set the destination sheet name.
// This is from https://stackoverflow.com/a/44563639
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
// 1. Retrieve values from the source sheet.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const srcSheet = ss.getSheetByName(srcSheetName);
const lastRow = srcSheet.get1stNonEmptyRowFromBottom(1);
const [[, , , ...header1], header2, ...srcValues] = srcSheet.getRange("A4:M" + lastRow).getValues();
// 2. Create an array for putting to the destination sheet.
const values = header1.reduce((ar, h, i) => {
srcValues.forEach(([a, b, c, ...dm]) => ar.push([h, a, b, c, dm[i] || 0, "", "", dm.pop(), h]));
return ar;
}, [["Data", "Tipo", "Cod", "Descrição", "Qtd", "Usuário", "TimeStamp", "Semana", "Data"]]);
// 3. Put the array to the destination sheet.
const dstSheet = ss.getSheetByName(dstSheetName);
dstSheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
When above script is run, the values are retrieved from srcSheetName and the converted values are put to dstSheetName .
Result:
When above script is run, the following result is obtained.
Note:
Unfortunately, from your question and sample Spreadsheet, I couldn't understand about Usuário and TimeStamp of the columns "F" and "G". At the sample output situation of Turn the data from the left into the format on the right side, Usuário and TimeStamp have no values.
References:
reduce()
forEach()
It is unclear why you would need to resort to scripting to look up those values, when a filter() formula would seem capable to do the same. Try this formula in cell D6:
=sum( iferror( filter(PrevProdDB2!$E$2:$E, PrevProdDB2!$B$2:$B = $A6, PrevProdDB2!$H$2:$H = $B$4, PrevProdDB2!$I$2:$I = D$4) ) )

Consolidate data into one master Google sheet using App Scripts

I am trying to consolidate data from multiple tabs into a consolidated sheet. Each tab is an individual form and has the same format. On the consolidated sheet, I want to re-arrange the data so the data field name is in a column, and data values are in rows. I tried the following:
function consolidateData(){
// defined all variables
var sheetNames = [];
var dataSheet = [];
var dataValues = [];
var conso=[];
var header = [["Faculty Name","Faculty ID","Date of Joining"]];
var ws = SpreadsheetApp.getActiveSpreadsheet();
// get all sheets
var allsheets = ws.getSheets();
for(var s in allsheets)
var sheet = allsheets[s];
sheetNames[s] = sheet.getName();
dataSheet[s] = ws.getSheetByName(sheetNames[s]);
// writing data into new sheet
var newSheet = ws.insertSheet().setName("Consolidated_Data");
newSheet.getRange("A1:C1").setValues(header);
var name = dataSheet[s].getRange("B1").getValue();
var id = dataSheet[s].getRange("B3").getValue();
var doj = dataSheet[s].getRange("B5").getValue();
var faculty = [(name),(id),(doj)];//convert into array
var facultycount = faculty.length;
for (var i = 0; i < faculty.length; i++)
//Loop through all rows and write them out starting on ROW2
{
newSheet.getRange(2 + i, 1).setValue(faculty[0]);//
newSheet.getRange(2 + i, 2).setValue(faculty[1]);//
newSheet.getRange(2 + i, 3).setValue(faculty[2]);//
}
}
There are four tabs and I expect to see results from each tab in the Consolidated_Data tab. But I only saw the last tab data got inserted repeatedly. Can anyone help? Thank you. Consolidated Data Sheet Example of an individual tab
While traversing through all your sheets, you haven't used curly braces after the for loop -
for(var s in allsheets)
So it's running the loop and the value of s stays at the last index of allsheets.
However, might I suggest a simplified version I have tested out -
function consolidateData () {
const headers = ["Faculty Name", "Faculty ID", "Date of joining"];
const rows = { "name": 0, "id": 2, "doj": 4 };
const consolidatedSheetName = "Consolidated_Data";
const ss = SpreadsheetApp.getActive();
const sheets = ss.getSheets();
let consolidatedValues = [];
// Setting headers
consolidatedValues.push(headers);
// Fetching values
for(let sheet of sheets) {
if(sheet.getName()==consolidatedSheetName) { continue; }
let data = sheet.getRange("B1:B5").getValues();
let faculty = [ data[rows.name][0], data[rows.id][0], data[rows.doj][0] ];
consolidatedValues.push(faculty);
}
// Adding to sheet
let consolidatedSheet = ss.getSheetByName(consolidatedSheetName);
if(!consolidatedSheet) {
consolidatedSheet = ss.insertSheet().setName(consolidatedSheetName);
}
let range = consolidatedSheet.getRange(1, 1, consolidatedValues.length, consolidatedValues[0].length); // 1, 1, 3, 3
range.setValues(consolidatedValues);
}
Issue:
The script is overwriting the same range here:
newSheet.getRange(2 + i, 1).setValue(faculty[0]);
Solution:
Add 1 for each row added:
newSheet.getRange(2 + i + s, 1).setValue(faculty[0]);
Or use sheet#appendRow()
newSheet.appendRow(faculty);
If you practice best practices, Your script can be simplified like this:
const consolidate = () => {
const ws = SpreadsheetApp.getActiveSpreadsheet(),
oldSheets = ws.getSheets(),
newSheet = ws.insertSheet().setName('Consolidated_Data');
newSheet.getRange(1, 1, 1 + oldSheets.length * 3, 3).setValues([
['Faculty Name', 'Faculty ID', 'Date of Joining'],
...oldSheets.map(sheet =>
sheet
.getRange('B1:B5')
.getValues()
.reduce((a, c, i) => (i % 2 === 0 ? [...a, c[0]] : a), [])
),
]);
};