I have a code that puts a timestamp in when column 1 is edited and then a second timestamp when another column has the word 'collected' input to it. From this I then work out time it took to be collected and use that data. However if someone edits column 1 again it updates the timestamp so I'm looking for a script to allow it to only do it on first edit. Here is my current script;
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
if( sheet.getName() == "CC sheet" ) {
//Update timestamp when changed to collected
var range = sheet.getActiveCell();
Logger.log(range.getColumn())
if( range.getColumn() == 7.0 ) { //if we are in the status column...
var nextCell = range.offset(0, 2);
if(range.getValue() == 'Collected')
if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date());
}
//end
}
if(e.source.getActiveSheet().getName() !== 'CC sheet' || e.range.columnStart !== 1) return;
e.range.offset(0, 5).setValue(e.value ? new Date() : null);
}
It is the bottom bit I need to change to only update on first edit. Any help with this would be much appreciated.
replace last row or code with this one:
if (e.range.offset(0, 5).getValue() === '') {
e.range.offset(0, 5).setValue(e.value ? new Date() : null);
}
it's the same 'is empty?' check, as you have in the first part of script.
Related
I have built a Google Sheet using scrips to automatically timestamp certain events on the sheet upon edit.
Two of the timers are built to time just the first edit of two particular cells:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "SUBARU" ) {
var r = s.getActiveCell();
if( r.getColumn() == 3 ) {
var nextCell = r.offset(0, 19);
if( nextCell.getValue() === '' )
nextCell.setValue(new Date());
}
}
}
Two additional timers time any instance two other cells are edited:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "SUBARU" ) {
var r = s.getActiveCell();
if( r.getColumn() == 9 ) {
var nextCell = r.offset(0, 15);
nextCell.setValue(new Date());
}
}
}
And three other timers time when three specific entries happen in one particular cell:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "SUBARU" ) {
var r = s.getActiveCell();
if( r.getColumn() == 5 ) {
var nextCell = r.offset(0, 20);
if( r.getValue() === "3 - Menu Ready")
nextCell.setValue(new Date()).setNumberFormat('dd-MM-yyyy HH:mm:ss');
}
}
}
My problem is that I have seven scripts per sheet, and 4 sheets using the scripts (so 28 total scripts running). My Google quote is 30 scripts running at the same time. Can anyone think of ways I can simplify these scripts to run quicker or combine any so that I have fewer running at any given time?
Any help would be greatly appreciated!!!
My suggestion for this is to group all logic into one "onEdit" function.
Here's my code approach/suggestion to handle it:
if(s.getName() == "SUBARU") {
//put the logic to handle sheet SUBARU
} else if(s.getName() == "ABC") {
//put the logic to handle sheet ABC
} else if(s.getName() == "DEF") {
//put the logic to handle sheet DEF
}
UPDATE: Got this to work with the following script:
function onEdit(e) {
var range = e.range;
var sheet = range.getSheet();
var name = sheet.getName();
var currentDate = new Date();
//variable
var startRow = 1;
//get modified row and column
var row = e.range.getRow();
var col = e.range.getColumn();
var currentDate = new Date();
if(col === 7 && row === 3 && sheet.getRange(1,14).getValue() == "" &&
sheet.getName() != "4-Transfer Walkthru" &&
sheet.getName() != "1-Cover Sheet" &&
sheet.getName() != "2-Inventory" &&
sheet.getName() != "3-Template"){
sheet.getRange(1,14).setValue(currentDate);
}
else if(row >= startRow){
sheet.getRange(2,14).setValue(currentDate);
}
}
Original Post:
I'm attempting to add a "last edited" timestamp to a cell within each tab of a doc that has many tabs, and will continue to have more tabs added/removed. Everything I've found so far either creates a timestamp whenever anything within the entire doc is edited, or it requires listing out each tab name in the script (which is not ideal as the tabs in this doc are ever-changing).
Is there a way to make edit timestamps specific to each tab, without having to list out each tab's name?
Here's what I have so far, which included a timestamp for when the tab is first created (run by any edits made to cell J3), as well as the timestamp that updates across all tabs any time anything is edited in entire doc:
function onEdit(e) {
addTimestamp(e);
}
function addTimestamp(e){
//variable
var startRow = 1;
//get modified row and column
var row = e.range.getRow();
var col = e.range.getColumn();
var currentDate = new Date();
if(col === 7 && row === 3 && e.source.getActiveSheet().getRange(1,14).getValue() == ""){
e.source.getActiveSheet().getRange(1,14).setValue(currentDate);
}
if(row >= startRow &&
e.source.getActiveSheet().getName() != "Transfer Walkthru" &&
e.source.getActiveSheet().getName() != "Cover Sheet" &&
e.source.getActiveSheet().getName() != "Inventory" &&
e.source.getActiveSheet().getName() != "Template"){
e.source.getActiveSheet().getRange(2,14).setValue(currentDate);
}
}
ETA: Example sheet
Thank you!
onEdit allows you to access the event object range from which you cn deduct the sheet where the edit took place
Then you can implement conditional statements into your code to specify what shall happen depending on which sheet has been edited.
The problem with your code is probably due to e.source.getActiveSheet() because the active sheet might not always be the edited sheet.
I recommend you to retrieve the sheet with e.range.getSheet() instead.
Sample:
function onEdit(e) {
var range = e.range;
var sheet = range.getSheet();
var name = sheet.getName();
var currentDate = new Date();
//variable
var startRow = 1;
//get modified row and column
var row = e.range.getRow();
var col = e.range.getColumn();
var currentDate = new Date();
if(col === 7 && row === 3 && sheet.getRange(1,14).getValue() == ""){
sheet.getRange(1,14).setValue(currentDate);
}
else if(row >= startRow &&
sheet.getName() != "Transfer Walkthru" &&
sheet.getName() != "Cover Sheet" &&
sheet.getName() != "Inventory" &&
sheet.getName() != "Template"){
sheet.getRange(2,14).setValue(currentDate);
}
}
I want to add the current data and time in a specific column with any edit in whole sheet. I tried to write a script and got a little bit success but could not get desired result.
When I run the below script then it insert the time stamp in the very next column but I want to insert the timestamp in a specific column e.g in Column D.
Secondly it only works when I change values in a cell, but I want to add time stamp also when I change even color of a cell too.
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() ) { //checks the column
var nextCell = r.offset (0,1) ;
// if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date() );
}
}
}
Kindly help me to get the desired result.
if you want to insert the timestamp in a specific column e.g in Column D:
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() ) { //checks the column
var nextCell = s.getRange('D' + r.getRow()); // change D to any column needed
// if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date() );
}
}
}
Notes:
onEdit(e) runs when a user changes a value in a spreadsheet.
tests show onEdit runs when cells borders are changed
onEdit does NOT run when color is changed, font is changed.
I'm trying to adapt my inEdit script to give not just a timestamp but also add a "2" in another field,
I thought the following would work but only the date works and it ignores my "2".
What am I missing for both the date and 2 to appear onEdit?
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Sanshiro" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 6 ) { //checks the column
var nextCell = r.offset(0, -5);
if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date());
nextCell = r.offset(0, 10);
if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue("2");
} }
I don't know if the check if the 'nextcell' is empty is really needed ? you still want to update that cell if a new edit takes place, right ? Anyway, I think you can simplify your script to:
function onEdit(e) {
if (e.source.getActiveSheet()
.getName() !== "Sanshiro" || e.range.columnStart !== 6) return //checks that we're on the correct sheet
e.range.offset(0, -5)
.setValue(new Date());
e.range.offset(0, 10)
.setValue(2);
}
I am using Google Spreadsheets and what I am trying to do is update the cells that contain a timestamp in the Time last Updated column each time I update a cell in the same row.
Is there any way I can achieve that?
Thanks in advance,
not tested but something like this should work. Since you didn't provide any details, you will have to change some variables according to your needs.
function onEdit(e) {
var startCol = 2,
endCol = 10,
tsCol = 11, //this is the column where the timestamp will appear
startRow = 2,
sheetName = 'Sheet1', //this is the name of the sheet you want the script to work on.
curSheet = e.source.getActiveSheet();
//exit script when edits are made another sheet, or in the first row, or before col 2 or after col 10
if (curSheet.getName() !== sheetName || e.range.columnStart < startCol || e.range.columStart > endCol || e.range.rowStart < startRow) return;
curSheet.getRange(e.range.rowStart, tsCol)
.setValue(new Date());
}