complicated way of dividing data

bertusavius

Board Regular
Joined
Feb 28, 2008
Messages
82
I have a table with a list of events that have ID, two time-values and two 'trip values'.



ID
Timestart
Timestop
tripstart
tripstop
25
6:55
7:55
259010
259030
25
7:06
7:55
259011
259030
25
7:11
7:57
259013
259030
25
7:17
7:57
259014
259030
25
7:23
7:57
259015
259030
25
7:27
7:59
259017
259031
25
7:29
7:58
259017
259031
25
7:40
7:59
259025
259031
25
8:11
8:21
259038
259043
25
8:41
9:07
259049
259063
25
8:48
9:16
259054
259064
78
13:24
13:34
259116
259122
78
13:40
14:14
259122
259134
78
13:45
14:22
259124
259136
78
13:54
14:22
259127
259136
78
14:03
14:23
259130
259136
78
14:35
14:58
259144
259148
78
14:36
14:58
259144
259148
78
14:43
15:06
259145
259150
78
14:52
15:38
259146
259162
78
15:19
15:42
259155
259163
78
15:27
15:47
259157
259164
78
15:54
16:02
259165
259167

<TBODY>
</TBODY>

<TBODY>
</TBODY>


To make things less abstract:
The trip-value is the value of a trip meter in a car in kilometers.
So the top record actualy says:
car nr 25 had an event that started at 06:55 at trip value 259010 and this event stopped at 07:55 coinciding with trip value 259030
You could say this is a list of events with corresponding accumulating properties, so wether the timeID starts or stops doesnt really matter. All the matters is that a certain time corresponds with a certain trip value.




Now wat I'd like is to create a measure that transforms and divides this information like this:



ID
binID
distance travelled
25
0700-0800
(value in kms)
25
0800-0900
(value in kms)
25
0900-1000
(value in kms)
78
0700-0800
(value in kms)
78
0800-0900
(value in kms)
78
0900-1000
(value in kms)

<TBODY>
</TBODY>

<TBODY>
</TBODY>



<TBODY>
</TBODY>
I have a table to relate to which contains binID, binstart and binstop
I also have a table for dates
Is it even worth contemplating to solve this in Powerpivot, because it seems quite daunting to me atm.



<TBODY>
</TBODY>
 
@mr C:
interesting approach. As long as the intervals are small and there are many events per hour, the averages work quite well.
But I'm affraid they're not accurate enough.

I'd like the cumulative values of the buckets to be as close as or equal to the real trip data.

I did not mean using an average, but using a calculated table within a SUMX function. I used linear extrapolation for the calculation, but you could use some more elaborate formula, if required.

If you have an event that spans over 3 time buckets, then you would have 3 rows in your calculated table, each with its extrapolated values for tripstart and tripstop.
 
Upvote 0

Excel Facts

Why does 9 mean SUM in SUBTOTAL?
It is because Sum is the 9th alphabetically in Average, Count, CountA, Max, Min, Product, StDev.S, StDev.P, Sum, VAR.S, VAR.P.
The Bin Data provided is not cummulative from One Bin two the Next (One hour to the next).... The Data in each bin is prorated for that Bin.

Here is the results of the data from your example.

As you see, the data from 8:00 AM to 8:59 AM (19.5) is less that that from the 7-8 AM hour (119.5)

Am I missing something

ID</SPAN>BIN</SPAN> Distance Traveled </SPAN>
25</SPAN>6</SPAN> 1.7 </SPAN>
25</SPAN>7</SPAN> 119.3 </SPAN>
25</SPAN>8</SPAN> 19.5 </SPAN>
25</SPAN>9</SPAN> 9.5 </SPAN>

<TBODY>
</TBODY><COLGROUP><COL span=2><COL></COLGROUP>
 
Upvote 0
Sorry for the delay.
I tested both your solutions.
They come up with exactly the same results.

If I use it on this different data for instance:
ABCD
32TX startTX stopINS_KILOMETERSTANDUIT_KILOMETERSTAND
3315:1815:23272690272692
3415:1515:59272690272712
3515:3315:44272698272705
3615:3315:47272698272706
3716:1616:25272716272718
3816:3816:47272720272724
3916:5216:57272725272728
4016:2016:37272716272720
4116:5917:12272728272731
4217:3117:32272734272734
4317:2417:31272731272734
4417:4417:56272737272742
4517:3718:05272735272745
4618:5419:19272762272771
4718:2519:10272751272768
4818:1318:18272747272748
4918:5019:49272761272794
5018:2118:38272749272755
5119:0219:15272763272770
5220:1520:31272811272821
5320:4420:51272832272834
5421:3421:40272836272839
5521:4021:47272839272841
5622:0022:24272850272868

<tbody>
</tbody>
Blad1
this is table 'data'

with this table 'buckets'

AEF
35BucketIDStart tijdEind tijd
3620003000-01-00 2:000-01-00 3:00
3730004000-01-00 3:000-01-00 4:00
3840005000-01-00 4:000-01-00 5:00
3950006000-01-00 5:000-01-00 6:00
4060007000-01-00 6:000-01-00 7:00
4170008000-01-00 7:000-01-00 8:00
4280009000-01-00 8:000-01-00 9:00
4390010000-01-00 9:000-01-00 10:00
44100011000-01-00 10:000-01-00 11:00
45110012000-01-00 11:000-01-00 12:00
46120013000-01-00 12:000-01-00 13:00
47130014000-01-00 13:000-01-00 14:00
48140015000-01-00 14:000-01-00 15:00
49150016000-01-00 15:000-01-00 16:00
50160017000-01-00 16:000-01-00 17:00
51170018000-01-00 17:000-01-00 18:00
52180019000-01-00 18:000-01-00 19:00
53190020000-01-00 19:000-01-00 20:00
54200021000-01-00 20:000-01-00 21:00
55210022000-01-00 21:000-01-00 22:00
56220023000-01-00 22:000-01-00 23:00
57230024000-01-00 23:000-01-00 0:00
58240025000-01-00 0:000-01-00 1:00
59250026000-01-00 1:000-01-00 2:00
6024002500

<tbody>
</tbody>
Blad2

Als using a calculated column estimated speed
=([UIT_KILOMETERSTAND]-[INS_KILOMETERSTAND])/(([TX stop]-[TX start])*24)


with a measure:
SUMX(
CROSSJOIN('data';'buckets');
IF(AND('data'[TX start] < 'buckets'[Eind tijd] ; 'data'[TX stop] > 'buckets'[Start tijd])
; if('buckets'[Eind tijd] > data[TX stop] ; data[TX stop]; 'buckets'[Eind tijd])
-
if('buckets'[Start tijd] < 'data'[TX start];'data'[TX start];'buckets'[Start tijd])
;0)*24*data[estimatedspeed])


I get this result:
ST
15RijlabelsMeting 1
162000300
173000400
184000500
195000600
206000700
217000800
228000900
239001000
2410001100
2511001200
2612001300
2713001400
2814001500
291500160039,00
301600170013,23
311700180018,98
321800190029,76
331900200045,02
342000210012,00
35210022005,00
362200230018,00
3723002400
3824002500
3925002600
40Eindtotaal181,00

<colgroup><col style="width: 25pxpx"><col><col></colgroup><thead>
</thead><tbody>
</tbody>
Blad3

The result is a perfectly round number which deviates (181/178)%
Also the numbers in the buckets don't really seem to correspond with reality.
 
Upvote 0
I'm affraid I'm not entirely set.
As you compare the data with the result, you see the bins do not acurately represent the actual driven miles per hour. Perhaps the Average speed could be more acurately calculated.

I'll be back tomorrow. Thank you for your swift replies.
 
Upvote 0
Oh... I was not aware that you were looking for a miles per hour (speed) calculation. I was look at it as the number of total miles traveled in each bin (hour)... Clearly two entirely different calculation!

let me take another look at the post and solutions.

also, for the sample data you provide, could you provide the number you would like to see in each bin. This would be a tremendous help
 
Last edited:
Upvote 0
I am still not real clear on your requirments, but Here is another shoot at the issue... The Code below provides
-The Miles Traveled in each hour (Bin)
-The Time of actual travel in each hour (Bin)
-The KmPH (Average)

Code:
Option Explicit
Type typRec
    ID As Integer
    BinArray(24) As Double
    BinMins(24) As Long
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 ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
        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)
                TotalMin = DateDiff("n", StartTime, EndTime)
                Rec(IdIdx).BinArray(BinIdx) = Rec(IdIdx).BinArray(BinIdx) + Miles
                Rec(IdIdx).BinMins(BinIdx) = Rec(IdIdx).BinMins(BinIdx) + TotalMin
            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)
                Rec(IdIdx).BinMins(BinIdx) = Rec(IdIdx).BinMins(BinIdx) + Min
                
                Perc = 60 / TotalMin
                For BinIdx = Hour(StartTime) + 1 To Hour(EndTime) - 1
                    Rec(IdIdx).BinArray(BinIdx) = Rec(IdIdx).BinArray(BinIdx) + (Miles * Perc)
                    Rec(IdIdx).BinMins(BinIdx) = Rec(IdIdx).BinMins(BinIdx)
                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)
                Rec(IdIdx).BinMins(BinIdx) = Rec(IdIdx).BinMins(BinIdx) + Min
            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
    
    ws.Cells(1, "A") = "ID"
    ws.Cells(1, "B") = "Bin (Hour)"
    ws.Cells(1, "C") = "Miles Traveled"
    ws.Cells(1, "D") = "Minutes"
    ws.Cells(1, "E") = "KmPH"
    
    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 & ":00 - " & (BinIdx + 1) & ":00"
                ws.Cells(RowNo, 3) = Format(Rec(I).BinArray(BinIdx), "0.00")
                ws.Cells(RowNo, 4) = Rec(I).BinMins(BinIdx)
                ws.Cells(RowNo, 5) = Format(Rec(I).BinArray(BinIdx) / Rec(I).BinMins(BinIdx) * 60, "0.00")
                RowNo = RowNo + 1
            End If
        Next BinIdx
    Next I
    
    ws.Rows("1:1").WrapText = True
    ws.Columns("C:C").Style = "Comma"
    ws.Columns("E:E").Style = "Comma"
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


Based on the Data in your most recent post, the code creates the following

ID</SPAN>Bin (Hour)</SPAN> Miles Traveled </SPAN>Minutes</SPAN> KmPH </SPAN>
1</SPAN>15:00 - 16:00</SPAN> 39.00 </SPAN>74</SPAN> 31.62 </SPAN>
1</SPAN>16:00 - 17:00</SPAN> 13.23 </SPAN>41</SPAN> 19.36 </SPAN>
1</SPAN>17:00 - 18:00</SPAN> 18.98 </SPAN>55</SPAN> 20.71 </SPAN>
1</SPAN>18:00 - 19:00</SPAN> 29.76 </SPAN>78</SPAN> 22.89 </SPAN>
1</SPAN>19:00 - 20:00</SPAN> 45.02 </SPAN>91</SPAN> 29.69 </SPAN>
1</SPAN>20:00 - 21:00</SPAN> 12.00 </SPAN>23</SPAN> 31.30 </SPAN>
1</SPAN>21:00 - 22:00</SPAN> 5.00 </SPAN>13</SPAN> 23.08 </SPAN>
1</SPAN>22:00 - 23:00</SPAN> 18.00 </SPAN>24</SPAN> 45.00 </SPAN>

<TBODY>
</TBODY><COLGROUP><COL><COL><COL><COL><COL></COLGROUP>
 
Upvote 0
Code:
Option Explicit
Const DateCol As Integer = 1
Const StartTimeCol As Integer = 2
Const EndTimeCol As Integer = 3
Const CarNoCol As Integer = 5
Const StartMileCol As Integer = 6
Const EndMileCol As Integer = 7
Type typRawRec
    t As Date
    mile As Long
End Type
Type typCar
    CarNo As Integer
    rec() As typRawRec
End Type
Type typDT
    trvlDate As String
    Car() As typCar
End Type
    
Sub Process()
    Dim ws As Worksheet
    Dim arrDt() As typDT
    
    Dim RowNo As Long
    Dim LastRow As Long
    
    Dim StartTime As Date
    Dim Idx As Long
    Dim I As Long
    
    Dim DtIdx As Integer
    Dim CarIdx As Integer
    
    Set ws = ThisWorkbook.Worksheets(1)
    LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    ReDim arrDt(0)
    ReDim arrDt(0).Car(0)
    ReDim arrDt(0).Car(0).rec(0)
    
    For RowNo = 2 To LastRow
        If Len(Trim(ws.Cells(RowNo, StartTimeCol))) > 1 Then
            
            DtIdx = FindDtIdx(ws.Cells(RowNo, DateCol), arrDt)
            CarIdx = FindCarIdx(ws.Cells(RowNo, CarNoCol), arrDt(DtIdx).Car)
            Idx = UBound(arrDt(DtIdx).Car(CarIdx).rec)
            
            ReDim Preserve arrDt(DtIdx).Car(CarIdx).rec(Idx + 2)
            Idx = Idx + 1
            arrDt(DtIdx).Car(CarIdx).rec(Idx).t = CDate(ws.Cells(RowNo, StartTimeCol))
            arrDt(DtIdx).Car(CarIdx).rec(Idx).mile = Val(ws.Cells(RowNo, StartMileCol))
            Call InsertRec(arrDt(DtIdx).Car(CarIdx).rec, Idx)
            
            Idx = Idx + 1
            'rec(Idx).Id = Val(ws.Cells(RowNo, 1))
            arrDt(DtIdx).Car(CarIdx).rec(Idx).t = CDate(ws.Cells(RowNo, EndTimeCol))
            arrDt(DtIdx).Car(CarIdx).rec(Idx).mile = Val(ws.Cells(RowNo, EndMileCol))
            Call InsertRec(arrDt(DtIdx).Car(CarIdx).rec, Idx)
        End If
    Next RowNo
    
    Call OutputAll(arrDt)
    
    MsgBox "Complete", vbInformation
End Sub
Function OutputAll(arrDt() As typDT)
    Dim ws As Worksheet
    Dim RowNo  As Integer
    Dim DtIdx As Integer
    
    Dim CarIdx As Integer
    
    Set ws = ThisWorkbook.Worksheets(2)
    ws.Cells.ClearContents
    RowNo = 1
    
    ws.Cells(RowNo, 1) = "Date"
    ws.Cells(RowNo, 2) = "Car"
    ws.Cells(RowNo, 3) = "Bucket"
    ws.Cells(RowNo, 4) = "Kms"
            
    For DtIdx = 1 To UBound(arrDt)
        For CarIdx = 1 To UBound(arrDt(DtIdx).Car)
            Call OutputData(ws, arrDt(DtIdx).Car(CarIdx).rec, arrDt(DtIdx).trvlDate, arrDt(DtIdx).Car(CarIdx).CarNo)
        Next CarIdx
    Next DtIdx
End Function
Function OutputData(ws As Worksheet, rec() As typRawRec, Dt As String, CarNo As Integer)
    Dim I As Integer
    Dim RowNo As Long
    
    Dim StartTime As Date
    Dim StartMiles As Long
    
    Dim ElapsedMin   As Long
    Dim ElapsedMiles   As Long
    
    Dim Perc As Single
    Dim Min As Integer
    
    StartTime = rec(1).t
    StartMiles = rec(1).mile
    
    Dim Car(0) As typCar
    RowNo = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row + 1
    
    For I = 2 To UBound(rec)
        
        If Hour(StartTime) <> Hour(rec(I).t) Then
            ElapsedMin = DateDiff("n", rec(I - 1).t, rec(I).t)
            ElapsedMiles = rec(I).mile - rec(I - 1).mile
            
            '----- Need to Adjust Bins
            '***** Determine Offset Percentage
            Min = DateDiff("n", rec(I - 1).t, CDate(Hour(rec(I - 1).t) + 1 & ":00:00"))
            Perc = Min / ElapsedMin
            
            '***** Apply Offset
            rec(I - 1).mile = rec(I - 1).mile + ElapsedMiles * Perc
            rec(I).mile = rec(I).mile - ElapsedMiles * (1 - Perc)
            
            '***** Output Data
            ws.Cells(RowNo, 1) = Dt
            ws.Cells(RowNo, 2) = CarNo
            ws.Cells(RowNo, 3) = Hour(StartTime) & ":00" & " ~ " & (Hour(StartTime) + 1) & ":00"
            ws.Cells(RowNo, 4) = rec(I - 1).mile - StartMiles
            
            '***** Reset start time and miles
            StartTime = rec(I).t
            StartMiles = rec(I).mile
            RowNo = RowNo + 1
            I = I + 1
        End If
    Next I
    
    Debug.Print CarNo, UBound(rec)
    
    ws.Cells(RowNo, 1) = Dt
    ws.Cells(RowNo, 2) = CarNo
    ws.Cells(RowNo, 3) = Hour(StartTime) & ":00" & " ~ " & (Hour(StartTime) + 1) & ":00"
    ws.Cells(RowNo, 4) = rec(I - 1).mile - StartMiles
            
End Function
Function InsertRec(arrRec() As typRawRec, Idx As Long)
    Dim I As Integer
    Dim xRec As typRawRec
    
    '*****  This function sorts the last record into the correct location
    For I = Idx - 1 To 1 Step -1
        If arrRec(I).t > arrRec(I + 1).t Then
            xRec = arrRec(I + 1)
            arrRec(I + 1) = arrRec(I)
            arrRec(I) = xRec
        Else
            Exit Function
        End If
    Next I
End Function
Function FindCarIdx(ByVal CarNo As Integer, Car() As typCar) As Integer
    Dim I As Integer
    
    For I = 1 To UBound(Car)
        If CarNo = Car(I).CarNo Then
            FindCarIdx = I
            Exit Function
        End If
    Next I
    
    ReDim Preserve Car(I)
    Car(I).CarNo = CarNo
    
    ReDim Car(I).rec(0)
    
    FindCarIdx = I
End Function
Function FindDtIdx(ByVal Dt As Date, arrDt() As typDT) As Integer
    Dim I As Integer
    
    For I = 1 To UBound(arrDt)
        If Dt = arrDt(I).trvlDate Then
            FindDtIdx = I
            Exit Function
        End If
    Next I
    
    ReDim Preserve arrDt(I)
    arrDt(I).trvlDate = Dt
 
    ReDim arrDt(I).Car(0)
    ReDim arrDt(I).Car(0).rec(0)
    
    FindDtIdx = I
End Function
 
Upvote 0
This version of the code accounts for the new columns that you added. It will also be able to to the calculations seperating the data by Date, Driver, Car and Bin.

Code:
Option Explicit
Const DateCol As Integer = 1
Const StartTimeCol As Integer = 2
Const EndTimeCol As Integer = 3
Const DriverCol As Integer = 4
Const CarNoCol As Integer = 5
Const StartMileCol As Integer = 6
Const EndMileCol As Integer = 7
Type typHourRec
    Used As Boolean
    
    MinMin As Long
    MaxMin As Long
    
    MinMile As Long
    MaxMile As Long
End Type
Type typRec
    Key As String
    HrDetail(24) As typHourRec
End Type
Sub Process()
    Dim ws As Worksheet
    Dim Rec() As typRec
    Dim Key As String
    Dim KeyIdx As Integer
    
    Dim RowNo As Long
    Dim LastRow As Long
    
    Dim I As Long
    
    ReDim Rec(0)
    
    Set ws = ThisWorkbook.Worksheets(1)
    LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    For RowNo = 2 To LastRow
        Key = Trim(ws.Cells(RowNo, DateCol)) & "~" & Trim(ws.Cells(RowNo, DriverCol)) & "~" & Trim(ws.Cells(RowNo, CarNoCol))
        KeyIdx = FindKeyIdx(Key, Rec)
        Debug.Print KeyIdx
        If Len(Trim(ws.Cells(RowNo, StartTimeCol))) > 1 Then
            Call UpdateRec(Rec(KeyIdx).HrDetail, StartTimeCol, StartMileCol, ws, RowNo)
            Call UpdateRec(Rec(KeyIdx).HrDetail, EndTimeCol, EndMileCol, ws, RowNo)
        End If
    Next RowNo
    
    Call OutputAll(Rec)
End Sub
Function OutputAll(Rec() As typRec)
    Dim ws As Worksheet
    Dim RowNo  As Integer
    Dim KeyIdx As Integer
    
    Dim v As Variant
    Dim I As Integer
    
    Set ws = ThisWorkbook.Worksheets(2)
    ws.Cells.ClearContents
    RowNo = 1
    
    ws.Cells(RowNo, 1) = "Date"
    ws.Cells(RowNo, 2) = "Driver"
    ws.Cells(RowNo, 3) = "Car"
    ws.Cells(RowNo, 4) = "Bucket"
    ws.Cells(RowNo, 5) = "Kms"
    
    For KeyIdx = 1 To UBound(Rec)
        Call OutputData(ws, Rec(KeyIdx).HrDetail, Rec(KeyIdx).Key)
    Next KeyIdx
End Function
Function OutputData(ws As Worksheet, HrDetail() As typHourRec, Key As String)
    Dim I As Integer
    Dim RowNo As Long
    
    Dim v As Variant
    Dim J As Integer
    
    Dim ElapsedMin   As Long
    Dim ElapsedMiles   As Long
    
    Dim Perc As Single
    Dim tempMin As Integer
    Dim tempMiles As Long
    
    RowNo = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row + 1
    
    For I = 2 To UBound(HrDetail)
        
        If HrDetail(I).Used Then
            v = Split(Key, "~")
            If UBound(v) >= 0 Then
                For J = 0 To 2
                    ws.Cells(RowNo, J + 1) = v(J)
                    Debug.Print v(J)
                Next J
            End If
            ElapsedMiles = 0
            ElapsedMiles = HrDetail(I).MaxMile - HrDetail(I).MinMile
            
            '***** Determine Offset Adj for the Start of the Hour
            If HrDetail(I - 1).Used Then
                tempMin = (60 - HrDetail(I - 1).MaxMin) + HrDetail(I).MinMin
                tempMiles = HrDetail(I).MinMile - HrDetail(I - 1).MaxMile
                Perc = HrDetail(I).MinMin / tempMin
                ElapsedMiles = ElapsedMiles + (tempMiles * Perc)
            End If
            
            '***** Determine Offset Ady for the Top of the Hour
            If (I < 24) Then
                If HrDetail(I + 1).Used Then
                    tempMin = (60 - HrDetail(I).MaxMin) + HrDetail(I + 1).MinMin
                    tempMiles = HrDetail(I + 1).MinMile - HrDetail(I).MaxMile
                    Perc = (60 - HrDetail(I).MaxMin) / tempMin
                    ElapsedMiles = ElapsedMiles + (tempMiles * Perc)
                End If
            End If
            
            'ws.Cells(RowNo, 1) = Dt
            'ws.Cells(RowNo, 2) = CarNo
            ws.Cells(RowNo, 4) = I & ":00" & " ~ " & (I + 1) & ":00"
            ws.Cells(RowNo, 5) = ElapsedMiles
            RowNo = RowNo + 1
        End If
        
    Next I
            
End Function
Function UpdateRec(HrDetail() As typHourRec, ByVal TimeColNo As Long, ByVal MileColNo As Long, ws As Worksheet, RowNo As Long)
    Dim TempTime As Date
    Dim Idx As Long
    
    TempTime = CDate(ws.Cells(RowNo, TimeColNo))
    Idx = Hour(TempTime)
    
    Select Case HrDetail(Idx).Used
        Case False
            HrDetail(Idx).MaxMin = Minute(ws.Cells(RowNo, TimeColNo))
            HrDetail(Idx).MinMin = Minute(ws.Cells(RowNo, TimeColNo))
            HrDetail(Idx).MaxMile = Val(ws.Cells(RowNo, MileColNo))
            HrDetail(Idx).MinMile = Val(ws.Cells(RowNo, MileColNo))
            HrDetail(Idx).Used = True
        Case True
            HrDetail(Idx).MaxMile = UpdateMax(HrDetail(Idx).MaxMile, Val(ws.Cells(RowNo, MileColNo)))
            HrDetail(Idx).MaxMin = UpdateMax(HrDetail(Idx).MaxMin, Minute(ws.Cells(RowNo, TimeColNo)))
            HrDetail(Idx).MinMile = UpdateMin(HrDetail(Idx).MinMile, Val(ws.Cells(RowNo, MileColNo)))
            HrDetail(Idx).MinMin = UpdateMin(HrDetail(Idx).MinMin, Minute(ws.Cells(RowNo, TimeColNo)))
    End Select
End Function
Function FindKeyIdx(ByVal Key As String, Rec() As typRec) As Integer
    Dim I As Integer
    
    For I = 1 To UBound(Rec)
        If Key = Rec(I).Key Then
            FindKeyIdx = I
            Exit Function
        End If
    Next I
    
    ReDim Preserve Rec(I)
    Rec(I).Key = Key
    
    'ReDim Rec(I).HrDetail(0)
    
    FindKeyIdx = I
End Function
Function UpdateMin(arrVal As Long, wsVal As Long) As Long
    If wsVal < arrVal Then
        UpdateMin = wsVal
    Else
        UpdateMin = arrVal
    End If
End Function
Function UpdateMax(arrVal As Long, wsVal As Long)
    If wsVal > arrVal Then
        UpdateMax = wsVal
    Else
        UpdateMax = arrVal
    End If
End Function
 
Upvote 0
Fantastic!
It works really well

Just having a very minor issue with the dates:
The database uses d/m/y layout for a date, but your macro transforms the dates into m/d/y. (which naturally causes an error as soon as the day exceeds 12)
 
Upvote 0

Forum statistics

Threads
1,215,886
Messages
6,127,583
Members
449,385
Latest member
KMGLarson

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top