Forum Discussion
Scaffold965
Jun 10, 2022Copper Contributor
Excel Script Data Validation
I am having an issue with creating data validation from inside an excel script. The purpose of this script is to create a selectable dropdown list of major types that are listed in a reference worksheet called Material Reference. Along row 1 the material main types are listed. These are available for dropdown selection in column F of the other worksheets in the workbook. In each respective column, under row 1, the material subtypes are listed. For example:
Aluminum Steel Plastic
Plate Plate Delrin
Bar Sheet Polycarbonate
The main problem I have is as follows: when I attempt to create data validation through excel scripts, I am thrown an error that states
Cannot set properties of undefined (setting 'rule')
Furthermore, in the IDE I see the following:
I am not sure what the error is. I am following the first example in this guide: https://docs.microsoft.com/en-us/office/dev/add-ins/excel/excel-add-ins-data-validation
await Excel.run(async (context) => {
let sheet = context.workbook.worksheets.getItem("Sample");
let range = sheet.getRange("MyRange");
range.load("address");
await context.sync();
console.log(`The address of the range "MyRange" is "${range.address}"`);
});
Here is my full code for reference:
function main(workbook: ExcelScript.Workbook) {
// When selecting a primary material, this function should find that material in "Material Reference" and the populat the cell to the right with a dropdown menu (data validation list) of the subtypes listed below that material in the "Material Reference" worksheet.
// figures out what worksheet is being edited
let worksheet = workbook.getActiveWorksheet();
let active = workbook.getActiveCell();
// this worksheet is a reference worksheet that has the information for different materials
let data = workbook.getWorksheet("Material Reference");
// establish row and column of current active cell
let col = active.getColumnIndex() + 1;
let row = active.getRowIndex() + 1;
// only run if the active cell is in column F and not in row 1, i.e in the "Stock Material" column
if (col == 6 && row > 1){
// establish the cell to its right, clears any existing data
let next = worksheet.getRange(num2col(col) + row.toString() + ":" + num2col(col) + row.toString());
next.clear();
// set up array of the correct materials
let materials = data.getRange("A1:XX1").getValues(); // extra long in case many many materials are added
let material_index = materials[0].indexOf(active.getValue());
// checks that it is a material index that makes sense just to catch stupid errors
if (materials[0][material_index] != "") {
// valid_range is set as the range below the stock material that was selected in column F. This range is from the "Material Reference" worksheet.
let valid_range = data.getRange(num2col(material_index) + "2:" + num2col(material_index) + "10").getValues();
// generates a data validation in-cell dropdown list of the possible material subtypes so that the correct subtype options can be selected.
next.dataValidation.rule = {
list: {
inCellDropDown: true,
source: valid_range
}
}
}
}
}
function num2col(num: number) {
// Takes a numeric column index and returns an alphabetical character reference to be used in addresses
num += 1;
let columnLetter = "",
t: number;
while (num > 0) {
t = (num - 1) % 26;
columnLetter = String.fromCharCode(65 + t) + columnLetter;
num = (num - t) / 26 | 0;
}
return columnLetter || undefined;
}
No RepliesBe the first to reply