Так что это решение можно оптимизировать и убрать, добавив некоторые функции, чтобы не повторять код. Но в качестве рабочей отправной точки вы могли бы иметь.
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 . Поэтому, чтобы убедиться, что вы понимаете, что происходит (на случай, если вы захотите его изменить), я go рассмотрю свой код, объясняя все шаги и методы, которые я использовал.
В основном код состоит из 4 частей. ,
// Get the working Sheets
var gameplan = ss.getSheetByName("gameplan");
var vehicle = ss.getSheetByName("vehicle");
var players = ss.getSheetByName("players");
Здесь в основном вызывается 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
. Тогда, поскольку тип возвращаемого значения Object[][]
, нам нужно выполнить итерацию и получить каждое отдельное значение и push
его в массив selectedVehicles
(или Players).
- Получение активных и невыбранных транспортных средств
// 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
для получения значений, но в В этом случае мы получаем два столбца: ACTIVE/INACTIVE
и id
. После этого мы выполняем итерацию по массиву, чтобы убедиться, что эта строка имеет статус ACTIVE
и идентификатор отсутствует в предыдущем selected массиве. Посмотрите на indexOf
. И мы храним все значения, соответствующие этим условиям, в новом массиве.
- Наконец, мы навязываем новую проверку данных
// Insert data validation for vehicles
var rule = SpreadsheetApp.newDataValidation().requireValueInList(activeVehicles, true).build();
gameplan.getRange("B2:B").setDataValidation(rule);
Для этого последнего бита, который вам нужно использовать, это метод newDataValidation()
, который создает a DataValidationBuilder
объектов. В этом объекте у вас есть много методов, чтобы заставить данные вести себя так, как вы хотите, один из них requireValueInList
, чтобы иметь выпадающий список с желаемыми значениями. В случае массив, который мы создали на предыдущем шаге. После использования build
мы можем добавить это новое правило к range
с помощью sedDataValidation
.