Google Apps Script/Javascript: 更快/更好的下拉选择解决方案,可在下方添加行?

huangapple go评论93阅读模式
英文:

Google Apps Script/Javascript: Faster/better solution for dropdown selection that adds rows beneath?

问题

我对JavaScript仍然很陌生,但我学到了很多。

我正在在Google Sheets上创建一个表单,用户可以进行选择,然后根据一些下拉行的选择,表单会显示或隐藏用户可以填写更多信息的特定行。该函数由“更改时”触发,因此我认为每当表单检测到已进行更改,它就会执行函数来隐藏或显示行。

如附图所示,我的脚本效果不错,但速度非常慢,有些响应时间接近3-4秒,然后脚本才会显示适当的行。

我的代码目前的工作方式如下:

// 你的JavaScript代码

是否有可能以更快的方式实现相同的效果?我尝试弄清如何追加行而不是隐藏/显示行,但似乎更复杂,而且可能需要更长的时间来添加行和输入值到相应的单元格中。

英文:

I'm still very new to Javascript, but I've been learning a lot.

I'm creating an intake form on Google Sheets where the user can make selections, and then depending on the selection on some dropdown rows, the sheet unhides certain rows beneath where the user can fill in more information. The function is triggered "on change", so I'm assuming that every time the sheet senses a change has been made, it then executes the function to hide or unhide rows.

Google Apps Script/Javascript: 更快/更好的下拉选择解决方案,可在下方添加行?

As you can see in the attached GIF, my script works pretty well, but it is terribly slow, with some response times approaching 3-4 seconds before the script unhides the appropriate rows.

The code that I have so far works like this:

function selectionUnHidesRows() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const values = sheet.getDataRange().getValues();
// Someone else gave me the following code to create variables from whatever values are in column A (the "header" column) and then grabs the value to the right of it in column B (the "input" column)
  const conversionObj = {
    "Client Marital Status": "clientMaritalStatus",
    "Client's Spouse's Name": "clientSpouseName",
    "How many children?": "numChildren",
  }
  const obj = values.reduce((o, [a, b]) => {
    if (conversionObj[a]) {
      o[conversionObj[a]] = b;
    }
    return o;
  }, {});
  const {clientMaritalStatus, clientSpouseName, numChildren} = obj;

// This looks through the sheet and finds the required text from Column A, here "Client's Spouse's Name"
  const clientSpouseTextFinder = sheet.createTextFinder("Client's Spouse's Name").findNext();
// once it's found the text, it gets the row
  const clientSpouseRow = clientSpouseTextFinder.getRow();

  switch(clientMaritalStatus) {
    case "married":
      sheet.showRows(clientSpouseRow); // if the dropdown next to "Client Marital Status" says "married", then show the row below that asks for the spouse's name
      break;
    default:
      sheet.hideRows(clientSpouseRow); // if the dropdown has anything other than "married", then hide the row below
    break;
  }
}

Are there potentially any faster ways of achieving the same thing? I tried to figure out how to append rows instead of hiding/unhiding rows, but it seemed more complicated and possibly would take longer to add rows and input values into the requisite cells.

答案1

得分: 1

以下是您要翻译的内容:

  const conversionObj = {
    "Client Marital Status": "clientMaritalStatus",
    "Client's Spouse's Name": "clientSpouseName",
    "How many children?": "numChildren",
  }

根据"clientMaritalStatus"的数据量,代码中的这一部分可能会导致加载时间较长:

switch(clientMaritalStatus) {
    case "married":
      sheet.showRows(clientSpouseRow); // 如果"Client Marital Status"旁边的下拉菜单显示"married",则显示下面询问配偶姓名的行
      break;
    default:
      sheet.hideRows(clientSpouseRow); // 如果下拉菜单显示除"married"以外的任何内容,则隐藏下面的行
    break;
  }

另一个明显导致速度变慢的因素是这一行:

 const clientSpouseTextFinder = sheet.createTextFinder("Client's Spouse's Name").findNext();

我认为这对代码有最大的影响,TextFinder类将始终遍历整个工作表,查找匹配提供文本的单元格,我认为更好的选择可能是类似这样的内容 (仅作为示例,此代码不会正常工作!)

 for(var i = source.getLastRow(); i > -1; i--) { //假设婚姻状况数据来自不同的工作表,并且在上面创建了一个名为"source"的变量来确定此数据的来源
      if(source[i].toString == "married"){
        var rowToHide = i;
      }
  sheet.hideRows(rowToHide)

主要区别在于通过提供特定范围,代码将仅在找到所需内容时运行,而不必遍历整个工作表。

请记住,上面提供的代码仅作为概念验证,肯定不适用于您的情况,可以根据您的情况制定更具体的解决方案,但为了这样做,我们需要一些示例数据,不需要具体名称或其他内容,只需要与您的工作表和数据集具有相同结构的内容,我将很乐意更新我的回答,以便更好地适应您的需求!

无论如何,我希望您能找到这些信息有用!

英文:

It seems to me that the problem might be in these two places:

  const conversionObj = {
    "Client Marital Status": "clientMaritalStatus",
    "Client's Spouse's Name": "clientSpouseName",
    "How many children?": "numChildren",
  }

Depending on the amount of data the "clientMaritalStatus" has this section of code:

switch(clientMaritalStatus) {
    case "married":
      sheet.showRows(clientSpouseRow); // if the dropdown next to "Client Marital Status" says "married", then show the row below that asks for the spouse's name
      break;
    default:
      sheet.hideRows(clientSpouseRow); // if the dropdown has anything other than "married", then hide the row below
    break;
  }

might actually take a long time to load.

The other thing that is most definitely making things slow is this line:

 const clientSpouseTextFinder = sheet.createTextFinder("Client's Spouse's Name").findNext();

I believe that this has the biggest impact on the code, the TextFinder class will always go through the entire sheet looking for a those cells that match the provided text, I believe a better option would be to have something like this (Just an example, the code will not work!):


 for(var i = source.getLastRow(); i > -1; i--) { //assuming that the marital status data is coming from a different sheet and that a variable "source" was created above to determinewhere this is coming from
      if(source[i].toString == "married"){
        var rowToHide = i;
      }
  sheet.hideRows(rowToHide)

The main difference is that by providing a specific range the code will only run until it finds what you are looking for instead of having to go through the entire sheet.

Please keep in mind that the code provided just above is only meant as a proof of concept and it will most definitely not work for you, something more specific to your situation can definitely be done but in order to do so we would need some sample data, no specific names or anything, just something that would have the same structure as the sheet and dataset you are using for your code with that information I will be happy to update my answer so it works better for you!

In any case I hope you can find this useful!

huangapple
  • 本文由 发表于 2023年5月7日 06:01:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191357.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定