Javascript 为什么我的下拉列表在从google sheet更新webapp中的第二个相关下拉列表时如此缓慢

Javascript 为什么我的下拉列表在从google sheet更新webapp中的第二个相关下拉列表时如此缓慢,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我有大约50个数据在第一个选择中,一些在第二个选择中。这是我的全部代码。 我的问题尤其是第一选择选项中的第一项选择。当选择第一个项目时,更新第二个选择选项的速度慢得令人烦恼 gs代码: function get1st() { var ss = getSS(); var sheet = ss.getSheetByName('data'); var range = sheet.getRange("A2:A");//or "A2:A" for all da

我有大约50个数据在第一个选择中,一些在第二个选择中。这是我的全部代码。 我的问题尤其是第一选择选项中的第一项选择。当选择第一个项目时,更新第二个选择选项的速度慢得令人烦恼

gs代码:

function get1st() {

var ss = getSS();
var sheet = ss.getSheetByName('data'); 
var range  = sheet.getRange("A2:A");//or "A2:A" for all data
var vA  = range.getValues();
var dataSize = vA.length;
var options = [];
Logger.log("array size="+ dataSize);
for(let i=2;i<range.getLastRow();i++){
  if(options.indexOf(val = sheet.getRange(i,1).getValue())===-1){
    options.push(val);
  }
  
}
// var dataArray = values.toString().split(",");
// var stringVal = JSON.stringify(dataArray);
// Logger.log(stringVal);
// return JSON.stringify(stringVal); //Modified
Logger.log(options);
return options;
函数get1st(){ var ss=getSS(); var sheet=ss.getSheetByName('data'); var range=sheet.getRange(“A2:A”);//或“A2:A”表示所有数据 var vA=range.getValues(); var dataSize=vA.length; var期权=[]; Logger.log(“数组大小=“+dataSize”); for(设i=2;i
此函数执行相同的操作,只是它一次获取所有必需的数据,并从vA使用这些数据,而不是从循环内部运行getValue()

function get2nd(first = 'X60') {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName('data');
  var range = sheet.getRange(2,1,sheet.getLastRow()-1,2);//returning first two columns rather than using getValue() to get them from inside the loop
  var vA = range.getValues();
  var options = [];
  vA.forEach(r=>{
    if(r[0]==first && !~options.indexOf(r[1])) {
      options.push(r[1]);
    }
  }) 
  Logger.log(options);
  return options;
}
你可能会发现读起来很有价值


此函数执行相同的操作,只是它一次获取所有必需的数据并从vA使用,而不是从循环内部运行getValue()

function get2nd(first = 'X60') {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName('data');
  var range = sheet.getRange(2,1,sheet.getLastRow()-1,2);//returning first two columns rather than using getValue() to get them from inside the loop
  var vA = range.getValues();
  var options = [];
  vA.forEach(r=>{
    if(r[0]==first && !~options.indexOf(r[1])) {
      options.push(r[1]);
    }
  }) 
  Logger.log(options);
  return options;
}
你可能会发现读起来很有价值

修改点:
  • 在脚本中,
    getValue()
    用于函数
    get1st
    get2nd
    中的for循环。在这种情况下,过程成本将变得很高。现有答案已经提到了这一点
  • 在您的情况下,如果在选择第一个下拉列表和第二个下拉列表之间的值时单元格值没有改变,那么从
    get1st()的电子表格中检索“A”和“B”列中的所有值如何
    ?这样,当选择第二个下拉列表时,第二个下拉列表的值可以在不使用
    google.script.run
    的情况下放入。我认为当
    google.script.run
    的使用次数减少时,流程成本将能够降低
当上述各点反映到脚本中时,它将变成如下所示

谷歌应用程序脚本端: 在这种情况下,使用一个函数
getValues()
,而不是
get1st()
get2nd()

Javascript方面: 请修改
AddList
SecondSelect
的功能,如下所示

AddList()
SecondSelect()
修改点:
  • 在脚本中,
    getValue()
    用于函数
    get1st
    get2nd
    中的for循环。在这种情况下,过程成本将变得很高。现有答案已经提到了这一点
  • 在您的情况下,如果在选择第一个下拉列表和第二个下拉列表之间的值时单元格值没有改变,那么从
    get1st()的电子表格中检索“A”和“B”列中的所有值如何
    ?这样,当选择第二个下拉列表时,第二个下拉列表的值可以在不使用
    google.script.run
    的情况下放入。我认为当
    google.script.run
    的使用次数减少时,流程成本将能够降低
当上述各点反映到脚本中时,它将变成如下所示

谷歌应用程序脚本端: 在这种情况下,使用一个函数
getValues()
,而不是
get1st()
get2nd()

Javascript方面: 请修改
AddList
SecondSelect
的功能,如下所示

AddList()
SecondSelect()

您应该避免使用像
“A2:A”
这样的范围,因为在getLastRow()和getMaxRows()之间经常返回大量尾随的空值。
getRange(2,1,sheet.getLastRow()-1,1)
是一个更好的方法。您应该避免使用像
“A2:A”
这样的范围,因为在getLastRow()和getMaxRows()之间经常返回大量尾随的空值.getRange(2,1,sheet.getLastRow()-1,1)是一种更好的方法。我使用了你的解决方案。这对我来说更容易理解。但我现在面临的一个问题是在android chrome浏览器上,我必须从第一个选项中选择两次,然后只更新第二个选项。令人惊讶的是,在我的笔记本电脑或PC中从来没有出现过这种情况。为什么我有线索?Youtube scre很抱歉,我没有Android设备,所以在这方面我没有帮助。谢谢你的帮助。我仍在试图弄清楚为什么下拉项目必须点击两次,有时点击另一个项目,然后再次点击选择列表中我想要的项目。然后更新第二个项目列表。这个问题在移动设备中。我用过yo你的解决方案。这对我来说更容易理解。但我现在面临的一个问题是在android chrome浏览器上,我必须从第一个选择中选择两次,然后只有第二个选择选项被更新。令人惊讶的是,在我的笔记本电脑或PC中从来都不是这样。为什么我有线索?Youtube屏幕录制抱歉,我没有android d设备,所以我在这方面没有帮助。谢谢你的帮助。我仍在试图找出为什么下拉项必须点击两次,有时点击另一个项目,然后再次点击选择列表中我想要的项目。然后更新第二个项目列表。这个问题在移动设备中。有人能告诉我SecondSelect函数的参数吗选项。国家在何处以及如何使用?我犹豫是否使用@Tanaike建议的代码,但当我真的使用完之后,我可以在我的电脑中看到谷歌chrome浏览器在速度上的差异。遗憾的是,android chrome浏览器有些不对劲。在我从第一个列表中选择第一个元素后,第二个列表不会更新。这只是第一个元素最后,将两个列表合并为一个,方法是将值'var dataRow=values.map(row=>{return row[0]+':“+row[1]});console.log(“dataRow”+dataRow);dataRow.forEach(函数(项,索引){let option=document.createElement(“option”);option.value=item;option.text=item;List.appendChild(option);});'@k
function get2nd(first = 'X60') {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName('data');
  var range = sheet.getRange(2,1,sheet.getLastRow()-1,2);//returning first two columns rather than using getValue() to get them from inside the loop
  var vA = range.getValues();
  var options = [];
  vA.forEach(r=>{
    if(r[0]==first && !~options.indexOf(r[1])) {
      options.push(r[1]);
    }
  }) 
  Logger.log(options);
  return options;
}
function getValues() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Sheet1');
  return sheet.getRange("A2:B" + sheet.getLastRow()).getValues();
}
let values = [];  // Added

function AddList() {
  google.script.run.withSuccessHandler(function(ar) {
    values = ar;  // Added
    List.length = 0;
    let option = document.createElement("option");
    option.value = "";
    option.text = "Select State";
    option.selected = true;
    List.appendChild(option);
    [...new Set(values.map(([a]) => a))]  // Modified
    .forEach(a => {
      let option = document.createElement("option");
      option.value = a;
      option.text = a;
      List.appendChild(option);
    });
  }).getValues();
}

window.onload = function() {
  AddList();
}
function SecondSelect(country) {
  var country = document.getElementById("List");
  list2.length = 0;
  let option = document.createElement("option");
  option.value = "";
  option.text = "Select State";
  option.selected = true;
  list2.appendChild(option);
  var v = country.value || 'X60';
  [...new Set(values.filter(([a]) => a == v).map(([,b]) => b))]  // Modified
  .forEach(function(item, index) {
    let option = document.createElement("option");
    option.value = item;
    option.text = item;
    list2.appendChild(option);
  });
}