【问题标题】:Google Sheets: INDIRECT() with a Range谷歌表格:带有范围的 INDIRECT()
【发布时间】:2019-06-29 17:10:15
【问题描述】:

这个问题可以改写为“在 FILTER() 中使用以编程方式生成的范围”,具体取决于回答的方法。

编辑- 似乎我在尝试展示我尝试过的内容时无意中包含了太多信息,因此我的问题不清楚。我在此编辑中所做的更改应该可以解决这个问题。

我目前正在使用以下功能进行过滤:

代码块 1

=filter('Data Import'!1:10000,'Data Import'!D:D<12)

导入数据后,D:D 列可以更改位置(例如,它可以在F:F 列中),但始终具有标题“student.grade”。

问题是:如何在过滤器函数中引用这个具有固定标题的可变位置列,如代码块 1 中给出的那样? 换句话说,我可以替换 'Data使用有效代码导入'!D:D`,无论标题为“student.grade?”的列的位置如何,该函数都可以工作。

我尝试过的:

我可以使用下面的代码正确地找到作为字符串的列的地址(无论它在数据导入之后是什么):

代码块 2

=substitute(address(1,match("student.grade",'Data Import'!1:1,0),4),1,"")&":"&substitute(address(1,match("student.grade",'Data Import'!1:1,0),4),1,"")

当标题“student.grade”在单元格D1中时,上面代码块2中的函数返回"D:D",当“student.grade”在单元格F1中时返回"F:F"。我想我可以简单地将这个值插入到FILTER() 函数中,然后继续我的快乐之路,但是为了将我的字符串转换为可用地址,我尝试在代码块 2 中生成的字符串上使用INDIRECT() 函数以上。

代码块 3

=filter('Data Import'!1:3351,'Data Import'!indirect(substitute(address(1,match("student.grade",'Data Import'!1:1,0),4),1,"")&":"&substitute(address(1,match("student.grade",'Data Import'!1:1,0),4),1,""),TRUE)<12)

公式无法正确解析。

简化同一函数的间接部分以测试它在给定范围时是否会产生相同的错误:

代码块 4

=filter('Data Import'!1:3351,indirect('Data Import'!&"D:D")<12)

这让我相信 INDIRECT() 不处理范围,或者如果是,我不知道语法。 This Stack Overflow post 似乎暗示这是可能的,但我无法弄清楚细节。

这个问题不是试图让其他人帮助我解决我的编程困境。我可以使用各种脚本、巨大的辅助 if 语句列等等来做到这一点。

问这个问题是为了了解如何将变量范围传递给过滤函数(如果可能的话)。

【问题讨论】:

  • 您在启动代码示例时并没有真正告诉我们您想要实现的目标(动态过滤器范围除外),也没有向我们展示您的数据是什么样的。请编辑您的问题以包含有关您正在使用的实际场景以及访问您的电子表格(或其版本)的更多信息 - 否则您的问题没有内容。
  • 我澄清了我的问题。大多数内容概述了我已经尝试过的内容,而不是提出问题。我建议改变你的语言以减少对抗(“你的问题没有内容”),以免引发防御性反应而不是有用的讨论。虽然您的评论是有效的(我没有很好地澄清我的问题),但很难不与您争论。
  • 点了。谢谢你提到它。
  • 在我看来,“student.grades”列缺乏确定性是一个问题。 FWIW,我编写了一个脚本来更新标题中包含“student.grades”的命名范围。我不会将其作为答案发布,因为它可能会阻止人们查看问题和/或发布可以处理可移动标题/列等的答案。如果您需要脚本,请告诉我。跨度>
  • 由于 player0 添加了基于公式的出色答案,我将添加脚本作为答案,以便您参考。

标签: google-apps-script google-sheets filter match spreadsheet


【解决方案1】:

我不知道你想要实现什么,但看看这个:

={'Data Import'!1:1;
 FILTER('Data Import'!1:10000, 'Data Import'!D:D < 12)}

或:

=QUERY(FILTER('Data Import'!1:10000, 'Data Import'!D:D < 12), 
 "select * label Col4 'student.grade'", 0)

【讨论】:

  • 实际情况比这要复杂得多——这就是为什么我没有为MWE提供超过几行代码的原因。也许编辑后的问题澄清了一些事情?
【解决方案2】:

再一次,也许这就是你想要的:

=FILTER('Data Import'!1:100000, 
 INDIRECT("'Data Import'!"&
 ADDRESS(1,       MATCH("student.grade", 'Data Import'!1:1, 0), 4)&":"&
 ADDRESS(1000000, MATCH("student.grade", 'Data Import'!1:1, 0), 4)) < 12)

【讨论】:

  • 不错。这适用于一个小的编辑来调整匹配函数中未排序的数据:=FILTER('Data Import'!1:100000, INDIRECT("'Data Import'!"&amp; ADDRESS(1,MATCH("student.grade", 'Data Import'!1:1,0), 4)&amp;":"&amp; ADDRESS(1000000, MATCH("student.grade", 'Data Import'!1:1,0), 4)) &lt; 12)
  • 同意; MATCH ->=MATCH("student.grade",'Data Import'!1:1,0).
【解决方案3】:

OP 现有的解决方案是基于 Filter 命令的。挑战在于包含“student.grade”的列不固定,但是 player0 提供了一个出色的基于公式的解决方案。

另一种可能是使用命名范围。以下代码在标题(第 1 行)中找到“student.grades”并相应地重新定义命名范围。

function so54541923() {

  // setup the spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheetname = "Data Import";
  var sheet = ss.getSheetByName(sheetname);

  // define the header row
  var getlastColumn = sheet.getLastColumn();
  var headerRange = sheet.getRange(1, 1, 1, getlastColumn);
  Logger.log("DEBUG: Header range = " + headerRange.getA1Notation()); //DEBUG

  // assign a variable for student Grades
  var grades = "student.grade";

  // get the headers and find the column containing "student grades"
  var headerData = headerRange.getValues();
  var gradesIndex = headerData[0].indexOf(grades);
  // add one to the index number to account for start=zero
  gradesIndex = gradesIndex + 1;
  Logger.log("DEBUG: gradesIndex = " + gradesIndex); //DEBUG

  // convert the column number to a letter 
  // assumes that student.grade will never get past column Z
  var temp, letter = '';
  if (gradesIndex > 0) {
    temp = (gradesIndex - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    gradesIndex = (gradesIndex - temp - 1) / 26;
  }
  Logger.log("DEBUG: the column is " + letter); //DEBUG

  //var newrange = "'" + sheetname + "'!"+letter+":"+letter+";";
  // Logger.log("the new range is "+newrange); 

  // get the named ranges
  var namedRanges = ss.getNamedRanges();
  Logger.log("DEBUG: number of ranges: " + namedRanges.length); //DEBUG

  // if named range is student grades, then update range
  if (namedRanges.length > 0) {
    for (var i = 0; i < namedRanges.length; i++) {
      var thename = namedRanges[i].getName();
      Logger.log("DEBUG: Loop: i: " + i + ", and the named range is " + thename); //DEBUG
      if (thename = "student.grade") {

        // Logger.log("DEBUG: The named range is student.grade");//DEBUG

        // set the new range based on the column found earlier
        var nonstringrange = sheet.getRange("'" + sheetname + "'!" + letter + ":" + letter);
        namedRanges[i].setRange(nonstringrange);
        Logger.log("DEBUG: The new range is " + namedRanges[i].getRange().getA1Notation()); //DEBUG

      } else {
        Logger.log("DEBUG: The named range is NOT grades"); //DEBUG
      }
    }
  }
}

【讨论】:

  • 我最近为另一个脚本做了这个,但是你的正确错误处理的解决方案要好得多。我希望我可以接受这两种解决方案作为答案 - 这对于希望对更改范围执行操作的任何人(即,带有移动标题的数据导入)都将很有用。这值得它自己的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多