OnEdit script to change timestamp when a row is edited (error) - google-apps-script

I found this script and am trying to use it in a google sheet. The trouble I am having is that I get an error message
You do not have permission to call setValue (line 8).
and when I change a value it will only create the timestamp for the first entry in a cell. If I edit the cell the timestamp does not change. Could someone take a look at this script to see what is wrong.
Here is the sheet
This is the script I am using:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
if( r.getColumn() != 2 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-08:00", "MM/DD/yy, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('M' + row.toString()).setValue(time);
}
}
In order to run the script I typed =onedit(a3:l3) it seemed like the only way to get it to work at all.
Thanks for any help

Try making the following commented changes to your code
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
if( r.getColumn() != 2 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-08:00", "MM/DD/yy, hh:mm:ss");
// remove this line below
SpreadsheetApp.getActiveSheet().getRange('M' + row.toString()).setValue(time);
//replace with this line below
return time;
}
}
Reference
You cannot set values to a cell outside of where the custom formula is being set on the spreadsheet, its illogical.

If you want to date/timestamp col M when edits are done in col B, try something like this:
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet();
if(s.getName() !== 'Sheet1' || e.range.columnStart != 2 || e.range.rowStart < 2) return;
e.range.offset(0, 11).setValue(e.value ? new Date() : "");
}
As this is an onEdit there is no need to enter a formula (=onedit()) in the spreadsheet. Note that:
- erasing a value in col B will cause the stamp to disappear (if you don't want this, just let me know).
- format col M as date/time via the 123-button.
See if this helps ?

Related

Google Sheets Script Editor minor adjustment

I currently have a script written (from help of others on forums) that has worked great for years. I'm now trying to use on another spreadsheet and just need to make a minor tweak in how it works. Here is current script:
function onEdit() {
var sheetName = "Master List";
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() !== sheetName) return;
var r = s.getActiveCell();
if( r.getColumn() != 5 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-05:00", "MM/dd/yyyy");
SpreadsheetApp.getActiveSheet().getRange('E' + row.toString()).setValue(time);
};
};
Its function previously was to put a date & timestamp in a specified column anytime an edit was made within a particular row. Basically it would tell me when the last edit was made on any given row.
Now I want column E (column 5) to be date stamped when only Column D (column 4) is edited. My use now is for price tracking. Column D will have the price and Column E will tell me the last time I updated the price in the spreadsheet.
I believe the edit needs made on the 5th line of code where it gets ActiveCell it needs a specified cell instead of any cell within the row. Please let me know the appropriate changes I should make. Thanks, Silas
function onEdit(e) {
const s = e.range.getSheet();
if (s.getName() == "Master List" && e.range.columnStart == 4 ) {
s.getRange(e.range.rowStart, 5).setValue(Utilities.formatDate(new Date(), "GMT-05:00", "MM/dd/yyyy"));
};
}
Just replace
if( r.getColumn() != 5 ) { //checks the column
with
if( r.getColumn() == 4 ) { //checks the column

Insert Timestamp when copy/paste whole row and value inserts/edits in Column C in google sheets

I tried inserting timestamp when a row is being copied and data inserts or edits in Column C same row cell, but it works only on manual entry, not on copy-paste.
Please suggest to me what I am missing or doing wrong.
function onChange() {
var s = SpreadsheetApp.getActiveSheet();
var sName = s.getName();
var r = s.getActiveCell();
var row = r.getRow();
var ar = s.getActiveRange();
var arRows = ar.getNumRows()
// Logger.log("DEBUG: the active range = "+ar.getA1Notation()+", the number of rows = "+ar.getNumRows());
if( r.getColumn() == 3 && sName == 'Sheet1') { //which column to watch on which sheet
// loop through the number of rows
for (var i = 0;i<arRows;i++){
var rowstamp = row+i;
SpreadsheetApp.getActiveSheet().getRange('F' + rowstamp.toString()).setValue(new Date()).setNumberFormat("MM/dd/yyyy hh:mm"); //which column to put timestamp in
}
}
}//setValue(new Date()).setNumberFormat("MM/dd/yyyy hh:mm:ss");
Use getLastColumn() to check whether column C is included in the pasted range.
Use getNumRows() to get the number of rows your copied range has, and so add the timestamp to all these rows.
No need to used an installed onChange() for this, a simple onEdit() is enough.
I'd also suggest to use event object in order to get information on which range was edited (even though this way you won't be able to fire this successfully from the script editor).
Edit: if you want to remove the timestamp when the range is cleared, you can just check that's the case, using every, or some, and clearContent if that's the case.
Code snippet:
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet();
var r = e.range;
var firstRow = r.getRow();
var numRows = r.getNumRows();
var firstCol = r.getColumn();
var lastCol = r.getLastColumn();
if((firstCol <= 3 || lastCol >= 3) && s.getName() == 'Sheet1') {
var emptyRange = r.getValues().every(row => row.every(value => value === ""));
var destRange = s.getRange(firstRow, 6, numRows);
if (emptyRange) destRange.clearContent();
else {
var dates = new Array(numRows).fill([new Date()]);
destRange.setValues(dates).setNumberFormat("MM/dd/yyyy hh:mm");
}
}
}
The following script will create timestamps starting from column F until the last column when you copy the row.
I think you are looking for this:
function onEdit(e) {
const startCol = 6; // column F
const s = e.source.getActiveSheet();
const sName = s.getName();
const ar = e.range;
const row = ar.getRow();
const arColumns = ar.getNumColumns();
const arRows = ar.getNumRows();;
if( sName == 'Sheet1') {
const rng = s.getRange(row,1,arRows,s.getMaxColumns());
check = rng.getValues().flat().every(v=>v=='');
if(check){
rng.clearContent();
}
else{
s.getRange(row,startCol,arRows,s.getMaxColumns()-startCol+1).setValue(new Date()).setNumberFormat("MM/dd/yyyy hh:mm");
}
}
}
Note:
Again, onEdit is a trigger function. You are not supposed to execute it manually and if you do so you will actually get errors (because of the use of the event object). All you have to do is to save this code snippet to the script editor and then it will be triggered automatically upon edits.

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

Only use script in one sheet

I use this script to set a timestamp when a cell is changed. But it triggers in all sheets, and I only want it to be triggered when I do a change in sheet "XXX"
function onEditDatoMaxboStart() {
var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("XXX"); //change this to the name of your sheet
var r = s.getActiveCell();
if( r.getColumn() != 29 ) {
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT+01:00", "dd.MM.yyyy hh.mm.ss");
SpreadsheetApp.getActiveSheet().getRange('AP' + row.toString()).setValue(time);
};
};
How do I lock it to only be triggered when I make a change in the sheet "XXX"?
You cannot lock onEdit triggers to be ran on specific Sheets. However, within your onEdit function, you can check whether the Sheet that has triggered the action is the one you are targeting. If it is not, you can just return from the function without really executing any action. Your modified function would look as follows (edited only the first two lines):
function onEditDatoMaxboStart(e) {
if (e.range.getSheet().getName() !== "XXX") return;
var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("XXX"); //change this to the name of your sheet
var r = s.getActiveCell();
if( r.getColumn() != 29 ) {
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT+01:00", "dd.MM.yyyy hh.mm.ss");
SpreadsheetApp.getActiveSheet().getRange('AP' + row.toString()).setValue(time);
};
};
Also, I suggest you check out this page on using events objects obtained in trigger functions.

Apps Script set ActiveUser and timestamp

Please help with setting active user in Column N. This script will timestamp column M whenever a cell in a row is updated. However, nothing updates in Column N for the active user.
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Log" ) { //checks that we're on the correct
sheet
var r = s.getActiveCell();
var user = Session.getActiveUser().getEmail();
if( r.getColumn() != 13 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-07:00", "yyyy-MM-dd, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('M' + row.toString()).setValue(time);
SpreadsheetApp.getActiveSheet().getRange("N" + row.toString()).setValue(user);
}
};
};
Am I using setValue(user) incorrectly?
Your call to setValue() looks fine. You may be encountering an authorization issue.
Can you successfully run this same code outside of the onEdit() trigger?
There are restrictions on the actions that can be performed inside of an onEdit trigger. See https://developers.google.com/apps-script/guides/triggers/