Google表格-多个从属下拉列表

时间:2018-09-30 13:45:31

标签: validation google-apps-script drop-down-menu google-sheets

我正在尝试创建一个描述并回答的从属列表(使用脚本)here.

我想要实现的是,如果从第1列的单元格中选择某个值(例如“第一个”),则同一行中下一个单元格的下拉选项应提供该列中的值范围在与第一个-左-单元格中的值具有相同标题的不同工作表中(即,第一工作表称为“选择器”-其中存在下拉菜单,在第二工作表中称为“ KAT”) )。然后,应根据行中每个第一个单元格的值,对每行进行这种设置。

我试图使用和修改建议的脚本,并查看了本文中的示例文件,但显然我对脚本没有足够的基本了解,因此无法正确修改和实现它。

有人可以帮助我使此动态下拉列表正常工作吗?

只是为了阐明我的最终意图:我想让此脚本首先运行,以便能够在多个文件上使用它。不过,我的最终目标是制作自动填充的下拉列表和选择器,以便我可以简单地在“选择器”表中填写数据,然后稍后可以在下面的单元格中选择这些相同的值(取决于行中第一个单元格的名称(值)=包含验证范围的列的第一个单元格)。我希望能够通过使用数据透视表或“ KAT”工作表中的任何其他公式来实现此目的,这些公式将从“选择器”工作表中汇总我的数据并将其作为下拉选项进行反馈...)。

谢谢您的帮助。

See the example sheet here

我使用的代码(如上所述):

function onEdit() 
    {
      var ss = SpreadsheetApp.getActiveSpreadsheet(),
          sheet = ss.getActiveSheet(),
          name = sheet.getName();
      if (name != 'Selector') return;
      var range = sheet.getActiveRange(),
          col = range.getColumn();
      if (col != 1) return;
      var val = range.getValue(),
          dv = ss.getSheetByName('KAT'),
          data = dv.getDataRange().getValues(),
          catCol = data[0].indexOf(val),
          list = [];
      Logger.log(catCol)
      for (var i = 1, len = 100; i < len; i++) // Problem is here, you have too many items in list! Cannot have more 500 items for validation
          list.push(data[i][catCol]);
      var listRange = dv.getRange(2,catCol +1,dv.getLastRow() - 1, 1)
      Logger.log(list)
      var cell = sheet.getRange(range.getRow(), col-1)
      var rule = SpreadsheetApp.newDataValidation()
      .requireValueInRange(listRange)   // Use requireValueIn Range instead to fix the problem
      .build();
      cell.setDataValidation(rule);
      Logger.log(cell.getRow())
    }

1 个答案:

答案 0 :(得分:1)

此问题涉及动态下拉列表。参考了先前有关StackOverflow(Google Sheets - Dependent drop-down lists)的问题和答案,并且该答案的代码未成功重新利用。

问题中的代码由于以下原因而不起作用:第20行

var cell = sheet.getRange(range.getRow(), col-1)

在所引用的代码中,下拉列表从F列开始(col = 6)。从属下拉列表的范围在左侧,因此从属列的定义为“ col-1”。在发问者的情况下,下拉列表从A列(col = 1)开始,从属下拉列表的范围从左到右。但是,未更改此代码行以考虑不同的布局。而不是“ col-1”,它应该是“ col + 1”。

其他事项

  • 除此之外,第16和17行执行循环以创建可用于依赖下拉列表的数组。但是,该循环是多余的,因为下拉列表是通过在“ KAT”工作表上创建并分配范围来实际定义的。
  • KAT的单元格A2包含一个公式:

    =sort(unique(Selector!$A$2:$A),1,true)

    这似乎很有用,因为它会自动将在“选择器”中输入的所有新下拉值添加到KAT的值列表中。实际上,这是没有用的,因为代码的依赖下拉列表构建在垂直而非水平上均有效。因此,添加到KAT的另一行本身并不会有助于建立从属下拉列表。

以下代码可用于构建从属下拉列表。我故意在代码中留下了许多“记录器”条目,以帮助发问者理解代码的工作原理。

function onEdit() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getActiveSheet();
    var name = sheet.getName();

    if (name != 'Selector') return;
    var range = sheet.getActiveRange();
    var col = range.getColumn();
    var dropdownrow = range.getRow(); // added for debugging and informationm

    if (col != 1) return;

    var val = range.getValue();
    Logger.log("the cursor is in 'Selector' in cell = " + range.getA1Notation()); //DEBUG
    Logger.log("That's row " + dropdownrow + ", and column " + col + ". The value selected = " + val); // DEBUG



    var dv = ss.getSheetByName('KAT');
    var data = dv.getDataRange().getValues();
    var catCol = data[0].indexOf(val);
    var list = [];
    var KAT_data = dv.getDataRange();
    var KAT_data_len = KAT_data.getLastRow(); // added to give 'for' loop a sensible range

    Logger.log("The data range on KAT is " + KAT_data.getA1Notation() + ", and the last row of data = " + KAT_data_len); //DEBUG
    Logger.log("KAT data = '" + data + "'"); // DEBUG
    Logger.log("Found the dropdown cell value of '" + val + "' in KAT as item #" + catCol); //DEBUG

    for (var i = 1, len = KAT_data_len; i < len; i++) { // Irrelevant because the data validation range is obtained by defining a range on KAT

        // Problem is here, the unique command in A2 creates a blank row
        // Logger.log("i="+i+", data = "+data[i][catCol]); // DEBUG
        list.push(data[i][catCol]);

    }

    var listRange = dv.getRange(2, catCol + 1, dv.getLastRow() - 1, 1);
    Logger.log("FWIW, this is the list after the loop= " + list); // DEBUG
    Logger.log("The contents for the new data validation range (taken from KAT) is " + listRange.getA1Notation()); // DEBUG
    Logger.log("The new validation range gets added to col = " + (col + 1)); // DEBUG

    //var cell = sheet.getRange(range.getRow(), col-1); // governs the next validation range. Example validation worked right to left, but this sheet works left to right. So must ADD 1, not subtract 1.
    var cell = sheet.getRange(range.getRow(), col + 1);
    Logger.log("The cell to be assigned the new validation range will be " + cell.getA1Notation()); // DEBUG
    var rule = SpreadsheetApp.newDataValidation().requireValueInRange(listRange).build(); // Build validation rule
    cell.setDataValidation(rule); // assign validation range to new cell

}

此代码值得吗?

所编写和引用的代码仅限于创建一级依赖下拉列表。就此而言,它的价值非常有限。有一种创建依赖下拉列表的不同方法。

自2014年以来,StackOverflow上的

How do you do dynamic / dependent drop downs in Google Sheets?”一直是讨论和更新动态相关下拉菜单技术的聚会场所。最新更新是Max Makhrov于2018年2月。这里描述的代码可能对发问者有用。