Autocomplete multiple dependent dropdowns lists - google-apps-script

In this sheet, I have multiple dependent dropdown lists. These dropdown lists evaluate if they have multiple or only one option available. If I only have one option, it will autocomplete with the single possible value.
This is an example of the sheet: https://docs.google.com/spreadsheets/d/13fIO3OgAALDVx5PmX6mx0RMdES4PUdsSBU9aBOQhwuk/edit?usp=sharing
The problem is that when I chose a client that only has one project, this project is completed automatically but the task isn't.
This is an example of what I want when I will select Client 3 in column A
Code I use:
var mainWsName = "Page 1";
var optionsWsName = "Data";
var firstLevelColumn = 1;
var secondLevelColumn = 2;
var thirdLevelColumn = 5;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var options = wsOptions.getRange(2,1,wsOptions.getLastRow()-1,7).getValues();
function onEdit(e){
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var row = e.range.getRow();
var col = e.range.getColumn();
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName()
if(wsName === mainWsName && c === firstLevelColumn && r > 3){
applyFirstLevelValidation(val,r)
}else if(wsName === mainWsName && c === secondLevelColumn && r > 3){
applySecondLevelValidation(val,r)
}
if(c === 1 && r > 3 && wsName === mainWsName && val === "intern"){
e.source.getActiveSheet().getRange(row,6).setValue("Not");
}else if(c === 1 && r > 3 && wsName === mainWsName && val !== ""){
e.source.getActiveSheet().getRange(row,6).setValue("Yes");
}else if(c === 1 && r > 3 && wsName === mainWsName && val === ""){
e.source.getActiveSheet().getRange(row,6).clearContent();
ws.getRange(r,secondLevelColumn).clearDataValidations();
}
}
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r,secondLevelColumn).clearContent();
ws.getRange(r,secondLevelColumn).clearDataValidations();
ws.getRange(r,thirdLevelColumn).clearContent();
ws.getRange(r,thirdLevelColumn).clearDataValidations();
} else{
ws.getRange(r,secondLevelColumn).clearContent();
ws.getRange(r,secondLevelColumn).clearDataValidations();
ws.getRange(r,thirdLevelColumn).clearContent();
ws.getRange(r,thirdLevelColumn).clearDataValidations();
var filteredOptions = options.filter(function(o){ return o[0] === val });
var listToApply = filteredOptions.map(function(o){ return o[1] });
var cell = ws.getRange(r,secondLevelColumn);
applyValidationToCell(listToApply,cell);
var rule = SpreadsheetApp.newDataValidation().requireValueInList(listToApply).build();//creo el dropdown
if(listToApply[1] || null){
applyValidationToCell(listToApply,cell);
}else{
cell.setDataValidation(rule).setValue(listToApply[0] || null);
}
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r,thirdLevelColumn).clearContent();
ws.getRange(r,thirdLevelColumn).clearDataValidations();
} else{
ws.getRange(r,thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r,firstLevelColumn).getValue();
var filteredOptions = options.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r,thirdLevelColumn);
applyValidationToCell(listToApply,cell);
var rule = SpreadsheetApp.newDataValidation().requireValueInList(listToApply).build();
cell.setDataValidation(rule).setValue(listToApply[0] || null);
}
}
function applyValidationToCell(list,cell) {
var rule = SpreadsheetApp.newDataValidation().requireValueInList(list).build();
cell.setDataValidation(rule);
}

Although I'm not sure whether I could correctly understand your question, for example, is the following modification the result you expect? In this modification, please modify the function of applyFirstLevelValidation as follows.
From:
if(listToApply[1] || null){
applyValidationToCell(listToApply,cell);
}else{
cell.setDataValidation(rule).setValue(listToApply[0] || null);
}
To:
if (listToApply[1] || null) {
applyValidationToCell(listToApply, cell);
} else {
cell.setDataValidation(rule).setValue(listToApply[0] || null);
applySecondLevelValidation(listToApply[0], r); // <--- Added
}

Related

How To Apply Google Apps Script For Multiple Dependent Drop Downs To Several Sheets?

Multiple Dependent Drop-Down Lists For Several Sheets
I am attempting to have the same dependent dropdown lists available on three sheets within the same document. So far it only works on sheet titled "Transactions 6080". What do I need to add to my code to make it work for sheets "Transactions 6586" and "Transactions 1002" as well?
var transactionsWsName = "Transactions 6080";
var categoriesWsName = "Categories";
var firstLevelColumn = 6;
var secondLevelColumn = 7;
var thirdLevelColumn = 8;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(transactionsWsName);
var wsCategories = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(categoriesWsName);
var categories = wsCategories.getRange(6, 6,wsCategories.getLastRow()-5, 3).getValues();
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName === transactionsWsName && c === firstLevelColumn && r > 5){
applyFirstLevelValidation(val,r);
} else if(wsName === transactionsWsName && c === secondLevelColumn && r > 5){
applySecondLevelValidation(val,r);
}
}
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
var filteredCategories = categories.filter(function(o){ return o[0] === val });
var listToApply = filteredCategories.map(function(o){ return o[1] });
var cell = ws.getRange(r, secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredCategories = categories.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredCategories.map(function(o){ return o[2] });
var cell = ws.getRange(r, thirdLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}
I don't see anything in your code referring to the other sheets you mentioned, "Transactions 6586" or "Transactions 1002". If you want the exact same thing to happen in each sheet, you'll need to add those other sheets to your if statement in the onEdit function, for example:
if((wsName === 'Transactions 6080' || 'Transactions 6586' || 'Transactions 1002') && c === firstLevelColumn && r > 5){
applyFirstLevelValidation(val,r);
} else if(wsName === transactionsWsName && c === secondLevelColumn && r > 5){
applySecondLevelValidation(val,r);
}
If those are the only three sheets in the spreadsheet, you may want to consider using an array rather than writing out each name:
var transactionSheets = [];
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i in sheets) {
transactionSheets[i] = sheets[i].getName();
}
Then you'd check the name of the edited sheet against each of the values in the array. This will save you time if you add additional sheets to the spreadsheet down the road.

Dependent drop down list auto-complete - google sheets script editor

I have a sheet that has multiple dependent dropdown lists. I took the base code from a tutorial.
Now I need that when I have a single option available in the dropdown list (for example in "Column Task") it auto-complete automatically.
This is an example:
https://docs.google.com/spreadsheets/d/13fIO3OgAALDVx5PmX6mx0RMdES4PUdsSBU9aBOQhwuk/edit?usp=sharing
Code i use:
var mainWsName = "Page 1";
var optionsWsName = "Data";
var firstLevelColumn = 1;
var secondLevelColumn = 2;
var thirdLevelColumn = 5;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var options = wsOptions.getRange(2,1,wsOptions.getLastRow()-1,7).getValues();
function onEdit(e){
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var row = e.range.getRow();
var col = e.range.getColumn();
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName()
if(wsName === mainWsName && c === firstLevelColumn && r > 3){
applyFirstLevelValidation(val,r)
}else if(wsName === mainWsName && c === secondLevelColumn && r > 3){
applySecondLevelValidation(val,r)
}
if(c === 1 && r > 3 && wsName === mainWsName && val === "intern"){
e.source.getActiveSheet().getRange(row,6).setValue("No");
}else if(c === 1 && r > 3 && wsName === mainWsName && val !== ""){
e.source.getActiveSheet().getRange(row,6).setValue("Yes");
}else if(c === 1 && r > 3 && wsName === mainWsName && val === ""){
e.source.getActiveSheet().getRange(row,6).clearContent();
ws.getRange(r,secondLevelColumn).clearDataValidations();
}
}//end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r,secondLevelColumn).clearContent();
ws.getRange(r,secondLevelColumn).clearDataValidations();
ws.getRange(r,thirdLevelColumn).clearContent();
ws.getRange(r,thirdLevelColumn).clearDataValidations();
} else{
ws.getRange(r,secondLevelColumn).clearContent();
ws.getRange(r,secondLevelColumn).clearDataValidations();
ws.getRange(r,thirdLevelColumn).clearContent();
ws.getRange(r,thirdLevelColumn).clearDataValidations();
var filteredOptions = options.filter(function(o){ return o[0] === val });
var listToApply = filteredOptions.map(function(o){ return o[1] });
var cell = ws.getRange(r,secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r,thirdLevelColumn).clearContent();
ws.getRange(r,thirdLevelColumn).clearDataValidations();
} else{
ws.getRange(r,thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r,firstLevelColumn).getValue();
var filteredOptions = options.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r,thirdLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell) {
var rule = SpreadsheetApp.newDataValidation().requireValueInList(list).build();
cell.setDataValidation(rule);
}
In your situation, how about the following modification?
Modified script:
In this modification, applySecondLevelValidation is modified as follows.
function applySecondLevelValidation(val, r) {
if (val === "") {
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredOptions = options.filter(function (o) { return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredOptions.map(function (o) { return o[2] });
var cell = ws.getRange(r, thirdLevelColumn);
// I modified below script.
var rule = SpreadsheetApp.newDataValidation().requireValueInList(listToApply).build();
cell.setDataValidation(rule).setValue(listToApply[0] || null);
}
}
In this modification, after the data validation was put, the 1st element of listToApply is set.

Applying google script to all sheets except specific

I am very new to google script trying to resolve key issues in business flow.
Through search have come up with the below script for multi-level data validation for sheet Template.
How can I edit this script to run for all Sheets except specific ones (ex. Sheet1, Sheet 2)
I have found the option of excluding sheets with the code below, but not sure how to use it and where to input it
var excludes = [];
// if (excludes.indexOf(s.getName()) != -1) return;
Thanks you in advance
var mainwsMaster = "Template";
var MenuWSname = "Master Menu"
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainwsMaster);
var wsMenu = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(MenuWSname);
var Menu = wsMenu.getRange(2,1,wsMenu.getLastRow()-1,3).getValues();
var firstColumn = 8;
var secondColumn = 9;
var thirdColumn = 10;
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName === mainwsMaster && c === firstColumn && r > 6){
applyFirstLevelValidation(val,r)
} else if(wsName === mainwsMaster && c === secondColumn && r > 6){
applySecondLevelValidation(val,r);
}
}//end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r,secondColumn).clearContent();
ws.getRange(r,secondColumn).clearDataValidations();
ws.getRange(r,thirdColumn).clearContent();
ws.getRange(r,thirdColumn).clearDataValidations();
} else {
ws.getRange(r,secondColumn).clearContent();
ws.getRange(r,secondColumn).clearDataValidations();
ws.getRange(r,thirdColumn).clearContent();
ws.getRange(r,thirdColumn).clearDataValidations();
var filteredOptions = Menu.filter(function(o){return o[0] === val });
var filteredpiata = filteredOptions.map(function(o){return o[1] } );
var cell = ws.getRange(r,secondColumn);
applyValidationToCell(filteredpiata,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r,thirdColumn).clearContent();
ws.getRange(r,thirdColumn).clearDataValidations();
} else {
ws.getRange(r,thirdColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstColumn).getValue();
var filteredOptions = Menu.filter(function(o){return o[0] === firstLevelColValue && o[1] === val });
var filteredpiata = filteredOptions.map(function(o){return o[2] } );
var cell = ws.getRange(r,thirdColumn);
applyValidationToCell(filteredpiata,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}
You mentioned this code:
var excludes = [];
// if (excludes.indexOf(s.getName()) != -1) return;
for your code it would look like this instead:
var excludes = ["Sheet1","Sheet2","OtherSheetToExclude","ETC"];
if (excludes.indexOf(wsName) != -1) {return};
You would place those two lines just after the wsName variable is declared in your onEdit(e) script.
It's basically saying. "Take the name of the sheet you've just edited and look for it in this list i just made called "Excludes". If you find it in there, STOP running this function."
Try
var excludes = ['Sheet1','Sheet2'];
and then, change as following
if( excludes.indexOf(wsName) == -1 && c === firstColumn && r > 6)
for instance, focused on the onEdit function
var firstColumn = 8;
var secondColumn = 9;
var excludes = ['Sheet1','Sheet2'];
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(excludes.indexOf(wsName) == -1 && c === firstColumn && r > 6){
activeCell.getSheet().getRange('A1').setValue('cas1')
} else if(excludes.indexOf(wsName) == -1 && c === secondColumn && r > 6){
activeCell.getSheet().getRange('A1').setValue('cas2')
}
}//end onEdit

Three drop down lists depending on each other

I need to get three depending drop-down lists, which depend on each other. Here is an editable sheet with the example. Cells in the yellow column contain a drop-down list which is based on usual data validation (Options sheet). Cells in the green column give a corresponding drop-down list, which is based on the script. And in blue column I need to get a corresponding list from the sheet Options with names corresponding with the data in the middle green column.
I will appreciate any help.
var mainWsName = "master";
var optionsWsName = "options";
var firstLevelColumn = 12;
var secondLevelColumn = 13;
var thirdLevelColumn = 14;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(optionsWsName);
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName === mainWsName && c === firstLevelColumn && r > 4){
applyFirstLevelValidation(val,r);
} else if(wsName === mainWsName && c === secondLevelColumn && r > 4){
applySecondLevelValidation(val,r);
}
} //end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
var filteredOptions = options.filter(function(o){ return o[0] === val });
var listToApply = filteredOptions.map(function(o){ return o[1] });
var cell = ws.getRange(r, secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredOptions =options.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r.thirdLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInlist(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule)
}
You want to show the dropdown list to the column "N" by the column "M".
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
options is not declared for the function of applyFirstLevelValidation and applySecondLevelValidation.
r.thirdLevelColumn of ws.getRange(r.thirdLevelColumn) occurs an error. Because r is the number.
.requireValueInlist(list) is .requireValueInList(list). It's a spelling mistake.
Modified script:
When your script is modified, please modify as follows.
From:
var filteredOptions = options.filter(function(o){ return o[0] === val });
To:
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === val });
and
From:
var filteredOptions =options.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
To:
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
and
From:
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r.thirdLevelColumn);
applyValidationToCell(listToApply,cell);
To:
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r, thirdLevelColumn); // <--- Modified
applyValidationToCell(listToApply,cell);
and
From:
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInlist(list)
.setAllowInvalid(false)
.build();
To:
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list) // <--- Modified
.setAllowInvalid(false)
.build();
Whole modified script:
var mainWsName = "master";
var optionsWsName = "options";
var firstLevelColumn = 12;
var secondLevelColumn = 13;
var thirdLevelColumn = 14;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(optionsWsName);
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName === mainWsName && c === firstLevelColumn && r > 4){
applyFirstLevelValidation(val,r);
} else if(wsName === mainWsName && c === secondLevelColumn && r > 4){
applySecondLevelValidation(val,r);
}
} //end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === val }); // <--- Modified
var listToApply = filteredOptions.map(function(o){ return o[1] });
var cell = ws.getRange(r, secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === firstLevelColValue && o[1] === val }); // <--- Modified
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r, thirdLevelColumn); // <--- Modified
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list) // <--- Modified
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule)
}
References:
getRange(row, column)
requireValueInList(values)
If I misunderstood your question and this was not the direction you want, I apologize.

Trying to make a three tiered dependent dropdown work on multiple sheets using appscript

I have been able to get my sheet to work seamlessly within one sheet but I need the ability to be able to use the script across multiple sheets in the same workbook, the problem I run into is without the isolation that is currently assigned it will edit every page with any changes. Does anyone have any ideas?
Here is the code that i am using for the script:
var mainWSName = "Tracker";
var optionsWsName = "Reference";
var firstLevelColumn = 1;
var secondLevelColumn = 2;
var thirdLevelColumn = 3;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWSName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(optionsWsName);
var options = wsOptions.getRange(12, 1,wsOptions.getLastRow()-1,3).getValues();
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if (wsName === mainWSName && c === firstLevelColumn && r > 1){
applyFirstLevelValidation(val,r);
} else if(wsName === mainWSName && c === secondLevelColumn && r > 1){
applySecondLevelValidation(val,r)
}
}//end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
var filteredOptions = options.filter(function(o){return o[0] === val });
var listToApply = filteredOptions.map(function(o){ return o[1]});
var cell = ws.getRange(r,secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredOptions = options.filter(function(o){return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r,thirdLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell) {
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}