Google 表格 - 使用 arrayformula 将多行数据合并为单行或单元格

时间:2021-05-19 23:13:07

标签: google-sheets array-formulas

我从我们的学生信息系统导出,每个学生都有多行,具体取决于家长输入的联系电子邮件地址的数量。

Sample data from the export

我想将所有联系地址合并到同一行的多列中,甚至全部合并到同一个单元格中也可以。经过大量搜索多次尝试后,我可以使用 =join(char(10), filter(extract.csv!G:G,extract.csv!A:A=J2)) 并手动填写公式下。 (虽然我宁愿不首先获得回报,而是在结果之间获得回报,但如果不可能,我可以接受它。)

我想要的是将它放在一个数组公式中,这样我就不必复制它,但我不知道如何调整对 J 行的最后一个引用。如果我保持原样,它会在每个单元格中放置相同的值以匹配 J2 数据。

with arrayformula

或者有其他方法可以得到我想要的东西吗?感谢您的帮助...我只是一个喜欢编码和自动化事情的老师,我一边学习一边学习零碎的东西!

3 个答案:

答案 0 :(得分:0)

这可能值得发布,因为在我意识到您为我们发布了一张表格之前,我只是创建了一些我自己的代表性数据(谢谢)。

=ArrayFormula(if(mod(sequence(countunique(A2:A),D2,0),D2)<countif(A2:A,unique(filter(A2:A,A2:A<>""))),
vlookup(vlookup(unique(filter(A2:A,A2:A<>"")),{A2:A,row(A2:A)},2,false)+MOD(sequence(COUNTUNIQUE(A2:A),D2,0),D2),{row(A2:A),B2:B},2,false),))

D2 是一个辅助单元格,其中包含每个学生的最大联系人数量 - 无论是通过公式还是手动输入。

enter image description here

我会看看你的数据,但我不太清楚是否应该先显示学生自己的电子邮件,然后是家长联系人?我有点希望没有填充辅助电子邮件,因为它会使事情进一步复杂化。

以下是您的数据的外观 - 相同的公式,但列略有不同:

=ArrayFormula(if(mod(sequence(countunique(A2:A),I2,0),I2)<countif(A2:A,unique(filter(A2:A,A2:A<>""))), vlookup(vlookup(unique(filter(A2:A,A2:A<>"")),{A2:A,row(A2:A)},2,false)+MOD(sequence(COUNTUNIQUE(A2:A),I2,0),I2),{row(A2:A),G2:G},2,false),))

其中 I2 当前设置为 5 - 可以从

=max(countif(A2:A,unique(filter(A2:A,A2:A<>""))))

如果你想让它更有活力。

enter image description here

问题是我目前想不出一种简单的方法来删除第一位学生的空白电子邮件地址(我有点惊讶下载中包含空白地址 - 数据质量?)。

答案 1 :(得分:0)

我添加了一个新工作表(“Erik 帮助”),它是您的“AutoFillData”工作表的副本。在我的工作表中,我清除了 AD 列,然后将以下公式放入 AD1:

`=ArrayFormula({"联系电子邮件";IF(J2:J="",,IFERROR(VLOOKUP(J2:J,{UNIQUE(FILTER(extract.csv!A2:A,extract.csv!A2: A<>"")),SUBSTITUTE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(IF(ISERROR(VLOOKUP(UNIQUE(FILTER(extract.csv!A2:A,extract.csv!A2:A<>""))& ""&TRANSPOSE(UNIQUE(FILTER("|"&{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G},{extract.csv!E2:E; extract.csv!F2:F;extract.csv!G2:G}<>"")))&"",extract.csv!A2:A&"|"&extract.csv!E2:E&"| "&extract.csv!F2:F&"|"&extract.csv!G2:G,1,FALSE)),,TRANSPOSE(UNIQUE(FILTER({extract.csv!E2:E;extract.csv!F2:F;extract) .csv!G2:G},{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G}<>"")))))," ",COUNTA(UNIQUE(过滤器({extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G},{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2 :G}<>"")))))," ",CHAR(10))},2,FALSE)))})'

完全解释这个公式需要很长时间。

一般来说,它的作用是形成一个虚拟的 2D 网格(用户从未见过),其中学生 ID 的唯一列表在左侧垂直运行,所有电子邮件地址的唯一列表(带有附加的轮廓线)在水平方向上运行顶端。如果在由 studentID|email1|email2|email3 混搭形成的任何字符串中找到学生 ID 和该电子邮件地址的组合,则该电子邮件地址填充虚拟网格;如果不是,则该网格的横截面为空。

这会留下一个网格,其中所有可能的电子邮件都在每个唯一 ID 对面的某处水平填充,而不是在单独的行上。

最后,QUERY 函数中的一个怪癖用于组合每行的所有非空条目。也就是说,QUERY 函数可以有任意数量的标题,而不仅仅是 0 或 1。通过让 QUERY 请求网格的每个电子邮件部分作为标题,然后TRIM排除空格,我们将每个学生 ID 的所有电子邮件汇总在一起。

然后只需将剩余的空格替换为换行符即可,即 CHAR(10)。

答案 2 :(得分:0)

以下是一些解决方案(分别在 kishkin 2 中的 kishkin 1 表中)。

单行中的电子邮件:

=ARRAYFORMULA(
  IF(
    J2:J = "",,
      TRIM(
        SPLIT(
          VLOOKUP(
            J2:J,
            SPLIT(
              TRANSPOSE(QUERY(
                QUERY(
                  FILTER({extract.csv!A:A & "♥", extract.csv!G:G & "♦"}, extract.csv!A:A <> ""),
                  "SELECT MAX(Col2)
                   GROUP BY Col2
                   PIVOT Col1",
                  1
                ),, COUNTA(extract.csv!A:A)
              )),
              "♥"
            ),
            2,
          ),
          "♦"
        )
      )
  )
)

enter image description here

单个单元格中的电子邮件:

={
  "CONTACT EMAILS";
  ARRAYFORMULA(
    IF(
      J2:J = "",,
        REGEXREPLACE(
          VLOOKUP(
            J2:J,
            SPLIT(
              TRANSPOSE(QUERY(
                QUERY(
                  FILTER({extract.csv!A:A & "♥", extract.csv!G:G & CHAR(10)}, extract.csv!A:A <> ""),
                  "SELECT MAX(Col2)
                   GROUP BY Col2
                   PIVOT Col1",
                  1
                ),, COUNTA(extract.csv!A:A)
              )),
              "♥"
            ),
            2,
          ),
          "(?m)^\s+|\s+$",
        )
    )
  )
}

enter image description here