当前位置: 首页 > 知识库问答 >
问题:

Google Sheets-多个相关下拉列表

潘志国
2023-03-14

我试图在这里创建一个描述和回答(用脚本)的依赖列表。

我想实现的是,如果从第1列的单元格中选择某个值(例如“First”),那么同一行下一个单元格中的下拉选项应提供不同表格中列的一系列值,这些列的标题与第一个左单元格中的值相同(即,第一个表格称为“Selector”)-其中有下拉列表,在第二张名为“KAT”的表格中,我有这些下拉列表的选项)。然后,根据行的每个第一个单元格的值,每一行都可以这样做。

我试图使用和调整建议的脚本,并审查了本文中的示例文件,但我显然缺乏对脚本的一些基本理解,无法正确地适应和实现它。

有人能帮我使这个动态下拉列表正常工作吗?

谢谢你的帮助。

请参见此处的示例表

我使用的代码(如上):

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个答案

靳举
2023-03-14

这个问题涉及动态下拉列表。之前关于StackOverflow的问题和答案(Google Sheets相关下拉列表)被引用,来自该答案的代码被重新使用失败。

问题中的代码不起作用的原因只有一个:第20行

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

在引用的代码中,下拉列表从列F(ol=6)开始。依赖项下拉列表位于左侧,因此依赖项列的定义为"col-1"。在提问者的场景中,下拉列表从A列(ol=1)开始,从属下拉列表的范围从左到右。然而,这行代码没有改变,以考虑不同的布局。而不是“col-1”,应该是“col-1”。

>

  • 除此之外,第16行和第17行执行一个循环来创建一个可能用于依赖下拉的数组。然而,循环是多余的,因为下拉列表实际上是通过在“KAT”表上创建和分配一个范围来定义的。
  • KAT的细胞A2包括一个公式:

    =排序(唯一(选择器!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
    
    }
    

    编写和引用的代码仅限于创建一级从属下拉列表。在这方面,它的价值非常有限。创建从属下拉列表的不同方法是合理的。

    “如何在Google工作表中进行动态/相关下拉列表?”自2014年以来,on StackOverflow一直是讨论和更新动态相关下拉列表技术的会议场所。最新更新由Max Makhrov于2018年2月发布。这里描述的代码可能对提问者有用。

  •  类似资料:
    • 我的谷歌表单使用了用户马克斯·马克洛夫(Max Makhrov)编写的代码,这里的代码,在D-F列(用于位置)和H-L列(用于目标)中创建多个相关的动态下拉列表 我想帮助修改脚本以完成两件事: 无论从第一列的下拉菜单中选择了什么活动,我都希望J-L列可以使用相同的下拉菜单选项(重复)。正如您所看到的,我找到了一种方法,但对我来说,它似乎笨重且不理想,并且为错误留下了太多的空间。用户不应该选择活动两

    • 我已经开始了一个有4个下拉列表的谷歌表。下拉列表2、3和4都取决于下拉列表1中的选择。我有下拉2工作,但不能在应用程序脚本编辑器的代码下拉3和4。 这是我题为“下拉列表”的工作表: 第1行位于下拉列表1中(事件/事件表的C列) 第4行至第10行位于下拉列表2中(“事件/事件”表的D列) 最后一行的第15行在下拉列表3中(事件/事件表的E列) 我有以下代码,仅适用于下拉列表2(事件/事件表的D列):

    • 我正在重新创建和扩展我以前制作的文档。我已经引入了我最初使用的脚本,并在我认为合适的地方对其进行了调整,以使其在本表中正常工作,但我一定错过了一些东西。可在此处找到涉及的3个电子表格文件的可编辑示例。这些文件是一个样本“价目表”、“目录”(它汇总了所有价目表中的制造商名称,还有一个“目录”选项卡,用于我的一个主要供应商未销售的杂项物品),以及“附录B”,这是我需要帮助的文件。 这份文件是我合同的增

    • 我已经根据这个脚本/教程创建了一个带有相关下拉列表的google工作表。这是我创建的工作表的副本。我的目标是使用下拉列表中的每个唯一值自动填充C列中的单元格,而不是创建一个与母版图纸C列中当前显示的下拉列表类似的下拉列表。我曾尝试通过VLOOKUP实现这一点,但只得到了错误的响应,可能是由于缺乏验证或其他我不熟悉的逻辑形式。如果A列或B列选项被修改,我还希望C列中的填充选项是清除的(clearCo

    • 根据第一个下拉列表项选择,我希望第二个下拉列表应该包含相关内容。在Java怎么能这样?例如,假设第一个下拉列表包含国家名称,第二个下拉列表包含国家名称。如果我从第一个下拉列表中选择一个特定的国家,比如“印度”,那么第二个列表应该只显示国家的相关邦,即“印度”的邦。并且这两个列表都是动态的。

    • 请原谅,如果这已经在其他帖子中得到了答复,但我一直在寻找这个,但找不到我的场景。我发现的所有示例都涉及静态列表,但我有一个表,将添加新的条目。我有一个4列的表,如下所示。 所以现在我需要做的是创建第二个下拉,它依赖于第一个下拉选择的值,然后只提供同一记录的其他3列的值。这应该不难,但我一直在努力寻找如何做到这一点,但没有成功。如何设置第二次验证来完成此操作?我尝试使用间接和vlookup的组合,但