list - 来自另一个电子表格的多个下拉列表,每个下拉列表中有 500 多个项目
问题描述
您好,提前感谢您的帮助,
我找到了很多关于此的其他主题,但我没有找到我的问题的答案,所以我在这里。
我的目标是根据另一列中的一个词自动在板中创建下拉列表(50-100 之间的下拉列表)。数据应该在另一个电子表格中,并且大多数下拉列表可以包含大约 600-700 项。请在下面的图片中查看更多说明:
board picture 如果在 F 列“designation”的第一个单词中找到工作表名称,则在 G 和 H 列中创建下拉列表 1 和 2。如果您选择 G 列“Libellés”中的一项,它会在指定表中对“MP”列和价格进行 Vlookup。同样,如果您在“MP”列中选择一个项目,它会在“Libellés”和“价格”中进行 Vlookup 匹配。
当所有工作表都在同一个电子表格中时,这工作正常,但是当所有数据表都在另一个电子表格中时,我找不到让它工作的方法。带有代码的电子表格将被复制很多次(每年 200 多次),所以我想将数据库表(15000+ 线 x 5 列)放在一个电子表格中,当我们打开这些电子表格时,它会提供所有其他“小”电子表格。
我尝试了很多选择:
- requireValueInList :这是行不通的,有些列表是 600-700 项,不适用于像这样的大列表。
- list from a range :范围太大,我有大约 50-100 个 100-700 项的下拉列表,这太多了,程序在结束前停止(而且我有一台好的计算机,大多数情况不是这样我的同事),所以这不是一个解决方案,或者我做错了。
- requireValueInRange :当所有内容都在同一个电子表格上时,这是我用来让它运行的,但如果数据在另一个电子表格上,则不能使用它。
有没有办法绕过 requireValueInRange 限制?这是我第一次使用谷歌应用脚本,所以请不要太苛刻地判断。
这是代码,当所有数据表与下拉列表的目标表位于同一个电子表格中时,它工作正常:
function onOpen(e) {
// sss for source spreadsheet where I have all datas, and tss for target spreadsheet where I want my lists to be created
var sss1 = spreadsheetApp.openById('blahblah');
var ssh1 = sss1.getSheetByName('Emballages');
var tss = SpreadsheetApp.getActiveSpreadsheet();
var tsh = tss.getActiveSheet();
var tsh1 = tss.getSheetByName('Fiche_eclate_CS');
// The below part is to update 2 lists, using datas from the sheet "emballages" in the source spreadsheet, all working fine except data validation rule, won't accept arguments
var sheet = tss.getSheets()[0];
var column = sheet.getRange("F:F").getValues();
var prow;
for (var i = 0; i < column.length; i++){
if (column[i][0] === "Packaging :") {
prow = i+1;
break;
}
}
var emblrow = ssh1.getRange('B:B').getLastRow();
var cel1D = tsh1.getRange(prow,7);
// This is where I have problems. The call ('B2:B'+ emblrow) is not accepted. I can't use this as data validation on another spreadsheet.
var cel2D = ssh1.getRange('B2:B'+ emblrow);
var ruleD = SpreadsheetApp.newDataValidation().requireValueInRange(cel2D).build();
cel1D.setDataValidation(ruleD);
var cel1M = tsh1.getRange(prow,8);
// Same problem here. The call ('A2:A'+ emblrow) is not accepted.
var cel2M = ssh1.getRange('A2:A'+ emblrow );
var ruleM = SpreadsheetApp.newDataValidation().requireValueInRange(cel2M).build();
cel1M.setDataValidation(ruleM);
// The below part is to update many lists, using datas from one sheet in the source spreadsheet. To find the good sheet in the other spreadsheet, I use the split function. This part is working fine. I only have problems with data validation rules, same as above.
var ui = SpreadsheetApp.getUi();
var button = ui.alert("Voulez vous mettre à jour toutes les listes de la feuille ?",ui.ButtonSet.YES_NO);
if (button == ui.Button.YES) {
var anchhrow;
var anchbrow;
var column1 = tsh1.getRange("B:B").getValues();
for (var i = 0; i < column1.length; i++){
if (column1[i][0] === "Anchor-haut") {
anchhrow = i+3;
break;
}
}
for (var i = 0; i < column1.length; i++){
if (column1[i][0] === "Anchor-bas") {
anchbrow = i;
break;
}
}
var rangeH1 = tsh.getRange('H'+anchhrow +':H'+anchbrow).getValues();
var range = tsh.getRange('H'+anchhrow +':H'+anchbrow);
var lrowH = rangeH1.length;
for (var k=0; k<lrowH; k++){
var rown = anchhrow + k;
var testrng = sheet.getRange("F" + rown);
if ( testrng == "" ) {
}
else {
var name = nom(tsh,rown);
var ssh3 = sss1.getSheetByName(name);
if (ssh3 == null){
}
else {
var flrow = ssh3.getRange('B2:B').getLastRow();
var rng1D = tsh1.getRange(k+anchhrow,7);
// same issu, can't use ('B2:B'+ flrow)for data validation
var rng2D = ssh3.getRange('B2:B'+ flrow);
var ruleD =
SpreadsheetApp.newDataValidation().requireValueInRange(rng2D).build();
rng1D.setDataValidation(ruleD);
var rng1M = tsh1.getRange(k+anchhrow,8);
// same here, can't use ('A2:A'+ flrow)for data validation
var rng2M = ssh3.getRange('A2:A'+ flrow );
var ruleM = SpreadsheetApp.newDataValidation().requireValueInRange(rng2M).build();
rng1M.setDataValidation(ruleM);
}
}
}
function nom(sheet,row){
var word = [{}];
var rng = sheet.getRange("F" + row);
var word = rng.getValue().split(" ");
Logger.log(word);
return word[0];
}
}
else {
}
// This part is where I control prices once all lists are updated, this is working fine.
var ui = SpreadsheetApp.getUi();
var button = ui.alert("Les listes ont été mises à jour. Voulez vous mettre à jour les prix ?",ui.ButtonSet.YES_NO);
if (button == ui.Button.YES) {
for(var j=0;j<lrowH; j++){
var cellI1 = tsh.getRange(j+anchhrow,8).getValue();
if (cellI1 == "") {
}
else {
var cellI2 = vlookup(ssh2,1,3,cellI1);
tsh.getRange(j+anchhrow,9).setValue(cellI2);
function vlookup(sheet, column, index, value) {
var lastRow=sheet.getLastRow();
var data=sheet.getRange(1,column,lastRow,column+index).getValues();
for(i=0;i<data.length;++i){
if (data[i][0]==value){
return data[i][index];
}
}
}
}
}
}
else {
}
Browser.msgBox ("MAJ feuille terminée");
}
如果您有不明白的内容或需要更多详细信息,请随时提出问题。
提前致谢,
解决方案
我建议
function betweenSpreadsheets() {
let localSs = SpreadsheetApp.getActiveSpreadsheet();
let distSsUrl = 'https://docs.google.com/spreadsheets/d/1H-Zh blah blah KHP7x8/edit?usp=sharing';
let distSsId = '1H-Zh blah blah KHP7x8';
let distSs1 = SpreadsheetApp.openById(distSsId)
let distSs2 = SpreadsheetApp.openByUrl(distSsUrl)
}
然后继续进行,就好像工作表在同一个电子表格中一样。
推荐阅读
- jenkins - 詹金斯新手;简单构建失败,步骤中未找到此类 DSL 方法“管道”
- angular - 为什么生成解析器的cli命令会抛出异常?
- python - 不再支持使用 folium.Map 并将列表喜欢传递给带有任何缺失标签的 .loc 或 []
- c# - 如何从 DevOps 更改多个 XML 元素内容
- c# - 安装 SDK 后缺少 Visual Studio 2019、.NET 5
- python - 如何使用 plt 函数构建条形图
- c# - NHibernate 拒绝验证 postgres12 中 varchar(255) 的字符变化
- rxjs - 即使没有活跃的订阅者,我使用 shareReplay() 的 Observable 会永远运行吗?
- python - 我无法计算二次方程
- excel - 如何最好地分组 RadioButtons VBA Excel