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.
Related
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 [];
}
Im getting my JSON inside {} but i need it inside [] so my other app can read it.
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))
Logger.log(makeObject(sheetB))
return ContentService.createTextOutput(JSON. stringify(result))
.setMimeType(ContentService.MimeType.JSON);
}
function makeObject(multiArr) {
var obj = [];
for(var i=1;i<multiArr.length;i++)
{
obj.push( {
"Question": multiArr[i][1],
"Answers" : [multiArr[i][3],multiArr[i][4],multiArr[i][5],multiArr[i][6]],
"right answer" : multiArr[i][7],
}
)
}
var myJSON=[{ "module": multiArr[1][0],
"Questions" : obj
}]
return JSON.stringify(myJSON);
}
CURRENT OUTPUT:
"{
sheetA: "[{"module":"ModuleA","Questions":[{"Question":"2+2=?","Answers":[7,11,12,4],"right answer":4},{"Question":"Q2","Answers":[1,2,1,3],"right answer":3},{"Question":"Q3","Answers":[10,230,23,44],"right answer":44}]}]",
sheetB: "[{"module":"ModuleB","Questions":[{"Question":"2+2=?","Answers":[7,11,12,4],"right answer":4},{"Question":"Q2","Answers":[1,2,1,3],"right answer":3},{"Question":"Q3","Answers":[10,230,23,44],"right answer":44}]}]"
}"
EXPECTED OUTPUT:same thing but all inside [...]
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);
}
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]){