实例需求:
- A列为待处理数据,日期有多种格式
- 单个日期:6.16
- 同月简写时间段:7.7-8,其含为7.7-7.8
- 跨月时间段:5.29-6.2
- 现在需要将A列日期,按照如下规则筛选,并提取开始日期和结束日期,填写在B列和C列
- 时间段(包含起止日期)大于等于5天
- 如果没有符合条件的时间段,B列和C列留空
- 如果有多个符合条件的时间段,提取最后一个,例如A2单元格中,5.15-19和5.29-6.2都符合条件,那么从5.29-6.2中提取起止日期
示例代码如下。
Sub SplitDate()Dim arrDT, arrDate, i As Long, j As LongDim dDate1 As Date, dDate2 As Date, iMth As LongConst DT_FORMAT = "yyyy-mm-dd"For i = 2 To Cells(Rows.Count, 1).End(xlUp).RowarrDT = Split(Cells(i, 1), ",")For j = UBound(arrDT) To 0 Step -1arrDate = Split(Replace(Replace(arrDT(j), "-", "|"), ".", "-"), "|")If UBound(arrDate) > 0 And IsDate(arrDate(0)) ThendDate1 = CDate(arrDate(0))iMth = Month(dDate1)If InStr(arrDate(1), "-") = 0 ThenarrDate(1) = iMth & "-" & arrDate(1)End IfdDate2 = CDate(arrDate(1))If dDate2 - dDate1 >= 4 ThenCells(i, 2) = Format(dDate1, DT_FORMAT)Cells(i, 3) = Format(dDate2, DT_FORMAT)Exit ForEnd IfEnd IfNextNext
End Sub
【代码解析】
第5~23行代码循环遍历A列单元格处理数据。
第6行代码将原日期使用逗号拆分为单个时间段。
第7~22行代码倒序处理拆分后的时间段。
第8行代码将数据段再次拆分。首先将减号替换为竖线,然后将小数点替换为减号,最后使用数据作为分割符拆分为起止日期。多次替换的目的是为了将起止日期转换为y-m
的格式,以便于后续处理。
第9行代码中UBound(arrDate) > 0
说明时间段包含两个日期,否则为单日期。
第10行代码中将拆分后的开始日期字符串转换为日期数据,年份将使用当前日历年,例如:Cdate("5-2")
的结果为2024/5/2
。
注意:本示例代码并不适用于计算跨年的日期间隔,例如12.30-1.2
第11行代码获取开始日期的月份。
第12行代码判断结束日期字符串中是否包含减号,如果不包含说明是简写格式,第13行在日期之前添加将添加月份和减号。
第15行代码将结束日期字符串转换为日期数据。
第16行代码判断日期间隔是否满足要求。
如果满足要求,第17~18行代码将开始日期和结束日期分别写入B列和C列。
第19行代码退出For循环。