Trigger onEdit() to update the same cell value in Google Sheets - google-apps-script

When I add a value to a cell it should get converted (in place) to a formatted value (a hyperlink in my case). This should not trigger another onEdit().
So say I enter "foo" the text automatically becomes http://bar.com/zee/foo
How do we do this using onEdit? Is there a better way to achieve the same result?

A script modifying cell content does not trigger the "edit" event. So you can achieve your goal without worrying about creating an infinite loop: modify the active cell using the new value in this cell.
function onEdit(e) {
if (e.value.oldValue === undefined) {
e.range.setValue('http://example.com/' + e.value);
}
}
The reason for conditional statement is to avoid putting content in the cell when the edit amounts to clearing out the cell. Such edits are detected as follows: when the cell content is deleted, e.value becomes an object in which the property oldValue represents the old value in the cell.

Related

Apps Script: do not recalculate if the cell on the right (next column) is marked as NO - How to get the value of the cell on the right of a give param [duplicate]

I am trying to figure out how to get the A1 Notation of a Cell calling a Custom Function.
I found this but this is for active cell. https://webapps.stackexchange.com/questions/54414/in-google-script-get-the-spreadsheet-cell-calling-a-custom-function
Essentially if I want Cell A5 to Call =TEST(). I want the function to return the text value A5.
I want to use this as a cache identifier for an API Call.
There are subtle differences in different range returning method names- active,current,selection:
The term "active range" refers to the range that a user has selected in the active sheet, but in a custom function it refers to the cell being "active"ly recalculated.
The current cell is the cell that has focus in the Google Sheets UI, and is highlighted by a dark border.
A selection is the set of cells the user has highlighted in the sheet, which can be non-adjacent ranges. One cell in the selection is the current cell, where the user's current focus is.
The first two are still range objects,while the latter is not. To reiterate, getActiveRange()
in a custom function it refers to the cell being "active"ly recalculated.
I want the function to return the text value A5.
Without Custom Functions,We can use:
=ADDRESS(ROW(),COLUMN())
With Custom function,We can use:
function test() {
return SpreadsheetApp.getActiveRange().getA1Notation();
}

Add Checkbox in Sheets based on Criteria

I'm looking for a way to add a functional checkbox to a cell, based on the value of another cell. I assume it may need to be script, as everything I've found so far has stated checkboxes are input only, and cannot be created with formulas.
I'm looking to create an unchecked checkbox in column C if the value in column B is a certain value (="Tech Notes"). If the value in column B does not fall under the specific criteria, no checkbox should appear at all in column C.
I did find a thread where checkboxes would appear in all cells of a column, but would be checked/unchecked based on criteria, but I'm looking for the criteria to determine whether the checkbox appears at all.
Here's a sample sheet
Is this possible?
Thank you!
Solution:
Since a script is acceptable, you can make a simple trigger to create and remove checkboxes upon editing the cell:
function onEdit(e) {
if (e.range.getColumn() == 2) {
var sheet = e.source.getActiveSheet();
if (e.value === "Tech Notes" ||
e.value === "Intake Process")
sheet.getRange(e.range.getRow(),3).insertCheckboxes();
else
sheet.getRange(e.range.getRow(),3).removeCheckboxes();
}
}
You don't need to execute this function manually in Google Apps Script, it will trigger everytime you edit the sheet.
Sample Data:
References:
Insert Checkboxes
Simple Triggers

code to find cell address for script - google sheets

I am using Google Sheets.
I have a spreadsheet with a column 'B' containing data which is conditionally formatted with background colors.
I need to place the hex code corresponding to the color in each cell of 'B' into the neighboring cell in 'C'.
I have the following code, which works:
function GetBackColorCode(cell)
{
return (SpreadsheetApp.getActiveSheet().getRange(cell).getBackground());
}
As you can see, however, this code requires manually inserting the proper column and row number in each and every cell. Thus, if I want the hex. code for the color in B14, I insert the following in C14:
=GetBackColorCode("b14")
This method would require me to manually imput about three hundred cells. Is there no way to automatically pick up the cell reference, with, for example, a 'this.someFunction()' call? Such that I can paste the call '=GetBackColorCode(this.someFunction())' into all the cells in column 'C' and each will automatically furnish the necessary reference to the cell to its immediate left?
Change your script to
function getHexCodes(range) {
return SpreadsheetApp.getActiveSheet()
.getRange(range).getBackgrounds();
}
then enter in C2 (or whatever your 'start row' will be)
=getHexCodes("B2:B")

Get Spreadsheet cell calling a custom function

I am trying to figure out how to get the A1 Notation of a Cell calling a Custom Function.
I found this but this is for active cell. https://webapps.stackexchange.com/questions/54414/in-google-script-get-the-spreadsheet-cell-calling-a-custom-function
Essentially if I want Cell A5 to Call =TEST(). I want the function to return the text value A5.
I want to use this as a cache identifier for an API Call.
There are subtle differences in different range returning method names- active,current,selection:
The term "active range" refers to the range that a user has selected in the active sheet, but in a custom function it refers to the cell being "active"ly recalculated.
The current cell is the cell that has focus in the Google Sheets UI, and is highlighted by a dark border.
A selection is the set of cells the user has highlighted in the sheet, which can be non-adjacent ranges. One cell in the selection is the current cell, where the user's current focus is.
The first two are still range objects,while the latter is not. To reiterate, getActiveRange()
in a custom function it refers to the cell being "active"ly recalculated.
I want the function to return the text value A5.
Without Custom Functions,We can use:
=ADDRESS(ROW(),COLUMN())
With Custom function,We can use:
function test() {
return SpreadsheetApp.getActiveRange().getA1Notation();
}

Increment Cell value by one by clicking

I want to write a formula in Google sheets so that I can attach to a button to make the value in a cell increase by 1 each time you click it.
Here is the best I could find on this topic.
I attempted to do this, but to no avail. I am using Windows 7 and Chrome.
First create a script to increment the cell value. For instance, to increment cell "A1" by one the following script would work:
function increment() {
SpreadsheetApp.getActiveSheet().getRange('A1').setValue(SpreadsheetApp.getActiveSheet().getRange('A1').getValue() + 1);
}
Save this script and open your spreadsheet and follow these steps:
Go to "Insert" > "Drawing" and draw a button using shapes and text.
Position your button accordingly, and right-click on it to display an
arrow on the side of it.
In the drop-down menu, select "Assign Script." and type the name of
your function. (In this case "increment")
The first time when you click on it, it'll ask for permission but
should work subsequently.
Update 2020
Motivation:
I would like to provide a different approach based on Marlon's comment:
what if we want to create multiple buttons to different rows and each
button modifies its own row? Is there a way not create this manually?
Solution:
You can use onSelectionChange to capture single click events and mimic the behaviour of a button.
The following script will increment the value of a cell in column A upon clicking on a cell in column B of the same row.
It also creates a "button" text on the fly but this is optional and up to the user.
To use this solution, simply copy & paste it to the script editor and save the changes. After that, it will automatically be used upon single click events. In this solution I used Sheet1 as the sheet name.
function onSelectionChange(e) {
const as = e.source.getActiveSheet();
const col = e.range.getColumn();
const row = e.range.getRow();
if (as.getName() == 'Sheet1' && col == 2){
const range = as.getRange(row,1);
range.setValue(range.getValue()+1);
e.range.setValue('Button');
}
}
Demonstration:
Restrictions:
While this approach works pretty well, there are two drawbacks:
There is a small delay between the clicks and the updates.
The trigger is activated when selecting a cell. If a cell is already selected, if you click it again the function won't trigger. You have to remove the current selection and then select it again.
Assign the following to a drawing inside your sheet and it will increase the value of the currently selected cell by 1:
function plusOne() {
var cell = SpreadsheetApp.getActiveSheet().getActiveCell();
var value = cell.getValue() * 1;
cell.setValue(value+1);
}