I am fetching data from an api to google sheet. all its getting is data string on a single cell. How can I format it into a table with headers. Part of the long string I am getting and the code are below.
String - {instantBuy=5679.95, pricechange=0, instantSell=5623.39, currency=AUD, 24hoursHigh=5848.86, market=5848.86, virtualCurrency=ETH, 24hoursLow=5848.86, sell=5848.86, volume=0.341947, buy=5848.86, pair=ETH-AUD} ...
Code:
function myQuotes() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName('Sheet1');
var url = "https://www.zebapi.com/pro/v1/market/";
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var data = JSON.parse(json);
mainSheet.getRange(4,2).setValue(data);
Thanks!
Use Object.entries(), like this:
function myQuotes() {
const url = "https://www.zebapi.com/pro/v1/market/";
const response = UrlFetchApp.fetch(url);
const json = response.getContentText();
const data = transpose_(Object.entries(JSON.parse(json)));
const targetRange = SpreadsheetApp.getActive().getRange('Sheet1!B4');
targetRange.offset(0, 0, data.length, data[0].length).setValues(data);
}
function transpose_(a) {
// #see https://stackoverflow.com/a/13241545/1536038
return Object.keys(a[0]).map(c => a.map(r => r[c]));
}
You may also want to take a look at ImportJSON.
I'm not very familiar with JavaScript, but you could try the search() method, which I believe returns the index at which the word is found. So for example, if you were trying to put data from "instantBuy", and put it in it's own row or column, you could do search("instantBuy"), get the string between that and the next index that search will return, search("pricechange")
Sorry if that was confusing!
Related
I have the following data example in a google sheet:
url
https://www.testwebsite.com/compute/v1/test/images-prd-5d4d/glob/images/testimage-vsfd
https://www.testwebsite.com/compute/v1/test/images-prd-5d4d/glob/images/testimage-sdawr|
What I need is to extract the data after the substring "images/" and have something like this:
url
extract
https://www.testwebsite.com/compute/v1/test/images-prd-5d4d/glob/images/testimage-vsfd
testimage-vsfd
https://www.testwebsite.com/compute/v1/test/images-prd-5d4d/glob/images/testimage-sdawr|testimage-sdawr
I have created the following function to get this but is only extracting everything after the last "-":
function strip() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet6");
const vs = sh.getRange(2,1,sh.getLastRow() - 1).getDisplayValues().flat();
let vo = vs.map(s => [s.match(/\b[0-9A-Zaz/]+$/gi)[0]]);
sh.getRange(2,2,vo.length,1).setValues(vo);
}
What is the proper way to extract the data it's mentioned above?
You could use this on Apps Script:
function strip() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet6");
const vs = sh.getRange(2,1,sh.getLastRow() - 1).getDisplayValues().flat();
const string= "/images/";
for (i = 0; i < vs.length; i++){
//Using substrings:
const extract = vs[i].substring(vs[i].indexOf(string) + string.length);
sh.getRange(i+2,2).setValue(extract);
//Using .split():
// const extract = vs[i].split(string); //This splits the string in 2.
// sh.getRange(i+2,2).setValue(extract[1]); //Adding the second part of the array;
}
}
If you want to do it like a custom function you can try the following code:
function strip(url) {
var text = url;
var splittedValue = text.split("/images/");
return splittedValue[1];
}
It would work something like this:
Input:
Result:
The script can also be changed to get a specific range of data automatically so that every time you add a new URL you get the result in the next column automatically, but this is just for you to get the idea.
References:
Custom Functions in Google Sheets
Say your URLs are in A2:A. You can use
=arrayformula(if(isblank(A2:A),,substitute(REGEXEXTRACT(A2:A,"/images/[A-Za-z0-9-_|/\.]+"),"/images/","")))
Use native formulas where possible. That is more efficient.
If you already dealt with the issue with run time delay, and have a need to use custom function for other reasons, you can match with the "/image/" part and then remove it, or, alternatively, specifying a capturing group. Also don't forget other value characters such as _, |.
I make a request to Go to Webinar API in Apps Script and the response is something like this:
{"joinUrl":"https://example.com","asset":true,"registrantKey":3669516009270899211,"status":"APPROVED"}
When I make a JSON.parse i get something like this:
{joinUrl=https://example.com, asset=true, registrantKey=3.6695160092708992E18, status=APPROVED}
The RegistrantKey changes, I dont know why.
Thats my code:
try{
var resp = UrlFetchApp.fetch(url,options)
var json=JSON.parse(resp);
return json
}catch(err){
Logger.log(err);
return err;
}
How about this answer? Please think of this as just one of several possible answers.
Issue and workaround:
I think that the reason of your issue is that 3669516009270899211 of "registrantKey":3669516009270899211 is used as the number. In Javascript, the maximum integer value is 9007199254740991. Ref So when 3669516009270899211 is converted to the number, it becomes 3.6695160092708992E18 and when this is converted to the string, it becomes 3669516009270899000.
So in this case, as one of several workaround, how about enclosing 3669516009270899211 by the double quotes like "registrantKey":"3669516009270899211"? By this, "3669516009270899211" is used ad the string, and you can retrieve the value of 3669516009270899211.
Modified script:
When your script is modified, how about the following modification?
From:
var resp = UrlFetchApp.fetch(url,options)
var json=JSON.parse(resp);
return json
To:
var resp = UrlFetchApp.fetch(url,options);
resp = resp.getContentText().replace(/registrantKey":(\d.+),/, "registrantKey\":\"$1\","); // Added
var json=JSON.parse(resp);
return json
Note:
As the test script, you can also use the following script.
var str = '{"joinUrl":"https://example.com","asset":true,"registrantKey":3669516009270899211,"status":"APPROVED"}';
str = str.replace(/registrantKey":(\d.+),/, "registrantKey\":\"$1\",");
var obj = JSON.parse(str);
Logger.log(obj)
Reference:
Number.MAX_SAFE_INTEGER
If I misunderstood your question and this was not the direction you want, I apologize.
I am currently working on a semester project for my university in which we want to log data from an Arduino to a Google Sheet.
I was following the numerous tutorials and examples that I could find on Google and it worked so far really, really well. My Arduino is able to upload data to said spreadsheet.
Unfortunately all those examples always only deal with one row to be filled. For our project we would like to fill 2 or 3 lines simultaneously.
I will shortly show what I have done so far and maybe you can help me solve my (probably easy) problem.
I created a google spreadsheet in which I want to log my data
I used the script from a tutorial that should fill one row.
By typing the following line in my browserhttps://script.google.com/macros/s/<gscript id>/exec?tempData=datahereI am now able to fill row one with my data in enter in the end of the url.
But how do I progress now, when I want to fill two or three rows of the table? I say that the author of the code already implemented an option to fill the third row, yet I can't find out what to input in my url then to fill it with data.
All my attempts to write something like
https://script.google.com/macros/s/<gscript id>/exec?tempData=datahere&tempData1=value2
just ended in writing
datahere&tempData1=value2
in my first row, not filling datahere into the first and value2 in to the second row.
How can I provide and write multiple rows of data?
The code in this script is:
/*
GET request query:
https://script.google.com/macros/s/<gscript id>/exec?tempData=data_here
*/
/* Using spreadsheet API */
function doGet(e) {
Logger.log( JSON.stringify(e) ); // view parameters
var result = 'Ok'; // assume success
if (e.parameter == undefined) {
result = 'No Parameters';
}
else {
var id = '<ssheet id>'; // Spreadsheet ID
var sheet = SpreadsheetApp.openById(id).getActiveSheet();
var newRow = sheet.getLastRow() + 1;
var rowData = [];
//var waktu = new Date();
rowData[0] = new Date(); // Timestamp in column A
for (var param in e.parameter) {
Logger.log('In for loop, param='+param);
var value = stripQuotes(e.parameter[param]);
//Logger.log(param + ':' + e.parameter[param]);
switch (param) {
case 'tempData': //Parameter
rowData[1] = value; //Value in column B
break;
case 'tempData1':
rowData[2] = value; //Value in column C
break;
default:
result = "unsupported parameter";
}
}
Logger.log(JSON.stringify(rowData));
// Write new row below
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
// Return result of operation
return ContentService.createTextOutput(result);
}
/**
* Remove leading and trailing single or double quotes
*/
function stripQuotes( value ) {
return value.replace(/^["']|['"]$/g, "");
}
I would suggest the following:
Create a 2d array of your data you wish to write to the spreadsheet. If your client on Arduino were using JavaScript this might look like :
var data = [
["row1value1", "row1value2"],
["row2value1", "row2value2"]
];
Convert this to JSON, again in JavaScript this might look like:
var json = JSON.stringify(data);
This gives you a string representation of your array.
Now make your request using this data. I would suggest you should look at using doPost instead of doGet, as you are sending data to the spreadsheet that updates state. However, for the purposes of getting something working, your URL would look like:
https://script.google.com/<.....>/exec?myarray=<stringified JSON>
In Apps Script, in your doGet (again, consider using doPost instead), you could then use:
// Get the JSON representation of the array:
var json = e.parameter.myarray;
// Convert back to 2d array
var data = JSON.parse(json);
Now you can write this to a Range in Sheets using setValues, e.g. assuming a rectangular 2d array:
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
Hope this helps
I have FlexTable with chekBoxes in first cell of each row, when checkBox is true data from FlexTable's row is collected in variable. Now I need to create document with table that contains table with data from variable. I tried to store string's value in Hidden but it doesn't work and can't figure out how to realise it.
All my (although the code is not really my, code is almost half #Sergeinsas's) code is avaliable here: http://pastebin.com/aYmyA7N2, thankyou in advance.
There are a few errors in your code... widgets like hidden can only have string values and they can only return string values when you retrieve their values.
One possible and easy way to convert arrays to string (and back) is to use a combination of join() and split() , here is the modified code (relevant part only) that works.
// Storing checked rows
function check(e) {
var checkedArray = [];
var data = sh.getRange(1,1,lastrow,lastcol).getValues();
for(var n=0; n < data.length;++n){
if(e.parameter['check'+n]=='true'){
checkedArray.push(data[n].join(','));// convert data row array to string with comma separator
}
}
var hidden = app.getElementById('hidden');
hidden.setValue(checkedArray.join('|'));// convert array to string with | separator
return app;
}
function click(e) {
var hiddenVal = e.parameter.hidden.split('|');// e.parameter.hidden is a string, split back in an array of strings, each string should be splitted too to get the original array of arrays
var d = new Date();
var time = d.toLocaleTimeString();
var table = []
for(var n in hiddenVal){
table.push(hiddenVal[n].split(','));// reconstruction of a 2D array
}
DocumentApp.create('doc '+time).getBody().appendTable(table);// the table is in the document
}
Full code available here
EDIT : suggestion : if you put your headers in your spreadsheet you could retrieve them in your final table quite easily like this :
function check(e) {
var checkedArray = [];
var data = sh.getRange(1,1,lastrow,lastcol).getValues();
checkedArray.push(data[0].join(','));// if you have headers in your spreadsheet, you could add headers by default
for(var n=0; n < data.length;++n){
if(e.parameter['check'+n]=='true'){
checkedArray.push(data[n].join(','));
}
}
You could also use data[0] in the doGet function to build the header of your UI, I think this would make your code more easy to maintain without hardcoding of data.... but this is only a suggestion ;-)
i got a quick one for someone who can help. I've downloaded some data from yahoo. I want to split the data into a N x 7 array. (is that the correct term?).
I want it to look like this:
[[2013-01-29,64.25,65.03,64.00,64.24,4883100,64.24],[2013-01-28,64.51,64.87,63.27,64.59,7591300,64.59],...]
but now, as you can see, it's not in that format. Novice to javascript. Please help.
function function() {
var ticker='YUM';
var startMonth=0; var startDate=1; var startYear=2013;
var endMonth=0; var endDate=25; var endYear=2013;
var fetchString="http://ichart.finance.yahoo.com/table.csv?s="+ticker+"&a="+startMonth+"&b="+startDate+"&c="+startYear+"&d="+endMonth+"e="+endDate+"&f="+endYear+"&g=d";
var response = UrlFetchApp.fetch(fetchString);
a=response.getContentText();
var allData = a.slice(a.indexOf("2013"));
}
Assuming you don't want the column headers, this is a one line change:
var allData = a.match(/(.*?)\n/g) // convert each line to a row
.splice(1) // remove headers row
.map(function(row){
return row.replace(/\n/,'').split(',');
}); // convert row string to array