如何总结日期?
例如:我有很多约会
A1: 1/2/2023
A2: 2/2/2023
A3: 3/2/2023
A4: 4/2/2023
A5: 6/2/2023
A6: 7/2/2023
A7: 8/2/2023
A8: 10/2/2023
A9: 12/2/2023
A10: 13/2/2023
A11: 16/2/2023
A12: 17/2/2023
A13: 20/2/2023
A14: 25/2/2023
VBA后如何设置结果显示如下?
1/2/2023-4/2/2023, 6/2/2023-8/2/2023, 10/2/2023, 12/2/2023-13/2/2023, 16/2/2023-17/2/2023, 20/2/2023, 25/2/2023
答案1
答案2
在我看来,为这个问题编写一个 UDF 比发明一个可行但难以理解和编辑的长公式要容易一些。
该功能可以非常简单,例如:
Function getListAsString(aData As Range) As String
Dim aTemp As Variant
aTemp = getSortedValuesFromRange(aData)
getListAsString = getListOfDateRngsAsString(aTemp)
End Function
由于源数据可能未排序,函数的第一行将作为参数传递的范围转换为已排序的数组。
第二行分析这个值数组并形成结果字符串。
getSortedValuesFromRange()
最终结果getListOfDateRngsAsString()
将取决于您对 VBA 编程的准备程度和您的聪明才智。我的代码版本如下所示:
Private Function getSortedValuesFromRange(aData As Range) As Variant
Dim oCell As Range
Dim aResult As Variant
Dim vDate As Double, sFormattedDate As String
aResult = Array()
For Each oCell In aData.Cells
sFormattedDate = Trim(oCell.Text)
If sFormattedDate <> vbNullString Then
vDate = oCell.value
Call AddOrReplace(vDate, sFormattedDate, aResult)
End If
Next oCell
getSortedValuesFromRange = aResult
End Function
Private Function getListOfDateRngsAsString(aData As Variant) As String
Dim aResult As Variant, sResult As Variant
Dim i As Long, j As Long
Dim prevDate As Variant, sPrevDate As String
If UBound(aData) < LBound(aData) Then Exit Function
ReDim aResult(0 To UBound(aData), 1 To 2)
aResult(0, 1) = LBound(aData)
aResult(0, 2) = LBound(aData)
j = 0
For i = LBound(aData) + 1 To UBound(aData)
If aData(i)(0) - aData(aResult(j, 2))(0) > 1 Then
j = j + 1
aResult(j, 1) = i
aResult(j, 2) = i
Else
aResult(j, 2) = i
End If
Next i
sResult = aData(aResult(0, 1))(1)
If aResult(0, 1) <> aResult(0, 2) Then sResult = sResult & "-" & aData(aResult(0, 2))(1)
For i = 1 To j
sResult = sResult & ", "
If aResult(i, 1) = aResult(i, 2) Then
sResult = sResult & aData(aResult(i, 1))(1)
Else
sResult = sResult & aData(aResult(i, 1))(1) & "-" & aData(aResult(i, 2))(1)
End If
Next i
getListOfDateRngsAsString = sResult
End Function
Private Sub AddOrReplace(key, value, aData)
Dim l&, r&, m&, N&, i&
l = LBound(aData)
r = UBound(aData) + 1
N = r
While (l < r)
m = l + Int((r - l) / 2)
If aData(m)(0) < key Then l = m + 1 Else r = m
Wend
If r = N Then
ReDim Preserve aData(0 To N)
aData(N) = Array(key, value)
ElseIf aData(r)(0) = key Then
aData(r)(1) = value
Else
ReDim Preserve aData(0 To N)
For i = N - 1 To r Step -1
aData(i + 1) = aData(i)
Next i
aData(r) = Array(key, value)
End If
End Sub
在单元格中写入=getListAsString(A1:A30)
并获取结果
1/2/2023-4/2/2023, 6/2/2023-8/2/2023, 10/2/2023, 12/2/2023-13/2/2023, 16/2/2023-17/2/2023, 20/2/2023, 25/2/2023