How can I combine the two onEdit? [duplicate] - google-apps-script

This question already has an answer here:
Merging or Combining two onEdit trigger functions
(1 answer)
Closed 2 years ago.
I made a dependent drop-down with a script.
I'd like to apply it to two sheets.
but only OnEdit1 works and onEdit2 doesn't work.
I don't know what to do with both sheets.
Do I have to add or do something to make two sheets work?
function onEdit(e){
oneEdit1(e);
var tabLists = "lists";
var tabValidation = "Question_B";
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makes = datass.getRange(1, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
oneEdit2(e);
var tabListss = "lists2";
var tabValidations = "Qeustion_R";
var sss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datasss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabListss);
var activeCell = sss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidations){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makess = datasss.getRange(1, 1, 1, datasss.getLastColumn()).getValues();
var makeIndexs = makess[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datasss.getRange(3, makeIndexs, datasss.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}

Two combine two onEdit functions in one:
define both of them outside of the main function
call them from the main function
Sample:
function onEdit(e){
oneEdit1(e);
oneEdit2(e)
}
function oneEdit1(e){
...
}
function oneEdit2(e){
...
}

Related

Having issues making dependent drop down lists

I've been trying to make dependent drop down lists using App script. When I select my independent drop down option, executions shows "Completed", yet it won't add in the dependent drop down in the column beside it.
I can't seem to figure out what's going wrong here:
function onEdit(){
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Exercise Index");
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 1 && activeCell.getRow() > 3 && ss.getSheetName()=="Weekly Template"){
activeCell.offset(0,1).clearContent().clearDataValidations();
var categories = datass.getRange(1,1,1,datass.getLastColumn()).getValues();
var catIndex = categories[0].indexOf(activeCell.getValue())+1;
if(catIndex != 0){
var validationRange = datass.getRange(2,catIndex,datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0,1).setDataValidation(validationRule);
}
}
}
Any help would be greatly appreciated as this is my first go at App Script.
I did manage to get it functioning as intended. Here's the script in case anyone comes across this in the future:
function onEdit(){
var tabLists = "Exercise Index";
var spreadsheet = SpreadsheetApp;
var activeSheet = spreadsheet.getActiveSpreadsheet().getActiveSheet();
var data = spreadsheet.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = activeSheet.getActiveCell();
if(activeCell.getColumn() == 1 && activeCell.getRow() > 3 && activeSheet.getSheetName().includes("Week")){
activeCell.offset(0, 1).clearDataValidations();
var makes = data.getRange(1, 1, 1, data.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = data.getRange(2, makeIndex, data.getLastRow());
var validationRule = spreadsheet.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}

I've combined two onedit scripts and only one is working

I combined the scripts to operate the two onedits. But only onedit1 works, and onedit2 doesn't work
I don't know which part I need to fix to make both of them work.
Should I add something to the onedit part? Or which part should I exclude?
function onEdit(e){
onedit1(e);
onedit2(e)
}
function onedit1(e){
var tabLists = "lists1";
var tabValidation = "Questions_B";
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makes = datass.getRange(1, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
function onedit2(e){
var tabLists = "lists2";
var tabValidation = "Questions_R";
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makes = datass.getRange(1, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}
}
}
}
You have defined onedit2 inside onedit1 but you never execute it. You only define it.
If you want to keep the two onEdit function apart then simply separate them so they can both be executed by the main onEdit:
function onEdit(e){
onedit1(e);
onedit2(e);
}
// onedit1
function onedit1(e){
var tabLists = "lists1";
var tabValidation = "Questions_B";
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makes = datass.getRange(1, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}
// onedit2
function onedit2(e){
var tabLists = "lists2";
var tabValidation = "Questions_R";
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makes = datass.getRange(1, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}

Google Sheets script - code optimization - one script, two sheets, same workbook

I have one workbook with multiple sheets and I've been running some simple scripts on two of those sheets (those sheets are basically copies of one another).
Once script creates a dropdown based on the value entered in one of the cells, while the second script adds a timestamp based on when the new dropdown was edited.
Initially I had two onEdit functions running on the first sheet.
Then I created a copy of these functions, with small amendments, to run on another sheet(same workbook)
Given that I don't really know how to have a separate script per worksheet I now have a one script with 4 similar onEdit functions.
Since I'm a total newbie I'm sure there's a better, more efficient way to write this code.
I'd appreciate your help in optimizing this.
function onEdit(e) {
addTimestamp(e);
addTimestamp2(e);
Dropdown(e);
Dropdown2(e);
}
function addTimestamp(e) {
var startRow = 2;
var targetColumn = 10;
var ws = "Tracker1";
var row = e.range.get.Row();
var col = e.range.getColumn();
if(col === targetColumn && row >= startRow && e.source.getActiveSheet().getName() === ws) {
var currentDate = new Date();
e.source.getActiveSheet().getRange(row,11).setValue(currentDate);
}
}
function addTimestamp2(e) {
var startRow = 2;
var targetColumn = 10;
var ws = "Tracker2";
var row = e.range.get.Row();
var col = e.range.getColumn();
if(col === targetColumn && row >= startRow && e.source.getActiveSheet().getName() === ws) {
var currentDate = new Date();
e.source.getActiveSheet().getRange(row,11).setValue(currentDate);
}
}
function Dropdown(){
var tabLists = "StatusFlow";
var tabValidation = "Tracker1"
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 9 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(o,1).clearContent().clearDataValidations();
var makes = datass.getRange(1,1,1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) +1;
if(makeIndex !=0) {
var validationRange = datass.getRange(2, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).setAllowInvalid(false).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}
function Dropdown2(){
var tabLists = "StatusFlow";
var tabValidation = "Tracker2"
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabLists);
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 9 && activeCell.getRow() > 1 && ss.getSheetName() == tabValidation){
activeCell.offset(o,1).clearContent().clearDataValidations();
var makes = datass.getRange(1,1,1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) +1;
if(makeIndex !=0) {
var validationRange = datass.getRange(2, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).setAllowInvalid(false).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}
here is a more efficient way to replace the two addTimestamp functions:
function onEdit(e) {
var activeSheet = e.source.getActiveSheet();
var activeSName = activeSheet.getName();
var row = e.range.get.Row();
var col = e.range.getColumn();
if ((activeSName == 'Tracker1' || activeSName == 'Tracker2') && col === 10 && row >= 2) {
activeSheet.getRange(row, 11).setValue(new Date());
}
}
You could give the two Dropdown functions a shot and see if you can do something similar. Nothing like learning-by-doing. :-D
Just be careful that in onEdit you are passing e to these Dropdown functions. But not using them in these functions.

Action script on one tab only

trying to get a script to only run on one tab, rather than impact all tabs - this one seems to be having an impact across multiple tabs for some reason.
Have tried declaring the name of the tab, which in this case would be:
"1. Scheduling"
but it breaks down and I get errors when trying to run the script. Any ideas?
function onEdit(){
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("3. Current_Team")
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1){
activeCell.offset(0, 1).clearContent().clearDataValidations();
var makes = datass.getRange(1, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0) {
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}
Try this:
function onEdit(e){
var sh=e.range.getSheet();
if(sh.getName()!='1. Scheduling')return;
var datash=e.source.getSheetByName("3. Current_Team")
if(e.range.columnStart==4 && e.range.rowStart>1){
e.range.offset(0, 1).clearContent().clearDataValidations();
var makes=datash.getRange(1, 1, 1, datash.getLastColumn()).getValues();
var makeIndex=makes[0].indexOf(e.value) + 1;
if(makeIndex != 0) {
var validationRange = datash.getRange(3, makeIndex, datash.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
e.range.offset(0, 1).setDataValidation(validationRule);
}
}
}

Google app scripts - Why is my onEdit() function taking so long?

Ok so I need to select a range that is around 350 rows and 4 columns, take the values from it and on every change in my drop down I search and compare the rows and columns from selected range and I'm finding the matches in order to filter out the drop down dataValidation's. But on every drop down change function takes around 5-6 seconds to complete.
I even tried selecting only the small range and it still uses the same amount of time. Here in code example I'm taking a range of around 20 rows and it still takes 5-6 seconds to complete.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("EAC Input");
var dataSS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Resource names");
var activeCell = ss.getActiveCell();
var column = activeCell.getColumn();
var lastRow = dataSS.getLastRow();
if(column == 1 || column == 2 || column == 3 || column == 4 && activeCell.getRow() > 5) {
var makeValue = activeCell.getValue();
if(makeValue == "" || makeValue == "WORKSTREAM:" || !isNaN(parseFloat(makeValue)) && isFinite(makeValue))
{
return;
}
var validationRange = dataSS.getRange("A36:D55").getValues();
var filteredRangeOfDepartments = [];
var filteredRangeOfPositions = [];
var filteredRangeOfEmployees = [];
for(var i = 0; i < validationRange.length; i++)
{
var rangeAtZero = validationRange[i][0];
var rangeAtOne = validationRange[i][1];
var rangeAtTwo = validationRange[i][2];
if(rangeAtZero== makeValue)
{
filteredRangeOfDepartments.push(rangeAtOne);
}
if(rangeAtOne == makeValue && rangeAtZero == activeCell.offset(0, -1).getValue())
{
filteredRangeOfPositions.push(rangeAtTwo);
}
if(rangeAtTwo == makeValue && rangeAtZero == activeCell.offset(0, -2).getValue() && rangeAtOne == activeCell.offset(0, -1).getValue())
{
filteredRangeOfEmployees.push(validationRange[i][3]);
}
}
if(column == 1)
{
var validationRule = SpreadsheetApp.newDataValidation().requireValueInList(filteredRangeOfDepartments, true).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
if(column == 2)
{
var validationRule = SpreadsheetApp.newDataValidation().requireValueInList(filteredRangeOfPositions, true).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
if(column == 3)
{
filteredRangeOfEmployees.push("TBC");
var validationRule = SpreadsheetApp.newDataValidation().requireValueInList(filteredRangeOfEmployees, true).build();`enter code here`
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
}