选择后从列表中删除项目 Dropdown Googlesheets Script
Removing item from a list once chosen Dropdown Googlesheets Script
我想从下拉列表中选择的项目中删除,然后下一个下拉列表将不再有该项目。我已经手动制作了一些东西,但是它需要很长时间并且不是很理想,因为你需要按顺序向下走,否则它会搞混。
https://docs.google.com/spreadsheets/d/1o3J1ZXzxQL11pdN1FDOQZ7YXbSib6A8KwkxBzO5bSM0/edit?usp=sharing
我制作了 3 个标签,一个是我解释我想要的,另一个是我手动制作的,这样你就可以了解它是如何工作的。但是请记住您需要按顺序手动进行的操作。我想让它查看一个范围,所以无论我选择哪个下拉菜单将其从列表中删除都没有关系。
如果无法按范围完成,则与手动方式相同,但脚本形式也会有很大帮助。
这是我尝试过的方法,但我对脚本编写真的很陌生,所以我什至可能还差得远:
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Dropdown');
//get's the value in range A1 ( the firstdropdown value )
var firstDrop = ss.getRange("A1").getValue();
//get's the value in range A3 ( the seconddropdown value )
var secondDrop = ss.getRange("A3").getValue();
//get the list ( I don't want to put the list in here sincec I'll be
//working with entries from google forms. so the list will be changing)
var list = ss.getRange("H1:H5").getValues();
if(firstDrop == list){
var newlist = (list-firstDrop);
}
}
我认为它应该是这样的:
function availableSlots(){
var form = FormApp.openByUrl('URL_OF_YOUR_FORM'); // TODO add your form url
// need to read what slots are available
var slots = SpreadsheetApp
.getActiveSpreadsheet()
.getRange("slots!A2:C10")
.getValues(); // TODO make sure getRange matches your quota range
var choice = [];
// loop through our available slots
for (s in slots){
// test if slot still available
if (slots[s][0] != "" && slots[s][2] > 0){
choice.push(slots[s][0]); // if so we add to temp array
}
}
var formItems = form.getItems(FormApp.ItemType.LIST); // our form list items
// TODO assumption that first select list is the one you want to change
// change formItems[n] if you have more than one select list
// and we just rewrite all the options to ones that are free
formItems[0].asListItem().setChoiceValues(choice);
}
由于我不确定您要使用哪个下拉菜单,我根据您的要求创建了一个示例 sheet(附在下面的照片)。为了减少我在 onEdit() 触发器上使用的其余下拉菜单输出的项目列表,以检查这些下拉菜单中的任何更改,并根据这些单元格值从中删除所需的项目列表。
以下代码段有自我解释的注释,说明我是如何实现它的:
function onEdit(e) {
// Get sheet
var sheet = SpreadsheetApp.getActive().getSheetByName('Share your Ideas here :)');
// Get list from range. Flat will make the 2D array returned by getVaues() into a 1D array
var list = sheet.getRange("E1:E5").getValues().flat();
// Get values from the dropdowns
var a = sheet.getRange("A1");
var b = sheet.getRange("B1");
var c = sheet.getRange("C1");
// Check if any of the values in the dropdowns match the list and if so remove them from
// the list
var index = list.indexOf(a.getValue()); if(index != -1){list.splice(index,1);}
index = list.indexOf(b.getValue()); if(index != -1){list.splice(index,1);}
index = list.indexOf(c.getValue()); if(index != -1){list.splice(index,1);}
// Create the data validation rule with the filtered list
var rule = SpreadsheetApp.newDataValidation().requireValueInList(list).setAllowInvalid(false).build();
// Create/update the dropdowns with the right filtered list
a.setDataValidation(rule);
b.setDataValidation(rule);
c.setDataValidation(rule);
}
参考资料
这可能对您有用 - 我认为它可以为您提供所需的结果,但它的外观并不理想。我已将其放入最后一个选项卡中的 sheet。我相信这与 Mateo 之前的回答是相同的方法,但是使用公式而不是代码。
=SORT(FILTER(B2:B;NOT(COUNTIF(A2:A;B2:B))))
其中 A 是您输入数据的列,B 是您的有效列表 names/words。
我使用此公式过滤每个下拉列表中显示的 words/names 列表。它从原始列表开始,并排除任何已经 selected 的列表。您的单元格的数据验证指向过滤后的列表,而不是原始列表。
缺点是一旦你select一个word/name,它就不再符合下拉单元格的条件,所以即使已经应用它的单元格也会显示为无效条目,有一个小的红色三角形。一个可行的解决方案的好处可能超过这个。
我想从下拉列表中选择的项目中删除,然后下一个下拉列表将不再有该项目。我已经手动制作了一些东西,但是它需要很长时间并且不是很理想,因为你需要按顺序向下走,否则它会搞混。
https://docs.google.com/spreadsheets/d/1o3J1ZXzxQL11pdN1FDOQZ7YXbSib6A8KwkxBzO5bSM0/edit?usp=sharing
我制作了 3 个标签,一个是我解释我想要的,另一个是我手动制作的,这样你就可以了解它是如何工作的。但是请记住您需要按顺序手动进行的操作。我想让它查看一个范围,所以无论我选择哪个下拉菜单将其从列表中删除都没有关系。
如果无法按范围完成,则与手动方式相同,但脚本形式也会有很大帮助。
这是我尝试过的方法,但我对脚本编写真的很陌生,所以我什至可能还差得远:
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Dropdown');
//get's the value in range A1 ( the firstdropdown value )
var firstDrop = ss.getRange("A1").getValue();
//get's the value in range A3 ( the seconddropdown value )
var secondDrop = ss.getRange("A3").getValue();
//get the list ( I don't want to put the list in here sincec I'll be
//working with entries from google forms. so the list will be changing)
var list = ss.getRange("H1:H5").getValues();
if(firstDrop == list){
var newlist = (list-firstDrop);
}
}
我认为它应该是这样的:
function availableSlots(){
var form = FormApp.openByUrl('URL_OF_YOUR_FORM'); // TODO add your form url
// need to read what slots are available
var slots = SpreadsheetApp
.getActiveSpreadsheet()
.getRange("slots!A2:C10")
.getValues(); // TODO make sure getRange matches your quota range
var choice = [];
// loop through our available slots
for (s in slots){
// test if slot still available
if (slots[s][0] != "" && slots[s][2] > 0){
choice.push(slots[s][0]); // if so we add to temp array
}
}
var formItems = form.getItems(FormApp.ItemType.LIST); // our form list items
// TODO assumption that first select list is the one you want to change
// change formItems[n] if you have more than one select list
// and we just rewrite all the options to ones that are free
formItems[0].asListItem().setChoiceValues(choice);
}
由于我不确定您要使用哪个下拉菜单,我根据您的要求创建了一个示例 sheet(附在下面的照片)。为了减少我在 onEdit() 触发器上使用的其余下拉菜单输出的项目列表,以检查这些下拉菜单中的任何更改,并根据这些单元格值从中删除所需的项目列表。
以下代码段有自我解释的注释,说明我是如何实现它的:
function onEdit(e) {
// Get sheet
var sheet = SpreadsheetApp.getActive().getSheetByName('Share your Ideas here :)');
// Get list from range. Flat will make the 2D array returned by getVaues() into a 1D array
var list = sheet.getRange("E1:E5").getValues().flat();
// Get values from the dropdowns
var a = sheet.getRange("A1");
var b = sheet.getRange("B1");
var c = sheet.getRange("C1");
// Check if any of the values in the dropdowns match the list and if so remove them from
// the list
var index = list.indexOf(a.getValue()); if(index != -1){list.splice(index,1);}
index = list.indexOf(b.getValue()); if(index != -1){list.splice(index,1);}
index = list.indexOf(c.getValue()); if(index != -1){list.splice(index,1);}
// Create the data validation rule with the filtered list
var rule = SpreadsheetApp.newDataValidation().requireValueInList(list).setAllowInvalid(false).build();
// Create/update the dropdowns with the right filtered list
a.setDataValidation(rule);
b.setDataValidation(rule);
c.setDataValidation(rule);
}
参考资料
这可能对您有用 - 我认为它可以为您提供所需的结果,但它的外观并不理想。我已将其放入最后一个选项卡中的 sheet。我相信这与 Mateo 之前的回答是相同的方法,但是使用公式而不是代码。
=SORT(FILTER(B2:B;NOT(COUNTIF(A2:A;B2:B))))
其中 A 是您输入数据的列,B 是您的有效列表 names/words。
我使用此公式过滤每个下拉列表中显示的 words/names 列表。它从原始列表开始,并排除任何已经 selected 的列表。您的单元格的数据验证指向过滤后的列表,而不是原始列表。
缺点是一旦你select一个word/name,它就不再符合下拉单元格的条件,所以即使已经应用它的单元格也会显示为无效条目,有一个小的红色三角形。一个可行的解决方案的好处可能超过这个。