【问题标题】:Google Apps Script - Spreadsheet - Create onEdit Dropdown list in a cell based on values not coming from a spreadsheetGoogle Apps 脚本 - 电子表格 - 根据不是来自电子表格的值在单元格中创建 onEdit 下拉列表
【发布时间】:2021-06-08 18:37:36
【问题描述】:

我已经看到了有关如何根据来自其他电子表格的范围值的值创建下拉列表的示例,下拉列表取决于单元格值。在我看到的所有示例中,值都来自其他电子表格的范围值。

我想要实现的是:

  • 在带有列标题的电子表格中,我没有行。
  • 当我编辑第一个单元格时,它会显示一个带有值的下拉列表。只有当我编辑单元格时。如果可能的话,我不想为固定数量的行预先填充 st 列的单元格,因为我认为这可能会消耗时间,而且我不知道一个文件中会有多少个单元格月。
  • 下拉列表中的值是从另一个 Google Workspace 服务中检索的。

我此刻的经历:

  • 我能够检索想要在下拉列表中显示的值
  • 如果我是对的,要构建一个下拉列表,可以使用 SpreadsheetApp.newDataValidation() 方法来构建下拉列表
  • 我能够设置一系列单元格的值(例如:A1:A10)并在每个单元格上显示一个下拉列表图标,但编辑单元格时显示的值类似于 val1;val2;val3...

我的问题:

  • 当我编辑单元格时,如何在第一列的单元格上动态创建一个动态下拉列表?如果必须预先填充第一列的单元格,那么至少为什么不这样做

我不知道iwa是否足够清楚。这是脚本的想法:

var v_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var v_sheet = v_spreadsheet.getActiveSheet();
// I imagine i could specify A1:A1 to specify only the cell that is being edited ?
var range = v_sheet.getRange("A2:A5");
// my array below is 2 dimensions : v_array[0][0] = 'val1', v_array[0][1] = 'val2', etc
range.setValues(v_array_taskLists);
var dd_values = range.getValues();
var validationRule   = SpreadsheetApp.newDataValidation().requireValueInList(dd_values).build();
range.setDataValidation(validationRule);

如您所见,我正在传递范围数据,这可能不是正确的方式

非常感谢任何帮助 非常感谢提前

【问题讨论】:

    标签: google-apps-script google-sheets dropdown


    【解决方案1】:

    好吧,既然您说您能够检索到要在下拉列表中显示的正确数据。您可以使用此函数来填充它。其中range 是一系列单元格,list 是您希望在下拉列表中显示的值列表。

    function setRangeDataValidation(range, list) {
      var rangelValidation = SpreadsheetApp.newDataValidation()
        .requireValueInList(list)
        .setAllowInvalid(false)
        .build();
      range.setDataValidation(rangelValidation);
    }
    

    您可以使用onChange 触发器动态更改下拉列表中可用的值(这是我在类似应用程序中使用的方法)。假设您希望在另一列(例如同一行中的 B)中进行一些更改时,更改列 A 中的数据验证。

    function onChange(e) {
        var ss = SpreadsheetApp.getActiveSpreadsheet();
        var ws = ss.getActiveSheet()
    
        if (e.changeType === 'EDIT') {
          var activeRange = ws.getActiveRange();
          var editCol = activeRange.getColumn();
          
          if (editCol === 1) {
            // in case more rows are changed at the same time (copy and paste)
            var numRows = activeRange.getNumRows();
            var startRow = activeRange.getRow();
    
            var yourList = //the list to be updated in the dropdown
    
            //You can loop through the list of values that were edited in column A in case you want a different dropdown in column B for each value passed in column A.
            for (var row = 0; row < numRows; row++) {
              // Here if you want different lists in the dropdown for different cells in columns A you can do the following
              //var cellColA = activeRange.getCell(startRow + row, 1).getValue();
              // yourList = updatedList;
    
              // Then et range of cell in column B
              var cellColB = ws.getRange(startRow + row, 2);
              setRangeDataValidation(cellColB, youList)
            }
          }
        }
    

    请记住,onChange 触发器是一个 installable 触发器,您可以通过这种方式安装:

    function createSpreadsheetChangeTrigger() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
    
      ScriptApp.newTrigger('onChange')
        .forSpreadsheet(ss)
        .onChange()
        .create();
    }
    

    注意事项:

    • 如果您只需要跟踪电子表格内容的更改,而不是其结构,那么使用可安装的onEdit() 触发器而不是onChange() 触发器可能更合适。
    • 通过onOpen 触发器安装它不是一个好主意,因为这会在每次打开电子表格时安装一个新触发器,并且最终会出现许多重复的触发器。

    【讨论】:

    • 嗨@everspader,首先,很多人感谢您花时间这么快回答我并试图帮助我。我将尝试逐步解释我所面临的问题: - 就在重新加载脚本绑定到的电子表格时,我得到一个“经典”GoogleJsonResponseException 异常失败,因为“缺少所需的身份验证凭据”,并期待有效的身份验证凭据( oAuth、cookie、..)。我尝试创建一个新的 GCP 项目,创建 oAuth,然后将我的脚本重新链接到该项目,但没有成功。所以我重命名了 onChange 函数并为其添加了一个触发器
    • @everspader 非常感谢您的反馈。我现在了解我的阵列的问题。我非常感谢您的帮助以及您为帮助我所花费的时间..
    • @everspader 再次感谢,我不敢相信你做了这一切。我已经阅读了你的 cmets,我完全理解这个机制。多亏了你,现在很多步骤都可以了。我的理解是我将无法: - 在单元格中输入编辑模式并在其中显示下拉列表选择器而不进行任何更改(在另一个单元格中,如您的依赖 DD。进入编辑模式时不会触发 OnEdit)所以我可以考虑: - 在第一次启动时,在 A2:A2 中显示第一行和 DD - 在上面的行中添加一个按钮,如“添加行”,它将添加一个带有 DD 的新空行
    • @everspader 我会继续你的代码和建议,并会让你知道。在所有情况下,我都非常感谢您花时间帮助我。这没有价格。我会随时通知您;)
    • @AlexisTruong 如果它解决了您的问题,请考虑接受此答案,请参阅stackoverflow.com/help/someone-answers
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多