来自另一个电子表格的多个下拉列表,每个电子表格中有超过 500 个项目
Multiple Dropdownlist from another spreadsheet with more than 500 items in each
您好,在此先感谢您的帮助,
我找到了很多关于此的其他主题,但我没有找到问题的答案,所以我来了。
我的目标是根据另一列中的单词自动在板中创建下拉列表(50-100 之间的下拉列表)。数据应该在另一个 spreadsheet 中,并且大多数下拉列表可以包含 600-700 个项目。
请查看下图以获取更多说明:
board picture
如果在 F 列“名称”的第一个单词中找到 sheet 名称,则在 G 列和 H 列中创建下拉列表 1 和 2。如果您选择 G 列“Libellés”中的项目,它会在指定的 sheet 中对“MP”列和价格进行 Vlookup。同样,如果您在“MP”列中选择一个项目,它会在“Libellés”和“price”中进行 Vlookup 以匹配。
当所有 sheet 都在同一个传播sheet 时,这工作正常,但是当所有数据 sheet 都是在另一个传播sheet。带有代码的spreadsheet会被复制很多次(每年200+),所以我想把数据库sheets(15000+lignes x 5列)放在一个spread[=43中=] 当我们打开它们时,它会喂养所有其他“小”传播sheets。
我尝试了很多选择:
- requireValueInList:这不起作用,一些列表有 600-700 个项目,不适用于像这样的大列表。
- 范围列表:范围太大,我有大约 50-100 个 100-700 项的下拉列表,这太多了,程序在结束前停止(而且我有一台好电脑,这是我的大多数同事都不是这种情况),所以这不是解决方案,或者我做错了。
- requireValueInRange :这就是我用来制作它的方法 运行 当一切都在同一个传播 sheet 上时,但如果数据在另一个上则不能使用它传播sheet.
有没有办法绕过 requireValueInRange 的限制?这是我第一次使用google应用程序脚本,所以请不要太苛刻地判断。
这是代码,当所有数据 sheet 与下拉列表的目标 sheet 处于相同的 sspreadsheet 时,它工作正常:
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)
}
然后继续,就好像工作表在同一个电子表格中一样。
您遇到的主要问题是由于您调用的是 getActiveSpreadsheet
方法而不是 openById(id)
。
但是,假设您的工作表名称相同,但它们只是在不同的电子表格中,并且您想继续使用 requireValueInRange
方法,我建议您在代码中添加以下行:
代码
function createDataValidation() {
let spreadsheetIds = ['SS_1_ID', 'SS_2_ID', ...];
for (let i=0; i<spreadsheetIds.length; i++) {
var tss = SpreadsheetApp.openById(spreadsheetIds[i]);
var tsh = tss.getActiveSheet();
var tsh1 = tss.getSheetByName('Fiche_eclate_CS');
// the rest of your code
}
}
上面的代码循环遍历所有电子表格 - 这是通过将要使用的电子表格的所有 ID 存储在 spreadsheetIds
变量中,然后使用 for
循环来完成的, 正在访问它们中的每一个并使用您已有的代码。
参考
您好,在此先感谢您的帮助,
我找到了很多关于此的其他主题,但我没有找到问题的答案,所以我来了。
我的目标是根据另一列中的单词自动在板中创建下拉列表(50-100 之间的下拉列表)。数据应该在另一个 spreadsheet 中,并且大多数下拉列表可以包含 600-700 个项目。 请查看下图以获取更多说明:
board picture 如果在 F 列“名称”的第一个单词中找到 sheet 名称,则在 G 列和 H 列中创建下拉列表 1 和 2。如果您选择 G 列“Libellés”中的项目,它会在指定的 sheet 中对“MP”列和价格进行 Vlookup。同样,如果您在“MP”列中选择一个项目,它会在“Libellés”和“price”中进行 Vlookup 以匹配。
当所有 sheet 都在同一个传播sheet 时,这工作正常,但是当所有数据 sheet 都是在另一个传播sheet。带有代码的spreadsheet会被复制很多次(每年200+),所以我想把数据库sheets(15000+lignes x 5列)放在一个spread[=43中=] 当我们打开它们时,它会喂养所有其他“小”传播sheets。
我尝试了很多选择:
- requireValueInList:这不起作用,一些列表有 600-700 个项目,不适用于像这样的大列表。
- 范围列表:范围太大,我有大约 50-100 个 100-700 项的下拉列表,这太多了,程序在结束前停止(而且我有一台好电脑,这是我的大多数同事都不是这种情况),所以这不是解决方案,或者我做错了。
- requireValueInRange :这就是我用来制作它的方法 运行 当一切都在同一个传播 sheet 上时,但如果数据在另一个上则不能使用它传播sheet.
有没有办法绕过 requireValueInRange 的限制?这是我第一次使用google应用程序脚本,所以请不要太苛刻地判断。
这是代码,当所有数据 sheet 与下拉列表的目标 sheet 处于相同的 sspreadsheet 时,它工作正常:
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)
}
然后继续,就好像工作表在同一个电子表格中一样。
您遇到的主要问题是由于您调用的是 getActiveSpreadsheet
方法而不是 openById(id)
。
但是,假设您的工作表名称相同,但它们只是在不同的电子表格中,并且您想继续使用 requireValueInRange
方法,我建议您在代码中添加以下行:
代码
function createDataValidation() {
let spreadsheetIds = ['SS_1_ID', 'SS_2_ID', ...];
for (let i=0; i<spreadsheetIds.length; i++) {
var tss = SpreadsheetApp.openById(spreadsheetIds[i]);
var tsh = tss.getActiveSheet();
var tsh1 = tss.getSheetByName('Fiche_eclate_CS');
// the rest of your code
}
}
上面的代码循环遍历所有电子表格 - 这是通过将要使用的电子表格的所有 ID 存储在 spreadsheetIds
变量中,然后使用 for
循环来完成的, 正在访问它们中的每一个并使用您已有的代码。