Это может пойти вниз, как ведущий воздушный шарик, и это может быть слишком сложно, но если вы ищете решение VBA, это должно работать для вас.
Добавьте приведенный ниже код в новый модуль в вашемРедактор VBA ...
Public Function CalculateNextAvailableDay(ByVal rngAvailableDays As Range, ByVal dtDate As Date, ByVal lngAvailableDayIndex As Long) As Date
Dim strThisDay As String, tmThisTime As Variant, i As Long, intAvailableDay As Integer, lngRow As Long, dtNextDate As Date, arrNextAvailableDates() As Variant
Dim lngArrayIndex As Long, intNextDateDay As Integer, lngMaxSecondsDiff As Long, lngSecondsDiff As Long, intDateOffset As Integer
Dim lngIndexToRemove As Long, x As Long, bBeenThrough As Boolean
Application.Volatile
' First, build up the range of next available DATES, not DAYS.
For lngRow = 1 To rngAvailableDays.Rows.Count
strThisDay = UCase(Trim(rngAvailableDays.Cells(lngRow, 1)))
tmThisTime = TimeValue(rngAvailableDays.Cells(lngRow, 2).Text)
Select Case strThisDay
Case "SUNDAY"
intAvailableDay = 1
Case "MONDAY"
intAvailableDay = 2
Case "TUESDAY"
intAvailableDay = 3
Case "WEDNESDAY"
intAvailableDay = 4
Case "THURSDAY"
intAvailableDay = 5
Case "FRIDAY"
intAvailableDay = 6
Case "SATURDAY"
intAvailableDay = 7
End Select
dtNextDate = DateValue(Split(CStr(dtDate))(0)) + tmThisTime
intDateOffset = 0
Do While 1 = 1
dtNextDate = DateAdd("d", intDateOffset, dtNextDate)
intNextDateDay = Weekday(dtNextDate)
intDateOffset = 1
If intNextDateDay = intAvailableDay And dtNextDate >= dtDate Then
' This date counts, add it to the list of available next dates.
ReDim Preserve arrNextAvailableDates(lngArrayIndex)
arrNextAvailableDates(lngArrayIndex) = dtNextDate
lngArrayIndex = lngArrayIndex + 1
Exit Do
End If
Loop
Next
' Now find the next available date.
For x = 1 To lngAvailableDayIndex
lngMaxSecondsDiff = 0
bBeenThrough = False
' We have all of the next available dates.
For i = 0 To UBound(arrNextAvailableDates)
If arrNextAvailableDates(i) <> "" Then
lngSecondsDiff = Abs(DateDiff("s", arrNextAvailableDates(i), dtDate))
If lngSecondsDiff < lngMaxSecondsDiff Or Not bBeenThrough Then
lngMaxSecondsDiff = lngSecondsDiff
lngIndexToRemove = i
bBeenThrough = True
End If
End If
Next
dtNextDate = arrNextAvailableDates(lngIndexToRemove)
arrNextAvailableDates(lngIndexToRemove) = ""
Next
CalculateNextAvailableDay = dtNextDate
End Function
... и для использования определите именованный диапазон с именем rngAvailableDays поверх (не включая заголовки) вашей первой таблицы.
С вашей матрицей измените заголовки «Доступная дата 1» и т. Д. На простые числа, например ...
- «Доступная дата 1», измените на «1»
- «Доступная дата 2», изменить на «2»
- «Доступная дата 3», изменить на «3»
Затем можно отформатировать их в ... »Доступная дата "0 ... поэтому они отображаются так, как они были раньше, но они должны быть просто числами.
Как только вы это сделаете, добавьте следующую формулу в первую ячейку вашей" следующей доступной даты"matrix ...
=CalculateNextAvailableDay(rngAvailableDays,$D2,E$1)
... заменяя" $ D2 "первой датой начала и" E $ 1 "заголовком" Available Date 1 "er field.
Теперь заполните и поперек и скрестите пальцы, это должно работать для вас.
ОБЯЗАТЕЛЬНО ФОРМАТИРУЙТЕ ДАТЫ КАК ДАТЫ И ВРЕМЕНИ КАК РАЗ!
Надеюсь, все ясно.
Дайте мне знать, как у вас дела.