Skip to content

Instantly share code, notes, and snippets.

@JonathanGawrych
Created September 15, 2023 23:44
Show Gist options
  • Save JonathanGawrych/0b843928b39d1add8517e6a37f0c43c0 to your computer and use it in GitHub Desktop.
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.
// 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