i need to run Google App script in onEdit [duplicate] - google-apps-script

This question already has an answer here:
onEdit simple trigger never seems to be triggered
(1 answer)
Closed 3 years ago.
I'm trying to create a script so that when I edit text in column A then it automatically deletes text that is in column D of the same row and if column C in the same row (it contains ID of file from my drive) is not empty then delete that file.
I successfully created it and it's working when explicitly run the script in test , but the onEdit event never seems to get fired (not seeing log messages even).
anyone have an idea how it works ?
function onEdit(e) {
var currentSheet = e.range.getSheet();
var sheetEdited = currentSheet.getName();
var rowEdited = e.range.getRow();
var columnEdited = e.range.getColumn();
// if cell edited in sheet name form 1 and in column 1 then
if(sheetEdited == "form 1" && ( columnEdited == 1)){
// delete text in edited row column D
currentSheet.getRange(rowEdited,4).setValue('');
// if on edited row column C(that contain doc id ) if filled then detele that file
if (sheetId != "") {
var sheetId = currentSheet.getRange(rowEdited,3).getValues();
DriveApp.getFileById(sheetId).setTrashed(true);
}
}
}

The problem is that simple triggers can't perform operations that require authorization. So you have to use an installable trigger. Don't forget to change the name of the function.
function onEdit(e) {
var sh = e.range.getSheet();
if(sh.getName()=="form 1" && e.range.columnStart==1){
sh.getRange(e.range.rowStart,4).setValue('');//D
var id=sh.getRange(e.range.rowStart,3).getValue();//C
if(id!="")DriveApp.getFileById(id).setTrashed(true);
}
}

Related

Google Sheets Script on Form sumbission [duplicate]

This question already has answers here:
Use a trigger to sort a sheet every time a form is submitted
(1 answer)
onEdit() function does not triggered when change was made by automatic script
(3 answers)
Closed last month.
I have a working script for Google sheets that checks 3 columns with trues and falses and writes baked TRUE/FALSE value for a 4th column when new data is entered.
function onEdit() {
var s = SpreadsheetApp.getActiveSheet(); if(s.getName() == "test" ) { //checks that we're on the right sheet
var r = s.getActiveCell();
if(r.getColumn() == 1) { //checks that the cell being edited is in column A
var trgtCell = r.offset(0, 7);
if(r.offset(0, 5) == "TRUE" && r.offset(0, 6) == "TRUE" && trgtCell.getValue() === ' ') //checks the rule + if the target (trgt) cell is empty
trgtCell.setValue("TRUE");
} else {
trgtCell.setValue("FALSE");
}}}
The sheet is connected with more Google Forms.
Now my script only works when data is manually entered but when the relevant form is submitted, it creates a new row and my script does not get active. I guess because it only triggers by "edit" which I guess is manually editing the sheets.
Can anyone help me how I could convert the script to work when form is submitted? That would be my main goal.

Having spreadsheet content move to another sheet when checkbox is clicked + dialog box show up [duplicate]

This question already has answers here:
How can I test a trigger function in GAS?
(4 answers)
Closed 6 months ago.
This post was edited and submitted for review 6 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I want to move a row from one spreadsheet (JobRequest) to another (Accepted) spreadsheet by clicking the checkbox automatically (no yes/no button) (located in col G). There are 7 columns of data to be moved. I want a dialog to popup at the time the box is checked too, to confirm that they have read that dialog box and accepted.
Ideally, I can log this and if they exit out of the dialog box the box unchecks, but I haven't gotten that far yet, so that's for another post.
For now, can you help be figure out where I went wrong for this checkbox to move to another sheet?
I keep getting the error
Error
TypeError: Cannot read property 'source' of undefined
I thought I already had it defined.
function onEdit(e){
const src = e.source.getActiveSpreadsheet();
const r = e.range;
if(src.getName()!= 'JobRequests' || r.columnStart !=7 || r.rowStart == 1) return;
const dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Accepted');
src.getRange(r.rowStart,1,1,7).moveTo(dest.getRange(dest.getLastRow()+1,1,1,7));
src.deleteRow(r.rowStart);
}
function showFeedbackDialog() {
var widget = HtmlService.createHtmlOutputFromFile("AcceptanceForm.html");
widget.setWidth(400);
widget.setHeight(500);
SpreadsheetApp.getUi().showModalDialog(widget, "Send feedback");
}
Modification points:
When I saw your question and script, the reason of your issue might be due to getActiveSpreadsheet() of const src = e.source.getActiveSpreadsheet();. e.souece returns Spreadsheet object. In this case, getActiveSpreadsheet() cannot be used. Please use getActiveSheet().
In order to open a dialog, in this modification, I used SpreadsheetApp.getUi().alert().
In order to record a log, I used other sheet.
In order to uncheck the checkbox, uncheck() is used.
When these points are reflected in your script, how about the following modification?
Modified script:
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if (src.getName() != 'JobRequests' || r.columnStart != 7 || r.rowStart == 1 || !r.isChecked()) return;
const ui = SpreadsheetApp.getUi();
const res = ui.alert("Move row?", ui.ButtonSet.YES_NO);
if (res == ui.Button.NO) {
r.uncheck();
return;
}
const dest = e.source.getSheetByName('Accepted');
src.getRange(r.rowStart, 1, 1, 7).moveTo(dest.getRange(dest.getLastRow() + 1, 1, 1, 7));
src.deleteRow(r.rowStart);
r.uncheck();
const log = e.source.getSheetByName("log") || e.source.insertSheet("log");
log.appendRow([new Date(), `row ${r.rowStart} was moved.`]);
}
When you use this script, please check the checkbox in column "G" of "JobRequests" sheet. By this, the script is run and you can see a dialog.
And, in this modification, a log is recorded to "log" sheet. But, in this case, please modify the log data in the above script for your actual situation.
References:
Event Objects
getActiveSheet()
uncheck()

Apps Script Trigger for IMPORTXML , OnChange / OnEdit [duplicate]

This question already has answers here:
onChange Trigger not working as expected
(1 answer)
Timestamp Google Script triggered by formula
(2 answers)
Closed 7 months ago.
I am currently in the middle of making a project, whereas data is being pulled from website via IMPORTXML. I tried editing and searching for an answer to the question: how do I get a Timestamp in Column "AP" when there is data changed to Column "N" ? I've tried simple & installable triggers, but none seem to work.
Link to the file (Spreadsheets)
I have never really had to use Apps Script for Google Spreadsheet, so I am sorry if there's some dumb coding there.
function onChange2(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
if(col == 14){
e.source.getActiveSheet().getRange(row,42).setValue(new Date());
}
}
Didn't work
function createSpreadsheetChangeTrigger() {
var ss = SpreadsheetApp.getActive();
var row = range.getRow();
var col = range.getColumn();
ScriptApp.newTrigger('onChange2')
.forSpreadsheet(ss)
.onChange()
.create();
if(col == 14){
source.getActiveSheet().getRange(row,42).setValue(new Date());
}
}
> No Luck here too

Apps Script to update Timestamp when data is inserted automatically in google sheet

This code works fine when data is edited in Column 3 or being copy-pasted but if the cursor remains at column 1 at the time of the whole row being copy/pasted, it won't update and secondly, if salesforce sends data to column 3, it doesn't work that time too, please help me here.
function onEdit() {
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");
Explanation:
Three important things to know:
As it is also stated in the official documentation, the onEdit triggers are triggered upon user edits. This function won't be triggered by formula nor another script. If salesforce or any other service except for the user, edits column C the onEdit trigger is not going to be activated. Workarounds exist, but these workarounds depend on the context of your specific problem. I would advice you to search or ask a specific question about it.
Regarding the other issue you have, you should get rid of active ranges and take advantage of the event object. This object contains information regarding the edit/edits user made.
As it is recommended by the Best Practices you should not set values in the sheet iteratively but you can to that in one go by selecting a range of cells and set the values. In your case, you want to set the same value in all of the cells in the desired range, hence setValue is used instead of setValues. But the idea is to get rid of the for loop.
Solution:
function onEdit(e) {
var s = e.source.getActiveSheet();
var sName = s.getName();
var ar = e.range;
var row = ar.getRow();
var arRows = ar.getNumRows()
if( ar.getColumn() == 3 && sName == 'Sheet1') {
s.getRange(row,6,arRows).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 script works only for data manually entered and not for data brought in through importrange in spreadsheet

I have this script to hide those rows which contains the word - 'Matured' (in column F)
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var r = e.source.getActiveRange();
if (sheet.getName() == "Follow-ups LAPL" && r.getColumnIndex() == 6 && r.getValue() == "Matured")
sheet.hideRows(r.getRowIndex(),1);
The problem is - the script does the job of hiding the row only when the 'Matured' is entered MANUALLY (in column F), but it does not work if the same is brought in through importrange (in same column F).
Is it by design, or is there any workaround?
Thanks for help!
It is by design. You may trigger the onchange event rather than the onEdit event for your use case or you may trigger both. See if onChange works in both cases, if so you may trigger only that. If it doesn't then you may trigger both events at the same time.
You may trigger multiple events on the same function by going to the Current Project's trigger as shown below:
You can create your own function and trigger every minute. But make sure in master spreadsheet (Spreadsheet id which you included in importrange) you delete empty cells or else in below loop sheet.getLastRow() will count empty cells too which will result in unnecessary iteration.
function onModified() {
var ss = SpreadsheetApp.openById('SPREADSHEET ID');
var sheet = ss.getSheetByName("Follow-ups LAPL");
var getData = sheet.getRange(1, 6, sheet.getLastRow(), 1).getValues();
Logger.log(getData.length);
for (var i = 0; i < getData.length; i++) {
if (getData[i][0] == "Matured") {
sheet.hideRows(i+1,1);
} else {
sheet.showRows(i+1, 1);
}
}
}