【问题标题】:Query and transpose data in Google Sheets在 Google 表格中查询和转置数据
【发布时间】:2020-06-05 13:40:21
【问题描述】:

我有一个如下所示的表格:

我想每年创建一行而不是一列,看起来像这样:

您可以在this google sheets获取样本数据。

我认为这将是使用查询甚至制作自定义函数的东西,但是我无法弄清楚如何去做(或至少接近)。有什么建议吗?

【问题讨论】:

  • 数据透视表....
  • 我无法真正看到数据透视表会发生这种情况。无论如何,我需要它在一个公式中,因为它会在不同的数据集上重复发生。
  • 我并不是说您使用电子表格中的数据透视表。我只是说这是一个数据透视表的问题。对对象也是如此,在这种情况下,对数组对象也是如此。保留所有创建的数组对象的列表,并使用它来创建最终输出..

标签: google-apps-script google-sheets google-sheets-formula google-sheets-query


【解决方案1】:

我相信你的目标如下。

  • 您希望使用内置函数或自定义函数实现问题中图片所示表格的转换。

对于这个,这个答案怎么样?在这个答案中,我想建议使用自定义功能。每个示例脚本都从单元格A2:H6 中检索源值。请注意这一点。

模式一:

在此模式中,使用自定义函数将值放入电子表格。请将以下脚本复制并粘贴到电子表格的脚本编辑器中。在这种情况下,请将自定义函数放到 =myFunction1() 这样的单元格中。

示例脚本:

function myFunction1() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const values = sheet.getRange("A2:H6").getValues();
  const headers = values.shift().splice(2);
  const res = values.reduce((ar, r) => {
    let temp = r.splice(0, 2);
    for (let i = 0; i < headers.length; i += 2) {
      let h = temp;
      ar.push(h.concat(headers[i].split("Revenues")[1].trim(), r.splice(0, 2)));
    }
    return ar;
  }, []);
  res.unshift(["Company", "Company code", "Year", "Revenues", "Costs"]);
  return res;
}

模式 2:

请将以下脚本复制并粘贴到电子表格的脚本编辑器中。当我看到您的示例电子表格时,转换表中的“收入”和“成本”列具有原始表的单元格坐标。因此,在此模式中,您的示例电子表格的目标被复制。但是,自定义函数不能直接放公式。所以在这个模式中,这个脚本不被用作自定义函数。所以为了测试这个,请用脚本编辑器运行它。

示例脚本:

function myFunction2() {
  // Ref: https://stackoverflow.com/a/21231012/7108653
  const columnToLetter = column => {
    let temp,
      letter = "";
    while (column > 0) {
      temp = (column - 1) % 26;
      letter = String.fromCharCode(temp + 65) + letter;
      column = (column - temp - 1) / 26;
    }
    return letter;
  };

  const sheet = SpreadsheetApp.getActiveSheet();
  const values = sheet.getRange("A2:H6").getValues();
  const headers = values.shift().splice(2);
  const res = values.reduce((ar, r, i) => {
    let temp = r.splice(0, 2);
    for (let j = 0; j < headers.length; j += 2) {
      let h = temp;
      const formulas = [`=${columnToLetter(j + 3)}${i + 3}`, `=${columnToLetter(j + 4)}${i + 3}`];
      ar.push(h.concat(headers[j].split("Revenues")[1].trim(), formulas));
    }
    return ar;
  }, []);
  res.unshift(["Company", "Company code", "Year", "Revenues", "Costs"]);
  sheet.getRange(23, 1, res.length, res[0].length).setValues(res);
}
  • 在此脚本中,当您使用脚本编辑器运行myFunction2 的函数时,结果值将来自单元格“A23”。

注意:

  • 如果不想放标题行,请删除res.unshift(["Company", "Company code", "Year", "Revenues", "Costs"]);
  • 请在 V8 中使用这些脚本。

参考资料:

【讨论】:

  • 很好的答案@Tanaike,谢谢。我正试图让它在这里工作:) 我正在尝试第一种模式,我有两个问题:(a) 如果我的收入列有点不同,比如“2019 年的收入”,代码是否保持不变? (b) 如果我有更多列,如“2019 年费用”、“2017 年费用”、“2018 年利润”、“2019 年利润”等,我应该将它们添加到 unshift 行中,对吗?
  • @abutremutante 感谢您的回复。我想回答您的另外 2 个问题。 A1。我的回答是针对你的问题。请注意这一点。因为我只从你的问题中获得了信息。因此,当Revenues 2019 更改为Revenues in 2019 时,Year 的值将变为in 2019。但不会发生错误。在这种情况下,请将split("Revenues")[1].trim()修改为split("Revenues in")[1].trim()
  • @abutremutante A2。在这种情况下,我认为情况与您的问题不同。因此,需要将解决方案视为与您的这个问题不同的情况。我深表歉意,我不能提出在各种情况下使用的脚本。这是因为我的技术不好。我想学习更多。顺便说一句,如果我的回答没有解决您的这个问题,我深表歉意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
相关资源
最近更新 更多