Option Explicit
Type typRec
ID As Integer
BinArray(24) As Double
End Type
Sub Calc()
Dim Rec() As typRec
ReDim Rec(0)
Dim ws As Worksheet
Dim RowNo As Long
Dim StartTime As Date
Dim EndTime As Date
Dim IdIdx As Integer
Dim BinIdx As Integer
Dim HourCnt As Integer
Dim Miles As Long
Dim TotalMin As Long
Dim Min As Integer
Dim Perc As Single
Set ws = ThisWorkbook.Worksheets("Sheet1")
RowNo = 2
For RowNo = 2 To 24
IdIdx = FindIdx(ws.Cells(RowNo, 1), Rec)
StartTime = ws.Cells(RowNo, 2)
EndTime = ws.Cells(RowNo, 3)
Miles = ws.Cells(RowNo, 5) - ws.Cells(RowNo, 4)
HourCnt = Hour(EndTime) - Hour(StartTime)
Select Case HourCnt
Case 0
BinIdx = Hour(StartTime)
Rec(IdIdx).BinArray(BinIdx) = Rec(IdIdx).BinArray(BinIdx) + Miles
Case Is > 0
TotalMin = DateDiff("n", StartTime, EndTime)
'***** Determine fractional time for 1st hour
BinIdx = Hour(StartTime)
Min = DateDiff("n", StartTime, CDate(BinIdx + 1 & ":00:00"))
Perc = Min / TotalMin
Rec(IdIdx).BinArray(BinIdx) = Rec(IdIdx).BinArray(BinIdx) + (Miles * Perc)
Perc = 60 / TotalMin
For BinIdx = Hour(StartTime) + 1 To Hour(EndTime) - 1
Rec(IdIdx).BinArray(BinIdx) = Rec(IdIdx).BinArray(BinIdx) + (Miles * Perc)
Next BinIdx
'***** Determine fractional time for Last hour
BinIdx = Hour(EndTime)
Min = DateDiff("n", CDate(BinIdx & ":00:00"), EndTime)
Perc = Min / TotalMin
Rec(IdIdx).BinArray(BinIdx) = Rec(IdIdx).BinArray(BinIdx) + (Miles * Perc)
Case Else
End Select
Next RowNo
Call OutputResults(Rec)
End Sub
Function OutputResults(Rec() As typRec)
Dim I As Integer
Dim BinIdx As Integer
Dim ws As Worksheet
Dim RowNo As Long
Set ws = ThisWorkbook.Worksheets("Sheet2")
ws.Cells.ClearContents
RowNo = 2
For I = 1 To UBound(Rec)
For BinIdx = 1 To 24
If Rec(I).BinArray(BinIdx) > 0 Then
ws.Cells(RowNo, 1) = Rec(I).ID
ws.Cells(RowNo, 2) = BinIdx
ws.Cells(RowNo, 3) = Rec(I).BinArray(BinIdx)
RowNo = RowNo + 1
End If
Next BinIdx
Next I
End Function
Function FindIdx(ID As Integer, Rec() As typRec) As Integer
Dim I As Integer
For I = 1 To UBound(Rec)
If Rec(I).ID = ID Then
FindIdx = I
Exit Function
End If
Next I
ReDim Preserve Rec(I)
Rec(I).ID = ID
FindIdx = I
End Function