Trouble triggering a macro when a specific cell has a specific value - google-apps-script

I'm trying to trigger a google sheet macro / apps script to reformat a sheet when a specific value is entered into a specific cell. I have been working on it to get it to work but without success.
Here is my code;
function onEdit(e) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getRange('C2');
var cellContent = cell.getValue();
if(cellContent === 'Past campaigns - actual cashflows to date only') {
spreadsheet.getRange('7:12').activate();
spreadsheet.getActiveSheet().hideRows(spreadsheet.getActiveRange().getRow(), spreadsheet.getActiveRange().getNumRows());
spreadsheet.getRange('13:13').activate();
}
};
I'm new to macros and apps scripts. I have tried to implement all the suggestions from the following links without success;
How can I get a macro to automatically trigger when a cell reaches a certain value in a Google Sheet?
https://developers.google.com/apps-script/guides/triggers
https://developers.google.com/apps-script/guides/sheets

As #Cooper has said you cannot make a trigger based on a cell value. Only on user changes.
You could try to make the onEdit trigger to execute only inside an if statement. But that's already what you have done.

Try this:
function onEdit(e) {
e.source.toast('Entry');
const sh=e.range.getSheet();
if(sh.getName()!='Sheet Name')return;//you need to change this sheetname
const X=sh.getRange('C2').getValue();
if(X=='Past campaigns - actual cashflows to date only') {
e.source.toast('flag1');
sh.hideRows(e.range.rowStart,e.range.rowEnd-e.range.rowStart+1);
}
}
It's not necessary to use activate in most scripts and certainly in this one since it has to finish in 30 seconds. They use activate in macros because they are following you actions as you move around the screen. But in a script, generally to don't want to interact with the screen very much because it slows down the script and it doesn't really accomplish anything.
I'm currently using in a script that run when a Spreadsheet opens up because it has a lot rows in it and I want it to go down to the last row. So activate is useful because I don't have to scroll down to the last row every time I open the spreadsheet.
try it this way:
function onEdit(e) {
//e.source.toast('Entry');
var sh=e.range.getSheet();
if(sh.getName()!='Sheet Name')return;//you need to change this sheetnamee
var X=sh.getRange('C2').getValue();
if(X=='Past campaigns - actual cashflows to date only') {
//e.source.toast('flag1');
sh.hideRows(e.range.rowStart,e.range.rowEnd-e.range.rowStart+1);
}
}
I hope you're not trying to run this from the script editor because that's not going to work.

Related

Trying to combine two working scripts does does not work

I'm trying to make a quick macro to grab the current date and time and put it in a cell. I want to make this a static time. I made a quick macro by recording and it works as I recorded it, but when I ran the recorded macro it does nothing. I am just doing a now function and then copying it and pasting the value on top. If I split it into two separate macros, it works. I have no idea what I am doing wrong. Any help is appreciated.
"Timestamp" does not work.
"Now" works.
"copypaste" works.
'''
function TimeStamp() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().setFormulaR1C1('=now()');
spreadsheet.getActiveRange().copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
function Now() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().setFormulaR1C1('=now()');
};
function copypaste() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getActiveRange().copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
'''
You may use date object to return timestamp compared with using =now formula, which is faster and prevent script to skip your next line:
function TimeStamp() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().setValue(new Date());
};
Reference
Get today date in google appScript
Edit: Original issue
In the original script, the script might not apply the changes after setting the formula =now() and before copy/paste, since spreadsheet operations are sometimes bundled together to improve performance. So it's treating the active range as empty, and after pasting this empty value, the cell will remain empty.
To avoid that, you could have used SpreadsheetApp.flush() after setting the formula =now().

Google Sheets Timestamp on change

What I'm trying to achieve is really simple however I'm super uncomfortable with the Google Sheet Script Editor.
I want the date in a certain cell updated whenever something changes on the active sheet.
That's what I got so far:
//Timestamp on change
function timestampOnChange() {
getActiveCell().setValue(new Date());
}
However, even that already returns error messages :/
Explanation:
You need to create an onChange() trigger of a particular
function which will update a specific cell of the active sheet when the spreadsheet
changes content or structure.
The updateCell() function updates the value of B1 with the current
timestamp of the active sheet.
I would advice you to update a specific sheet instead of the active
sheet by using:
const sh = ss.getSheetByName('Sheet1');
instead of:
const sh = ss.getActiveSheet();
Solution:
In more detail, The createOnChangeTrigger() function will create
the onChange() trigger that will execute updateCell() when there
is a change in the content or structure of the spreadsheet file and in our case the active sheet.
function createOnChangeTrigger(){
const ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger("updateCell")
.forSpreadsheet(ss)
.onChange()
.create();
}
function updateCell(){
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();
sh.getRange('B1').setValue(new Date());
}
Instructions:
Copy/Paste both functions in the script editor and execute createOnChangeTrigger() only once.
References:
onChange()
From the question:
//Timestamp on change
function timestampOnChange() {
getActiveCell().setValue(new Date());
}
However, even that already returns error messages
The above code returns an error because theres isn't a built-in Google Apps Script function named getActiveCell(). To get the active cell you could use
SpreadsheetApp.getCurrentCell()
or
SpreadsheetApp.getActiveRange()
or if you use an edit event object (let say that it's a assigned to e) you could use e.range
It's worthy to not that if you use setValue(new Date()) on the active cell what ever that was entered on that cell will be overwritten.
On Web Applications, a sister site of Stack Overflow, there a lot of Q/A about timestamps in Google Sheets, actually, there is tag for them ---> https://webapps.stackexchange.com/questions/tagged/google-sheets-timestamp. So far there are 102 questions with this tag.

How to get an IFTTT action in Google Sheets to trigger a script?

I have an IFTTT applet that will update cell C65 in my google sheet. I'd like that sheet to run a function submitData() whenever cell C65 is changed. As many know, however, the onEdit and onChange functions do not trigger from IFTTT actions, only from manual inputs.
I've learned this from searching for answers, and nobody seems to be able to explain a workaround. The strangest thing here is that when I first put it together today, it actually worked perfectly. I then swapped google accounts and made other changes that didn't relate to the code or IFTTT applet and all of a sudden it stopped working entirely, even when switching back to the correct google account.
This is the onEdit code that works for screen inputs but not when my IFTTT enters a value into the cell:
function onEdit(e){
var cellAddress,cellAddressToTestFor;
cellAddressToTestFor = 'C65';
// Get cell edited - If it's C65 then do something
cellAddress = e.range.getA1Notation();
Logger.log('cellAddress: ' + cellAddress);
if (cellAddress === cellAddressToTestFor) {
//To Do - Code here if cell edited is correct
submitData();
};
}
Is there any way to get the IFTTT event to trigger my submitData function?
So the 'on edit' trigger won't work with IFTTT changes, but the 'on change' installable trigger will. However, the event object passed by the On Change trigger does not contain 'range', so there's no way to easily check the edited cell's location. To do so:
function onChange(e){
var cellAddress,cellAddressToTestFor;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var activeSheetName = activeSheet.getSheetName();
cellAddressToTestFor = 'C65';
// Get cell edited - If it's C65 then do something
cellAddress = activeSheet.getActiveRange().getA1Notation();
Logger.log('cellAddress: ' + cellAddress);
if (cellAddress === cellAddressToTestFor) {
//To Do - Code here if cell edited is correct
submitData();
};
}

How can I get a macro to automatically trigger when a cell reaches a certain value in a Google Sheet?

What I need is for a macro I've recorded called SwitchHotSeat to trigger when the value of cell F3 goes above £1,000,000.00 0r 1000000 or the LEN of cell F3 goes over that length.
I can find guides for doing this in Excel, but not for Google Sheets. below is just the code for my macro.
function SwitchHotSeat() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('3:3').activate();
spreadsheet.getActiveSheet().deleteRows(spreadsheet.getActiveRange().getRow(), spreadsheet.getActiveRange().getNumRows());
spreadsheet.getActiveRangeList().setBackground('#ff0000')
.setFontColor('#ffffff');
};
The macro works fine. I just need a way of triggering it when that cell goes over the 1000000.
You could use simple or installable triggers. See
https://developers.google.com/apps-script/guides/triggers
https://developers.google.com/apps-script/guides/triggers/installable
Example of using onEdit simple trigger
function onEdit(e){
if(/* add here your conditions */) {
SwitchHotSeat();
}
}
NOTE: on edit and on change triggers are triggered only when an user edit the spreadsheet.
Just in case it helps anyone else with a similar issue, I discovered (by logging) that it was returning an object, rather than a number before, so the following code worked fine in the end.
function onFormSubmit(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var millionaire24 = ss.getSheetByName('Millionaire24.');
var cellValue = millionaire24.getRange(3,6,1,1).getValues();
Number(cellValue)
if(cellValue[0] >= 1000000)switchHotSeat();
}

Why doesn't the trigger work for the script running a function on my google spreadsheet?

So I'm using a script on my googledoc spreadsheet that goes through a column and counts a certain number of occurrences of specified formatting. (i.e. in my spreadsheet "=myFunction()")
The function works fine, but my problem is despite setting up a trigger to run the script "onEdit", it never does it. I have to open the script up and save it each time I want it to update on my spreadsheet.
I've been looking up for hours but no one seems to have my question. There are no errors sent by the notifications. The code (though I don't think it's terribly relevant) for my function is:
function CountIfNotStrikeThrough2()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mysheet = ss.getActiveSheet();
var mydatarange = mysheet.getRange(1,1,390,1);
var numRows = mydatarange.getLastRow();
var rowindex = mydatarange.getRowIndex();
var columnindex = mydatarange.getColumnIndex();
var total =0;
for(i=rowindex;i<=numRows;i++)
{
if(mydatarange.offset(i-1, columnindex-1, 1, 1).isBlank() != true && mydatarange.offset(i-1, columnindex-1, 1, 1).getFontLine() != "line-through")
{
total++;
}
}
return total;
}
I know there's a thread here that has a comprehensive list of when the onEdit trigger doesn't activate. (here) For example, if you setup Data Validation and select an item from the list of values in the validation, it doesn't trigger the onEdit function.
Besides that, could you try a simple trigger instead of installable? This is to say, instead of explicitly associating CountIfNotStrikeThrough2() to the onEdit trigger, please try re-naming the function to "onEdit()" instead and see if that works. This creates an implicit or simple trigger. I've had trouble in the past with installable vs. simple triggers.
Also, please share the exact action you're performing to test the trigger.
Reference: https://developers.google.com/apps-script/understanding_triggers