I need function to simply trigger another function if a specific Google Sheet column's value (or values) is "START".
Something like this:
If column AUTO!N2:N is "START", then trigger the function letsStart()"
If column AUTO!N2:N is not "START", then do nothing.
Simple as that :)
Is this possible?
The letsStart() function already ends with:
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("AUTO")
.getRange('N2:N')
.createTextFinder('START')
.replaceAllWith('STOP')
...and working fine.
This is to avoid unintended looping.
I believe your goal is as follows.
You want to run a function of letsStart() when the cells AUTO!N2:N includes a value of "START".
In this case, how about the following 2 patterns?
Pattern 1:
In this pattern, when a cell in AUTO!N2:N is edited and the cell value is "START", letsStart() is run.
function onEdit(e) {
const { range, source } = e;
const sheet = range.getSheet();
const value = range.getValue();
if (sheet.getSheetName() != "AUTO" || range.columnStart != 14 || range.rowStart == 1 || value != "START") return;
letsStart();
// or range.setValue("STOP");
}
In this sample, a simple trigger of OnEdit is used. So, when you use this script, please edit a cell of AUTO!N2:N. By this, the script is run. When you put "START" to AUTO!N2:N, letsStart() is run.
Please be careful about this.
In this case, I thought that range.setValue("STOP"); might be able to be also used instead of letsStart();.
Pattern 2:
In this pattern, when the cells AUTO!N2:N includes a value of "START", letsStart() is run.
function myFunction() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("AUTO");
const lastRow = sheet.getLastRow();
if (lastRow == 0) return;
const textFinder = sheet.getRange("N2:N" + lastRow).createTextFinder("START").matchEntireCell(true);
if (!textFinder.findNext()) return;
letsStart();
// or textFinder.replaceAllWith("STOP");
}
When this script is run, when the cells AUTO!N2:N includes a value of "START", letsStart() is run. Althought I'm not sure your whole script of letsStart(), when I saw your script of letsStart(), I thoug that in this case, I thought that letsStart(); might be able to be replaced with textFinder.replaceAllWith("STOP");.
For example, when myFunction is modified to onEdit, this script can be also used with the simple trigger of OnEdit.
References:
createTextFinder(findText) of Class Range
Simple Triggers
Related
I've got a script that's doing some onEdit formatting on a sheet of mine. All the rest is working well, and I wanted to include a line that deletes spaces from number values I'm importing. That last line is not working.
Any ideas what I'm missing here?
function onEdit(e) {
var cell = e.range;
var sh = e.source.getActiveSheet();
if(sh.getName() === "Trading Journal") {
cell.setBackground('#fff');
cell.setFontSize(10)
cell.setFontFamily()
cell.replace(/\s/g, "")
}
}
https://docs.google.com/spreadsheets/d/1rkjO-ITeLdIHq-LLHfHcp6-1j1R0-giS6HGbwYdJ5Ek/edit?usp=sharing
Did a bit of research regarding this, and it seems that .replace() is a string method and therefore may not work with numbers. Reference
But if you only need to remove whitespaces from numbers, here is a simple solution:
function rSpaces() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var cell = ss.getActiveCell();
cell.trimWhitespace();
}
You can assign this on an onEdit trigger and check this documentation for any font modifications you want to add.
I'm trying to make a script that, whenever triggered, runs through each row checking if the checkboxes in column F are checked. If so, the content of column A in that row is replaced with a 0. Upon running the code, nothing happens. I am not sure where the script gets caught up, but I would assume it's in the for() loop. I have also included a picture of the spreadsheet itself for easier understanding. Any help is appreciated.
My code:
function onEditButAgain(event){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var editedCell = sheet.getActiveCell();
var columnToSortBy = 6;
if(editedCell.getColumn() == columnToSortBy)
{
for(var x = 2; x<=100; x++)
{
var checked = sheet.getRange(x, 6);
if(checked.isChecked == true)
{
var date = sheet.getRange(x, 1);
date.setValue("0");
}
}
}
}
The image of the spreadsheet itself:
Explanation:
Your goal is to manually execute a script that will change the value in column A whenever the cell in the same row in column F is checked.
The obvious issue in the code is isChecked which should be isChecked(). You use parenthesis when you want to execute a function and in this case you want to execute isChecked.
In this case, an onEdit script will be redundant. If you want to use an onEdit trigger with the name onEditButAgain you have to create an installable trigger. But you don't need an installable trigger for this purpose.
Although you can wrap up the following code in this answer in a simple onEdit() function, the event object is not used and the code won't be 100% efficient. But if you want to run it manually, you don't need a trigger anyway.
When you use a loop, it is not a good practice to use methods like getRange or isChecked or setValue because these methods are computationally expensive and your script will very slow. Work with arrays instead and getValues/setValues.
Solution:
function myFunction(){
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1'); // change it to your sheet name
const valA = sh.getRange('A2:A'+sh.getLastRow()).getValues().flat();
const cb = sh.getRange('F2:F'+sh.getLastRow()).getValues().flat();
const new_valA = cb.map((c,i)=> [c ? "0" : valA[i]]);
sh.getRange(2,1,new_valA.length,new_valA[0].length).setValues(new_valA);
}
So I have a spreadsheet up for the purpose of documenting descriptions of functions found in some python files. TLDR these descriptions are hard to read due to the clutter left over from the files.
So my solution to solve this was:
function onEdit(e) {
const desFix = ['"', '
'];
let activeSheet = e.source.getActiveSheet();
let range = e.range;
const desc = range.getValue();
const rdesc = desc.toString();
for (let i=0; i<desFix.length; i++){
const rep = rdesc.replace(desFix[i]," ");
range.setValue(rep);
}
}
But it only works on the first occurrence when I need it to happen multiple times. Everything I've found and tried to implement/translate over to spreadsheet api breaks. Any idea of what I need to do to make it run multiple times?
I believe your goal as follows.
You want to convert the values of " and
to " " in the active range in the Google Spreadsheet.
You want to run the script using the OnEdit trigger.
Modification points:
In your script, the same rdesc is used by rdesc.replace(desFix[i]," ") in the for loop. By this, only the 1st
at 2nd loop is replaced. I think that this is the reason of your issue.
And, I think that setValue is used in the for loop, the process cost will be high.
In your case, I thought that TextFinder might be suitable.
So in this answer, I would like to suggest to modify your script using TextFinder. When your script is modified using TextFinder it becomes as follows.
Modified script:
function onEdit(e) {
const desFix = ['"', '
'];
desFix.forEach(f => e.range.createTextFinder(f).matchCase(true).replaceAllWith(" "));
}
When you use this, for example, please edit a cell. By this, the script is run by OnEdit trigger and " and
in the value in the cell are replaced to " ".
Note:
When you want to run the script with the script editor, you can also use the following script. When you use the following script, please run myFunction() at the script editor. By this, all cell values in the active sheet are checked.
function myFunction() {
const desFix = ['"', '
'];
const sheet = SpreadsheetApp.getActiveSheet();
desFix.forEach(f => sheet.createTextFinder(f).matchCase(true).replaceAllWith(" "));
}
References:
Class TextFinder
google-apps-scropt
I thought that these links might be useful.
I'm trying to come up with an IF statement that will trigger my macro to run based on a specific value in one cell. My Spreadsheet has many tabs. This is for a forecasting template.
Here is what I have come up with but I am running out of ideas..
function Sum_Calcs() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Integrity Check'), true);
spreadsheet.getRange(K20).getValue(getActiveRange(), true);
if(activeRange === "1") {
}
//My Script is then located beneath//
Any help is much appreciated!
You need to
implement an onEdit function to re-evaluate the if statement each time the value in "K20" was changed (please note that it will work automatically only if the value has been changed manually, by a human)
A second function (macro) that will be called within the if statement if your condition is fulfilled
Based on your code snippet above there some things you need to change:
When you use the method getValue() to retrieve the value of a cell - do not specify any parameter within the brackets () of the method. Instead, assign the return value of this method to a variable
If you want to retrieve a cell value (or perform any other operation) in a certain sheet, use getSheetByName() instead of setActiveSheet
To compare within an if statement the actual value against an integer (number) use if(activeRange == 1)
Note that when getting a range in A1 notation you need to use quotes ("")
Sample code based on your situation:
function myForecastMacro(){
// specify here what shall happen if your "if" statement is fulfilled
function onEdit() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('Integrity Check');
var activeRange=sheet.getRange("K20").getValue();
if(activeRange == 1) {
myForecastMacro();
}
}
I've been working on this script in Google Apps Script for a little while now and think I've got it almost figured out. I could really use another pair of eyes though, as it hasn't yet worked to completion.
What I'm trying to do:
I'm working on a sheet dealing with tentative and actual dates. These two dates are in adjacent columns. Once the "actual" date gets filled into its cell, I would like the "tentative" date to be deleted.
Here is my script thus far:
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange('F4:F');
var range2 = sheet.getRange('E4:E');
var rule = range.getDataValidation();
if (rule != null) {
var criteria = rule.getCriteriaType();
var args = rule.getCriteriaValues();
var clear = range2.clear({validationsOnly: false});
}
}
What do I need to do to get this script running?
It appears you want to delete the value in column E if column F was filled. If so, I don't see the need for dealing with data validation rules. The following script checks that the edited cell is in column F, row >= 4, and that the new value in the cell is a date. If these conditions hold, it clears the cell to the left (using offset).
function onEdit(e) {
if (e.range.getColumn() == 6 && e.range.getRow() >= 4) {
if (e.range.getValue() instanceof Date) {
e.range.offset(0, -1).clear();
}
}
}
Note: this script uses the event object passed to onEdit function. Interestingly, its "value" property turned out to be not useful here, because it is not a date object even when a user enters a date. This is what I use e.range.getValue() instead.