【问题标题】:Merge values in multiple columns into one将多列中的值合并为一列
【发布时间】:2019-02-08 06:17:16
【问题描述】:

我有如下数据结构:



正如您在 J 列 中看到的,我正在尝试将列 A & C & E 中的数据合并到一列中> & G

我正在使用这个公式:

=IF(ROW()<=COUNTA($A:$A);INDEX($A:$C;ROW();COLUMN(A1));INDEX($A:$C;ROW()-COUNTA($A:$A)+1;COLUMN(C1)))

如您所见,我得到了列 K 中的值。目前,此公式仅合并两列。 如何修改它以合并所有四列?


以及如何仅从 第 5 行 开始获取这些值?
列高会不断变化:有时A列有10个值,有时有2个值。


可以接受任何 excel 公式或任何 VBA 代码。

【问题讨论】:

  • “合并”是什么意思?是否在行上获得第一个非空结果(a、c、e 和 g 列)?

标签: vba excel excel-formula


【解决方案1】:

有一种相当标准的方法可以从一列而不是多列中检索唯一值。要实现从多列中检索,您需要将多个公式堆叠在一起,并将处理传递给连续列,以排除较早的公式错误。

      

J5 中的数组公式¹是,

=IFERROR(INDEX($A$5:$A$99, MATCH(0, IF(LEN($A$5:$A$99), COUNTIF(J$4:J4, $A$5:$A$99), 1), 0)),
 IFERROR(INDEX($C$5:$C$99, MATCH(0, IF(LEN($C$5:$C$99), COUNTIF(J$4:J4, $C$5:$C$99), 1), 0)),
 IFERROR(INDEX($E$5:$E$99, MATCH(0, IF(LEN($E$5:$E$99), COUNTIF(J$4:J4, $E$5:$E$99), 1), 0)),
 IFERROR(INDEX($G$5:$G$99, MATCH(0, IF(LEN($G$5:$G$99), COUNTIF(J$4:J4, $G$5:$G$99), 1), 0)),
 ""))))

我只包含了 A、C、E 和 G 列,因为您的示例数据仅显示 B、D、F 和 H 列中的重复项。


¹ 数组公式需要使用 Ctrl+Shift+Enter↵ 完成。如果输入正确,Excel 会将公式用大括号括起来(例如 {})。你不用自己输入大括号。一旦正确输入第一个单元格,它们就可以像任何其他公式一样被填充或向下或向右复制。尝试将全列引用减少到更接近代表实际数据范围的范围。数组公式以对数方式消耗计算周期,因此最好将引用范围缩小到最小值。请参阅Guidelines and examples of array formulas 了解更多信息。

【讨论】:

  • 这完美地回答了这个问题。但是,如果您有重叠列表并希望保留顺序,您可以使用我在此处概述的方法合并列对并合并结果 - 我承认有点麻烦。 stackoverflow.com/questions/29995903/…
  • 这是一个漂亮的公式。关于您关于多列困难的观点,我继续添加了一个答案,该答案首先构建一个列,然后在其上运行通常的公式。您将帮助列换成嵌套较少的公式。
【解决方案2】:

这个答案是另一种思考可用于此类任务的公式的方式。 @Jeeped 指出很难在多列中找到唯一值。然后我的第一步是创建一个列。

如果您可以使用辅助列,那么这些公式可能比已经提议的嵌套 IFERROR 更容易维护。尽管乍一看,它们同样难以理解。另一个好处是,如果涉及的列数增加,它可以很好地扩展。

可以使用CHOOSE 和一些INDEX 数学来构建一组分隔列的单列数组。诀窍是CHOOSE 将在给定数组作为选择参数时并排连接不连续的范围。如果这以相同大小的列开始,则可以使用除法和 mod 数学将其转换为单个列。

范围图片显示了四组数据,其中重复项以红色显示。

F2:F31中的

公式是一个数组公式。这是将所有列组合成一个数组,然后再组合成一个列。我乱序选择列只是为了强调它正在处理一个不连续的范围。

=INDEX(CHOOSE({1,2,3,4}, A2:A7,C2:C7,B2:B7,D2:D7), MOD(ROW(1:30)-1, ROWS(A2:A7))+1,INT((ROW(1:30)-1)/ROWS(A2:A7))+1)

H2 中并复制下来的数组公式是唯一值的标准公式。一个例外是,我没有像往常一样避免空白,而是避免使用 0 值。

=IFERROR(INDEX(F2:F31,MATCH(0,IF(F2:F31=0,1,COUNTIF($H$1:H1,F2:F31)),0)),"")

关于这种方法的其他几个方面:

  • CHOOSE 中,我使用的是{1,2,3,4}。这可以替换为 TRANSPOSE(ROWS(1:4)) 或您拥有的任何数量的列。
  • 在 2 个位置还有一个 ROWS(A2:A7),这可能只是 2:71:6 或用于列大小的任何大小。我使用了其中一个数据范围,以便简化着色并强调它需要与块的大小相匹配。
  • ROW(1:30) 用于表示要收集的总项目数。它真的只需要1:24,因为有6*4 项目,但我在测试时把它变大了。

这种方法肯定有几个缺点,但保留在工具箱中可能是一个不错的技巧。永远不知道什么时候你可能想从不连续的范围中创建一列。最大的缺点是数据列都需要相同大小(当然还有辅助列)。

【讨论】:

  • 我试过这个,但我什至无法模拟你的结果。是不是因为我的分隔符是 ; 而不是 "," 会影响 choose 功能?但是,我用分号替换了所有逗号。但没有成功。
  • @Mpondomise,抱歉,甚至没有注意到上面的不同分隔符。 CHOOSE 应该采用 row 数组。如果要删除那里的分隔符,只需使用TRANPOSE(ROW(1:4)) 而不是{1,2,3,4},它将返回相同的数组。 ROW() 通常返回一个列数组,TRANSPOSE 翻转它。
  • 您能否修改您的答案,以便我明白您的意思?我可能会以错误的方式重现它。谢谢
  • 公式为:=INDEX(CHOOSE(TRANSPOSE(ROW(1:4)), A2:A7,C2:C7,B2:B7,D2:D7), MOD(ROW(1:30)-1, ROWS(A2:A7))+1,INT((ROW(1:30)-1)/ROWS(A2:A7))+1)。我相信现在将所有逗号都翻转为分号是安全的。
【解决方案3】:

此代码将满足您的要求:

Sub MoveData()

START_ROW = 5
START_COL = 1
STEP_COL = 2
OUTPUT_ROW = 5
OUTPUT_COL = 10

Row = START_ROW
Col = START_COL
Out_Row = OUTPUT_ROW
While Col < OUTPUT_COL
    While Cells(Row, Col).Value <> ""
        Cells(Out_Row, OUTPUT_COL).Value = Cells(Row, Col).Value
        Out_Row = Out_Row + 1
        Row = Row + 1
    Wend
    Row = START_ROW
    Col = Col + STEP_COL
Wend

结束子

【讨论】:

  • 您的公式效果很好!但这是一个小问题:它在碰到非空单元格后不会停止寻找值。也就是说:如果其中一列中有一个空白单元格,并且在该空白单元格之后,有一些数据,它不包括该空白单元格之后的那些数据。但是 Jeeped 的答案确实包括任何包含数据的单元格。您能否修改它并将您的答案放在我为此创建的new question 中。
【解决方案4】:

认为你们让这件事变得复杂了。只需将数据范围拉入 power query ,选择所有列并取消它们,这会将所有数据放入单个列中

【讨论】:

    猜你喜欢
    • 2020-05-01
    • 1970-01-01
    • 2016-01-10
    • 2022-11-17
    • 2020-04-14
    • 2011-02-27
    相关资源
    最近更新 更多