split the sheet into different workbooks by column values with dynamic range in apps script - google-apps-script

I want to split the google sheet into different workbooks, not tabs in the same workbook based on values in column A. Although I have got a script that splits the data into different workbooks but the data range in it is not dynamic like the number of columns to be added into each workbook are fixed. I want them to be dynamic like till the last column of the data range. I have tried a lot to make it dynamic by adding loops but it shows The number of columns in the data does not match the number of columns in the range. The data has 1 but the range has 12. this error. The data in the log has almost no difference for the fixed range (which is working fine) and for the dynamic range that I have tried to it But don't know why it is showing error. Have got stuck into it. any help will be highly appreciated.
This the function that I am trying.
function splitSheets() {
var theWorkbook = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = theWorkbook.getSheetByName("Master");
var slc = theSheet.getDataRange().getLastColumn()
var slcv = theSheet.getRange("B1:B" + slc).getValues()
var sheets = theWorkbook.getSheets();
for (i = 0; i < sheets.length; i++) {
switch(sheets[i].getSheetName()) {
case "Master":
break;
default:
theWorkbook.deleteSheet(sheets[i]);
}
}
var key = theSheet.getRange("A:A").getValues();
var rows = theSheet.getDataRange().getValues();
var headerFormat = theSheet.getRange("2:2").getValues();
var folderId = '16XVypjB5_PWe2PaBIREpDGCNQlZuWL4k'
var completedSheets = [];
for (var i = 2; i < key.length; i++) {
// if(completedSheets.includes('Blank') && key[i][0] === ""){
// }else{
if(!completedSheets.includes(key[i][0]) ) {
if (key[i][0] === "") {
var name = 'Blank'
var resource = {
title: name,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var insertedFile = Drive.Files.insert(resource)
var csid = insertedFile.id
var currentSheet = SpreadsheetApp.openById(csid).getSheetByName("Sheet1")
// var currentSheet = theWorkbook.insertSheet("Blank");
} else {
var name = key[i][0]
var resource = {
title: name,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var insertedFile = Drive.Files.insert(resource)
var csid = insertedFile.id
var currentSheet = SpreadsheetApp.openById(csid).getSheetByName("Sheet1")
// var currentSheet = theWorkbook.insertSheet(key[i][0]);
}
var theNewRows =[];
var b=0;
for(var j = 1; j < rows.length; j++) {
var rown = []
for(var c = 0; c < slcv.length; c++){
// some other trials
// if((rows[j][0] == key[i][0]) || (rows[j][0] === '' && currentSheet.getName() == "Blank")){
// theNewRows[b]=[];
// theNewRows[b].push (
// rows[j][c].toString()
// This although adds the data and range dynamically but also shows the mentioned error.
rown.push(rows[j][c])
// );
// b++;
// }
}
if((rows[j][0] == key[i][0]) || (rows[j][0] === '' && currentSheet.getName() == "Blank")){
theNewRows[b]=[];
theNewRows[b].push (
rown.toLocaleString()
// These are the fixed column for data rnage
// rows[j][0],rows[j][1],rows[j][2],rows[j][3],rows[j][4],rows[j][5],rows[j][6],rows[j][7],rows[j][8],rows[j][9],rows[j][10],rows[j][11]
);
b++;
}
Logger.log(rown)
}
Logger.log(theNewRows)
// Logger.log(theNewRows)
currentSheet.getRange("1:1").setValues(headerFormat)
var outrng = currentSheet.getRange(2,1,theNewRows.length, slc);//Make the output range the same size as the output array
outrng.setValues(theNewRows);
currentSheet.autoResizeColumns(1, slc);
if(currentSheet.getSheetName() == 'Blank') {
completedSheets.push('Blank');
last = "Blank";
}else{
completedSheets.push(key[i][0])
last = key[i][0]
// }
}
}
}
SpreadsheetApp.setActiveSheet(theWorkbook.getSheetByName('Master'));
}

I overhauled and improved your script to be more readable and use a lot less Spreadsheet calls by using array methods instead.
Script:
function splitSheets() {
var folderId = '*** FOLDER ID ***';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheets = spreadsheet.getSheets();
var sheet = spreadsheet.getSheetByName('Master');
// delete sheets that are not named 'Master'
sheets.forEach(sheetIter => {
if(sheetIter.getSheetName() != 'Master')
spreadsheet.deleteSheet(sheetIter);
});
var data = sheet.getDataRange().getValues();
// remove 1st row (blank row)
data.shift();
// remove 2nd row from data and assign as headers
var headers = data.shift();
// get unique list of sheet names from column A
var sheetNames = data.map(row => row[0]).filter(onlyUnique);
// loop those unique sheetNames
sheetNames.map(sheetName => {
// filter data by getting only rows with same column A and sheetName
var outputData = data.filter(row => row[0] == sheetName);
// add header from data filtered
outputData.unshift(headers);
var resource = {
title: sheetName || 'Blank',
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var file = Drive.Files.insert(resource);
var currentSheet = SpreadsheetApp.openById(file.id).getSheetByName('Sheet1');
// write data filtered with the header
currentSheet.getRange(1, 1, outputData.length, outputData[0].length).setValues(outputData);
// resize the columns
currentSheet.autoResizeColumns(1, outputData[0].length);
});
}
// function to get unique values from array using filter
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
Sample Output:

Related

how to copy a range with groups information?

I copy "range" from one sheet to another using range.copyTo(..) function, it doesnt copy group information
var destSheet = some_sheet;
var sourceRange=SpreadsheetApp.getActiveSheet().getRange("A1:H10");
sourceRange.copyTo(destSheet.getRange(1,1));
Values, format, formula are copied. Not groups
Issue and workaround:
In the current stage, it seems that the dimension groups cannot be directly copied by copyTo method. So, in order to copy the dimension groups, it is required to retrieve the dimension groups and put them.
When Sheets API is used, the dimension groups can be retrieved as an object. Using this, in this answer, I would like to propose to use Sheets API. When this is reflected in your script, it becomes as follows.
Modified script:
Before you use this script, please enable Sheets API at Advanced Google services. And, please set your destination sheet name.
function deleteDimensionGroups_(sheetId, sheet) {
var obj = [...(sheet.rowGroups || []), ...(sheet.columnGroups || [])];
if (obj.length == 0) return [];
return obj
.sort((a, b) => a.depth < b.depth ? 1 : -1)
.map(o => {
o.range.sheetId = sheetId;
delete o.depth;
return { deleteDimensionGroup: o };
});
}
// Please run this function.
function main() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssId = ss.getId();
var srcSheet = ss.getActiveSheet();
var dstSheet = ss.getSheetByName("Sheet2"); // Please set your destination sheet name.
var sourceRange = srcSheet.getRange("A1:H10");
sourceRange.copyTo(dstSheet.getRange(1, 1));
// Copy dimension groups.
var { sheets } = Sheets.Spreadsheets.get(ssId, { ranges: [srcSheet.getSheetName(), dstSheet.getSheetName()] });
var sheet = sheets[0];
var obj = [...(sheet.rowGroups || []), ...(sheet.columnGroups || [])];
if (obj.length == 0) return;
var sheetId = dstSheet.getSheetId();
var reqs = deleteDimensionGroups_(sheetId, sheets[1]);
var requests = [...reqs, ...obj
.sort((a, b) => a.depth > b.depth ? 1 : -1)
.map(o => {
o.range.sheetId = sheetId;
delete o.depth;
return { addDimensionGroup: o };
})];
Sheets.Spreadsheets.batchUpdate({ requests }, ssId);
}
Note:
In this sample script, the existing dimension groups are deleted from the destination sheet and the new dimension groups are copied. If you don't want to delete the dimension groups in the destination sheet, please modify the above script as follows.
From:
var reqs = deleteDimensionGroups_(sheetId, sheets[1]);
To:
var reqs = [];
References:
Method: spreadsheets.batchUpdate
AddDimensionGroupRequest
Added:
From your following reply,
It's full of informations. Trying to adapt it and create a copyToWithGroup(sourceRange, destRange).. not so easy at my level. But I have materials in your answer to work with.
If you want to limit the range using var sourceRange = srcSheet.getRange("A1:H10");, how about the following sample script?
Sample script:
function deleteDimensionGroups_(sheetId, obj) {
if (obj.length == 0) return [];
return obj
.sort((a, b) => a.depth < b.depth ? 1 : -1)
.map(o => {
o.range.sheetId = sheetId;
delete o.depth;
return { deleteDimensionGroup: o };
});
}
// Please run this function.
function main() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssId = ss.getId();
var srcSheet = ss.getActiveSheet();
var dstSheet = ss.getSheetByName("Sheet2"); // Please set your destination sheet name.
var sourceRange = srcSheet.getRange("A1:H10"); // In this sample, this range is used.
sourceRange.copyTo(dstSheet.getRange(1, 1));
// Copy dimension groups in "sourceRange".
var startRowIndex = sourceRange.getRow() - 1;
var endRowIndex = startRowIndex + sourceRange.getNumRows();
var startColumnIndex = sourceRange.getColumn() - 1;
var endColumnIndex = startColumnIndex + sourceRange.getNumColumns();
var { sheets: [src, dst] } = Sheets.Spreadsheets.get(ssId, { ranges: [srcSheet.getSheetName(), dstSheet.getSheetName()] });
var check = f => f.filter(({ range }) => {
if (range.dimension == "ROWS" && range.startIndex >= startRowIndex && range.endIndex <= endRowIndex) {
return true;
} else if (range.dimension == "COLUMNS" && range.startIndex >= startColumnIndex && range.endIndex <= endColumnIndex) {
return true;
} else {
return false;
}
});
var [src2, dst2] = [src || [], dst || []].map(e => {
var temp = [];
if (e.rowGroups && e.rowGroups.length > 0) temp = [...temp, ...check(e.rowGroups)];
if (e.columnGroups && e.columnGroups.length > 0) temp = [...temp, ...check(e.columnGroups)];
return temp;
});
if (src2.length == 0) return;
var sheetId = dstSheet.getSheetId();
var reqs = deleteDimensionGroups_(sheetId, dst2);
var requests = [...reqs, ...src2
.sort((a, b) => a.depth > b.depth ? 1 : -1)
.map(o => {
o.range.sheetId = sheetId;
delete o.depth;
return { addDimensionGroup: o };
})];
Sheets.Spreadsheets.batchUpdate({ requests }, ssId);
}

when i run my script to fetch data from other 2 sheets it is arranged the shown in picture of master sheet

master sheet
this is my code
the names are displayed under names numbers to be displayed under numbers but it is displayed under names ..I have 2 sheets named as{name,number} and a master sheet contains id,name number.
when i run the script it ftches data but not accordingly
function addMenu()
{
var menu = SpreadsheetApp.getUi().createMenu('Merge');
menu.addItem('Run Script', 'MergeSheets');
menu.addToUi();
}
function onOpen()
{
addMenu();
}
//combine data from multiple sheets
function MergeSheets() {
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var data = null;
var RetrieveSheet = null;
var PasteSheet = ss.getSheetByName("Master");
var sheets = ['Name','Number'];
PasteSheet.getRange(2,1,PasteSheet.getLastRow(),PasteSheet.getLastColumn()).clear();
for (var i =0; i<sheets.length; i++){
RetrieveSheet = ss.getSheetByName(sheets[i]);
if (RetrieveSheet.getName() != 'Master'){
data = RetrieveSheet.getRange(2,1,RetrieveSheet.getLastRow(),RetrieveSheet.getLastColumn());
data.copyTo(PasteSheet.getRange(parseInt(PasteSheet.getLastRow())+1,1));
}
}
}
//update data changes to each sheets
function updateBasedSheet()
{
var master = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Master');
var valueMaster = master.getRange(2, 1, master.getLastRow(), master.getLastColumn()).getValues();
var Name = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Name');
var Number = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Number');
var dataName = valueMaster.filter( function(item){
return item[2] === 'Name';
}
);
var Number = valueMaster.filter( function(item){
return item[2] === 'Number';
});
Name.getRange(1, 3, dataName.length, dataName[0].length).setValues(dataName);
Number.getRange(1, 3, dataNumber.length, dataNumber[0].length).setValues(dataNumber);
}
If you simply want to join 2 sheets, and they have same length and id correspondesce, you can use
var data1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Name').slice(1);
var data2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Number').slice(1);
var mergedData = data1.map( (index, row) => row.concat(data2[index]) );
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Master')
.getRange(2, 1, mergedData.length, mergedData[0].length)
.setValues(mergedData);

Google App Script to Search data from multiple files and displaying multiple row

I want users to search for their info from multiple sheet files and display multiple results boxes(row) but currently it's searching from one sheet and displaying only the first result(row) and not displaying the rest results.
What do I need to change in the script?
function submitData(obj){
var ss = SpreadsheetApp.openById("SHEETID");
var sheet = ss.getSheetByName("SHEETNAME");
var flag = 1 ;
var lr = sheet.getLastRow();
for(var i = 1;i <= lr;i++){
var id = sheet.getRange(i, 1).getValue();
if(id == obj){
flag = 0;
var B = sheet.getRange(i, 2).getValue();
var C = sheet.getRange(i, 3).getDisplayValue();
var data ="<div class="card"><h3>Info1:"+B+"</h3><p>Info2:"+C+"</p></div>";
return data;
}
}
if(flag==1){
var data = '<div class="carderror">Data not found</div>';
return data;
}
index.html
<input id="id" class="form-control">
<button type="submit" onclick="info()"> search</button>
<div id="result"></div>
<script>
function info () {
let obj = document.querySelector('#id').value;
let updateLocation = document.querySelector('#result');
updateLocation.innerHTML = "Searching...";
function onFailure(error){
let warning = error;
updateLocation.innerHTML = warning;
};
function onSuccess(response){
let result = response;
updateLocation.innerHTML = result;
};
google.script.run.withFailureHandler(onFailure)
.withSuccessHandler(onSuccess)
.submitData(obj);
};
</script>
You're only opening a single sheet file in your example. If you want to search multiple you'll have to specify which files you want to open and loop through them. My example below assumes all the files have the same sheet name.
Right now you're returning the first matched result, which is causing your search function to exit prematurely. To display multiple results you can push the matched lines to an array, then return that array once all the scanning is complete.
function submitData(obj) {
//specify what sheet IDs you want to search
var sheetNames = ['foo', 'bar', 'bla']
//create an array to push results to
var inject = []
for (var i = 0; i < sheetNames.length; i++) {
var sheetName = sheetNames[i]
var ss = SpreadsheetApp.openById(sheetName);
var sheet = ss.getSheetByName("SHEETNAME");
var flag = 1;
var lr = sheet.getLastRow();
for (var i = 1; i <= lr; i++) {
var id = sheet.getRange(i, 1).getValue();
if (id == obj) {
flag = 0;
var B = sheet.getRange(i, 2).getValue();
var C = sheet.getRange(i, 3).getDisplayValue();
var data = "<div class='card'><h3>Info1:" + B + "</h3><p>Info2:" + C + "</p></div>";
//push result to array
inject.push(data)
}
}
}
if (flag == 1) {
var data = '<div class="carderror">Data not found</div>';
return data;
} else {
//return joined array as string
return inject.join()
}
}
Multi-spreadsheet search
function MultiSearch() {
const ss = SpreadsheetApp.getActive();
const idsh = ss.getSheetByName("ssids");
const rsh = ss.getSheetByName("Results");
rsh.getRange(2,1,rsh.getLastRow() - 1, rsh.getLastColumn()).clearContent()
const ids = idsh.getRange(2,1,idsh.getLastRow() - 1,idsh.getLastColumn()).getValues().filter(r => r[2] == "TRUE").map(r => r[1]);
const r = SpreadsheetApp.getUi().prompt("Search Dialog","Enter Search String",SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(r.getSelectedButton() == SpreadsheetApp.getUi().Button.OK && r.getResponseText().length > 0) {
ids.forEach(id => {
let ss = SpreadsheetApp.openById(id);
let tf = ss.createTextFinder(r.getResponseText()).findAll();
tf.forEach(f =>{
rsh.appendRow([ss.getName,f.getSheet().getName(),f.getRow(),f.getColumn()]);
})
})
}
}
ssids Sheet:
Results Sheet:

Getting data from a column and pasting it in a row

I'm trying to get the data from an original sheet named "Interface Boletagem" that is column C rows 6 to 28 and paste this data in a new sheet named "Boletador (Dados)" on the last blank row and in different columns. Basically transposing all the data from the original sheet.
I managed to make it work, but the current script is taking a long time to complete... Any tips on how to optimize it?
function submitDataInbound(){
//declare a variable and set the reference of active google sheet
var myGoogleSheet=SpreadsheetApp.getActiveSpreadsheet();
var shUserForm=myGoogleSheet.getSheetByName("Interface Boletagem");
var datasheet=myGoogleSheet.getSheetByName("Boletador (Dados)");
//code to update the data on database sheet
var ui=SpreadsheetApp.getUi();
var columnToCheck = datasheet.getRange("A:A").getValues();
function getLastRowSpecial(range){
var rowNum = 0;
var blank = false;
for(var row = 0; row < range.length; row++)
if(range[row][0] === "" && !blank){
rowNum = row;
blank = true;
}else if(range[row][0] !== ""){
blank = false;
};
return rowNum;
};
var blankRow=getLastRowSpecial(columnToCheck) + 1;
datasheet.getRange(blankRow,1).setValue(shUserForm.getRange("C26").getValue());//ID
datasheet.getRange(blankRow,2).setValue(shUserForm.getRange("C27").getValue());//DF
datasheet.getRange(blankRow,3).setValue(shUserForm.getRange("C11").getValue());//VMN
datasheet.getRange(blankRow,4).setValue(shUserForm.getRange("C12").getValue());//VME
datasheet.getRange(blankRow,5).setValue(shUserForm.getRange("C21").getValue());//Dea
datasheet.getRange(blankRow,6).setValue(shUserForm.getRange("C22").getValue());//PS
datasheet.getRange(blankRow,7).setValue(shUserForm.getRange("C23").getValue());//LSBD
datasheet.getRange(blankRow,8).setValue(shUserForm.getRange("C24").getValue());//SS
datasheet.getRange(blankRow,9).setValue(shUserForm.getRange("C20").getValue());//TID
datasheet.getRange(blankRow,10).setValue(shUserForm.getRange("C6").getValue());//Cli
datasheet.getRange(blankRow,11).setValue(shUserForm.getRange("C28").getValue());//CV
datasheet.getRange(blankRow,12).setValue(shUserForm.getRange("C7").getValue());//Moe
datasheet.getRange(blankRow,13).setValue(shUserForm.getRange("C16").getValue());//TFX
datasheet.getRange(blankRow,14).setValue(shUserForm.getRange("C8").getValue());//QtME
datasheet.getRange(blankRow,15).setValue(shUserForm.getRange("C9").getValue());//TxBco
datasheet.getRange(blankRow,16).setValue(shUserForm.getRange("C10").getValue());//TxCli
datasheet.getRange(blankRow,17).setValue(shUserForm.getRange("C14").getValue());//IOF
datasheet.getRange(blankRow,18).setValue(shUserForm.getRange("C13").getValue());//Tar
datasheet.getRange(blankRow,19).setValue(shUserForm.getRange("C17").getValue());//BPar
datasheet.getRange(blankRow,20).setValue(shUserForm.getRange("C19").getValue());//Nat
datasheet.getRange(blankRow,21).setValue(shUserForm.getRange("C18").getValue());//CBPar
datasheet.getRange(blankRow,22).setValue(shUserForm.getRange("C15").getValue());//IR
ui.alert('Boletado')
shUserForm.getRange("C6").clear();
shUserForm.getRange("C7").clear();
shUserForm.getRange("C8").clear();
shUserForm.getRange("C9").clear();
shUserForm.getRange("C10").clear();
shUserForm.getRange("C11").clear();
shUserForm.getRange("C12").clear();
shUserForm.getRange("C13").clear();
shUserForm.getRange("C14").clear();
shUserForm.getRange("C15").clear();
shUserForm.getRange("C16").clear();
shUserForm.getRange("C17").clear();
shUserForm.getRange("C18").clear();
shUserForm.getRange("C19").clear();
shUserForm.getRange("C6").setBackground('#BEBEBE');
shUserForm.getRange("C7").setBackground('#BEBEBE');
shUserForm.getRange("C8").setBackground('#BEBEBE');
shUserForm.getRange("C9").setBackground('#BEBEBE');
shUserForm.getRange("C10").setBackground('#BEBEBE');
shUserForm.getRange("C11").setBackground('#BEBEBE');
shUserForm.getRange("C12").setBackground('#BEBEBE');
shUserForm.getRange("C13").setBackground('#BEBEBE');
shUserForm.getRange("C14").setBackground('#BEBEBE');
shUserForm.getRange("C15").setBackground('#BEBEBE');
shUserForm.getRange("C16").setBackground('#BEBEBE');
shUserForm.getRange("C17").setBackground('#BEBEBE');
shUserForm.getRange("C18").setBackground('#BEBEBE');
shUserForm.getRange("C19").setBackground('#BEBEBE');
}
I believe your goal is as follows.
You want to reduce the process cost of your script.
In this case, how about the following modification? In order to retrieve the values from the scattered cells, I used Sheets API. And, in order to clear and set background to the cells "C6", "C7", "C8", "C9", "C10", "C11", "C12", "C13", "C14", "C15", "C16", "C17", "C18", "C19", shUserForm.getRange(6, 3, 14).clear().setBackground('#BEBEBE') is used.
Modified script:
Before you use this script, please enable Sheets API at Advanced Google services.
function submitDataInbound() {
var myGoogleSheet = SpreadsheetApp.getActiveSpreadsheet();
var shUserForm = myGoogleSheet.getSheetByName("Interface Boletagem");
var datasheet = myGoogleSheet.getSheetByName("Boletador (Dados)");
var ui = SpreadsheetApp.getUi();
var columnToCheck = datasheet.getRange("A:A").getValues();
function getLastRowSpecial(range) {
var rowNum = 0;
var blank = false;
for (var row = 0; row < range.length; row++)
if (range[row][0] === "" && !blank) {
rowNum = row;
blank = true;
} else if (range[row][0] !== "") {
blank = false;
};
return rowNum;
};
var blankRow = getLastRowSpecial(columnToCheck) + 1;
var ranges1 = ["C26", "C27", "C11", "C12", "C21", "C22", "C23", "C24", "C20", "C6", "C28", "C7", "C16", "C8", "C9", "C10", "C14", "C13", "C17", "C19", "C18", "C15"];
var values = Sheets.Spreadsheets.Values.batchGet(myGoogleSheet.getId(), { ranges: ranges1.map(e => `'Interface Boletagem'!${e}`) }).valueRanges.map(({ values }) => values[0][0]);
datasheet.getRange(blankRow, 1, 1, values.length).setValues([values]);
ui.alert('Boletado');
shUserForm.getRange(6, 3, 14).clear().setBackground('#BEBEBE');
}
Reference:
Method: spreadsheets.values.batchGet

Replace character using google apps script

I have a column which is a date in string format with this format
2020-02-23T12:14:06+0000
And i want to remove the T and replace it with space and also just completely remove the last part (+0000)
I have tried this
var A1 = CONTENT.getRange("B:B").getValue();
var A1String = A1.toString().replace("T*", "");
but it doesn't work.
Any ideas?
This is the original script in which i want to incorporate it into.
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('sheetname');
var range = sheet.getRange("A:C");
var response = UrlFetchApp.fetch("API CALL");
var dataAll = JSON.parse(response.getContentText());
var dataSet = dataAll.data;
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([new Date(),data.created_time,data.message,data.permalink_url,
data.reactions.summary.total_count
,data.comments.summary.total_count,data.insights.data[1].values[0].value,data.insights.data[2].values[0].value,data.insights.data[3].values[0].value,data.insights.data[0].values[0].value['link clicks'],data.insights.data[0].values[0].value['photo view'],data.insights.data[0].values[0].value['other clicks'],data.insights.data[0].values[0].value['video play'],data.insights.data[4].values[0].value,data.insights.data[5].values[0].value,data.insights.data[6].values[0].value,data.insights.data[7].values[0].value["like"],data.insights.data[7].values[0].value["love"],data.insights.data[7].values[0].value["wow"],data.insights.data[7].values[0].value["haha"],data.insights.data[7].values[0].value["sorry"]]); //your JSON entities here
}
Logger.log(rows)
//sheet.getRange(getlastRow() + 1, 1, rows.length, 2).setValues(rows);
sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 22).setValues(rows);
/**
* Removes duplicate rows from the current sheet.
*/
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetname');
var data = sheet.getDataRange().getValues();
data.reverse(); //reverses the row order.
var last=sheet.getLastRow();
var newData = new Array();
for(i in data){
//Logger.log(i);
var row = data[i];
//Logger.log(row[5]);
var duplicate = false;
for(j in newData){
//Logger.log(newData[j][3]);
if(row[3] == newData[j][3]){
duplicate = true;
}
}
if(!duplicate){
newData.push(row);
}
}
newData.reverse(); // reverses your data back to its original order.
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
//
//
If you want to remove always the same thing (i.e. "T" and "+0000"), you could use the following script:
The result obtained: 2020-02-23 12:14:06
CODE:
// ---------- Menu ----------
// Add a Menu named Format Date to run the script
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Format Date')
.addItem('Go!', 'FormatDate')
.addToUi();
}
function FormatDate() {
var ss = SpreadsheetApp.getActiveSheet(),
array = [];
ss.getRange("B2:B") // Choose the range here
.getValues()
.forEach(function (dates) {
// "T" is replaced with a space: " " and "+0000" is replace with empty:""
[["T", " "], ["+0000", ""]]
.map(function (a, i) {
return dates = replace(dates.toString(), a[0], a[1])
})
array.push([dates])
});
// You can set a different column to write the data
// Or keep B2:B to overwrite your data
ss.getRange("B2:B")
.setValues(array)
}
function replace(d, a, r) {
return d.indexOf(a) > -1 ? d.split(a)
.join(r) : d;
}
Credit: got inspired by JPV's code to a different question long time ago