onEdit function - google-apps-script

in google apps script, how can I automatically run a script when I change the background color of a cell?
When I change the background color of a cell, the spreasheet is automatically saved and it says also when last edit was made, but if I try to use this event on an onEdit function to run a script, it doesn't recognize the event and does nothing. Thanks

onEdit is going to fire when any cell value changes, not with any formatting changes. You'll have to place the rules to change the bg colors in the script, assuming that the rules are based on cell values already in the sheet.

I'm afraid you'll have to manage this using a 'trick' as there is indeed no automatic trigger for background color changes.
Just a suggestion : If your spreadsheet is not too big you could simply memorize the whole color description in a string you previously stored in script properties and, based on a timer trigger, check if something has changed.
If this solution is acceptable for you (the timer trigger and not an immediate reaction) give it a try...
Use this var for example :
var backGroundString = SpreadsheetApp.getActiveSheet().getDataRange().getBackgrounds().toString()
and compare it to the same value stored in scriptProperties, if different, trigger your event...
I know it's a bit clunky but right now I see no other simple way to get what you want.
You could add a few conditions to make it work only at some moments or when the spreadsheet is open...

Related

Edit cell above cell that called a function?

I'm using Google Apps Script to make a function that will be called in a Google Sheet. The function does some auto calculating for a spell effect. Some spells need the player to provide extra info (How many people are you shielding, etc) and some don't need any additional inputs. If extra info is needed, the user provides it in the cell directly above the cell that calls the function. I'll call this the "input cell" for clarity. The "function cell" is the one that calls the function, directly below the input cell.
My question is this: if the extra info is unneeded, as determined by conditionals within the function, how do I overwrite the contents of the input cell with '-'? I can't put a formula within that cell directly, because the user would overwrite the formula when entering the additional information. The function also returns a value to the cell that called it.
I've tried a bunch of techniques but I can't figure out how to do it.
I tried returning an array of both values, but it flows downwards instead
of upwards, and I couldn't find anything for "return array offset
upwards" or something to that effect.
I can't use absolute references
like "L17" because the function can be called from many places on the
sheet, and it also only needs to mess with the cell directly above it.
using setValue() or setValues() threw a "no permission" error.
I would attach my code, but it's a mess of half-deleted attempts that didn't work, and wouldn't be much help at all. I also don't want to ask anything too specific, for fear of running into the https://xyproblem.info problem. I just want to be able to have a function edit the cell directly above it, and I don't care about which technique gets that accomplished.
Any help is greatly appreciated. Thank you!
No cell can contain both a formula(or a output of a formula) and simultaneously contain a user entered value. That was always the case with any spreadsheet, Excel or Google sheets or any other. It's one or the other. Choose one and redraw your logic!
For your specific problem, if you can reflow your logic, you might try simple triggers like onEdit.

How to setup the "onChange" trigger in Google Sheet script editor

I need to get a Google sheet's cell background color hex code into that same cell.
This is the function I currently use:
function BGHEX(row, column) {
var background = SpreadsheetApp.getActive().getDataRange().getCell(row, column).getBackground();
return background;
}
Now I have 2 issues:
I need the function to run again when the cell's background color is edited. I know I need to use the installable trigger "onChange" but no idea how to set it up.
I need this script & function to run on a duplicate of this Google Sheet file (meaning other sheet id's).
Thanks in advance for your help!
Follow these steps to setup an onChange trigger in your spreadsheet
Open your Apps Script project.
At the left, click Triggers alarm.
At the bottom right, click Add Trigger.
Select and configure the type of trigger you want to create.
Click Save.
Your trigger setup should look like this:
To detect background change in your spreadsheet, you need to have an Event Object to determine which changeType the user made. For this scenario, we need 'FORMAT'.
Also, to change the background color of a cell or range, the user must click or highlight the range. Using getActiveRange() will help us determine which range is being edited.
Code:
function onBGChange(e) {
if(e.changeType == 'FORMAT')
Logger.log(SpreadsheetApp.getActive().getActiveRange().getBackground());
}
Example:
Here I change the background color of A1
Output:
Executions Tab:
To apply this to another spreadsheet, you need to replicate the code and trigger set up. A script is bound to the spreadsheet where it was created and functions like getActive() and getActiveRange() will only work on the spreadsheet the script was bound to.
References:
Installable Triggers
Event Object
getActiveRange()

Google Sheets - Track Current Cell Selection?

How to Get the currently selected cell/range? was asked 3.5 years ago, but I'm hoping maybe some progress was made since then.
I'd like to make an interactive spreadsheet where there's a boolean grid that will display more information about the status of the currently selected cell in a static location, allowing users to quickly navigate using the arrow keys.
Referencing the previous instance of this question, I tried using the custom function below to get the cell address, although this isn't very dynamic.
function currentCell() {
return SpreadsheetApp.getActive().getActiveRange().getA1Notation();
}
When testing, this function returns the address of the cell the function is called from. I've tried pressing F5 while highlighting another cell and nothing happened. I've also dragged the formula across a selection and each cell only contains its own address (according to the documentation, it should contain the range).
I've also read Henrique's post on caching from 2012, and while I don't completely understand it, I get that we could not get scripts which update without edits being made or manual formula updates.
I would ideally like for the current cell to be tracked without any extra prompts from the user besides arrow key navigation or clicking to select a cell, but if pressing a non-altering key (like Enter) would allow for tracking, that would be fine. I also only need the selected cell, rather than a range, if that makes things easier.
Explicit Question: Is it possible to track the position of the currently selected cell in Google Sheets and store that position in a separate cell? If not, is there a way to do this without altering cell values?
EDIT: Adding an example for clarity. In this conceptual example, A2 =currentCell() as described above. If I were to hit the right arrow key, A2 would update to display I4, since it is now the current selection.
EDIT2: Jason Allshorn's response to Google app script monitor spreadsheet selected ranges appears to give a way of displaying the current selection (range) on the HTML input text. I'd like to do this, but store the value in a static cell on the sheet rather than input text. I'm new to scripting in Sheets and really only know what I've found for resolving this issue, so if I'm overlooking something, please let me know. I did look at Jason's example sheet and it wasn't clear to me what was actually happening there.
You will have to apply the technique suggested on How do I make a Sidebar display values from cells?. This consist on using using client-side code to constantly pulling values from the spreadsheet and then do the corresponding task.
One approach is to use a side-panel with an input field to set the cells to be tracked and another input field to set the destination cell.
You will have to use the onSelectionChange event in the app script to capture any selection change and then get the range name and put it in desired cell.
Something like the below:
function onSelectionChange(e) {
const range = e.range;
//Return in case of multi cell selection
if(range.getNumRows() !== 1 || range.getNumColumns() !== 1) return;
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A2").setValue(range.getA1Notation());
}
You can see the official documentation here

Changing date range for chart based on selected dropdown value

I have a Google Spreadsheet like this with a chart and a dropdown menu. I would like the data range of that chart to update based on a value selected from a dropdown menu.
I thought I might be able to add a Google App Script to the dropdown menu, but I can't find a way to add such script to anything but a drawing. Can someone tell me how to achieve this? Or point me into the right direction (Doc link?) as I'm new to both Google Spreadsheets and App Scripts.
Update:
From the comments it seems using App Scripts onEdit trigger might work.
The idea would be
to trigger onEdit when the value from the dropdown cell changes
fetch the cell value to use as an argument for another function
that in turn alters the data range of a chart.
As far as I can see onEdit triggers with changes made to any cell. Is there a way to limit this trigger to specific cells/ranges?
If I were you, I would use your drop-down menu as reference in a Query(). Often, I'll use a Query() in a hidden section of columns on my sheet, and use that hidden section as the data range for my charts. For example, if your drop down was in A1 you could have in B1 a Query() that uses a cell reference to find your data, and then hide columns B through however many you need to display your data. Then you make your data range B1:D (or whatever the range actually ended up being). Your example sheet has been moved to your trash, but if you share a data set with me, I could show you a pertinent example. Here is a less than pertinent example Ta-Da. I know that it is probably too general to use for your specific case, but perhaps if we knew more we could point you to a more specific work-around.

How can you monitor for click events in Google Apps script for spreadsheets?

I'm managing a Google spreadsheet with a script. onEdit is working - I can colour a cell red by putting
SpreadsheetApp.getActiveRange().setBackgroundRGB(255, 0, 0);
in the onEdit function. I would like to put the same code in a onClick function, so that when a user clicks on a cell it immediately turns red. Is this possible? I can't find any way to do it in the documentation.
As stated on the comments above before there's no way (right now) to create an onClick() function for Google Spreadsheets. That makes sense due to the fact that the google app script functions are processed in the server, the amount of load generated by onClick() events execution would make pretty easy to deplete all the quota of requests provided by default.
You should be using the documentation for creating a button and clicking on it.
You can get closer....Create a validation for the cells with an option...like "Done". Click the dropdown, select Done. now create a trigger onChange or onEdit to fire. You can get a cell/range contextualized function....like firing on a row or column. This is easy to replicate and program for
You can add a Drawing as a button - https://developers.google.com/apps-script/guides/menus#clickable_images_and_drawings_in_google_sheets
I believe the new trigger onSelectionChange(e) will achieve this. It's in the docs but at time of writing isn't yet working on my sheet. https://developers.google.com/apps-script/guides/triggers?hl=en
Try this for a click event:
function onSelectionChange(e) {
e.source.toast('Sheet: ' + e.range.getSheet()(.getName() + ' Range: ' + e.range.getA1Notation());
}
Create a "Drawing" with background transparent; then move and place the drawing on top of the cell you need and then assign the script to the drawing.