Excel Script Data Validation

Copper Contributor

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: 

Scaffold965_0-1654878348936.png

 

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;
}

 

 

 

0 Replies