Вы можете сделать что-то вроде этого:
Sub Tester()
Dim rng As Range, ws As Worksheet, c As Range
Set ws = ActiveSheet
Set rng = ws.Range("A1:A" & ws.Cells(Rows.Count, 1).End(xlUp).Row)
Set c = ClosestTimeCell(rng, "06:30")
Debug.Print c.Address, Format(c.Value, "hh:mm:ss")
Set c = ClosestTimeCell(rng, "18:30")
Debug.Print c.Address, Format(c.Value, "hh:mm:ss")
End Sub
'return the cell in rng with the closest match to the provided time
Function ClosestTimeCell(rng As Range, theTime As String) As Range
Dim diffs, pos
'Get all the absolute differences from the desired time
' Returns an array of values (evaluated as an array formula)
diffs = rng.Parent.Evaluate("ABS(" & rng.Address & "-TIMEVALUE(""" & theTime & """))")
'get the position of the smallest difference
pos = Application.Match(Application.Min(diffs), diffs, 0)
Set ClosestTimeCell = rng.Cells(pos)
End Function
РЕДАКТИРОВАТЬ - после просмотра исходного файла ...
Подход к формуле массива:
Подход VBA:
Sub Tester()
Dim rng As Range, ws As Worksheet, rngDays As Range, rngTimes As Range
Dim startTime, endTime, numDays, dict As Object, data()
Dim startD, endD, k, bFirst As Boolean
Dim days, times, i As Long, d, t, currentDay, n As Long, v, indx As Long
Set dict = CreateObject("scripting.dictionary")
Set ws = Sheets("Sheet1")
Set rngDays = ws.Range("B1:B" & ws.Cells(Rows.Count, 2).End(xlUp).Row)
startTime = ws.Range("H2").Value
endTime = ws.Range("I2").Value
days = rngDays.Value
times = rngDays.Offset(0, 1).Value
'get the unique days to assess
'we started from row 1 to avoid offsets, so ignore the headers...
For i = 2 To UBound(days, 1)
If Not dict.exists(days(i, 1)) Then dict.Add days(i, 1), dict.Count + 1
Next i
'use this for tracking start/end time differences (col 1 and 3)
' and row numbers with smallest deltas (cols 2 and 4)
ReDim data(1 To dict.Count, 1 To 4)
For i = 2 To UBound(days, 1)
indx = dict(days(i, 1)) '>> "row" in 2-D tracking array
bFirst = IsEmpty(data(indx, 1)) 'first row for this day?
t = times(i, 1)
startD = CDbl(Abs(t - startTime)) 'start delta
endD = CDbl(Abs(t - endTime)) 'end delta
'compare, and track smallest deltas and row numbers
If bFirst Or startD < data(indx, 1) Then
data(indx, 1) = startD
data(indx, 2) = i
End If
If bFirst Or endD < data(indx, 3) Then
data(indx, 3) = endD
data(indx, 4) = i
End If
Next i
'print each day and "best match" start/end time rows
For Each k In dict
Debug.Print k, data(dict(k), 2), data(dict(k), 4)
Next k
End Sub