多个期间的天数,减去任何重叠

时间:2018-09-04 10:04:08

标签: excel vba excel-formula

我正在尝试计算开始日期和结束日期之间的天数减去任何重叠部分。

Date A              Date B      Days taken  
01/01/2018          01/01/2018  0   
01/01/2018          05/01/2018  4   
01/01/2018          10/01/2018  9    
12/01/2018          15/01/2018  3   

Total: 16   
Total Days minus overlap: 12

完成该项目所需的总天数为16天。一旦我们去除了重叠的4天,我们剩下12天。

这是一个简单的示例。我想计算出6-12个月内的总天数减去重叠部分。

最初,我尝试将数组公式与宏结合使用以对数据进行排序。它似乎可以解决重叠问题,但会产生错误的结果。

=SUMPRODUCT(--($F$4:$F$234=R4),--($D$4:$D$234>$C$5:$C$235),--($C$5:$C$235<>""),($D$4:$D$234-$C$5:$C$235)-($D$4:$D$234-$D$5:$D$235)*($D$4:$D$234>$D$5:$D$235)*($D$5:$D$235<>0)) 

然后我尝试了一些VBA(我的知识很基础)。计算出日期之间的每个唯一日期。但是,例如,我不希望将日期A包括在内。

日期A:01/01/2018 日期B:2018年5月1日

这应该总共4天。

Option Explicit
Function UniqueDayCount(rStart As Range, rEnd As Range) As Long
    Dim col As Collection
    Dim vStart As Variant, vEnd As Variant
    Dim I As Long, J As Long

vStart = rStart
vEnd = rEnd

On Error Resume Next
Set col = New Collection
For I = 1 To UBound(vStart)
    For J = vStart(I, 1) To vEnd(I, 1)
        col.Add Item:=J, Key:=CStr(J)
    Next J
Next I
On Error GoTo 0

UniqueDayCount = col.Count

End Function

1 个答案:

答案 0 :(得分:0)

鉴于您对停留时间的定义(不包括工作的第一天),我认为您需要做的就是修改UDF,以减去开始日期的唯一计数(而且我可能会重命名UDF因为它实际上不是UniqueDayCount):

编辑

根据您在下面的评论,我更改了算法。我正在使用Dictionary对象,因为它更灵活,并且创建了唯一日期和重叠计数的列表。由于不包括任何流程的开始日期,因此我们排除了该流程的第一个日期。看来可以给您期望的结果

请注意,我使用了早期绑定作为参考,但是,如果要分发它,您可能需要将其转换为后期绑定。

Option Explicit
'Set Reference to Microsoft Scripting Runtime
'  or use Late Binding
Function UniqueDayCount(rStart As Range, rEnd As Range) As Long
    Dim dDTS As Dictionary
    Dim vStart As Variant, vEnd As Variant
    Dim I As Long, J As Long, V As Variant
    Dim lDaysTot As Long

vStart = rStart
vEnd = rEnd

Set dDTS = New Dictionary
For I = 1 To UBound(vStart, 1)
    If Not IsDate(vStart(I, 1)) Then Exit For
    For J = vStart(I, 1) To vEnd(I, 1)
        If Not J = vStart(I, 1) Then
        If Not dDTS.exists(J) Then
            dDTS.Add Key:=J, Item:=0
        Else
            dDTS(J) = dDTS(J) + 1
        End If
        End If
    Next J
    lDaysTot = lDaysTot + vEnd(I, 1) - vStart(I, 1)
Next I

I = 0
For Each V In dDTS.keys
    I = I + dDTS(V)
Next V

UniqueDayCount = lDaysTot - I

End Function