【问题标题】:Filter a sheet based on criteria selected on another sheet and carried as an array根据在另一个工作表上选择并作为数组携带的标准过滤工作表
【发布时间】:2022-08-21 07:31:44
【问题描述】:

我设计用于分析十年一次的人口普查的 Google 表格要求合并单元格并使用两行来处理每个人口普查记录。由于合并了单元格,我的用户无法使用正常的 Google 表格过滤过程,因此我需要创建一种替代方法来过滤记录。我遇到了障碍。我创建了一个允许用户设置所需过滤条件的工作表。但我无法选择将其转换为可用的 GAS 脚本。 (我不会将所有将两行记录提取到另一张工作表并过滤掉每条记录除一行之外的所有代码的代码复杂化,然后可以使用这些代码过滤和重建过滤后的两行记录形式。)

过滤标准表(见下文)最多允许九级标准。在右侧,我显示了对用户隐藏的列,但允许我捕获在脚本中创建过滤器所需的信息。 I 列有脚本中需要的操作符文本,G 列是(在第一行的情况下)人口普查年在被过滤的工作表中的列,C 列有条件。我已经收集了一个数组中的值,我正在调用 filterArray。

我需要检查标准的每一行,确定是否进行了选择。如果是这样,我需要过滤条件。这是我的 For 循环:

  // Gather filters from Filter Criteria
   for (var i = 0; i <= 9; i = i + 1) { 
     if(filterArray[i][0]!==\"\"){
       myFilterText = SpreadsheetApp.newFilterCriteria()+\".\"+filterArray[i][8]+\"(\"+filterArray[i][2]+\")\"
       myFilter.setColumnFilterCriteria(filterArray[i][6],myFilterText)
     }
   }

最后一行触发此消息:

例外:参数(数字、字符串)与 SpreadsheetApp.Filter.setColumnFilterCriteria 的方法签名不匹配。

如果我没有将数组用作变量,我希望它在通过第一个循环时基本上看起来像这样:

   for (var i = 0; i <= 9; i = i + 1) { 
     if(\'A7\'!==\"\"){
       myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberLessThan(1850);
       myFilter.setColumnFilterCriteria(10,myFilterText)
     }
   }

除了尝试使用数组内容的第一个代码之外,我还尝试创建整个字符串 \"SpreadsheetApp.newFilterCriteria().\"+filterArray[i][8]+\"(\"+filterArray[ i][2]+\")\" 作为 myFilterText 的内容。我犯了同样的错误。

如何将用户选择的条件转换为可以运行以过滤记录的代码?

  • 我不得不为我糟糕的英语水平道歉。不幸的是,我无法理解您的展示图片和展示脚本之间的关系。可以问一下它的详细情况吗?而且,我无法理解How can I turn the criteria the user is selecting into a code that can run to filter records?。我可以问你目标的细节吗?
  • 感谢@Tanaike 愿意查看它。我意识到我以非常复杂的方式提出了这个问题,并且可能已经达到了重点。无论如何,我已经找到了一种让它工作的方法,我将添加它。它并不优雅,但它完成了。再次感谢!
  • 谢谢你的回复。我很高兴您的问题得到了解决。

标签: arrays google-apps-script google-sheets filter


【解决方案1】:

我找到了一个解决方案,不幸的是,它的代码量很大。我正在使用 switch-case 来评估每个可能的过滤条件并编码我需要的变量。与我发布的问题相关的代码部分现在是:

/**
   * Activating Filter and pasting records to new sheet called "Filtered Records_Prep"
   */
  var filterRange = spreadsheet.getActiveRange().getA1Notation();
    var myFilter = spreadsheet.getRange(filterRange).createFilter();
  var myFilterText = ""
  var sheet = spreadsheet.getActiveSheet();
  // Filter selection to row 1 of each set, eliminating 2s and blanks
  var Filter_Criteria0 = SpreadsheetApp.newFilterCriteria().whenNumberEqualTo(1);
  myFilter.setColumnFilterCriteria(3,Filter_Criteria0);
  // Gather filters from Filter Criteria
   for (var i = 0; i <= 9; i = i + 1) { 
     if(filterArray[i][0]!==""){
       myCol = filterArray[i][6];
       myFilterCondition = filterArray[i][8];
       myFilterCriteria = filterArray[i][2];
       switch(myFilterCondition) 
        {            
        case "whenNumberEqualTo":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberEqualTo(myFilterCriteria);
              break;    
        case "whenNumberNotEqualTo":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberNotEqualTo(myFilterCriteria);
              break;
        case "whenNumberContains":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberContains(myFilterCriteria);
              break;
        case "whenNumberDoesNotContain":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberDoesNotContain(myFilterCriteria);
              break; 
        case "whenCellEmpty":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenCellEmpty();
              break;
        case "whenCellNotEmpty":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenCellNotEmpty();
              break;
        case "whenNumberGreaterThan":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberGreaterThan(myFilterCriteria);
              break;
        case "whenNumberGreaterThanOrEqualTo":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberGreaterThanOrEqualTo(myFilterCriteria);
              break;    
        case "whenNumberLessThan":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberLessThan(myFilterCriteria);
              break;
        case "whenNumberLessThanOrEqualTo":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberLessThanOrEqualTo(myFilterCriteria);
              break;
        case "whenNumberStartsWith":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberStartsWith(myFilterCriteria);
              break; 
        case "whenNumberEndsWith":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberEndsWith
          (myFilterCriteria);
              break; 
        case "whenTextEqualTo":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenTextEqualTo(myFilterCriteria);
              break;    
        case "whenTextNotEqualTo":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenTextNotEqualTo(myFilterCriteria);
              break;
        case "whenTextContains":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenTextContains(myFilterCriteria);
              break;
        case "whenTextDoesNotContain":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenTextDoesNotContain(myFilterCriteria);
              break; 
        case "whenTextStartsWith":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenTextStartsWith(myFilterCriteria);
              break; 
        case "whenTextEndsWith":
          myFilterText = SpreadsheetApp.newFilterCriteria().whenTextEndsWith
          (myFilterCriteria);
              break; 
        default:
              ui.alert("This criteria was not found.")
      }
       myFilter.setColumnFilterCriteria(myCol,myFilterText);
     } else {
       return false;
     }
   }

【讨论】:

    猜你喜欢
    • 2017-07-29
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多