Google Sheets Apps Script to copy (GoogleFinance) data archive via appendRow - google-apps-script

I'm using in Sheets the GoogleFinance-API to get the current $/€ exchange course.
I'm archiving this data via an apps script - reading out the fields and writing those back in the sheet using appendRow - for testing purposes I did it on a minute interval...
It worked for about 10 rows - after this it writes instead of the stock-exchange value a date '30.12.1899 23:41:33' in the field (the logs in apps scripts are fin though) - have no clue where it comes from and what I'm doing wrong here - please have a look at the screen grabs
function saveData() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var data = sheet.getRange(5,1,1,2).getValues();
var time = data[0][0];
var stock = data[0][1];
Logger.log(time+" ::: "+stock);
sheet.appendRow(data[0]);
Logger.log(data);
}
just added the images here - stackoverflow is not very intuitive for 1st time users.

Related

ImportHTML won't update data

I'm trying to use ImportHTML in Google Spreadsheets to update data regularly. The standard ImportHTML-code updates once an hour which is too slow, so I found some Google Script to do it every minute. (I should mention I'm not a developer so I'm kinda operating blind)
However, the script doesn't replace the old data with the new data (which is the idea). I need to remove all data from the spreadsheet for it to update the information. It seems to me te script is executing, but simply doesn't overwrite when cells are already filled. This is the Script I'm using:
function myFunction() {
var sh = SpreadsheetApp.getActiveSheet();
var r = "A1";
var insertDataOption = 'overwrite';
var f = '=ImportHTML("URL";"table";1)';
sh.getRange(r).setFormula(f) .onChange;
}
I hope you can help, thankS
If you add the same formula it might not not trigger a IMPORTHTML update. To make it work, first you could to clear the cell holding the IMPORTHTML formula, in this case A1, force the spreadsheet update, then add the formula.
function myFunction() {
var sh = SpreadsheetApp.getActiveSheet();
var r = "A1";
var insertDataOption = 'overwrite';
var f = '=ImportHTML("URL";"table";1)';
var range = sh.getRange(r);
range.clear();
SpreadsheetApp.flush();
range.setFormula(f);
}
By the other hand if you are already using Google Apps Script, instead of using IMPORTHMTL you could use the Fetch Service to to the same job. This will require more coding but you will have more control over how frequently is updated your spreadsheet.
Resources
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#flush
Related (More recent first)
Google Sheets IMPORTHTML
ImportHTML recalculation by the minute
Script to refresh data with IMPORTHTML in Google Sheets
Trigger importHTML in Google Apps Script
Importing javascript table into Google Docs spreadsheet

Convert onEdit script to manually running script

The script has the purpose of writing the datetimestamp to a specific cell the moment when a cell in column 4 has the text Assign.
I have a script that theoretical works but I'm getting my data from Appsheet. The problem with this is that Appsheet writes data into my sheet but the script wont see it as edited cells, so it wont write the time stamp.
But my knowledge about Apps Scripts is pretty bad. And I am getting errors with the source line and the col, val lines.
function onEdit(e) {
var sh = e.source.getActiveSheet();
var row = e.range.getRow();
var col = e.range.getColumn();
var val = sh.getRange(row, 4).getValue();
//check if sheet is 'Blad1' & value is 'Assign'
if (sh.getSheetName() === 'Blad1' && val == 'Assign') {
var tz = e.source.getSpreadsheetTimeZone();
var date = Utilities.formatDate(new Date(), tz, 'dd-MM-yyyy hhmmss');
//set date in column 14 for same row
sh.getRange(row, 14).setValue(date);
}
}
I want to convert my script to a manually run script with a time-based trigger of 1 min. That way I hope the script will see the changed cell to Assign.
The problem is rooted in apps script triggers restrictions, specifically in their inability to listen to script-based events. I would suggest deploying your script as a WebApp with doGet() / doPost() functions to listen to API requests and, if I am correct in assuming that AppSheet works similarly to Zapier, etc., add a step that calls your WebApp after making changes to your Spreadsheet.
Please, see this guide on WebApps, its pretty straightforward to follow.
P.s. Btw, refrain from creating triggers acting as event listeners, you will easily cap your quotas!

How to set daily google app script to output fixed value

Am quite new with Google Scripts and wondering if anyone can help with this.
I've connected Google Analytics to Google Sheets (via add-on) and made settings so that conversion numbers are generated daily into a new google sheet tab (sheetB).
I'd like to match dates then copy the conversion data from sheetB to sheetA (master sheet which has acts like a dashboard).
The above can be done using this formula:
=IF(DA2=JuicerSessTime!$A$16,JuicerSessTime!$B$16)
The problem I'm facing is that since the above is a formula, I can't save the conversion data as a fixed value. So yesterday's value would show as FALSE from the formula above.
I'd like to be able to keep and save all daily generated values.
I've tried to create a google script below but it doesn't seem to work, hope someone can help.
function moveOneValuesOnlyToday() {
var mydate = new Date();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sdate = ss.getRange('sheetB!B2');
var sdate2 = ss.getRange('sheetA!DA2');
var source = ss.getRange('sheetA!DA5');
if (sdate == sdate2){
source.copyTo(ss.getRange('sheetA!DA6'), {contentsOnly: true});
}
}
Thanks in advance!

Can I add a formula to a google form response using Apps Script?

Apologies as I am a beginner to coding. I am interested in using Google Apps Script to automate the analysis of a Google Form response.
The simple example I have is for the spreadsheet of responses for a form asking people:
1) how many players there were?
2) where they finished [1st, 2nd, etc,]
On submission of the form I want to run a script that calculates how may points they received and inserts this value in the next available column (column E in this example).
I have tried writing my first Apps Script to automate this process, but without success.
SAMPLE CODE:
function onFormSubmit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Form Responses Master");
var players = e.values[2];
var place = e.values[3];
var positionPoints = e.values[4];
var positionPoints = (players - place + 1);
return positionPoints;
}
I know there are workarounds available by creating duplicate pages, but I was hoping someone might be able to advise me on how to code a solution in App Scripts, in the hope I might get a better understanding of the coding process.
You can write your appscript in the response collector spreadsheet itself instead of writing your code in form's script editor.
So, go to your response sheet and paste this code.
function myFunction()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses Master");
var rowNo = sheet.getLastRow();
var colNo = sheet.getLastColumn();
sheet.getRange(rowNo, colNo).setValue("=(C"+rowNo+"-D"+rowNo+")+1");
}
Now, go to Resources -> Current project triggers. Click on add new and set these values in drop downs: myFunction - From Spreadsheet - On form submit.
And you are done. Whenever a new response is submitted, position points will be calculated automatically.
Here,
variable sheet gets your active spreadsheet for different sheet operations which you can perform.
rowNo and colNo as seen in the code, simply fetches the value of last row/column respectively of spreadsheet in which something is written.
And, to set formula in column 'E', you can use setValue. Hence, "=(C"+rowNo+"-D"+rowNo+")+1" will be converted to (C2-D2)+1 in case of second row and so on for next rows.
getRange is simply used to tell the script that write formula inside particular cell.

How to merge a large number of form response sheets into one master sheet. (Google Sheets)

I have a spreadsheet in which I have the form response sheets from a large number of forms (quizzes). As all the forms contain the same format, number and order of questions I want to collect them all into one sheet.
I know this can be done using the query({sheet1!range,sheet2!range...}) But the size of this query would be huge (have over 25 forms!) and it would require me to fiddle around with this formula every time I add a new form.
What i initially investigated was creating a list of sheets in a range and then tried to get arrayformula query to run through that list using indirect. This however did not work and after asking on this forum have been told that that cannot be done.
I was advised to look into scripts and have spent all weekend trying to find a script that can do this. I have however failed.
I need the script to copy the last row of a form response sheet to the bottom of a master sheet. I would like the script to do this to all response sheets (I have a naming format for sheets that would allow the script to easily see which sheets to incorporate). I would imagine I need to use the onSubmit() function but not sure.
Overview
I don't think that using a on submit trigger is a good idea because there are several forms involved and a large number of responses. By the other hand could be conflicts if several responses are submitted very close. IMHO a better approach is to run the script by demand (manually) or by using a time-driven trigger.
As Google Apps Script execution time should not exceed six minutes1, instead of checking each sheet for new responses I think that a better approach is to clear the master sheet and append all the sheet responses at once. This could work if there will no be notes, comments, custom formats, data validations or data changes applied directly on the master sheet.
Script
Below is a script that joins the content of form responses sheets that are in the same spreadsheet to a sheet named 'Master'. It could be easily adapted, I think.
It's assumed that the spreadsheet only contains form responses sheets and the 'Master' sheet.
/**
* Joins the data from form responses sheets on a master responses sheet.
* Assumes that the master sheet has the form response headers and
* that there aren't extra columns.
*/
function joinSheetsData() {
// Initialize loop variables
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var masterName = 'Master'; // Change this.
var masterSheet = ss.getSheetByName(masterName);
var headers = [masterSheet.getDataRange().getValues()[0]];
var masterdata = [];
// Loop to append form responses from all response sheets to one array.
for(var i = 0; i < sheets.length; i++){
if(sheets[i].getName() != masterSheet.getName()){
var data = sheets[i].getDataRange().getValues();
data.splice(0,1);
masterdata = append(masterdata,data);
}
}
// Clear the master sheet.
masterSheet.clear();
// Add the headers to the master sheet.
var masterheadersRow = masterSheet.getRange(1, 1, 1,
masterdata[0].length);
masterheadersRow.setValues(headers);
// Send the resulting array to the master sheet.
var masterdataRange = masterSheet.getRange(2, 1, masterdata.length,
masterdata[0].length);
masterdataRange.setValues(masterdata);
}
/*
* Auxiliary function to append 2D arrays.
*/
function append(a,b){
for(var i = 0; i<b.length; i++){
a.push(b[i]);
}
return a;
}