Я буду использовать стандартный подход для нахождения перекрытия между двумя датами и разделю задачу на три части, как в моем ответе на этот недавний вопрос .
(1) Первая часть находит совпадение между диапазоном дат пользователя и одним или несколькими периодами пересмотра в целых месяцах и нуждается в формуле массива. Я решил использовать функцию Datedif 1 , чтобы получить разницу в месяцах между началом и концом перекрытий. Если перекрытия нет, дата начала, введенная в Datedif, будет после даты окончания, и она возвратит ошибку, которая может быть перехвачена Iferror. Если даты пользователя начинаются в A2 и B2, это дает в C2:
=SUM(IFERROR((DATEDIF(IF(K$2:K$8>A2,K$2:K$8,A2),IF(L$2:L$8<B2,L$2:L$8,B2),"m")+1)*M$2:M$8,0))
, который должен быть введен как формула массива с помощью Ctrl Shift Введите
Приведенный выше результат включает первый и последний месяцы, введенные пользователем, даже если они являются неполными месяцами. Затем необходимо вычесть все пропущенные дни в первый и последний месяцы.
(2) Недостающие дни в первом месяце в виде доли от числа дней в этом месяце в D2:
=SUMIFS($M$2:$M$8,$K$2:$K$8,"<="&A2,$L$2:$L$8,">="&A2)*(A2-EOMONTH(A2,-1)-1)/(EOMONTH(A2,0)-EOMONTH(A2,-1))
Замечание OP, это также можно было сделать с помощью sumproduct, vlookup или index / match.
(3) Пропущенные дни в прошлом месяце как доля дней в этом месяце в E2:
=SUMIFS($M$2:$M$8,$K$2:$K$8,"<="&B2,$L$2:$L$8,">="&B2)*(EOMONTH(B2,0)-B2)/(EOMONTH(B2,0)-EOMONTH(B2,-1))
Всего всего (1) - (2) - (3) или
=C2-D2-E2
Я поместил результаты двух примеров ОП для сравнения в H2 и H3: мои результаты согласуются с ними в первых 3 значимых цифрах.
n*3.97*113%
(n*2.03*113%)+(n*5.65*119)
Во всех случаях я установил n = 1 и проигнорировал тот факт, что ставка указана в процентах.
Это показывает, как результаты будут рассчитываться вручную:
1 Плюсы использования Datedif:
(1) Работает через границы года в отличие от просто использования функции месяца.
(2) Удобно работает с Iferror для определения несовпадающих диапазонов дат.
Минусы использования Datedif:
(1) Это недокументированная функция, которая может быть отозвана в будущем.
(2) В данном конкретном случае все вычисления дат выполняются в одном и том же году, поэтому можно использовать месяц.