Количество дней в нескольких периодах, минус любое перекрытие - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь рассчитать дни между списком дат начала и окончания минус любое совпадение.

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: 05/01/2018

Это должно составить 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 голосов
/ 04 сентября 2018

Учитывая ваше определение времени ожидания, не считая первого дня работы, я думаю, все, что вам нужно сделать, - это изменить свой UDF так, чтобы вычесть уникальное число дат начала (и я, вероятно, переименовал бы UDF поскольку это на самом деле не UniqueDayCount):

EDIT

Исходя из ваших комментариев ниже, я изменил алгоритм. Я использую объект 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...