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.
Related
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.
I am using below code to get the last update date in Column B. Now when I protect the column B (because I don't want the other users to make any changes) and share this sheet with other users the update is not happening.
I would appreciate your help.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = "Sheet1";
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() !== sheetName) return;
var r = s.getActiveCell();
if( r.getColumn() != 2 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT+5", "dd/MM/yy, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('B' + row.toString()).setValue(time);
};
};
Instead of using an simple trigger use an installable trigger.
The above is because simple triggers are only able to execute tasks that don't require authorization.
I have a very frustrating problem on my hands and I turn to you for help once more. I had the onEdit() function below which, together with the auxiliary functions, worked fine.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var activeCell = activeSheet.getActiveCell();
//Check if the sheet is a JOb sheet and the cell us the status cell
if ( activeSheet.getName().indexOf("Job ID") != -1 && activeCell.getRow() == 4 && activeCell.getColumn() == 15 ) {
var targetSheet = ss.getSheetByName('Active Jobs');
var jobRowNumber = findJobIdRow();
var sourceCell = activeSheet.getRange(4,15);
sourceCell.copyTo(targetSheet.getRange(jobRowNumber,16));
}
if (activeSheet.getName().indexOf("Job ID") != -1 && activeCell.getRow() == 2 && activeCell.getColumn() == 15){
var switchValue = activeCell.getValue();
switch (switchValue){
case "On hold (i)":
case "On hold (ii)":
case "On hold (iii)":
case "To be assigned":
//Write date to active jobs sheet
addDateToActive("TBC");
break;
case "In progress":
var newDate = Browser.inputBox("Please enter report out date, example 18-Aug-2017");
addDateToActive(newDate);
break;
//default:
//Browser.msgBox("GOTHERE");
}
}
}
function findJobIdRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var jobID = ss.getActiveSheet().getRange(2,1).getValue();
var column = ss.getSheetByName('Active Jobs').getRange(2,1,ss.getSheetByName('Active Jobs').getMaxRows()-2,1);
var values = column.getValues(); // get all data in one call
for(var ct = 0; ct < values.length-1; ct++){
if(values[ct][0] == jobID){
var ct = ct+2;
break;
}
}
return ct;
}
function addDateToActive(input){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var activeCell = activeSheet.getActiveCell();
var jobid = activeSheet.getRange(2,1).getValue().toString();
var activeJobSheet = ss.getSheetByName("Active Jobs");
var activeJobs = activeJobSheet.getRange(1,1,activeJobSheet.getLastRow(),1).getValues();
activeJobs = ColumnToArray(activeJobs);
var jobrow = activeJobs.indexOf(jobid)+1;
if (jobrow == -1){
Browser.msgBox("Job Id not preent on Active Jobs sheet");
}else{
activeJobSheet.getRange(jobrow,15).setValue(input);
}
}
Then I included some code in this script which was supposed to send out some e-mails to people if some dates were approaching today's date. There were some problems with that code because of authorization requirement so I moved it into it's own separate function and came back to the original script that is posted above. Now the problem I am facing is, although this script works fine if ran from the script editor, manually run from a drawing button in the spreadsheet, or is ran by a on edit trigger I set up from the "Current project triggers" menu, it will not do the entire script if the script is triggered by the onEdit() function name. It does the first bit where it copies the content of a cell across but not the second bit with the case switch.
The obvious fix would be to just set up the trigger from the "Current project triggers" but this onEdit detection needs to apply to anyone in my team that edits this sheet. If I set it up like that it will work for me but no one else from my team.
Any help would be appreciated.
Setting up the trigger via the function name onEdit() proving tricky I wrote this bit of code and attached it to a drawing in the sheet. Then instructed all the users to click it which set up the trigger for them. This solved the problem and the trigger works fine now.
function triggerSetUp(){
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("enforcer").forSpreadsheet(sheet).onEdit().create();
}
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/
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 ?