如果行中有值,则连接列中的单元格

Concatenate cells in a column if there is a value in the row

我是 Excel 宏的新手,所以我正在寻找一些帮助来创建一个宏,它允许我连接 excel sheet 包含以下格式的详细信息。

我需要以下面的格式呈现数据

我尝试在几个在线论坛上搜索解决方案,甚至尝试使用 concatenate, if 和 Isblank 的不同功能组合,但我无法获得所需的结果。我提前道歉,如果解决方案非常简单,我可能会忽略,但自从最近几天以来我一直在绞尽脑汁解决这个问题,我希望我能在这个论坛上找到解决我的问题的方法。非常感谢任何帮助和指导。

提前致谢。

我认为下面的过程会达到您的预期。请尝试。

Sub ConcatEntries()
    ' 299

    Const TitleClm      As String = "A"     ' change to suit
    Const ItemClm       As String = "B"     ' change to suit
    Const FirstDataRow  As Long = 2         ' change to suit
    
    Dim Spike()         As String           ' for output
    Dim i               As Long             ' index of Spike()
    Dim Concat          As String           ' concatenation
    Dim R               As Long             ' loop counter: sheet rows
    
    Application.ScreenUpdating = False
    ' the number of Spike elements should be much larger than what you ever expect
    ReDim Spike(1 To 100)                   ' prepare for results
    i = UBound(Spike)
    With Worksheets("Sheet1")               ' change to suit
        ' loop from last used cell to FirstDataRow
        For R = (.Cells(.Rows.Count, ItemClm).End(xlUp).Row) To FirstDataRow Step -1
            i = i - 1
            Spike(i) = .Cells(R, ItemClm).Value & " "
            If Len(.Cells(R, TitleClm).Value) Then
                .Cells(R, ItemClm).Value = Trim(Join(Spike))
                ReDim Spike(UBound(Spike))
                i = UBound(Spike)
            Else
                .Rows(R).Delete
            End If
        Next R
    End With
    Application.ScreenUpdating = True
End Sub

请注意代码顶部的三个常量。您可以调整它们的值以满足工作表中的设置。您还可以在代码中更改正在执行操作的工作表的名称。我的代码引用了“Sheet1”。

在第一列中使用 =FILTER(A:A,A:A<>"") 为日期创建溢出范围。 在它旁边的列中使用=IFERROR(TEXTJOIN(" ",1,INDEX(B:B,MATCH(C1,A:A,0)):INDEX(B:B,MATCH(1,(A:A<>"")*(ROW(A:A)>MATCH(C1,A:A,0)),0)-1)),TEXTJOIN(" ",1,INDEX(B:B,MATCH(C1,A:A,0)):INDEX(B:B,MAX((B:B<>"")*ROW(B:B))))) 它使用索引获取从日期匹配到下一个日期(负 1)的范围的开始,并使用最后一个范围的错误处理,它在 B 列中查找最后一个非空行。

当然你需要在引用范围时引用正确的sheet。还建议缩小范围以获得更好的性能。

这是答案之后的问题,但是这个问题很有趣。这是一个没有帮助器的公式:

=LET( data, A1:B11,
   dates, INDEX(data, , 1),
     rseq, SEQUENCE( ROWS( data ) ),
     nb, NOT(ISBLANK(dates)),
     dateCol, INDEX(FILTER(dates,nb),MMULT(--( rseq >= TRANSPOSE( rseq ) ), --nb )),
   table, CHOOSE( {1,2}, dateCol, SUBSTITUTE(INDEX( data, , 2),0,"") ),
   uDates, TRANSPOSE(UNIQUE(dateCol)),
   CTA, SUBSTITUTE(UNIQUE(TRANSPOSE(IF(dateCol=uDates,INDEX(table, , 2),"")),TRUE),0,""),
   cStr, LET( m, CTA,
               rSeq, SEQUENCE( ROWS(m) ),
               L, MMULT( LEN(m)--(m<>""), SIGN( SEQUENCE( COLUMNS(m) ) ) ) - 1,
               i, MMULT(--( TRANSPOSE( rSeq ) < rSeq ), L ) + rSeq,
              IFERROR( MID( TEXTJOIN( " ", TRUE, m ), i, L ), "" ) ),
   CHOOSE( {1,2}, TRANSPOSE(uDates), cStr )  )

其中输入 A1:B11 放在 data 中。是的,这可以简化,因为它是将两个解决方案拼接在一起,但是由于答案已经确定并且已经有一个干净的非VBA解决方案,所以最好将所有部分都暴露出来。