如何动态分组数组文字中的多个制表符范围(通过使用通配符)?

How do I group multiple tab ranges in array literal dynamically(by using wildcard)?

我有一个包含多个标签的电子表格,例如

“总结”
“第 1 周”
“第 2 周”
“积压”

周数不固定。以后我可能会随着时间的推移添加更多的标签,例如
“第 3 周”
“第 4 周”
...

在“摘要”选项卡中,我想列出所有“周”选项卡中 A 列(删除标题)的所有数据。 目前,我必须在查询范围参数中手动添加“Week”的所有选项卡名称,例如

=query({'Week 1'!A2:A; 'Week 2'!A2:A}, "select *")

但我想在以后添加更多标签时自动创建它,方法如下:

=query({"Week *"}!A2:A, "select *")

我该怎么做?

解释:

您可以使用 Google Apps Script 来完成此任务。

以下脚本:

  • 获取包含名称的传播sheet 文件的所有 sheet Week,
  • 遍历这些 sheet 并构造一个字符串对象,它可以是 在查询公式中使用,
  • 将生成的公式设置到 Summary sheet 的单元格 A1。请随意修改下面代码中的A1

我还添加了一个功能,可以在 sheet 之上创建一个 宏按钮 ,因此您可以从 sheet 本身使用此功能(请参阅下面的说明)。


解决方案:

请按照说明 (gif) 使用以下代码:

function getQuery() {
  const ss = SpreadsheetApp.getActive();
  const summary_sheet = ss.getSheetByName('Summary');
  const sheet_names = ss.getSheets().filter(fsh=>fsh.getName().includes("Week")).map(sh=>sh.getName())
  var weeks = [];
  sheet_names.forEach(wk => 
                      weeks.push(`'${wk}'!A2:A`)
                     )
  summary_sheet.getRange('A1').setFormula(`=query({${weeks.join(";")}}, "select *")`)

}

function onOpen() {
  SpreadsheetApp.getUi()
  .createMenu('Macros')
  .addItem('Get Query', 'getQuery')
  .addToUi();
}

说明:

在脚本编辑器中保存代码片段后,刷新 sheet/browser。


参考文献:

Google Apps Script 图书馆:

JavaScript 图书馆:

一种选择是完全摆脱 QUERY 公式并改用 Apps 脚本 Custom Function

首先,通过选择工具 > 脚本编辑器 打开绑定脚本,并将以下函数复制到脚本中:

function SUMMARIZE_WEEKTABS() {
  const ss = SpreadsheetApp.getActive();
  const weekSheets = ss.getSheets().filter(sheet => sheet.getName().startsWith("Week "));
  const summarySheet = ss.getSheetByName("Summary");
  let weekData = weekSheets.map(weekSheet => {
    return weekSheet.getRange(2, 1, weekSheet.getLastRow()).getValues().flat();    
  });
  weekData = weekData[0].map((_, colIndex) => weekData.map(row => row[colIndex]));
  return weekData;
}

函数SUMMARIZE_TABS returns 从名称以"Week " 开头的所有工作表中A 列的数据。一旦在您的脚本中定义了它,您就可以像使用任何工作表 built-in 函数一样使用它。例如,参见:

更新:

如果您希望所有数据都写入同一列,请改用:

function SUMMARIZE_WEEKTABS() {
  const ss = SpreadsheetApp.getActive();
  const weekSheets = ss.getSheets().filter(sheet => sheet.getName().startsWith("Week "));
  const summarySheet = ss.getSheetByName("Summary");
  let weekData = weekSheets.map(weekSheet => {
    return weekSheet.getRange(2, 1, weekSheet.getLastRow() - 1).getValues();    
  }).flat();
  return weekData;
}

参考: