Installable On edit Trigger Not Firing - google-apps-script

I have a container-bound script attached to a Google Sheet for which I've manually added an On edit installable trigger. I'm using an installable trigger rather than a simple trigger because I want the script to run from the sheet owner's account (my account) no matter who the user is who made the edit. The script is as follows:
function checkTimecardRange() {
var activeSS = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = activeSS.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var approvalTimestamp = activeSheet.getRange("V" + row);
var timecardRange = activeSheet.getRange("A" + row + ":V" + row);
if(timecardRange.isBlank()==false) {
lockTimecardRange(timecardRange, row);
}
}
function lockTimecardRange(timecardRange, row) {
var protection = timecardRange.protect().setDescription('Timecard Row' + row);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
It works fine when I run it manually, but the On edit trigger that I set up for it will not fire. I changed the trigger to a test script:
function log(){
console.log("Hello worlds");
}
and that doesn't fire either. Any assistance in getting the onEdit installable trigger to fire would be greatly appreciated. The edits based on which I expect the trigger to fire are manual edits (at this point I'm just typing in random values) and they are made from the account that owns the sheet and created the scripts.

Well, it turns out that it was a glitch on Google's side. All I had to do was delete the trigger, save, then re-add the trigger without any changes, and everything worked just fine. Go figure.

Related

onEdit specific cell copy data from one google sheets to another

In google sheets, I am trying to get one data to copy from one sheet to another.
I have this code which is working however I would like it to run onEdit when changing cell E4 in Googlesheet1. I am new at this and doesn't seem to get it to quite work with the solutions I found online.
function ExportRange() {
var destination = SpreadsheetApp.openById('googlesheet1');
var destinationSheet = destination.getActiveSheet();
var destinationCell = destinationSheet.getRange("AC3");
var cellData = '=IMPORTRANGE("https://docs.google.com/spreadsheets/googlesheet2", "AE10:AE9697")';
destinationCell.setValue(cellData);
}
Chose between a simple and installable onEdit trigger, depending on your requirements
For most applciaitons a simple onEdit trigger is sufficient, to use it you just need to rename your function ExportRange() to onEdit()
Take advantage of event objetcs that give you informaiton about the event that fired the trigger
So, the trigger onEdit can give you among others information about the event range - that is the range that has been edited
Now you can implement an if statement to specify that the rest of the funciton shall only be run if the event range and the corresponding sheet are as required
Sample:
function onEdit(event) {
var range = event.range;
var sheet = range.getSheet();
if(range.getA1Notation() == "E4" && sheet.getName() == "Googlesheet1"){
var destination = SpreadsheetApp.openById('googlesheet1');
var destinationSheet = destination.getActiveSheet();
var destinationCell = destinationSheet.getRange("AC3");
var cellData = '=IMPORTRANGE("https://docs.google.com/spreadsheets/googlesheet2", "AE10:AE9697")';
destinationCell.setValue(cellData);
}
}
Please note that this function can only be fired by the trigger in
case of an edit. If you try to run it manually, it will give you an
error because event (and thus event.range) will be undefined if
the funciton was not called by an edit event.

onEdit function update undo history

I need to store the last modification user and date of a sheet in developer metadata.
I use the onEdit function to update these metadata at each edit of a sheet (please see the code below)
My problem is the metadata creation/update is taken into account in the undo history.
So users need to ctrl+Z three times for one cancel...
Do you know a way to avoid this behavior?
function onEdit(e) {
// Prevent errors if no object is passed.
if (!e) return;
var dateMetadata;
var dateKey = 'lastModificationDate';
var userMetadata;
var userKey = 'lastModificationUser';
// Get the active sheet.
var sheet = e.source.getActiveSheet();
var user = e.user.getEmail();
var date = Math.floor(Date.now() / 1000);
metadatas = sheet.getDeveloperMetadata();
for each (var m in metadatas) {
if (m.getKey() === dateKey) {
dateMetadata = m;
}
if (m.getKey() === userKey) {
userMetadata = m;
}
}
if (dateMetadata) {
dateMetadata.setValue(date);
} else {
sheet.addDeveloperMetadata(dateKey, date);
}
if (userMetadata) {
userMetadata.setValue(user);
} else {
sheet.addDeveloperMetadata(userKey, user);
}
}
After the script was run, when one time "ctrl+Z" is pushed, you want to undo the put value.
In your current script, after a value is put to a cell, the undo can be done by pushing 3 times "ctrl+Z".
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
When the Spreadsheet is opened from outside and modify the Spreadsheet with the script, even when "ctrl+Z" is pushed, the undo cannot be done. In your case, I thought that this can be used.
Use var sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName) instead of var sheet = e.source.getActiveSheet().
Modified script:
When your script is modified, it become as follows.
From:
function onEdit(e) {
To:
function installedOnEdit(e) {
In this case, please install the installable OnEdit event trigger for the function of installedOnEdit. By this, openById can be used.
And also, please modify as follows.
From:
var sheet = e.source.getActiveSheet();
To:
var id = e.source.getId();
var sheetName = e.source.getActiveSheet().getSheetName();
var sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
Note:
When the installable OnEdit event trigger is used, the double run of functions can be prevented by changing the function name from onEdit to installedOnEdit. Ref
In this case, unfortunately, it cannot confirm using the event object whether "ctrl+Z" was pushed. By this, the added developer metadata cannot be canceled with "ctrl+Z". Please be careful this.
As another method, of course, I think that you can also use Sheets API in your situation.
References:
Simple Triggers
Installable Triggers
Asynchronous Processing using Event Triggers
openById(id)
getSheetByName(name)
If I misunderstood your question and this was not the direction you want, I apologize.

Create a trigger that works if the person is not an editor

I want people to jump to the current date row when opening the sheet. However, this should be the case for everyone viewing the sheet and irrespective of their edit-rights. For example, I want that people edit the current date row in the sheet every day over the link. In this case, onOpen() does not work. Is there any alternative or modification to the function?
I am informed about onOpen trigger, however, this would not work if somebody is editing the sheet only over the link with edit rights.
This is e.g. the code I would like to work for everyone:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("B:B");
var values = range.getValues();
var day = 24*3600*1000;
var today = parseInt((new Date().setHours(0,0,0,0))/day);
var ssdate;
for (var i=0; i<values.length; i++) {
try {
ssdate = values[i][0].getTime()/day;
}
catch(e) {
}
if (ssdate && Math.floor(ssdate) == today) {
sheet.setActiveRange(range.offset(i,0,1,1));
break;
}
}
}
I found the options: Edit Triggers
To manually create an installable trigger through a dialog in the script editor, follow these steps:
From the script editor, choose Edit > Current project's triggers.
Click the link that says: No triggers set up. Click here to add one now.
Under Run, select the name of function you want to trigger.
Under Events, select either Time-driven or the Google App that the script is bound to (for example, From spreadsheet).
Select and configure the type of trigger you want to create (for example, an Hour timer that runs Every hour or an On open trigger).
Optionally, click Notifications to configure how and when you are contacted by email if your triggered function fails.
Click Save.
Google Explanation to Edit Triggers

Google sheets - User/Email stamp triggered ON EDIT works only with OWNER account - how to enable user/email stamps for all editors?

I need a solution to enable all editors to leave their name stamps after they make changes in a sheet. I was able to come up with script code which does work ONLY FOR OWNER.
I tried to authorize the script by running the script manually from editors accounts - the app has the authorization but even though it doesn't work for Editors.
Norbert Wagner: "However authorizing from the script editor did not work for me. But as soon as I added a menu in the document and executed the function from there, I got an authorization request in the document. From then on also the onEdit function works, for all users. I did this as the documents owner though. " -
maybe this is the solution? But how can I run the onEdit from the
document? Simple edit doesn't work, but how about this menu? Is there
a way to execute ALL SCRIPTS AND FORCE AUTHORIZATION from document level?
function onEdit(e) {
// Your sheet params
var sheetName = "Arkusz1";
var dateModifiedColumnIndex = 3;
var dateModifiedColumnLetter = 'C';
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 user = Session.getActiveUser().getEmail();
user = String(user);
user = user.replace('#gmail.com', '');
var dateModifiedRange = sheet.getRange(dateModifiedColumnLetter + row.toString());
dateModifiedRange.setValue(user);
};
};
This function works only when using owner account.
Even after Editor has authorised script manually from script editor - the onEdit user stamp function doesn't trigger.
Below is another function which I used for testing. When I run it manually from editors account IT WORKS - it saves editor's name in A1.
function USERNAME(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0]; // this will assign the first sheet
var cell = sheet.getRange('A1');
var d = new Date();
d.setHours(d.getHours() +1);
var user = Session.getActiveUser().getEmail();
user = String(user);
user = user.replace('#gmail.com', '');
cell.setValue(user);
}
In fact you have to use installable trigger.
Rename your function onEdit(e) with another name for example customFunction(e)
Then you setup an installable trigger using this function :
function createTrigger(){
ScriptApp.newTrigger('customFunction')
.forSpreadsheet(SpreadsheetApp.openById('YOU_SHEET_ID'))
.onEdit()
.create();
}
Or you can setup the trigger manually by going to 'Edit >> Current project's triggers >> Click on + button (bottom right)'
By this way trigger will run each time there is an Edit no matter the user.
Stéphane

onEdit Installable Trigger not firing

I'm trying to create a script in Google Sheets that will send me an automated email every time that a value within a given column ("Column H") drops below a certain threshold. I've currently got the following script written, which includes an installable onEdit trigger. However, the script is not running when the spreadsheet is edited:
function StationeryEdited(e){
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getRange(2, 8, 200, 1).getValues();
var newValue = e.value;
if (newValue < "10"){
MailApp.sendEmail("test#test.co", "TEST", "TEST");
}
function createSpreadsheetEditTrigger(){
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger(StationeryEdited)
.forSpreadsheet(ss)
.onEdit()
.create();
}
}
Have you tried putting function name in quotation marks like this?
ScriptApp.newTrigger('StationeryEdited')
Also, you can simply go to Edit -> Current project triggers and configure the trigger for your function manually select the following options for the 'StationeryEdited' function
Try this and set the installable trigger through the script editor:
function onEdit(e) {
var editColumn=e.range.getSheet().getActiveCell().getColumn()
if(editColumn==8 && e.value>10){
MailApp.sendEmail("test#test.co", "TEST", "TEST");
}}