问题描述
我是 Excel 宏的新手,所以我正在寻找一些帮助来创建一个宏,这将允许我连接包含以下格式详细信息的 Excel 工作表的列中的值。
我需要以以下格式呈现数据
我曾尝试在几个在线论坛上搜索解决方案,甚至尝试使用 concatenate、if 和 Isblank 进行不同的函数组合,但我无法获得所需的结果。我提前道歉,以防解决方案是我可能忽略的非常简单的事情,但自过去几天以来我一直在绞尽脑汁解决这个问题,我希望我能在这个论坛上找到我的问题的解决方案。任何帮助和指导将不胜感激。
提前致谢。
解决方法
这是在答案之后,但问题很有趣。这是一个没有帮助的公式:
=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},SUBSTITUTE(INDEX( data,2),"") ),uDates,TRANSPOSE(UNIQUE(dateCol)),CTA,SUBSTITUTE(UNIQUE(TRANSPOSE(IF(dateCol=uDates,INDEX(table,"")),TRUE),""),cStr,LET( m,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 ),L ),"" ) ),TRANSPOSE(uDates),cStr ) )
输入 A1:B11 放置在 数据 中的位置。是的,这可以简化,因为它将两个解决方案拼接在一起,但由于答案已经得到确认并且已经有一个干净的非 VBA 解决方案,最好让所有部分都暴露出来。
,我认为下面的程序会满足您的期望。请尝试。
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,0)),0)-1)),TEXTJOIN(" ",MAX((B:B<>"")*ROW(B:B)))))
它使用 index 来获取从日期匹配到下一个日期(减去 1)的范围的开始,以及最后一个范围的错误处理,它在 B 列中查找最后一个非空行。>
当然,您在引用范围时需要引用正确的工作表。还建议缩小范围以获得更好的性能。