GAS:在 N 行中复制一个数据验证(下拉列表)并在每个下拉列表中设置唯一值

GAS: copy one data validation (dropdown) in N number of rows and set unique value in each dropdown

为清楚起见进行了编辑并添加了图片

使用 Google Apps 脚本,我如何:

  1. 将第 2 节 sheet(G11:H11,带有复选框和下拉菜单)的范围复制到范围 G12:G25 N 次(基于数量MASTER DROPDOWN sheet 中 non-empty 行的 header 标题与 'Section 2'!A2) 相同,然后

  2. 在每个下拉列表中设置不同的值(每个唯一值列在 MASTER DROPDOWN sheet 下的正确 header 下)。

例如,第一张图片是“MASTER DROPDOWN”sheet。

第二张图片是“第 2 部分”sheet。用户可以使用页面右侧的按钮添加或删除列表中的项目。

最后一张图片是“第 2 部分”sheet。我不明白如何为此编写代码...当用户按下“重置列表”按钮时,我想复制复选框和下拉菜单(来自 G11:H11)N 次(N=3 基于来自第 2 部分主下拉列表中的项目)。在每个下拉列表中,我想为 MASTER DROPDOWN sheet 中原始列表中的每个项目设置值。此过程应该是动态的,并且适用于第 1 节和第 3 节 sheet(目前不在sheet)。

任何关于脚本措辞的建议 search/learn 关于这种类型的功能,或者关于脚本的一些指导都非常感谢。这是我目前拥有的代码的 link...

https://docs.google.com/spreadsheets/d/1ZdlJdhA0ZJOIwLA9dw5-y5v1FyLfRSywjmQ543EwMFQ/edit?usp=sharing

function newListAlert (){
  var ui = SpreadsheetApp.getUi();
  var response = ui.alert("Are you sure you want to delete your current list and create a new one?",ui.ButtonSet.YES_NO);
 
  if(response == ui.Button.YES) {
    newList();
  } else {
  }
}

function newList() {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var range = ss.getRange("G11:H25");
  var options = {contentsOnly: true, validationsOnly: true};
 
  //clear current list
  range.clear(options);

  //add new item to list in first row of range
  addNewItem();

  //copy new datavalidation row above based on number of non-empty rows in MASTER DROPDOWN with same header as active sheet (-1)
  var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MASTER DROPDOWN");
  var range = ss.getRange("A2");
    
    if (range.getCell(1,1)){

    var section = datass.getRange(1,1,1,datass.getLastColumn()).getValues();
    var sectionIndex = section[0].indexOf(range.getValue()) + 1;

    var validationRange = datass.getRange(4,sectionIndex,19);//19 columns: checklist has a maximum of 18 rows (+ 1 for "select option")
    }

    }

根据您的情况,如何修改newList()如下?

修改后的脚本:

function newList() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var sheetName = sheet.getSheetName();
  sheet.getRange("G11:H25").clear({ contentsOnly: true, validationsOnly: true });
  var srcSheet = ss.getSheetByName("MASTER DROPDOWN");
  var values = srcSheet.getDataRange().getValues();
  var obj = values[0].map((_, c) => values.map(r => r[c])).reduce((o, [h, , , ...v], i) => {
    if (h != "") {
      v = v.filter(String);
      v.shift();
      o[h] = { values: v, range: srcSheet.getRange(4, i + 1, v.length + 1) };
    }
    return o;
  }, {});
  if (obj[sheetName]) {
    var validationRule = SpreadsheetApp.newDataValidation()
      .setAllowInvalid(false)
      .setHelpText('Select an option from the menu. To add more options to the dropdown list, go to MASTER DROPDOWN tab.')
      .requireValueInRange(obj[sheetName].range, true)
      .build();
    var d = obj[sheetName].values.map(_ => [validationRule]);
    var v = obj[sheetName].values.map(e => [e]);
    sheet.getRange(sheet.getLastRow() + 1, 8, obj[sheetName].values.length).setDataValidations(d).setValues(v).offset(0, -1).insertCheckboxes();
  }
}
  • 当此脚本为 运行 时,DataValidations 的值从 sheet“MASTER DROPDOWN”中检索,并使用 sheet 名称,dataValidation创建规则,并将其放入“H”列。而且,复选框被放置在 dataValidations 相同行的“G”列中。

  • 在这种情况下,例如,当您添加新的 sheet of "Section 1" 和 运行 newList() 时,下拉列表包括“Engineering ”和“设计”放在“H”列,复选框也放在“G”列。

注:

  • 在此修改中,sheet名称如“Section 2”用于搜索“MASTER DROPDOWN”栏sheet。所以请注意这一点。

  • 并且,在您当前的脚本中,最后一行用于放置下拉列表和复选框。所以当你要修改这个的时候,请修改上面的脚本。

  • 此示例脚本适用于您的示例 Spreadsheet。所以当你实际的 Spreadsheet 被更改时,这个脚本可能无法使用。请注意这一点。

参考文献: