Automatic data record in Google Sheets - google-sheets

I receive the data on the P/E multiple in Google Sheets via GOOGLEFINANCE in the following manner:
=GOOGLEFINANCE("GOOGL","pe")
How to write script in Google Sheets that would record the P/E values (or better the values of a particular cell) every day as at, say, 21:00?

Use Google Apps Script.
You want to write a function that uses the Spreadsheet API to get the value of a given Range in a given Sheet, and then append that value in a new row on a different sheet.
You also want to set up a time-based trigger to execute that function.
As an example, for a bound script with only one worksheet:
function copyA1toA2onSameSheet() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheet.getRange("A2").setValue(
sheet.getRange("A1").getValue()
);
}
Note that getActiveSheet will always return the first sheet from a time-based trigger, as there is no UI instance. If you need a different sheet, consider getSheetByName, or using getSheets().

Related

Google drive sheets importrange

I am looking for a way to import the data from one google drive sheet to another using ImportRange formula. However, I want the data to be synced once per day at a certain time instead of automatically updating as the formulas seems to do. Any help would really be appreciated
Formula used:
={IMPORTRANGE(B2,"sheet1!$A$1");IMPORTRANGE(B3,"sheet1!$A$1");IMPORTRANGE(B4,"sheet1!$A$1"); IMPORTRANGE(B5,"sheet1!$A$1");
IMPORTRANGE(B6,"sheet1!$A$1")
}
You can create a Script (Google Apps Script) that copies the data automatically with Time-driven Triggers (https://developers.google.com/apps-script/guides/triggers).
function copyData() {
// Gets data
var data = SpreadsheetApp.openById("ID1").getSheetByName("SheetName").getRange("A1:B2").getValues();
// Copies data
SpreadsheetApp.openById("ID2").getSheetByName("SheetName").getRange("A1:B2").setValues(data);
}

Google-Sheet - query multiple unknown sheets?

Context: I need to develop a Google Sheet to manage yearly cost and revenues from the Charity where I volunteer. This file will be updated from volunteers, so I need to develop a structure which they can use with easiness.
My idea:
have a front sheet with a summary from activities and charts
let volunteers duplicate a template event cost and revenue and add their c&r
Result would have as much sheets as many Events and Charity or Fundraising events/campaign.
But, since the number of sheets is unknown till the end of the year, how can I have a summary sheet?
E.G. How can I sum all costs and all rev? Can I query to search in **all existing sheets the cell that follows an exact string (e.g. Total Rev)?**
You can write an Apps Script - a Google Script service based on Javascript
It is relatively simple to learn and use and it will allow you to loop dynamically through all the sheets without knowing in advance how many there will be.
The following sample script iterates through all sheets minus the master sheet of the spreadsheet to which it is bound and sums the values of the cells "A10" (if this is the cell where you have your costs) together. Finally it sets the value of the sum into the cell "A10" fo the master sheet.
function myFunction() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sheets=ss.getSheets();
var sum=0;
for (var i=0; i<sheets.length; i++){
if(sheets[i].getName()!="Master"){
var value=sheets[i].getRange("A10").getValue();
sum=sum+value;
}
}
ss.getSheetByName("Master").getRange("A10").setValue(sum);
}
If you take some time to get familiar with Apps Script, you will be able to easily adapt the sample above to your needs.
I would recommend that the volunteers don't fill out anything on the sheet at all.
You can collect all you need from the volunteers via a google Form. That form will dump all the data into a single tab in google sheets from which it will be easy to analyze and summarize the data that you want to see and share with the whole team.

Is there a Google Sheets formula expression that only evaluates when the sheet is edited?

The title sums it up pretty well. I need a cell of my document to reflect the last time any cell in the document updated. "=now()" doesn't work, because now() is evaluated any time the sheet is evaluated - even if there is no change. This means that even the simple act of hitting the browser's reload button causes now() to update its cell - TWICE!
I'd rather not use the onEdit trigger in script, because that would require that I add that script to 1000+ sheets. I already have a way to edit document through the python sheets API, so it would be fairly easy to automatically add the expression wherever I need it.
Volatile spreadsheet functions are not suitable for timestamps, for the reason you stated.
Use a trigger. You don't need to add a script to each sheet. A single stand-alone Google Apps Script can automatically install an "on edit" trigger for multiple spreadsheets, using forSpreadsheet(key) method. Example:
var ids = ['ss_id1', 'ss_id2', ... ]; // array of spreadsheet IDs
for (var i = 0; i < ids.length; i++) {
ScriptApp.newTrigger('timestamp').forSpreadsheet(ids[i]).onEdit().create();
}
function timestamp(e) {
e.source.getActiveSheet().getRange(1, 1).setValue(new Date());
}
Now, whenever one of the listed spreadsheets is edited, the cell A1 of the sheet that was edited in it will have the time of the edit.
This probably won't work for 1000 triggers, because of current limitations of 20 triggers per user per script. Looks like you'll need 50 copies of the stand-alone script, which is a stretch but still manageable.
Another alternative is to run a scheduled Google Apps Script that retrieves "last modified" dates of spreadsheets in the directory (using DriveApp) and edits those in the spreadsheets.
Yet another is to give up. Maybe you don't need a cell to hold information that is already available in spreadsheet interface, "last edited".

Google Sheets Function to determine when a referenced document was last altered

Context:
I have a Google Sheets document with my daily tasks in it. Many of my tasks involve me checking to see if changes have been made to other Google Sheets (referenced in my daily task document) in the past day.
Goal:
I want a function which will tell me when one of the referenced Google sheets was last altered.
Here is an example:
https://docs.google.com/spreadsheets/d/1JV-ZvO1P5PPU2Eoi7qSIKaeBWgHkmAA0BLEh8OmLCGI/edit?usp=sharing
I want the function to be in the B column.
This is fairly simple but will take a bit of code. You can go to Tools> Script Editor and create a function like such:
function timestamp() {
return new Date()
}
You can then use that function in an If statement like the following:
IF(A2="","",timestamp(A2))
If the cell is blank the function will return blank, but when the cell is updated it will timestamp the change in that cell.
If you are unfamiliar with Apps Script you can learn how it works here.

How to use ARRAYFORMULA + FILTER within Google Spreadsheet?

I have a Google spreadsheet with basically a dictionary of key/value pairs. Keys are unique. In a second sheet I need to add one or more rows for every key in the dictionary with some data. In this very sheet I'd need to also report the proper value for each key.
To do so I have tried to combine the ARRAYFORMULA function with a number of other functions on the very first row of the second sheet to avoid (if possible) the need to copy the same formula on all rows of the value column.
So far, neither QUERY nor FILTER worked.
QUERY requires all data, there included the arguments to the WHERE predicate, to reside on a single sheet. In my case, the filtering key would be on the second sheet while the dictionary is on the first one. So this cannot be used at all.
FILTER seems to have a weird (to me) behavior when both used in conjunction with ARRAYFORMULA and without it.
You can have a look to my test Google Sheet
here or to snapshots here with ARRAYFORMULA (column B), without it (column C) and what I'd like to get (column D):
A little step further from pnuts' solution provides the "perfect" result without the "N/A" cells:
=ARRAYFORMULA(IF(A3:A="";"";VLOOKUP(A3:A;KEYS!A1:B;2;FALSE)))
Of course there is a major impact on the performances as the VLOOKUP is run once for every single line in in the second sheet (and this was also why I was trying to use FILTER).
Those performances are quite low even with the currently linked example sheet, which is really skinny.
In Row3 please try:
=ArrayFormula(vlookup(A3:A;KEYS!A$1:B$5;2;0))
you can use a From spreadsheet - On change event trigger to call code like below:
function CopyPasteWastageRows() {
var spreadsheet = SpreadsheetApp.getActive().getSheetByName("<<Sheet-Name>>");
spreadsheet.getRange('Q2').activate();
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
spreadsheet.getRange('Q2').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
spreadsheet.getRange('Q2').activate();
};
Try:
=ARRAYFORMULA(IF(LEN(A3:A); VLOOKUP(A3:A;KEYS!A1:B;2;FALSE);))
That should get the keys, as far as values are entered in col A.

Resources