Created
September 15, 2023 23:44
-
-
Save JonathanGawrych/0b843928b39d1add8517e6a37f0c43c0 to your computer and use it in GitHub Desktop.
An apps script to detect when a Category is updated in a google spreadsheet, to update the subcategory data validation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// When editing a cell that has data validation of the named range "CategoryList" | |
// The cell to the right of it will have it's data validation set to the name range of category + "List" | |
function onEdit(e) { | |
// Logger.log('start'); | |
// Go see what was edited. Grab the top left cell in case they pasted both category and subcategory | |
const edited = e.range.offset(0, 0, 1, 1); | |
const spreadsheet = edited.getSheet().getParent(); | |
// See if it has a validation | |
const validation = edited.getDataValidation(); | |
if (validation == null) { | |
return; | |
} | |
// See if it points to a range | |
if (validation.getCriteriaType() != SpreadsheetApp.DataValidationCriteria.VALUE_IN_RANGE) { | |
return; | |
} | |
// Go get that range | |
const validationRange = validation.getCriteriaValues()[0]; | |
// Go find if that range is based on a named range | |
const namedRange = spreadsheet.getNamedRanges().find((namedRange) => { | |
// Logger.log('test: %s %s', namedRange.getRange().getA1Notation(), validationRange.getA1Notation()); | |
return namedRange.getRange().getA1Notation() === validationRange.getA1Notation() | |
}); | |
// We couldn't find a named range | |
if (namedRange == null) { | |
// Logger.log('could not find parent'); | |
return; | |
} | |
// We only care about the categories range | |
if (namedRange.getName() !== 'CategoriesList') { | |
// Logger.log('not the right name'); | |
return; | |
} | |
// Get the subcategory | |
const childCell = edited.offset(0, 1); | |
const subNamedRangeName = edited.getValue() + 'List'; | |
const subNamedRange = spreadsheet.getRangeByName(subNamedRangeName); | |
// If the value is not a named range, then we can't do anything. | |
if (subNamedRange != null) { | |
// At this point we modified a cell who's data validation is the parent categories list. | |
// Now we need to set the child validation range. We'll assume the cell to the right is the spot to do it. | |
childCell.setDataValidation(SpreadsheetApp.newDataValidation() | |
.requireValueInRange(subNamedRange) | |
.setAllowInvalid(false) | |
.build() | |
); | |
} else { | |
// The validation isn't valid anymore (perhaps because a value was deleted) | |
// Remove the child validation | |
childCell.clearDataValidations(); | |
} | |
} | |
function backfill() { | |
const backfillRange = SpreadsheetApp.getActiveSpreadsheet().getRange('K4:K48'); | |
for (let row = 0; row < backfillRange.getNumRows(); row++) { | |
const backfillCell = backfillRange.offset(row, 0, 1, 1); | |
onEdit({range: backfillCell}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment