Working in AppScript with Google Sheets and I have this script working to add notes based off of a cell value in a different column (selectedCell3 portion of the script). I'm wanting to add logic that essentially ADDS new text to the notes IF the cell value is changed. This is as far as I've gotten...
Still learning... be kind :)
//* Creates a Date Stamp if a column is edited.
//*/
//CORE VARIABLES
// The column you want to check if something is entered.
var COLUMNTOCHECK = 22;
// The SECOND column you want to check if something is entered.
var COLUMNTOCHECK2 = 18;
// The THIRD column you want to check if something is entered.
var COLUMNTOCHECK3 = 10;
// Where you want the date time stamp offset from the input location. [row, column]
var DATETIMELOCATION = [0,1];
// Where you want the SECOND date time stamp offset from the input location. [row, column]
var DATETIMELOCATION2 = [0,1];
// Where you want the THIRD date time stamp offset from the input location. [row, column]
var DATETIMELOCATION3 = [0,1];
// Sheet you are working on
var SHEETNAME = 'PM AUGUST 2022'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// var notesSheet = ss.getSheets()[0];
// var values_range = sheet.getRange("L2:L" + sheet.getLastRow());
// var notes_range = sheet.getRange("Z2:Z" + sheet.getLastRow());
// var notes = notes_range.getValues();
//checks that we're on the correct sheet.
if( sheet.getSheetName() == SHEETNAME ) {
var lastRow = sheet.getLastRow();
var selectedCell = ss.getActiveCell();
//checks the column to ensure it is on the one we want to cause the date to appear.
if( selectedCell.getColumn() == COLUMNTOCHECK && selectedCell.getValue() == "Billing") {
var dateTimeCell = selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
}
var selectedCell2 = ss.getActiveCell();
if (selectedCell2.getColumn()==COLUMNTOCHECK2 && selectedCell2.getValue() !== ""){
var dateTimeCell2 = selectedCell2.offset(DATETIMELOCATION2[0],DATETIMELOCATION2[1]);
dateTimeCell2.setValue(new Date());
}
var selectedCell3 = ss.getActiveCell();
//var notesSheet = ss.getSheets()[0];
var values_range = sheet.getRange("J2:J" + lastRow);
var notes_range = sheet.getRange("L2:L" + lastRow);
var notes = notes_range.getValues();
var oldValue = notes.oldValue;
if (selectedCell3.getColumn()==COLUMNTOCHECK3 && selectedCell3.getValue() !== ""){
var dateTimeCell3 = selectedCell3.offset(DATETIMELOCATION3[0],DATETIMELOCATION3[1]);
dateTimeCell3.setValue(new Date());
if (oldValue != null) {
notes += 'Prior Entry :' + oldvalue;
}
values_range.setNotes(notes);
}
}
}
I think this is what you were shooting for
function onEdit(e) {
var sh = e.range.getSheet();
if (sh.getName() == 'PM AUGUST 2022') {
var lastRow = sh.getLastRow();
if (e.range.columnStart == 22 && e.value == "Billing") {
e.range.offset(0, 1).setValue(new Date());
}
if (e.range.columnStart == 18 && e.value !== "") {
e.range.offset(0, 1).setValue(new Date());
}
if (e.range.columnStart == 10 && e.value !== "") {
e.range.offset(0, 1).setValue(new Date());
let ts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy MM dd HH:mm:ss")
sh.getRange(e.range.rowStart, 10).setNote(sh.getRange(e.range.rowStart, 10).getNote() + '\n' + sh.getRange(e.range.rowStart, 10).getValue() + ts);
}
}
}
Demo:
Related
The code works when one row is edited at a time. But I need to copy and paste multiple rows as well, and the timestamp only appears on the first row (where I paste it).
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var row = range.getRow();
var activeSheetName = 'Analysis';
var statusColumnNum = 17;
var updateColumnNum = 15;
if(sheetName == activeSheetName)
{
if(spreadSheet.getActiveSheet().getRange(row,statusColumnNum).getValues() == 'No Further Action' || spreadSheet.getActiveSheet().getRange(row,statusColumnNum).getValues() == 'Invalid Code' || spreadSheet.getActiveSheet().getRange(row,statusColumnNum).getValues() == 'For BAF Filing'){
if(spreadSheet.getActiveSheet().getRange(row,updateColumnNum).getValue() == ''){
var new_date = new Date();
spreadSheet.getActiveSheet().getRange(row,updateColumnNum).setValue(new_date).setNumberFormat("MM/dd/yyyy hh:mm:ss A/P");
}
}
else{
spreadSheet.getActiveSheet().getRange(row,updateColumnNum).setValue('');
}
}
}
In your script, how about the following modification?
Modified script:
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheet = spreadSheet.getActiveSheet();
var sheetName = sheet.getName();
var activeSheetName = 'Analysis';
var statusColumnNum = 17;
var updateColumnNum = 15;
var texts = ['No Further Action', 'Invalid Code', 'For BAF Filing'];
if (sheetName == activeSheetName) {
var range = sheet.getRange(range.rowStart, statusColumnNum, range.rowEnd - range.rowStart + 1);
var values = range.getValues();
var new_date = new Date();
range.offset(0, updateColumnNum - statusColumnNum)
.setNumberFormat("MM/dd/yyyy hh:mm:ss A/P")
.setValues(values.map(([q]) => [texts.includes(q) ? new_date : null]));
}
}
In this case, when this script is run by copying and pasting the values, all edited rows are checked. By this, the date is inserted into your expected rows.
Reference:
map()
Am trying to make it possible, After updated previous step use can update next step and i will get timestamp for all updates.
function onEdit(e) {
var range = e.range
var sheet = range.getSheet();
var sheetName = "Not Open";
var editedRow = range.getRow();
var editedColumn = range.getColumn();
var checkbox = sheet.getRange(editedRow, 45).getValue();
if (sheet.getName() == sheetName && editedColumn == 51 && editedRow > 2 && checkbox == false) {
Browser.msgBox("You Can't Complete This Task Befor Previous task Done");
e.range.setValue(e.oldValue);
}
addTimestamp(e);
}
function addTimestamp(e)
{
//variables
var startRow = 8;
var targetColumn45 = 45;
var targetColumn51 = 51;
var WS = "Not Open";
//get modified row and column
var row = e.range.getRow();
var col = e.range.getColumn();
if(col === targetColumn45 && row >= startRow && e.source.getActiveSheet().getName() === WS) {
var currentDate = new Date();
e.source.getActiveSheet().getRange(row, 43).setValue(currentDate);
e.range.setValue(e.oldValue);
}
if(col === targetColumn51 && row >= startRow && e.source.getActiveSheet().getName() === WS) {
var currentDate = new Date();
e.source.getActiveSheet().getRange(row, 49).setValue(currentDate);
}
}
I have to create one process having 10 steps to complete one work.
step 1,2,3 will start when new form submitted with new entry.
step 4,5,6 will start after completion of step 3.
continue......
end of process
At the end I will get total days to complete one task and delay time.
Because I'm low of scripting but I really have to use it (I didn't found any other solution) I would like to ask you for a help with timestamp.
I'm looking for help with function onEdit that would allow me to add timestamp in specific column (S) in each of row while editing specific ranges F4:Q4, F5:Q5. The most important thing there is that I would like to avoid few rows (because it's a title rows and I don't want to add timestamp while changing title rows)
Part of it is working with code below, But there's not included mechanism of editing only specific range (any change in whole row is noticed as a modification) and also there is nothing for skipping the title rows
function onEdit(e) {
// Your sheet params
var sheetName = "Sklad";
var dateModifiedColumnIndex = 4;
var dateModifiedColumnLetter = 'S';
var range = e.range; // range just edited
var sheet = range.getSheet();
if (sheet.getName() !== sheetName) {
return;
}
// If the column isn't our modified date column
if (range.getColumn() != dateModifiedColumnIndex) {
var row = range.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-08:00", "dd/MM/yy, hh:mm:ss");
var dateModifiedRange = sheet.getRange(dateModifiedColumnLetter + row.toString());
dateModifiedRange.setValue(time);
};
};
I would be very grateful for your help,
Regards
You can add the number of header rows as part of your second if()
This change will not add a timestamp in the first 4 rows if edited.
if (range.getColumn() != dateModifiedColumnIndex && range.getRow() > 4) {
Thank you #James
It works for me as
function onEdit(e) {
// Your sheet params
var sheetName = "Sklad";
var dateModifiedColumnIndex = 3;
var dateModifiedColumnLetter = 'S';
var range = e.range; // range just edited
var sheet = range.getSheet();
if (sheet.getName() !== sheetName) {
return;
}
// If the column isn't our modified date column
if (range.getColumn() != dateModifiedColumnIndex && range.getRow() > 3 && range.getRow() != 8 && range.getRow() != 15 && range.getRow() != 32 && range.getRow() < 49) {
var row = range.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT", "dd-MM-yyyy");
var dateModifiedRange = sheet.getRange(dateModifiedColumnLetter + row.toString());
dateModifiedRange.setValue(time);
};
};
I have the below script that adds a timestamp when a new row of data is added.
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet();
if(s.getName() !== 'Sheet7' || e.range.columnStart != 1 || e.range.rowStart < 1) return;
e.range.offset(0, 1).setValue(e.value ? new Date() : "");
}
I tried the below for adding the checkbox, doesnt work.
function AddCheckBox() {
var cell = SpreadsheetApp.getActive().getDataRange('A1:B');
var criteria = SpreadsheetApp.DataValidationCriteria.CHECKBOX;
var rule = SpreadsheetApp.newDataValidation()
.requireCheckbox()
.build();
cell.setDataValidation(rule);
}
I would like it to also add a checkbox as well to the column next to where the timestamp appears.
Thanks in Advance
I just worked it out if anyones interested
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet();
if(s.getName() !== 'TEST' || e.range.columnStart != 1 || e.range.rowStart < 1)
return;
e.range.offset(0, 1).setValue(e.value ? new Date() : "");
var spreadsheet = SpreadsheetApp.getActive();
var cell = SpreadsheetApp.getActive().getRange('C1');
var criteria = SpreadsheetApp.DataValidationCriteria.CHECKBOX;
var rule = SpreadsheetApp.newDataValidation()
.requireCheckbox()
.build();
cell.setDataValidation(rule);
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('C1').activate();
spreadsheet.getCurrentCell()
.getNextDataCell(SpreadsheetApp.Direction.DOWN).activate();
spreadsheet.getActiveRange()
.autoFillToNeighbor(SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
spreadsheet.getRange('A1').activate();
}
I've was wondering if what to do is possible and how to go about it. This is For Google Sheets. Here is the script I'm using (Found this script and edited it for my use):
function onEdit(e) {
var s = e.source.getActiveSheet().getName();
var cols = [5];
if (s !== 'Michele' && s !== 'Janet' && s !== 'Stephanie' || cols.indexOf(e.range.columnStart) ==-1 || !e.value) return;
e.range.offset(0,1).setValue(Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy HH:mm:ss"));
}
Column 5 (E) has the option to choose different statuses. So far, I have it putting the TimeStamp of Column 5's change in its adjacent column, 6 (F). What I'm trying to figure out is if the status is changed again (Pending -> Confirmed-> Installed-> ect) , instead of updating Column 6, which would already be TimeStamped, it will instead move on to Column 7, then 8, then 9, ect.
Let me know if more detail is needed.
Thanks a Bunch!
I've tested this code and it works. It finds the number of cells to the right of column E that already have values in them, and then calculates what the next empty column is, and writes the new date to the next empty column.
function onEdit(e) {
var sh = e.source.getActiveSheet();
var s = sh.getName();
var lastCol = sh.getLastColumn();
var cols = [5];
var startCol = SpreadsheetApp.getActiveSpreadsheet().getRangeByName('ColumnE').getColumn();
//In the spreadsheet, name a range that is in the column you want to start at
if (s !== 'Michele' && s !== 'Janet' && s !== 'Stephanie' || cols.indexOf(e.range.columnStart) ==-1 || !e.value) return;
var rowEdited = e.range.getRow(); //Get the row that was edited
//Start in row edited and column 6, get 1 row and X columns
var datesInCells = sh.getRange(rowEdited,startCol,1,lastCol - 5).getValues();
Logger.log('datesInCells: ' + datesInCells);
Logger.log('datesInCells.length: ' + datesInCells[0].length);
var numberOfDates = 0;
for (var i=0;i<datesInCells[0].length;i+=1) {
if (datesInCells[0][i] !== "") {
numberOfDates +=1;
};
};
Logger.log('numberOfDates: ' + numberOfDates);
var colToWriteTo = startCol + numberOfDates;
var newDate = Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy HH:mm:ss");
//var theStatus = sh.getRange(rowEdited, 5).getValue();
var theStatus = e.value;
var bothStatusAndDate = newDate + " : " + theStatus;
sh.getRange(rowEdited,colToWriteTo).setValue(bothStatusAndDate);
};
Version two:
function onEdit(e) {
var sh = e.source.getActiveSheet();
var s = sh.getName();
var lastCol = sh.getLastColumn();
var cols = [5];
if (s !== 'Michele' && s !== 'Janet' && s !== 'Stephanie' || cols.indexOf(e.range.columnStart) ==-1 || !e.value) return;
var rowEdited = e.range.getRow(); //Get the row that was edited
//Start in row edited and column 6, get 1 row and X columns
var datesInCells = sh.getRange(rowEdited,6,1,lastCol - 5).getValues();
Logger.log('datesInCells: ' + datesInCells);
Logger.log('datesInCells.length: ' + datesInCells[0].length);
var numberOfDates = 0;
for (var i=0;i<datesInCells[0].length;i+=1) {
if (datesInCells[0][i] !== "") {
numberOfDates +=1;
};
};
Logger.log('numberOfDates: ' + numberOfDates);
var newDate = Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy HH:mm:ss");
if (numberOfDates > 4) {
var existingValues = sh.getRange(rowEdited,7,1,4).getValues();
sh.getRange(rowEdited,6,1,4).setValues(existingValues);
sh.getRange(rowEdited,10).setValue(newDate);
return;
};
var colToWriteTo = 6 + numberOfDates;
sh.getRange(rowEdited,colToWriteTo).setValue(newDate);
};