Trigger a function when one cell is edited in Google Sheets - google-apps-script

after some hours of reading documentation and other answers I couldn't solve my problem.
I'm trying to trigger a formula when one cell is edited. I get it to run when I just ask a value to be set (see commented line in the code) but not when I call another formula.
Here's the script:
function onEdit() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var column = cell.getColumn();
if ( row ===1 && column ===4 && sheet.getName() ==="Hoja 1" ) {
sendData();
//sheet.getRange(1,1).setValue("5");
}
function sendData() {
var sheet = SpreadsheetApp.openById("1pxS9F9YEagzzRyTOqIDGVpDaCEiY_Z1DOYxq1QVzWGk");
var source_sheet = sheet.getSheetByName("Hoja 1");
var target_sheet = sheet.getSheetByName("Hoja 2");
var range1 = source_sheet.getRange(1, 7, 6, 1).getValues();
target_sheet.getRange(1,1,6,1).setValues(range1);
}
}

You have to pass the sheet into the called function this way:
sendData(spreadsheet);
function sendData(sheet) {
...
}
onEdit() is a simple trigger. Simple triggers cannot access services that require authorization. So it cannot call SpreadsheetApp.openById().
https://developers.google.com/apps-script/guides/triggers#restrictions
And pay attention -- in the function sendData() you're using the name sheet but it's a spreadsheet actually. This is not an error but it can be confusing a bit.

Related

Replace function with text in specific cell - Apps script

I tried to use the following code to replace the current cell formula with test text instead.
function replace_content() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var cellRange = sheet.getActiveCell();
cellRange.setValue("test")
return true
)
But something goes wrong and I get this error msg
Error
Exception: You do not have permission to call setValue (line 59).
Please advice.
This function runs for me with no problems:
function replace_content() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var cellRange = sheet.getActiveCell();
cellRange.setValue("test")
return true;
}

Google App Script - How to set a trigger that is activated every time a specific cell in a specific column is filled

I am doing an app with sheets api but some formulas of the sheet has some conflicts with the appended data by the api, so i need to do an autofill every time a new row is appended but i can´t set a trigger like that so i am forced to run the code every time i fill a new row. my actual code is here:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
ss.getRange("I2").setFormula(`formula`);
var lr = ss.getLastRow();
var fillDownRange = ss.getRange(2,9,lr-1);
ss.getRange("I2").copyTo(fillDownRange);
}
This function onEdit is triggered everytime an edit to the sheet happens.
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var col = cell.getColumn();
// if edited cell is "I2"
if (row == 2 && col == 9) {
// do something
}
}
myFunction below is triggered everytime user inserts row (see createTrigger at the bottom). This is not the same as appending rows via api but you might be able to use this.
function myFunction(e) {
var sheet = SpreadsheetApp.getActiveSheet();
// if user inserted row in sheets app
if (e.changeType === 'INSERT_ROW') {
// do something
}
}
You need to run createTrigger once to install the onChange trigger for myFunction.
function createTrigger() {
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("myFunction")
.forSpreadsheet(sheet)
.onChange()
.create();
}
There are other available changeType here for onChange trigger so you might want to check it out as that might be useful to you.

How to apply a Google Apps Script to an entire Google Sheets spreadsheet?

I'm trying to apply one script that will run on an entire Google Sheets spreadsheet, not just one tab. I have multiple tabs all with the same format; I want the script to look at the data validation in column F for every tab and if "Not Applicable" is selected for any row, move the contents of that entire row to a tab called "Not Applicable Items"
I have no experience writing scripts, so I copied the script I'm currently using from a forum topic. It successfully moves the rows to the correct tab, but only for the specified active sheet. I want the script to look at the entire spreadsheet and move any row marked "Not Applicable."
How can I do this? Here's my code:
function onEdit() {
var sheetNameToWatch = "Floorplan + Calendars";
var columnNumberToWatch = 5; // column A = 1, B = 2, etc.
var valueToWatch = "Not Applicable";
var sheetNameToMoveTheRowTo = "Not Applicable Items";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if (
sheet.getName() == sheetNameToWatch &&
range.getColumn() == columnNumberToWatch &&
range.getValue() == valueToWatch
) {
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet
.getRange(range.getRow(), 1, 1, sheet.getLastColumn())
.moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
All of the scripts in a given project have access to all of the sheets in the spreadsheet. Thats why we recommend that you write you onEdit(e) script like this:
function onEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()!="Sheet Name") return;
This limits the script from performing operations on unwanted sheets.
However, in your case you want all sheets involved in the onEdit(e) function so this is not necessary.
Personally, I wouldn't run this function in an onEdit() function because it's liable to take longer than 30 seconds. But the functionality you requested is accomplished with the following script. exclA is an array of sheet names that you don't want to include in your "Not Applicable" search like the sheet named "Not Applicable Items".
function notApplicable() {
var ss=SpreadsheetApp.getActive();
var dsh=ss.getSheetByName('Not Applicable Items')
var exclA=["Not Applicable Items"];
var shts=ss.getSheets();
for(var i=0;i<shts.length;i++) {
var name=shts[i].getName();
if (exclA.indexOf(shts[i].getName())==-1) {
var sh=shts[i];
var rg=sh.getDataRange();
var vA=rg.getValues();
var d=0;
for(var j=0;j<vA.length;j++) {
if(vA[j][5]=="Not Applicable") {
dsh.appendRow(vA[j]);
sh.deleteRow(j+1-d++)
}
}
}
}
}
I think that a lot of users over use the onEdit() capability.
You can grab each spreadsheet in a for loop by doing
for(var i = 0; i < [number of sheets]; i++){
sheet = ss.getSheets()[i];
. . . [rest of the code]
}
and include what you're trying to do inside the for loop to do with each sheet.

Google Spreadsheet onEdit - limit to a range

I would like to fire a trigger with onEdit if a event (edit a cell) happens in a specific range of a Sheet (NOT all Sheet)?
Exemple: I only want to trigger if a cell of the range called "trgRng" (C10:C250) of Sheet_1 is edited.
I coded as below, but it trigger all sheets not only a specific range of a specific sheet
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// source sheet
var sSh = ss.getSheetByName("Diario");
var aCell = sSh.getActiveCell().getValue();
// destiny sheet - set value from source sheet
var dSh = ss.getSheetByName("Auxiliar");
dSh.getRange('L4').setValue(aCell);
}
Is it possible? How?
I already solve it:
{
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// source sheet
var sSh = e.source.getActiveSheet();
var maxRow = sSh.getMaxRows();
var name = sSh.getName();
var rng = e.range;
var rngCol = rng.getColumn();
if (sSh.getName() == "Diário" && rng.getColumn() == 8) {
ss.getSheetByName("Diário");
var aCell = sSh.getActiveCell().getValue();
// target sheet
var shD = ss.getSheetByName("Auxiliar");
shD.getRange('L4').setValue(aCell);
}
}
}

Google Spreadsheet opening the last edited cell using script

Using the following code allows the last edited cell to open when reopening a google spreadsheet.
function setTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger("myFunction").forSpreadsheet(ss).onEdit().create();
}
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var sName = sheet.getName();
var currentCell = sheet.getActiveCell().getA1Notation();
UserProperties.setProperty("mySheetName", sName);
UserProperties.setProperty("myCell", currentCell);
}
function onOpen() {
var lastModifiedSheet = UserProperties.getProperty("mySheetName");
var lastModifiedCell = UserProperties.getProperty("myCell");
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(lastModifiedSheet).getRange(lastModifiedCell).activate();
}
I have a cell which has
=today()
Which updates so the code doesn't open the last row of my spreadsheet, but opens in the cell that updates with today().
How would I update the script to open the spreadsheet at my last edited cell in the last row of the spreadsheet?
Can you try this:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var sName = sheet.getName();
var currentCell = sheet.getActiveCell().getA1Notation();
var temp = "";
if (currentCell != "A1") {temp = currentCell;}
UserProperties.setProperty("mySheetName", sName);
UserProperties.setProperty("myCell", temp);
}
I added a temp variable and am doing a check (assuming only A1 has the today() function) before updating temp. Seems to work.