我想实现以下方案,我有一个游戏,并且设置过程需要根据可用性将排队连接到2个数据库。
1。玩家2。车辆
阵容包括“ builder”,这意味着每个单元都有一个连接到数据库的下拉列表,并显示可用的对象。
我的目标
提交或从列表中选择一个对象后,我需要立即自动更新下拉列表,因此,一旦我从下拉列表中删除了一个对象,则下一个单元格将不再具有该对象。由于该对象再次可用,因此必须返回到下拉列表。
我做了什么?
我在数据库端做了一些公式,因此,一旦我从下拉列表本身为列表分配对象后,便可以从自动更新的列创建下拉列表。
第1栏:包括所有可用的载具/播放器第2栏:包括所有分配的载具/玩家第3列:使用公式= SORT(FILTER(E2:E,F2:F=""),1,true)
问题
虽然此方法“有效”,但下拉列表自动更新的方式存在一些问题如果我添加了所有可用设备,然后删除了项目,那么它可能可用于另一个cell / slot,则如果我删除“ 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);
}
不清楚您是否曾使用过Apps Script。因此,为了确保您能理解正在发生的事情(以防您要对其进行修改),我将遍历我的代码,解释我所使用的所有步骤和方法。
基本上,代码分为4部分。
// Get the working Sheets
var gameplan = ss.getSheetByName("gameplan");
var vehicle = ss.getSheetByName("vehicle");
var players = ss.getSheetByName("players");
这里基本上是在电子表格上调用getSheetByName()
。
getSheetByName()
所以这里只是重复相同的代码两次。在每个工作表内调用 // 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])
}
方法。然后,因为返回类型为getRange
,我们需要遍历并获取每个单独的值,然后将其getRange
放入Object[][]
(或玩家)数组。
push
因此这里使用相同的selectedVehicles
方法来获取值,但是在这种情况下,我们要检索两列 // 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])
}
}
和getRange
。之后,我们遍历数组,确保该行的状态为getRange
,并且该ID不位于先前的selected数组中。看一下ACTIVE/INACTIVE
。然后,我们将与这些条件匹配的所有值存储在新数组中。
id
对于这最后一点,您需要使用的是创建ACTIVE
对象的indexOf
方法。在该对象中,您有很多方法可以使数据按您的期望方式运行,其中之一就是indexOf
包含所需值的下拉列表。如果是我们在上一步中创建的数组。使用// Insert data validation for vehicles
var rule = SpreadsheetApp.newDataValidation().requireValueInList(activeVehicles, true).build();
gameplan.getRange("B2:B").setDataValidation(rule);
之后,我们可以将此新规则添加到带有newDataValidation()
的newDataValidation()
中。
我有一种解决您的问题的方法,但是对于每个选择,它都需要一个“帮助程序”列/行,并且还需要一个“检查程序”列。