插入所需行的查询(导入范围)以避免数据覆盖

Query(Importrange) with insertion of needed rows to avoid data overwrite

我想开发一个脚本,允许在 A 列中应用相同的函数,同时引用下面的所有行(从 A1 到 A600),这是一个查询(导入范围),其行数是inserted 不固定(从 1 到 300),因此必须在复制数据之前插入。

我首先在单元格 A1 中开发了一个公式,该公式运行良好,但这意味着要在单元格中复制块 600 次以覆盖所有行:

`={Query(IMPORTRANGE('Master Table Projects'!T503,"Impacted Formula!A5:R1000"),"where Col1 is not Null");Query(IMPORTRANGE('Master Table Projects'!T467,"Impacted Formula!A5:R1000"),"where Col1 is not Null");Query(IMPORTRANGE('Master Table Projects'!T15,"Impacted Formula!A5:R1000"),"where Col1 is not Null")}

因此,我必须开发一个带有循环的脚本,以查看将此公式从 T1 应用到 T600。我试过了:

function myFunction() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(2,2, lastRow-1, lastColumn-1);
  for (r=1; r<100;r++) {
    var sa=(Query(IMPORTRANGE('Master Table Projects'!Tr,"Impacted Formula!A5:R1000"),"where Col1 is not Null")); 
   ss.getRange(r,1).setValue(sa); 
  };

这不起作用,因为我收到一条警告消息: “语法错误:参数列表后缺少 )(第 19 行,文件“learnings.gs”)”

我不是编程方面的专家,但是: 我想我的“var sa”没有正确设置,但我不知道如何更正它。 Tr 对我来说意味着“T1 到 T600”,但很可能它写得不好。

我附上了我想要获得的结果的图片: expected results

通过添加@ziganotschka 提出的代码行

sheet.getRange("A" + sheet.getLastRow()).setValue(sa);

我在新图片中附上了结果,这是一个很好的改进,因为只显示了有一些结果要显示的导入行,但是: 仍然存在导入数据重叠的问题。最后一行(对应于 T999)必须手动删除才能看到一些结果。improved macro

如果您单击电子表格的 link,之后我可以为您提供访问权限,但由于我公司的限制,我无法共享 public link(此选项已被阻止) .

能否帮我更正这些行以使其正常工作?

感谢@ziganotschka 这里是工作代码:

  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var limit = ss.getSheetByName('Master Table Projects').getRange("T2").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
  Logger.log(limit);
  for (var r=2; r<=limit; r++) { 
    var sa="=Query(IMPORTRANGE('Master Table Projects'!T"+r+',"Impacted Formula!A5:R1000"),"where Col1 is not Null")'; 
    var firstEmptyRow = sheet.getRange("A1").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow()+1;
      Logger.log(firstEmptyRow);
    sheet.getRange("A" + firstEmptyRow).setValue(sa);
    SpreadsheetApp.flush();
  }
}

非常感谢 伊萨

如果你有一个有效的公式,为了给它分配一个动态行索引,你需要正确地连接它:

  • 当您构建变量 sa 时,它可以由对其他变量和文本的引用组成
  • 必须将文本指定为字符串,用单引号或双引号将=t 括起来
  • 如果您的文本(公式)已经包含一些引号,请确保调整外包装引号以确保交替使用单引号 (') 和双引号 (") 或转义引号- 参见
  • 对于公式,= 应该是文本的一部分
  • 要连接文本部分和变量引用,请使用 + 符号
  • 您的 IMPORTRANGE 公式可能 return 空行,每次设置新公式时都必须查询下一个空闲行。
  • 对此有用的方法是 getNextDataCell()

样本:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var limit = ss.getSheetByName('Master Table Projects').getRange("T2").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
  for (var r=2; r<=limit; r++) { 
    var sa="=Query(IMPORTRANGE('Master Table Projects'!T"+r+',"Impacted Formula!A5:R1000"),"where Col1 is not Null")'; 
    var firstEmptyRow = sheet.getRange("A2").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow()+1;
    sheet.getRange("A" + firstEmptyRow).setValue(sa);
    SpreadsheetApp.flush();
  }
}

备注:

  • 在每一行中使用 setValue() 不是好的做法,为了将来考虑将请求存储在一个数组中,并在退出 for 循环后将所有值都放在一个到传播 sheet 与 setValues()
  • 仔细检查您的公式是否正确(IMPORTRANGE 期望 URL 到 spreadhsheet)

更新

  • 为确保公式不会相互覆盖,您可以实施: sheet.getRange("A" + sheet.getLastRow()+1).setValue(sa);
  • 但是,在您的情况下,导入范围创建的空行不是脚本,尽管查询“其中 Col1 不为空”。
  • 因此,最好将所有查询与 ; 连接起来并将它们设置到同一个单元格中
  • 如果要动态检索sheet 'Master Table Projects'中的最后一行和列T,可以实现

var limit = ss.getSheetByName('Master Table Projects').getRange("T2").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();

然后循环直到limit

样本:

function myFunction2() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var sa="={";
  var limit = ss.getSheetByName('Master Table Projects').getRange("T2").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
  for (var r=2; r<limit; r++) { 
    var sa1="Query(IMPORTRANGE('Master Table Projects'!T"+r+',"Impacted Formula!A5:R1000"),"where Col1 is not Null")';
    sa=sa+sa1+";";
  }
  sa = sa.slice(0,-1) +"}";
  sheet.getRange("A2").setValue(sa);
}