I have problem with value setting in googlesheet. Googlesheet setValue support only array but i need to put object in rows.
I tried use appendRow but it won't work in custom functions. I also tried setValue with converting my objects to array but then i missed some data.
This is my fetching function. It works and gets all data i need but it's really hard for me to place it into googlesheet.
function importTrelloJSON(url){
var response = UrlFetchApp.fetch(url);
var content = response.getContentText();
var data = JSON.parse(content);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var trelloJSON = data.map(function(el, index) {
var customFieldItems = el.customFieldItems.map(function(el){
return [el.idCustomField, el.value.number];
});
return { name: el.name, customFieldItems: customFieldItems };
});
retrun trelloJSON;
}
and this is my JSON structure, sometimes there is nested data
[
{
"id": "5ce26ef1d5bdac4ec20e8982",
"name": "WWW",
"customFieldItems": []
},
{
"id": "5ced04d96ec7ed6120b5e91d",
"name": "Marketing",
"customFieldItems": []
},
{
"id": "5cfed3d8e88f931008aa58ad",
"name": "Reset softu Android",
"customFieldItems": [
{
"id": "5cfed4145d019516555a9086",
"value": {
"number": "100"
},
"idCustomField": "5ced79c27bbd7102945ba1ff",
"idModel": "5cfed3d8e88f931008aa58ad",
"modelType": "card"
}
]
},
I tried using ready importJSON function https://github.com/bradjasper/ImportJSON but it's not working with my queries.
Thanks for help.
//edit
Now i can display data but when i push to array i have problem with range. The number of data columns does not match the number of columns in the range.
I tried Math.max.apply(Math, trelloJSON.map(function (el) { return el.length })). But it's not working anymore.
Here is my new code:
function importTrelloJSON(url){
var response = UrlFetchApp.fetch(url);
var content = response.getContentText();
var data = JSON.parse(content);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var mainArray = new Array();
var trelloJSON = data.map(function(el, index) {
mainArray = [];
mainArray.push(el.name);
el.customFieldItems.map(function(el){
mainArray.push(el.idCustomField);
mainArray.push(el.value.number);
});
Logger.log(mainArray);
return mainArray;
});
sheet.getRange(1,1, trelloJSON.length, Math.max.apply(Math, trelloJSON.map(function (el) { return el.length }))).setValues(trelloJSON);
}
Related
I am using this app script code to get a JSON format of some data in a sheet in Google Sheets.
function doGet(request){
var mode = request.parameter.mode;
var search = request.parameter.q;
var sheetname = "Members"; //sheet name
var startcol = 1;
var endcol = 10;
var filtercol = 7;
var doc = SpreadsheetApp.openById(PropertiesService.getScriptProperties().getProperty("key"));
var sheet = doc.getSheetByName(sheetname);
var lastrow = sheet.getLastRow();
var rows = [];
var range = sheet.getRange(2,startcol,lastrow, endcol);
var values = range.getValues();
for(var row in values) {
rows.push([]);
for(var col in values[row]){
rows[row].push(values[row][col]);
}
}
//data retrieved, JSON formatting begins below (on the basis of presence of a filtering key)
if(search != null) { //if there is something to filter
var rowstoreturn = rows.filter(a => a[filtercol] == search);
return ContentService.createTextOutput(JSON.stringify({"data":rowstoreturn,"error":false})).setMimeType(ContentService.MimeType.JSON);
}
return ContentService.createTextOutput(JSON.stringify({"data":rows,"error":false})).setMimeType(ContentService.MimeType.JSON);
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
PropertiesService.getScriptProperties().setProperty("key", doc.getId());
}
(In my above script, if I want to get filtered data, I'll send the parameter q, else not. So if I've sent it, I'd get a JSON which consits of filtered data.)
A successful run of the above code gives me this result -
{
"data": [
[
"LM-6000",
"Yes",
"Mr.",
"John",
"Doe",
1998,
"B.Com",
1234567890,
"sample#gmail.com",
"NYC"
]
],
"error": false
}
Now, as you can see, these are just the cell values - what I want to do is get respective column name along with the value. Something like this -
{
"data": [
[
{
"Membership No.": "LM-6000",
"Logged In": "Yes",
"Salutation": "Mr.",
"FName": "John",
"LName": "Doe",
"GradYr": 1998,
"Course": "B.Com",
"Mobile No.": 1234567890,
"Email ID": "sample#gmail.com",
"City": "NYC"
}
]
],
"error": false
}
How should I modify my code to get the expected result? Any help is appreciated :) Thanks!
As far as I can tell you want to convert the array into an object, where keys of the object are the column headers and values of the object are the array elements. It can be done with a loop:
var headers = ['a','b','c'];
var row = ['cell1','cell2','cell3'];
var obj = {};
row.forEach((cell,i) => obj[headers[i]] = cell);
console.log(obj);
Expected output:
{
"a": "cell1",
"b": "cell2",
"c": "cell3"
}
So, the last lines of the function doGet() should look something like this:
...
if (search != null) {
var rows = rows.filter(a => a[filtercol] == search);
}
// get the first row of the table as a header
var header = sheet.getRange(1,startcol,1,endcol).getValues().flat();
// convert array of rows into the array of objects
rows = rows.map(row => {
var obj = {};
row.forEach((cell,i) => obj[headers[i]] = cell);
return obj;
})
// return the array of objects
return ContentService
.createTextOutput(JSON.stringify({"data":[rows],"error":false}))
.setMimeType(ContentService.MimeType.JSON);
}
I'm getting values of the sheet in JSON format. My Sheet
I've added this code in appscript to get JSON:
var ss = SpreadsheetApp.openByUrl("Spreadsheet URL");
var sheet = ss.getSheetByName('Sheet1');
function doGet(e){
var action = e.parameter.action;
if(action == 'getItems'){
return getItems(e);
}
}
function getItems(e){
var records={};
var rows = sheet.getRange(2, 1, sheet.getLastRow() - 1,sheet.getLastColumn()).getValues();
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
record['customerName'] = row[0];
record['docketNo']=row[1];
record['docketDate']=row[2];
record['destination']=row[3];
record['weight']=row[4];
data.push(record);
}
records = data;
var result=JSON.stringify(records);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
Current JSON data:
[
{
"customerName":"cash",
"docketNo":"d87976489",
"docketDate":"2021-08-14T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"cash",
"docketNo":"d87976480",
"docketDate":"2021-08-12T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"abc",
"docketNo":"d87976482",
"docketDate":"2021-09-12T18:30:00.000Z",
"destination":"mumbai",
"weight":2
}
]
I want this JSON data:
[
{
"customerName":"cash",
"docketNo":"d87976489","d87976480",
"docketDate":"2021-08-14T18:30:00.000Z","2021-08-12T18:30:00.000Z",
"destination":"kanpur","kanpur",
"weight":1,1
},
{
"customerName":"abc",
"docketNo":"d87976482",
"docketDate":"2021-09-12T18:30:00.000Z",
"destination":"mumbai",
"weight":2
}
]
I have the same customer names therefore, I want unique data. I've searched many websites & videos but I didn't get one.
Please give me appscript code to get this data!
You can do it with some Javascript acrobatics
Sample:
function makeJsonUnique() {
var json = [
{
"customerName":"cash",
"docketNo":"d87976489",
"docketDate":"2021-08-14T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"cash",
"docketNo":"d87976480",
"docketDate":"2021-08-12T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"abc",
"docketNo":"d87976482",
"docketDate":"2021-09-12T18:30:00.000Z",
"destination":"mumbai",
"weight":2
}
]
var customerNames = json.map(e=>e.customerName)
var uniqueCustomerNames = [...new Set(customerNames)]
var newJSON =[]
uniqueCustomerNames.forEach(function(name){
var tempObj ={}
tempObj.customerName = name
var jsonSubsets = json.filter(function(obj){return obj.customerName == name})
tempObj.docketNo = jsonSubsets.map(obj=>obj.docketNo).join(",")
tempObj.docketDate = jsonSubsets.map(obj=>obj.docketDate).join(",")
tempObj.destination = jsonSubsets.map(obj=>obj.destination).join(",")
tempObj.weight = jsonSubsets.map(obj=>obj.weight).join(",")
console.log(JSON.stringify(tempObj))
newJSON.push(tempObj)
})
console.log(newJSON)
}
Used methods:
map()
filter()
...newSet()
push()
join()
I am seeking help with the following case
I have a spreadsheet, and it contains few filter views - f1, f2, ...
I have an app script associated with the spreadsheet. I have enabled Resources > Advanced Google Services to access the Sheets API v4.
Currently, I access that data as
var fruits = Sheets.Spreadsheets.Values.get("1YBPXShvssFpTI-5dPSsy_N_iEVaeHezdxymsdxpTy6w", "Fruits!A:B").values;
And I get the corresponding data back.
I would now, like to only get the data that is used by the filter view, so that I do not bring the entire data which is not necessary and slows down the processing.
I saw that there is something called Sheets.Spreadsheets.getByDataFilter(resource, spreadsheetId), but I am not sure how to create the resource object.
Given my filters, and knowing the spreadsheet Id, how do I only fetch the data based on the filter names that I know?
UPDATE
My latest attempt looks like
var ss = SpreadsheetApp.getActiveSpreadsheet();
function getUnpostedItems() {
Logger.log("This function will prioritize the new items that are added into the inventory");
var sheet = ss.getSheetByName("Items");
var filterSettings = {};
filterSettings.criteria = {};
var condition = {
"condition": {
"type": "LESS_THAN",
"values": [
{ "userEnteredValue": "=NOW()-30" }
]
}
}
filterSettings['criteria'][1] = {
'condition': condition
};
var filterSettings = {
range: {
sheetId: sheet.getSheetId(),
},
}
var req = {
"setBasicFilter": {
"filter": filterSettings
}
}
// var items = Sheets.Spreadsheets.batchUpdate({'requests': [req]}, ss.getId());
var items = ss.getRange("Items!A:B").getValues()
// var items1 = Sheets.Spreadsheets.Values.get("1YBPXShvssFpTI-5dPSsy_N_iEVaeHezdxymsdxpTy6c", "Items!A:B").values
Logger.log("Found items:" + items.length);
return [];
}
But no luck so far!
As per #tanaike's help, I was able to get the following working
function getUnpostedItems() {
Logger.log("This function will prioritize the new items that are added into the inventory");
// var ss = SpreadsheetApp.getActiveSpreadsheet(); // Added
var sheet = ss.getSheetByName("Items"); // Modified
var values = sheet.getDataRange().getValues();
Logger.log("VALUES "+values.length);
//var newCriteria = SpreadsheetApp.newFilterCriteria().whenDateBefore(new Date()).build();
var newCriteria = SpreadsheetApp.newFilterCriteria().whenDateBefore(subDaysFromDate(new Date(), 30)).build();
var range = sheet.getFilter().setColumnFilterCriteria(1, newCriteria).getRange(); //The 1-indexed position of the column.
// values = range.getValues();
// I added below script.
var res = Sheets.Spreadsheets.get(ss.getId(), {
ranges: ["Items"], // <--- Please set the sheet name.
fields: "sheets/data"
});
var values = res.sheets[0].data[0].rowMetadata.reduce(function(ar, e, i) {
if (!e.hiddenByFilter && res.sheets[0].data[0].rowData[i]) {
ar.push(
res.sheets[0].data[0].rowData[i].values.map(function(col) {
return col.userEnteredValue[Object.keys(col.userEnteredValue)[0]];
})
);
}
return ar;
}, []);
Logger.log("VALUES "+values.length);
Logger.log("VALUES "+values);
//Logger.log("Found Items:" + items.length);
return [];
}
I want to get a JSON out my spreadsheet that looks like this() and to extract a JSON file like this:
[{ "module": "ModuleA",
"Questions" : [{
"Question": "xxxx",
"Answers" : ["1","2","3"],
"right answer" : "2",
}
]
This is what i have by now but its not in the coreect hierarchy
function doGet(){
var ss = SpreadsheetApp.openById('14-vl75N4mAv9FdZNHIhX_lhtQ-XY17lOvEnLIjiSwDc');
var result={};
var sheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetA')
.getDataRange()
.getValues();
var sheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetB')
.getDataRange()
.getValues();
result.sheetA = makeObject(sheetA);
result.sheetB = makeObject(sheetB);
Logger.log(result.sheetA)
//return ContentService.createTextOutput(JSON. stringify(result))
//.setMimeType(ContentService.MimeType.JSON);
}
function makeObject(multiArr) {
var obj = {};
var headers = multiArr.shift()
for(var i = 0; i< headers.length; i++){
obj[headers[i]]= multiArr.map(function(app){
return app[i];
});
}
return obj;
}
What about this solution?
function doGet(){
var ss = SpreadsheetApp.openById('14-vl75N4mAv9FdZNHIhX_lhtQ-XY17lOvEnLIjiSwDc');
var result={};
var sheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetA')
.getDataRange()
.getValues();
var sheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetB')
.getDataRange()
.getValues();
result.sheetA = makeObject(sheetA);
result.sheetB = makeObject(sheetB);
Logger.log(makeObject(sheetA))
}
function makeObject(multiArr) {
var obj = [];
for(var i=1;i<multiArr.length;i++)
{
obj.push( {
"Question": multiArr[i][1],
"Answers" : [multiArr[i][2],multiArr[i][3],multiArr[i][4]],
"right answer" : multiArr[i][5],
}
)
}
var myJSON=[{ "module": multiArr[1][0],
"Questions" : obj
}]
return JSON.stringify(myJSON);
}
You can push into an array your data formatted according to the hierarchy of
your choice, populate it within a loop with the contents of each row
in your sheet and then JSON.stringify it.
This works as above provided you have only one module per sheet. Otherwise, you need to implement an additional function which would detect in which row ModuleA ends and ModuleB starts.
I'm using Google Apps Scripts to parse some JSON and it's not working...
Here's my pseudo-code:
function fetchInsta() {
var url = "xxx";
Logger.log(url);
var result = UrlFetchApp.fetch(url);
var json = JSON.parse(result.getContentText());
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var existingids = sheet.getRange("D:D");
for(i in json.data){
for(j in existingids){
if(json.data[i].id = existingids[i]){
var match = true;
}
}
if(match != true){
var id = json.data[i].id;
var image = json.data[i].images.standard_resolution.url;
var username = json.data[i].user.username;
var link = json.data[i].link;
var date = json.data[i].createdtime;
sheet.appendRow([image,username,link,id,date]);
Logger.log([image,username,link,id,date]);
}
}
}
I've removed the URL as it has my API key in it. But here's a sample of the JSON returned:
"data":[
{
"attribution":null,
"tags":[ ],
"type":"image",
"location":{ },
"comments":{ },
"filter":"Normal",
"created_time":"1430751422",
"link":"https:\/\/instagram.com\/p\/2Q6AiIG4hT\/",
"likes":{ },
"images":{ },
"users_in_photo":[ ],
"caption":{ },
"user_has_liked":false,
"id":"977536242480285779_10266761",
"user":{ }
},
I'm getting the variables image, username, link fine - but id and date are both undefined. Any ideas what's happening? What am I doing wrong?
This line of code:
if(json.data[i].id = existingids[i]){
Is using an assignment operator to test for equality. Equality tests are done with double or triple equal signs. If in doubt, use triple equal signs.
Should be:
if(json.data[i].id === existingids[i]){