Google表格:具有范围的

时间:2019-02-05 19:44:22

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

这个问题可以改写为“在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”位于单元格"D:D"中时,上述代码块2中的函数返回D1,而当“ student.grade”位于单元格{{中时,则返回"F:F" 1}}。我以为我可以简单地将此值插入F1函数中并以自己的方式使用,但是为了将字符串转换为可用地址,我尝试在生成的字符串上使用FILTER()函数在上面的代码块2中。

代码块3

INDIRECT()

公式无法正确解析。

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

代码块4

=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)

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

这个问题并不是试图让别人帮助我解决编程难题。我可以使用各种脚本,辅助if语句的巨型列等等来实现。

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

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

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
      }
    }
  }
}

答案 2 :(得分:0)

我不知道您想要实现什么,但请看一下:

={'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)