Call every even column for timestamp script - google-apps-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"))
}
}

Related

Google Sheets: Tracking date changes by stage with automated timestamp recording

I'm trying to track the date at which a particular stage is selected from a dropdown list, so that I can measure the time between stages. Here is the spreadsheet: https://docs.google.com/spreadsheets/d/1GEJKCtLgsIobA0u3_GYqYwA6FQuSi64u4ORgTATn92U/edit?usp=sharing
I've been working with different examples to record the timestamp when a cell is changed, but I can't seem to find a way to record a timestamp in different cells dependent upon the value selected in the dropdown.
Does anyone know if something like this is possible? A function like this will get me the timestamp in a single column/cell, but I want to be able to populate the different timestamps corresponding to the value in the dropdown in different cells:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Tracking" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 2 ) { //checks the column
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //is empty?
var time = new Date();
time = Utilities.formatDate(time, "GMT", "HH:mm:ss");
nextCell.setValue(time);
};
};
}
Solution:
You would need to have some parsing of the cell value to separate the number component, compute the offset cell, and write the timestamp there.
Note that my modified code also uses the event object e, as this lessens the calls to SpreadsheetApp and makes each execution a little bit faster.
Sample Code:
function onEdit(e) {
var r = e.range;
var off = 0;
if (r.getSheet().getName() == "Tracking") { //checks that we're on the correct sheet
if (r.getColumn() == 2) { //checks the column
var arr = e.value.split(" "); // parse the cell value
if (arr[0] == "Start") {
off = 1;
}
else if (arr[0] == "Stage") {
off = parseInt(arr[1]) + 1; // compute offset
}
else return;
var nextCell = r.offset(0, off);
if (nextCell.getValue() === '') { //is empty?
var time = new Date();
time = Utilities.formatDate(time, "GMT", "HH:mm:ss");
nextCell.setValue(time);
}
}
}
}
Sample Output:
References:
Event Objects | onEdit(e)

Google Sheets - multiple columns with auto timestamp

I am creating a sheet that once a job is assigned to someone, the time is automatically input to the cell beside it.... and when complete, the time is automatically put into the cell beside that one.
I have included a picture of the idea I am going for. Any help would be appreciated. Thanks!
If you set the trigger, it should be enough for you to + adjust the condition there.
I don´t know, when you need fixed date?
function insert_timestamp() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
var tz = Session.getScriptTimeZone();
if( r.getColumn() != 0 ) {
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, tz, "dd.MM.yyyy");//"dd.MM.yyyy hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('C' + row.toString()).setValue(time);
}
}
There is an onEdit trigger for the SpreadsheetApp which you can use. Basically, every time you edit a cell, the onEdit function runs and passes and event. You can then check that event against some criteria and gof rom there. The documentation below does not seem up to date, but the code did work for me. Finally, you can then select how you want the date displayed using the format settings in the Spreadsheet.
function onEdit( event ) {
const currentRow = event.range.rowStart;
const currentCol = event.range.columnStart;
const value = event.value
// if it is in in Column F (6) or Column H (8)
// you could also check the value here against something
if( currentCol === 6 || currentCol === 8 ){
// put the current time in the column next to the current one
SpreadsheetApp.getRange( currentRow, currentCol + 1).setValue( new Date() )
}
}
See here for reference: onEdit
I have tried this code below to add time stamps just to 6 and 8. but it input a time stamp beside every cell i edit..
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Work Orders" ) { //checks that we're on Sheet1 or not
var r = s.getActiveCell();
if( r.getColumn() == 6, 8 ) { //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());
}
}
}

How To Add User To Cell Showing Who Edited Row in Google Sheets?

I have a script for GOogle Sheets that works almost perfectly.I just need one addition:
To add the logged in user to the cell.
I have a sheet called "GMB Descriptions"
When a user enters information in any cell row in column 4, it shows the date & time in column 5 of the same row. No problem.
The issue is I want it to show the logged in user in that cell as well
Currently (script below) shows: MM/dd/yyyy - hh:mm a
I want it to show: MM/dd/yyyy - hh:mm a - LoggedIn User
I understand it would use the user email who made the change to that row.
Summary: How do I add the code to the following script to also show the user who made that edit?
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "GMB Descriptions" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 4 ) { //checks the column
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //is empty?
var time = new Date();
time = Utilities.formatDate(time, "GMT-8", "MM/dd/yy - h:mm a");
nextCell.setValue(time);
};
};
}
Try this:
function onEdit(e) {
var rg=e.range;
var sh=rg.getSheet();
var name=sh.getName();
if( name=="GMB Descriptions") {
if( rg.columnStart==4) {
var nextCell = rg.offset(0, 1);
if( nextCell.getValue()=='') {
var dt=Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yy - h:mm a");
nextCell.setValue(Utilities.formatString('%s\n%s',dt,Session.getActiveUser().getEmail()));
}
}
}
}
Session.getActiveUser()
Restrictions with Simple Triggers
Restrictions with Installable Triggeres
The modified (and slightly reduced) script is below:
function onEdit(e) {
var rg = e.range;
if (rg.getSheet().getName() == "GMB Descriptions" && rg.columnStart == 4) {
var nextCell = rg.offset(0, 1);
if (nextCell.getValue() == '') {
var dt = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy - h:mm a - ");
var userMail = e.user.getEmail();
nextCell.setValue(dt + userMail);
}
}
}
Thanks to Cooper for Utilities hint, it works fine. We use e.user.getEmail() assuming no security problems (according to asker opinion). While testing for me, it works as expected.

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('')};
}
}
}

howto adapt onEdit function to fire for specific value

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);
}
}
};
};
}