从属动态填充下拉列表 Google Sheet
Dependent dynamically populated dropdown list Google Sheet
我只是想在输入街道名称时自动填充所有链接到特定街道的路段的点路段。
当街道名称输入到 C 列时,D 列应该有一个仅包含该街道的点段的下拉列表。
虽然我意识到这可以简单地通过在“数据”选项卡中创建过滤器来实现,但我正在尝试创建一个不允许这样做的表单,因此需要编写脚本。
这是 Google sheet:
https://docs.google.com/spreadsheets/d/1QbTqPegE_GLj9V6x5uCNNXAoi0v12Pmaelhc7uaMknE/edit?usp=sharing
我已经编写了这段代码,但是我无法按街道过滤。
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(sourceRange,
true).build();
range.setDataValidation(rule);
}
function onEdit() {
var aSheet = SpreadsheetApp.getActiveSheet();
var aCell = aSheet.getActiveCell();
var aColumn = aCell.getColumn();
if (aColumn == 3 && aSheet.getName() == 'Sheet1') {
var range = aSheet.getRange(aCell.getRow(), aColumn + 1);
var sourceRange = aSheet.getRange('Sheet1!B2:B5131');
setDataValid_(range, sourceRange)
}
}
如有任何帮助,我们将不胜感激。
你很接近,但你应该使用 requireValueInList
而不是 requireValueInRange
。您正在通过 sourceRange
,这等于 all 个点段。
要完成过滤,您需要查看所有街道值。如果街道值与选择相匹配,则将相邻点段保存到单独的列表中。保存所有这些点段后,将其传递给 requireValueInList
。为此,您需要通过它来利用getValues()
to get the range values as an array and loop。
我做了一些其他修改:
- 在
onEdit
中,您应该使用 event object
- 更改了您的变量名称,以便更容易理解
- 添加检查以确保 Street 单元格不为空(从单元格中删除值时无需触发操作)
- 添加了执行过滤的函数
getPointSegments
删除了 setDataValid_
函数,因为它降低了您的代码的可读性,而且在我看来,不值得成为它自己的函数
function onEdit(event) {
var eventSheet = event.range.getSheet();
var eventCell = event.range;
var eventColumn = eventCell.getColumn();
var eventValue = eventCell.getValue();
if (eventColumn == 3 && eventSheet.getName() == "Sheet1" && eventValue != "") {
var pointRange = eventSheet.getRange(eventCell.getRow(), eventColumn + 1);
var pointSegments = getPointSegments_(eventSheet, eventValue);
var rule = SpreadsheetApp.newDataValidation().requireValueInList(pointSegments, true).build();
pointRange.setDataValidation(rule);
}
}
function getPointSegments_(sheet, selectedStreet) {
var streetsAndPoints = sheet.getRange("A2:B").getValues();
var pointSegments = [];
for (var i=0; i<streetsAndPoints.length; i++) {
var street = streetsAndPoints[i][0];
var pointSegment = streetsAndPoints[i][1];
if (street === selectedStreet)
pointSegments.push(pointSegment);
}
return pointSegments;
}
最后,请确保您在 Street 字段中的数据验证看起来像这样(我实际上建议 "Reject input" 处理无效数据)。
我只是想在输入街道名称时自动填充所有链接到特定街道的路段的点路段。 当街道名称输入到 C 列时,D 列应该有一个仅包含该街道的点段的下拉列表。 虽然我意识到这可以简单地通过在“数据”选项卡中创建过滤器来实现,但我正在尝试创建一个不允许这样做的表单,因此需要编写脚本。
这是 Google sheet:
https://docs.google.com/spreadsheets/d/1QbTqPegE_GLj9V6x5uCNNXAoi0v12Pmaelhc7uaMknE/edit?usp=sharing
我已经编写了这段代码,但是我无法按街道过滤。
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(sourceRange,
true).build();
range.setDataValidation(rule);
}
function onEdit() {
var aSheet = SpreadsheetApp.getActiveSheet();
var aCell = aSheet.getActiveCell();
var aColumn = aCell.getColumn();
if (aColumn == 3 && aSheet.getName() == 'Sheet1') {
var range = aSheet.getRange(aCell.getRow(), aColumn + 1);
var sourceRange = aSheet.getRange('Sheet1!B2:B5131');
setDataValid_(range, sourceRange)
}
}
如有任何帮助,我们将不胜感激。
你很接近,但你应该使用 requireValueInList
而不是 requireValueInRange
。您正在通过 sourceRange
,这等于 all 个点段。
要完成过滤,您需要查看所有街道值。如果街道值与选择相匹配,则将相邻点段保存到单独的列表中。保存所有这些点段后,将其传递给 requireValueInList
。为此,您需要通过它来利用getValues()
to get the range values as an array and loop。
我做了一些其他修改:
- 在
onEdit
中,您应该使用 event object - 更改了您的变量名称,以便更容易理解
- 添加检查以确保 Street 单元格不为空(从单元格中删除值时无需触发操作)
- 添加了执行过滤的函数
getPointSegments
删除了
setDataValid_
函数,因为它降低了您的代码的可读性,而且在我看来,不值得成为它自己的函数function onEdit(event) { var eventSheet = event.range.getSheet(); var eventCell = event.range; var eventColumn = eventCell.getColumn(); var eventValue = eventCell.getValue(); if (eventColumn == 3 && eventSheet.getName() == "Sheet1" && eventValue != "") { var pointRange = eventSheet.getRange(eventCell.getRow(), eventColumn + 1); var pointSegments = getPointSegments_(eventSheet, eventValue); var rule = SpreadsheetApp.newDataValidation().requireValueInList(pointSegments, true).build(); pointRange.setDataValidation(rule); } } function getPointSegments_(sheet, selectedStreet) { var streetsAndPoints = sheet.getRange("A2:B").getValues(); var pointSegments = []; for (var i=0; i<streetsAndPoints.length; i++) { var street = streetsAndPoints[i][0]; var pointSegment = streetsAndPoints[i][1]; if (street === selectedStreet) pointSegments.push(pointSegment); } return pointSegments; }
最后,请确保您在 Street 字段中的数据验证看起来像这样(我实际上建议 "Reject input" 处理无效数据)。