Google apps script 基于选定对象自动更新excel/google工作表中的下拉列表

Google apps script 基于选定对象自动更新excel/google工作表中的下拉列表,google-apps-script,google-sheets,dropdown,Google Apps Script,Google Sheets,Dropdown,我想实现以下场景,我有一个游戏,安装过程需要一个连接到2个数据库的队列,基于可用性 1。玩家 2。车辆 该列表包括一个“生成器”,这意味着每个单元格都有一个连接到数据库的下拉列表,并显示可用对象 我的目标 我需要在提交或从列表中选择一个对象时自动更新下拉列表,以便在单击下拉列表后,下一个单元格将不再包含该对象,而且如果我从列表中删除对象,该对象必须返回下拉列表,因为它再次可用 我做了什么? 我在数据库端做了一些公式,这样可以从一列创建下拉列表,一旦我从下拉列表本身为列表指定了一个对象,该列就会自

我想实现以下场景,我有一个游戏,安装过程需要一个连接到2个数据库的队列,基于可用性

1。玩家
2。车辆

该列表包括一个“生成器”,这意味着每个单元格都有一个连接到数据库的下拉列表,并显示可用对象

我的目标

我需要在提交或从列表中选择一个对象时自动更新下拉列表,以便在单击下拉列表后,下一个单元格将不再包含该对象,而且如果我从列表中删除对象,该对象必须返回下拉列表,因为它再次可用

我做了什么?

我在数据库端做了一些公式,这样可以从一列创建下拉列表,一旦我从下拉列表本身为列表指定了一个对象,该列就会自动更新

第1列:包括所有可用车辆/玩家
第2列:包括所有分配的车辆/玩家
第3列:使用公式=
排序(过滤器(E2:E,F2:F=“”),1,true),从第2列减去第1列,生成下拉列表

问题

虽然这种方法“有效”,但我对下拉菜单自动更新的方式有一些问题 如果我添加所有可用设备,然后删除和项,以便它可以用于其他单元格/插槽,下拉列表将不会自动正确更新,如果我删除“unit 4”,下拉列表将显示另一个可用对象“unit 8”

我能做些什么来解决我的问题?

我正在为电子表格添加链接,以便更容易理解我的问题

谢谢你们


因此可以优化并清除此解决方案,添加一些函数以避免重复代码。但作为一个工作的起点,你可以

function onEdit(e) {
  var ss = SpreadsheetApp.getActive();

  // Get the working Sheets
  var gameplan = ss.getSheetByName("gameplan");
  var vehicle = ss.getSheetByName("vehicle");
  var players = ss.getSheetByName("players");

  // Get current selected vehicles
  var _selectedVehicles = gameplan.getRange(2, 2, gameplan.getLastRow() - 1).getValues();
  var selectedVehicles = [];
  for(var i = 0; i < _selectedVehicles.length; i++){
    selectedVehicles.push(_selectedVehicles[i][0])
  }

  // Get current selected players
  var _selectedPlayers = gameplan.getRange(2, 1, gameplan.getLastRow() - 1).getValues();
  var selectedPlayers = [];
  for(var i = 0; i < _selectedPlayers.length; i++){
    selectedPlayers.push(_selectedPlayers[i][0])
  } 





  // Get active and unselected Vehicles
  var activeVehicles = [];
  var vehicleValues = vehicle.getRange(2, 1, vehicle.getLastRow() - 1, 2).getValues();

  for(var i =0; i < vehicleValues.length; i++){
    if(vehicleValues[i][0] == "ACTIVE" && selectedVehicles.indexOf(vehicleValues[i][1]) == -1){
      activeVehicles.push(vehicleValues[i][1])
    }
  }

  // Get active and unselected players
  var activePlayers = [];
  var playerValues = players.getRange(2, 1, players.getLastRow() - 1, 2).getValues();

  for(var i =0; i < playerValues.length; i++){
    if(playerValues[i][0] == "ACTIVE" && selectedPlayers.indexOf(playerValues[i][1]) == -1){
      activePlayers.push(playerValues[i][1])
    }
  }  



  // Insert data validation for vehicles
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(activeVehicles, true).build();
  gameplan.getRange("B2:B").setDataValidation(rule);

  // Insert data validation for Players
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(activePlayers, true).build();
  gameplan.getRange("A2:A").setDataValidation(rule);



}
这里基本上是调用电子表格上的

  • 获取已选择的值
因此,这里使用相同的方法获取值,但在本例中,我们检索两列,
ACTIVE/INACTIVE
id
。 之后,我们遍历数组,确保该行的状态为
活动
,并且id不在先前选择的数组中。看这张照片。我们将所有符合这些条件的值存储在一个新数组中

  • 最后,我们实施新的数据验证

对于最后一点,您需要使用的是创建对象的方法。在这个对象中,有很多方法可以让数据按照您想要的方式运行,其中一个方法是使用下拉列表显示您想要的值。在本例中,是我们在上一步中创建的数组。使用后,我们可以使用

将此新规则添加到
范围
,这样可以优化并清除此解决方案,添加一些函数以避免重复代码。但作为一个工作的起点,你可以

function onEdit(e) {
  var ss = SpreadsheetApp.getActive();

  // Get the working Sheets
  var gameplan = ss.getSheetByName("gameplan");
  var vehicle = ss.getSheetByName("vehicle");
  var players = ss.getSheetByName("players");

  // Get current selected vehicles
  var _selectedVehicles = gameplan.getRange(2, 2, gameplan.getLastRow() - 1).getValues();
  var selectedVehicles = [];
  for(var i = 0; i < _selectedVehicles.length; i++){
    selectedVehicles.push(_selectedVehicles[i][0])
  }

  // Get current selected players
  var _selectedPlayers = gameplan.getRange(2, 1, gameplan.getLastRow() - 1).getValues();
  var selectedPlayers = [];
  for(var i = 0; i < _selectedPlayers.length; i++){
    selectedPlayers.push(_selectedPlayers[i][0])
  } 





  // Get active and unselected Vehicles
  var activeVehicles = [];
  var vehicleValues = vehicle.getRange(2, 1, vehicle.getLastRow() - 1, 2).getValues();

  for(var i =0; i < vehicleValues.length; i++){
    if(vehicleValues[i][0] == "ACTIVE" && selectedVehicles.indexOf(vehicleValues[i][1]) == -1){
      activeVehicles.push(vehicleValues[i][1])
    }
  }

  // Get active and unselected players
  var activePlayers = [];
  var playerValues = players.getRange(2, 1, players.getLastRow() - 1, 2).getValues();

  for(var i =0; i < playerValues.length; i++){
    if(playerValues[i][0] == "ACTIVE" && selectedPlayers.indexOf(playerValues[i][1]) == -1){
      activePlayers.push(playerValues[i][1])
    }
  }  



  // Insert data validation for vehicles
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(activeVehicles, true).build();
  gameplan.getRange("B2:B").setDataValidation(rule);

  // Insert data validation for Players
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(activePlayers, true).build();
  gameplan.getRange("A2:A").setDataValidation(rule);



}
这里基本上是调用电子表格上的

  • 获取已选择的值
因此,这里使用相同的方法获取值,但在本例中,我们检索两列,
ACTIVE/INACTIVE
id
。 之后,我们遍历数组,确保该行的状态为
活动
,并且id不在先前选择的数组中。看这张照片。我们将所有符合这些条件的值存储在一个新数组中

  • 最后,我们实施新的数据验证

对于最后一点,您需要使用的是创建对象的方法。在这个对象中,有很多方法可以让数据按照您想要的方式运行,其中一个方法是使用下拉列表显示您想要的值。在本例中,是我们在上一步中创建的数组。使用后,我们可以使用将此新规则添加到
范围中。

我有办法解决您的问题,但它要求每个选择都有一个“helper”列/行以及一个“checker”列

检查器将检查项目是否已使用,每个项目的帮助器列将基于剩余的可用选择

使用第1列和第2列,您只需要为每个选择添加一个辅助列

Below is an example:
A                   B   B   D   E                   Column 1 (K)   Column 2(L)
Chosen number 1     3   3   2   4                   Random items    
Chosen number 2     5   5   2   4                       1               3
Chosen number 3     1   1   2   4                       2            available
Chosen number 4         2   4                           3               1
Chosen number 5         2   4                           4            available
                                                        5               2


The formula in column C is '=B'
The formula in column D is '=transpose(filter($K$2:$K$6,$L$2:$L$6="available"))'
The data validation in column B is range C:F.
Column 1 includes all options
Column 2 includes all available options and the formula in column 2 is '=iferror(match(K2,$B$1:$B$5,0),"available")'

The purpose of column C is to allow for your data validation to be valid, even after entering in the selection.


我有办法解决您的问题,但它要求每个选择都有一个“helper”列/行以及一个“checker”列

检查器将检查项目是否已使用,每个项目的帮助器列将基于剩余的可用选择

使用第1列和第2列,您只需要为每个选择添加一个辅助列

Below is an example:
A                   B   B   D   E                   Column 1 (K)   Column 2(L)
Chosen number 1     3   3   2   4                   Random items    
Chosen number 2     5   5   2   4                       1               3
Chosen number 3     1   1   2   4                       2            available
Chosen number 4         2   4                           3               1
Chosen number 5         2   4                           4            available
                                                        5               2


The formula in column C is '=B'
The formula in column D is '=transpose(filter($K$2:$K$6,$L$2:$L$6="available"))'
The data validation in column B is range C:F.
Column 1 includes all options
Column 2 includes all available options and the formula in column 2 is '=iferror(match(K2,$B$1:$B$5,0),"available")'

The purpose of column C is to allow for your data validation to be valid, even after entering in the selection.


请选择一种方法,如果它们有一些相似之处,差异会使许多答案在不同平台上无法使用。请选择一种方法,如果它们有一些相似之处,差异会使许多答案在不同平台上无法使用。首先,我要说哇,感谢你在我的问题上所做的努力,我没有尝试脚本的原因之一是,多用户将对此工作表具有受保护的访问权限,因此执行此操作时脚本不是最好的。不过,如果你能给我一些建议,我将不胜感激。不管怎样,我会测试你的代码,然后会给你回复。所以在测试脚本后,一切正常,我能够按照要求自动更新。关于使用您的脚本,我还有一个问题,在从一个单元格中删除可用对象并显示在下拉列表中后,如何加快可用对象的速度?从下拉列表中删除已经添加的内容是一样的吗?它可以工作,但需要在其他地方单击2或4下才能刷新数据(下拉列表对象)。我在尝试添加另一个具有相同功能的列时疯了。但是,由于我不熟悉脚本,语法方面我失败了,您能告诉我如何使用o添加另一列吗
// Insert data validation for vehicles
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(activeVehicles, true).build();
  gameplan.getRange("B2:B").setDataValidation(rule);
Below is an example:
A                   B   B   D   E                   Column 1 (K)   Column 2(L)
Chosen number 1     3   3   2   4                   Random items    
Chosen number 2     5   5   2   4                       1               3
Chosen number 3     1   1   2   4                       2            available
Chosen number 4         2   4                           3               1
Chosen number 5         2   4                           4            available
                                                        5               2


The formula in column C is '=B'
The formula in column D is '=transpose(filter($K$2:$K$6,$L$2:$L$6="available"))'
The data validation in column B is range C:F.
Column 1 includes all options
Column 2 includes all available options and the formula in column 2 is '=iferror(match(K2,$B$1:$B$5,0),"available")'

The purpose of column C is to allow for your data validation to be valid, even after entering in the selection.