Google Script - onEdit(e) to trigger specific cell change - google-apps-script

I'm currently using the below script to trigger an automatic cell edit. However, as a script basically runs every time any cell on the worksheet is edited, I wonder if there is a way to modify it so that it only works when let's say a cell B24 is edited or a range of cells from B24 - B30 are then trigger the script. It seems like an onEdit (e) function could be an answer but I'm struggling to modify the code accordingly. Would you guys be so kind and help?
function myfunction() {
var app = SpreadsheetApp;
var targetSheet = app.getActiveSpreadsheet().getSheetByName("ABC");
targetSheet.getRange(154,2).setValue("Bingo");
}
When using the below onEdit(e) I keep receiving an error message " target sheet not defined"
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var column = range.getColumn();
var row = range.getRow();
if(sheetName == 'Harmonogram wpłat' && column == 2 && row == 24)
{
SpreadsheetApp.getActiveSpreadsheet().gatSheetByName('ABC').getRange('B154').setValue('Bingo');
}
}

Most likely, the error is due to the typo in the last line of your code.
gatSheetByName('ABC')
should be
getSheetByName('ABC')
See if that helps?

Modification points:
You have a typo as the other answer has already mentioned. It should be getSheetByName(name) and not gatSheetByName(name).
You want to execute the script when a cell in the range B24 - B30 is edited. To achieve that you need to modify the if condition to include that range:
if(sheetName == 'Harmonogram wpłat' && column == 2 && row > 23 && row<31)
SpreadsheetApp.getActiveSpreadsheet() can be replaced by spreadSheet since e.source is exactly the same thing.
Solution:
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var column = range.getColumn();
var row = range.getRow();
if(sheetName == 'Harmonogram wpłat' && column == 2 && row > 23 && row<31){
spreadSheet.getSheetByName('ABC').getRange('B154').setValue('Bingo');
}
}

Related

Run app script if cell in specific sheet changes value

I want to run this script automatically whenever the value in cell A1 in sheet "NETRankingsRohdaten" changes. Thanks for help.
function NETsaveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var reportSheet = ss.getSheetByName("NETRankingsRohdaten");
var recordsSheet = ss.getSheetByName("NETDatabase")
var NETsaveData = reportSheet.getRange("A2:F")
.getValues();
var lastRow = recordsSheet.getLastRow();
//copy data
recordsSheet.getRange(lastRow+ 1, 1, NETsaveData.length, 6)
.setValues(NETsaveData);
}
I believe your goal is as follows.
You want to run the script when the cell "A1" of "NETRankingsRohdaten" sheet is edited.
In this case, how about using OnEdit trigger? When OnEdit trigger is used, your script becomes as follows.
Modified script:
function onEdit(e) {
var range = e.range;
var reportSheet = range.getSheet();
if (reportSheet.getSheetName() != "NETRankingsRohdaten" || range.rowStart != 1 || range.columnStart != 1) return;
var ss = e.source;
var recordsSheet = ss.getSheetByName("NETDatabase")
var NETsaveData = reportSheet.getRange("A2:F").getValues();
var lastRow = recordsSheet.getLastRow();
recordsSheet.getRange(lastRow + 1, 1, NETsaveData.length, 6).setValues(NETsaveData);
}
In this case, when the cell "A1" of "NETRankingsRohdaten" sheet is edited, the script is run. So, when you directly run this function, an error occurs. Please be careful about this.
Note:
If you want to use NETsaveData(), you can also use the following script. In this case, your NETsaveData() is not modified. But when the cell "A1" of "NETRankingsRohdaten" sheet is edited, the script is run.
function onEdit(e) {
var range = e.range;
var reportSheet = range.getSheet();
if (reportSheet.getSheetName() != "NETRankingsRohdaten" || range.rowStart != 1 || range.columnStart != 1) return;
NETsaveData();
}
References:
Simple Triggers
Event Objects

Apps Script onEdit to add/clear timestamp across multiple sheets if a checkbox is checked/unchecked

I've got the script below working except for the bottom portion starting at //3. The initial portion works on my first sheet listed and adds a timestamp if a checkbox is checked, clears it if it is unchecked. However, it only works on the first sheet, and I need it to work on the second sheet listed as well. The data is set up differently on each sheet so that's why I have these broken out. I'd appreciate any guidance, I'm very new to Apps Script and learning so I'm sure it's a novice and silly mistake:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
var r = ss.getActiveCell();
//1.Change 'Sheet1' to match your sheet name
if (r.getColumn() == 1 && ss.getName()=='Sheet1') { // 2. If Edit is done in column 1 make change in column 4(D) then:
var celladdress ='D'+ r.getRowIndex();
if(r.getValue() !="" && r.getValue() !=" "){
ss.getRange(celladdress).setValue(new Date()).setNumberFormat("MM/DD/YYYY hh:mm:ss");
} else{
ss.getRange(celladdress).clearContent();
}
//3.Change 'Sheet2' to to match your sheet name
if (r.getColumn() == 1 && ss.getName()=='Sheet2') { // 4. If Edit is done in column (G) then:
var celladdress ='G'+ r.getRowIndex();
if(r.getValue() !="" && r.getValue() !=" "){
ss.getRange(celladdress).setValue(new Date()).setNumberFormat("MM/DD/YYYY hh:mm:ss");
} else{
ss.getRange(celladdress).clearContent();
}
}
}
}
Modification points:
In your script, I thought that an object for searching the sheet name might be able to be used.
In this modification var obj = {Sheet1: "D", Sheet2: "G"} is used.
For example, obj["Sheet1"] returns D. This is used for the modified script.
About the checkbox, you can also use isChecked() for checking whether the checkbox is checked.
When above points are reflected to your script, it becomes as follows.
Modified script:
function onEdit(e) {
var r = e.range;
var ss = r.getSheet();
// Prepare an object for searching sheet name.
var obj = {Sheet1: "D", Sheet2: "G"};
// Using the object, check the sheet and put or clear the range.
if (r.getColumn() == 1 && obj[ss.getSheetName()]) {
var celladdress = obj[ss.getName()] + r.getRowIndex();
if (r.isChecked()) {
ss.getRange(celladdress).setValue(new Date()).setNumberFormat("MM/DD/YYYY hh:mm:ss");
} else {
ss.getRange(celladdress).clearContent();
}
}
}
In this case, the event object is used. But if you want to directly run the function at the script editor, please modify as follows.
From
var r = e.range;
var ss = r.getSheet();
To
var ss = SpreadsheetApp.getActiveSheet();
var r = ss.getActiveCell();
References:
Event Objects
isChecked()

Run trigger script when a one or more cells change in a range

I'm new to google sheets & script app. I'm using google sheets to maintain real-time project budgets. I've created a history tab to capture historical high level information (project code, category, Total Approved Budget, Projected Cost, Date stamp). Each time the scrip runs, it captures 4 rows of data.
function recordHistory() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('ForMaster');
var sheet2 = ss.getSheetByName('History');
var data = sheet1.getRange('S84:W87').getValues();
var last_row = sheet2.getLastRow();
sheet2.getRange(last_row + 1,1,4,5 ).setValues(data);
}
I'd like to set up a trigger that runs where ever there is a change to any of the cells in data range (S84:W87).
I've tried the following, but it doesn't seem to work.
function setupTrigger() {
ScriptApp.newTrigger('recordHistory')
.forSpreadsheet('1TSX27lzmOpv6P8Z8zJJhYem_yLQwP-gYK4WYHJ3LEuA')
.onEdit()
.create();
}
function recordHistory(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('ForMaster');
var sheet2 = ss.getSheetByName('History');
var data = sheet1.getRange('S84:W87').getValues();
var last_row = sheet2.getLastRow();
sheet2.getRange(last_row + 1,1,4,5 ).setValues(data);
}
Explanation:
You don't need an installable trigger since you don't use any service that requires permission.
You can use a simple onEdit(e) trigger instead.
In order to define the range S84:W87 that you would like to accept edits, you can do that:
row>=84 && row <= 87 && col >=19 && col <=23
84 is the starting row, 87 is the end row, column 19 is S and column 23 is W.
Also you want to only accept edits on the sheet ForMaster.
Therefore the if statement would look like that:
if(as.getName()=="ForMaster" && row>=84 && row <= 87 && col >=19 && col <=23)
Solution:
function onEdit(e) {
const ss = e.source;
const as = ss.getActiveSheet();
const row = e.range.getRow();
const col = e.range.getColumn();
if(as.getName()=="ForMaster" && row>=84 && row <= 87 && col >=19 && col <=23){
const sheet2 = ss.getSheetByName('History');
const data = as.getRange('S84:W87').getValues();
const last_row = sheet2.getLastRow();
sheet2.getRange(last_row + 1,1,data.length,data[0].length).setValues(data);
}
}
Note that!
The onEdit triggers are triggered upon user edits. This function won't be triggered by formula nor another script.
Again, this is a trigger function. You are not supposed to execute it manually and you will actually get errors. All you have to do is to save this code snippet to the script editor and then it will be triggered automatically upon edits.

Only execute onEdit if the users make edit within a specific range

How can I trigger onEdit only when users make any edits with a specific range in Google App Script?
You cannot create an onEdit that only fires when certain cells are edited, but you can put a condition in the beginning of your function to check if the edited cells are part of the range you want to track changes from. You can do that with the use of an event object for that.
For example, you can do this (check inline comments):
function onEdit(e) {
// Information from edited range:
var range = e.range;
var editedRow = range.getRow();
var editedCol = range.getColumn();
var editedSheet = range.getSheet();
// Range to track (please change accordingly):
var sheetName = "Sheet To Track";
var minCol = 3;
var maxCol = 7;
var minRow = 2;
var maxRow = 5;
// Check that edited sheet, column and row are the ones you want to track changes from:
if (editedSheet.getName() === sheetName && editedRow >= minRow && editedRow <= maxRow && editedCol >= minCol && editedCol <= maxCol) {
// Actions to perform if edited range is correct
}
}
The function above will first check if the edited range is (1) between columns 3 and 7, (2) between rows 2 and 5 and (3) in the sheet called Sheet To Track.
Reference:
Event Objects: Edit

Script to Move Range Showing No Error but Not Executing

Learning scripts by trial and error. Please forgive probable ignorance in the question. I want a script to move a specific range (but not the whole row) in the active sheet to be positioned above another range in the active sheet. I want this move to take place upon edit and only when the text in column H is "C". The script I have so far runs with no errors but does not affect any change. Additionally, I would like this same thing to happen not only for row 4 but for rows 4-18. I was simply going to copy successful lines multiple times and update range for each, but I am sure there is a better way?
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var rangetoWatch = ("F4:I4");
var columnNumberToWatch = 8;
var valueToWatch = "C";
if (sheet.getName() == sheet && sheet.getRange() == range.getColumn() == columnNumberToWatch && rangetoWatch.getValue() == valueToWatch) {
sheet.getRange("F20:I").moveTo(sheet.getRange("F21"));
sheet.getRange("F4:I4").moveTo(sheet.getRange("F20:I20"));
}
}
in case anyone stumbles across this thread in the future... i finally figured out what I was trying to accomplish. a sample script is below.
function movedown(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var row = range.getRow();
var mini = sheet.getRange(row, 1, 1, 3);
var columnNumberToWatch = 3;
var valueToWatch = "C";
if (range.getColumn() == columnNumberToWatch && range.getValue() == valueToWatch) {
sheet.getRange("A15:C").moveTo(sheet.getRange("A16"));
sheet.getRange(row, 1, 1, 3).copyTo(sheet.getRange("A15:C15"));
sheet.getRange(row, 1, 1, 3).clear({contentsOnly:true});
}
}
I think this is what you want. But I did not find your explanation to be very clear.
function onEdit(e) {
var sheet=e.range.getSheet();
//next line not required if you want it to happen on all sheets
if(sheet.getName()!='SomeSheetName'){return;}//keep the process from only happening on one sheet
if(e.range.rowStart>=4 && e.range.rowStart<=18 && e.range.columnStart==8 && e.value=='C') {
sheet.getRange(20,6,sheet.getLastRow(),4).moveTo(sheet.getRange(21,6));
sheet.getRange(e.range.rowStart,6,1,4).moveTo(sheet.getRange(20,6,1,4));
}
}