howto adapt onEdit function to fire for specific value - function

In an 'onEdit' function, all examples that I find in this forum or elswhere contain the same (or similar) line to define the source, like:
if( r.getColumn() == 5 ) { //checks updates in column E
I cannot find how to adapt this, but I want my onEdit function to fire only if the column is set to a specific value:
if value of column E is set to "done" then perform rest of the function

Try something like this:
function onEdit(e) {
if (e.range.getColumn() === 5 && e.value.toLowerCase() === 'done')
Logger.log('Todo');
}
See Understanding Events.

I have solved this with following script:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "TaskBoard" ) { //checks that we're on the correct sheet; "TaskBoard"
var r = s.getActiveCell();
if( r.getColumn() == 2 ) { //checks updates in column B
var cellContent = r.getValue();
if (cellContent == 'Done')
{
var nextCell = r.offset(0, 4); //offset to same row, and column F; B+4
if( nextCell.getValue() === '' ) //is empty?
{
var time = new Date();
time = Utilities.formatDate(time, "CET", "yyyy-MM-dd");
nextCell.setValue(time);
}
}
};
};
}

Related

How to merge two onEdit so I can run two scripts on the same sheet?

I know there are probably many posts about the same thing but I don't understand a thing at all. I haven't slept for an entire day just reading all about this. I have ZERO knowledge about scripts and I've been cramming information for the past few hours.
I just need help merging two onEdit scripts together since I've read that one sheet can only run one onEdit script.
My first script (that I copy-pasted from online) is to auto-hide a row based on a specific value:
function myFunction() {
}
var SHEET = "2022";
var VALUE = "Cancelled/Removed";
var COLUMN_NUMBER = "6"
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
if(SHEET == activeSheet.getName()){
var cell = ss.getActiveCell()
var cellValue = cell.getValue();
if(cell.getColumn() == COLUMN_NUMBER){
if(cellValue == VALUE){
activeSheet.hideRow(cell);
};
};
};
}
And this is the 2nd script to automatically input the exact time when I input value into a cell:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "2022" ) { //checks that we're on Sheet1 or not
var r = s.getActiveCell();
if( r.getColumn() == 1 ) { //checks that the cell being edited is in column A
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //checks if the adjacent cell is empty or not?
nextCell.setValue(new Date());
}
}
}
If someone could help me with this, if possible, in the most simplified way possible. I really don't understand most of these stuff.
The simplest option for you is to just combine them into one function. Like this:
function onEdit(e) {
var SHEET = "2022";
var VALUE = "Cancelled/Removed";
var COLUMN_NUMBER = "6"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
if(SHEET == activeSheet.getName()){
var cell = ss.getActiveCell()
var cellValue = cell.getValue();
if(cell.getColumn() == COLUMN_NUMBER){
if(cellValue == VALUE){
activeSheet.hideRow(cell);
}}}
if( activeSheet.getName() == "2022" ) { //checks that we're on Sheet1 or not
var r = activeSheet.getActiveCell();
if(r.getValue() != ""){
if( r.getColumn() == 1 ) { //checks that the cell being edited is in column A
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //checks if the adjacent cell is empty or not?
nextCell.setValue(new Date());
}}}}
Note: I added if(r.getValue() != ""){ so that it only puts the date in the adjacent cell if you actually put a value in the cell. If you want it to update the date even if you just delete something you will want to get rid of that line and one of the } at the end.

Combining two onEdit() in single Google Sheets App Script

I am trying to combine two onEdit functions in a single App Script. I have read through other posts on this subject and feel like I have integrated their suggestions but it is still not working.
Function A (timeStamp) places a time stamp in column B when columnn A is edited
Function B (arhviveRow) copies the edited row to sheet "Inactive" when a check box is marked True on sheet "Active" and then deletes the row from sheet "Active".
Both functions work correctly when run separately, but only the second function works when combined.
function onEdit(e) {
timeStamp();
archiveRow();
//Automatically stamp date and time on line
function timeStamp() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Active" ) { //checks that we're on Sheet1 or not
var r = s.getActiveCell();
if( r.getColumn() == 1 ) { //checks that the cell being edited is in column A
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === "" ) //checks if the adjacent cell is empty or not?
nextCell.setValue(new Date() + new (Time));
}
}
}
//Archive and delete line
function archiveRow(){
//ColumnNumberToWatch defines which column on sheet to monitor for an edit
var ss = e.source,
sheet = ss.getActiveSheet(),
range = e.range,
targetSheet,
columnNumberToWatch = 9; // column A = 1, B = 2, etc
// "sheet.getName() ===" defines which sheet to watch for the edit
// "targetSheet =" defines sheet to copy data to
if (sheet.getName() === "Active" && e.value === "TRUE" && e.range.columnStart === columnNumberToWatch) {
targetSheet = "Inactive"
} else if (sheet.getName() === "Inactive" && e.value === "FALSE" && e.range.columnStart === columnNumberToWatch) {
targetSheet = "Active"
}
//Copies data to last row in targetSheet and then deletes from source sheet
ss.getSheetByName(targetSheet)
.appendRow(sheet.getRange(e.range.rowStart, 1, 1, sheet.getLastColumn())
.getValues()[0])
sheet.deleteRow(e.range.rowStart);
}
}
Any insights into where I went wrong would be greatly appreciated.
Thanks!
The new Date() object should already contain the time, and there is no Javascript Object for new Date(Time).
It should look like this:
function timeStamp() {
var s = SpreadsheetApp.getActiveSheet();
Logger.log(s);
if( s.getName() == "Active" ) { //checks that we're on Sheet1 or not
var r = s.getActiveCell();
if( r.getColumn() == 1 ) { //checks that the cell being edited is in column A
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === "" ) {//checks if the adjacent cell is empty or not?
nextCell.setValue(new Date().toLocaleString());
}
}
}
}
Sample output for the date:
Active Sheet
Once the checkbox was clicked setting the value to TRUE, appends the row to the "Inactive" sheet.
Inactive Sheet
function onEdit(e) {
const sh = e.range.getSheet();
const name = sh.getName():
if (name == "Active" && e.range.columnStart == 1) {
e.range.offset(0, 1).setValue(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss"));
}
if (name == 'Active' && e.range.columnStart == 9 && e.value == "TRUE") {
let tsh = e.source.getSheetByName('Inactive');
tsh.appendRow(sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).getValues()[0]);
sh.deleteRow(e.range.rowStart())
} else if (name = 'Inactive' && e.range.columnStart == 9 && e.value == "FALSE") {
let tsh = e.source.getSheetByName('Active');
tsh.appendRow(sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).getValues()[0]);
sh.deleteRow(e.range.rowStart());
}
}

Call every even column for timestamp script

I am trying to create a timestamp for our Google Sheets script. The main goal is to create a script, which would make a timestamp in every "odd" column if something is added to any "even" column.
Right now, I have found this:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Sheet1" ) {
var r = s.getActiveCell();
if( r.getColumn() == 13 ) {
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' )
var time = new Date();
time = Utilities.formatDate(time, "GMT", "HH:mm:ss");
nextCell.setValue(time);
};
};
}
It works perfectly, but unfortunately, only for the 13th column. How to make this code work for every even column?
You can use the modulo operator (as explained here) to check if the edited column is 'even' or 'odd'. Asuming you want the code to work on 'Sheet1', see if this code works for you
function onEdit(e) {
if(e.source.getActiveSheet().getName() !== 'Sheet1' ||
e.range.columnStart % 2 > 0) return;
var off = e.range.offset(0, 1);
if(!off.getValue()){
off.setValue(Utilities.formatDate(new Date(), "GMT",
"HH:mm:ss"))
}
}

How can I clear a specific cell when another cell has been cleared?

I have a script for Google Docs spreadsheet where, when any cell in a specific column is populated it automatically places a timestamp in a different column on that row:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Sheet1" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 9 ) { //checks the column
var nextCell = r.offset(0, 3);
if( nextCell.getValue() === '' ) //is empty?
var time = new Date();
time = Utilities.formatDate(time, "Canada/Eastern", "M/dd/Y, h:mm:ss");
nextCell.setValue(time);
};
};
}
The script works great. However, I'd like the script to delete that timestamp if said cell has been cleared.
Or perhaps I can put the question a bit differently: How can I clear a specific cell when another specific cell in that row has been cleared?
the code is almost the same, I simplified it a bit to make it easier to understand what it's doing.
Edit :
better code to prevent issues when just modifying a cell in col 9.
I used the parameter coming in the onEdit trigger (called e in this example), see docs for details on that.
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet();
Logger.log(JSON.stringify(e)+' ------------------> value = '+e.value);
var r = e.range;
var nextCell = r.offset(0, 3);
if( s.getName() == "Sheet1" && r.getColumn() == 9 ){ //checks that we're on the correct sheet & column
if( nextCell.getValue() === '' && e.value !=null){ //is empty?
var time = new Date();
time = Utilities.formatDate(time, "Canada/Eastern", "M/dd/Y, h:mm:ss");
nextCell.setValue(time);
}else{
if(e.value==null){ nextCell.setValue('')};
}
}
}

Best practice Google Scripts with two functions

I'm not sure what my issue is here. I have an office visitor sign in/out Google spreadsheet. This is how I'm trying to get it to work. When a visitor selects a checkbox in the "in" column a timestamp will display in the next column. When a visitor selects a checkbox in the "out" column a timestamp will display in the next column. Currently this is how it's working: When I have only the first function in the code editor a timestamp displays in column 4 - like it's supposed to. When I add the second function a timestamp displays in column 6, but not in column 4. It's like the second function is overriding the first. What would correct the issue?
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "SignInOut" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 3 ) { //checks the column
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date());
}
}
}
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "SignInOut" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 5 ) { //checks the column
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date());
}
}
}
Both functions have the same name, so it will run the last.
Perhaps you can avoid having to define 2 times the same function, try something like:
function onEdit(e) {
var s = e.source.getActiveSheet(), r, colCell, nextCell;
if(s.getName() === 'SignInOut') { //checks that we're on the correct sheet
r = e.range; //s.getActiveCell();
colCell = r.getColumn();
if(colCell === 3 || colCell === 5) { //checks the column
nextCell = r.offset(0, 1);
if(nextCell.getValue() === '') //is empty?
nextCell.setValue(new Date());
}
}
}