Option Explicit
Const cDateCol As Long = 2
Const cTimeCol As Long = 3
Const cPupilLeftCol As Long = 6
Const cPupilRightCol As Long = 7
Const cInterpLeftCol As Long = 8
Const cInterpRightCol As Long = 9
Sub Demo1()
Dim ws As Worksheet
Dim iLastRow As Long, iRow As Long, iStartRow As Long
Dim rUp As Range, rDown As Range, rLeftPupil As Range, rRightPupil As Range, rCurrent As Range
Dim dUp As Double, dDown As Double, dCurrent As Double
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set ws = ActiveSheet
'find last row
iLastRow = ws.Cells(ActiveSheet.Rows.Count, cTimeCol).End(xlUp).Row
'clear 0 len strings
For iRow = 2 To iLastRow
If Len(ws.Cells(iRow, cPupilLeftCol).Value) = 0 Then ws.Cells(iRow, cPupilLeftCol).ClearContents
If Len(ws.Cells(iRow, cPupilRightCol).Value) = 0 Then ws.Cells(iRow, cPupilRightCol).ClearContents
Next iRow
'fill in the knowns
For iRow = 2 To iLastRow
'if we got it, use it
If ws.Cells(iRow, cPupilLeftCol).Value > 0# Then
ws.Cells(iRow, cInterpLeftCol).Value = ws.Cells(iRow, cPupilLeftCol).Value
End If
If ws.Cells(iRow, cPupilRightCol).Value > 0# Then
ws.Cells(iRow, cInterpRightCol).Value = ws.Cells(iRow, cPupilRightCol).Value
End If
Next iRow
'interpolate left
iStartRow = ws.Cells(1, cPupilLeftCol).End(xlDown).Row
For iRow = iStartRow To iLastRow
If ws.Cells(iRow, cPupilLeftCol).Value > 0# Then GoTo NextRowLeft
Set rUp = ws.Cells(iRow, cPupilLeftCol).End(xlUp).EntireRow
If rUp.Row < 2 Then GoTo NextRowLeft
Set rDown = ws.Cells(iRow, cPupilLeftCol).End(xlDown).EntireRow
If rDown.Row > iLastRow Then GoTo NextRowLeft
Set rCurrent = ws.Rows(iRow)
Set rLeftPupil = rCurrent.Cells(1, cInterpLeftCol)
dDown = pvtMakeDateTime(rDown.Cells(1, cDateCol).Value, rDown.Cells(1, cTimeCol).Value)
dUp = pvtMakeDateTime(rUp.Cells(1, cDateCol).Value, rUp.Cells(1, cTimeCol).Value)
dCurrent = pvtMakeDateTime(rCurrent.Cells(1, cDateCol).Value, rCurrent.Cells(1, cTimeCol).Value)
rLeftPupil.Value = dCurrent - dUp
rLeftPupil.Value = rLeftPupil * (rDown.Cells(1, cInterpLeftCol).Value - rUp.Cells(1, cInterpLeftCol).Value)
rLeftPupil.Value = rLeftPupil.Value / (dDown - dUp)
rLeftPupil.Value = rLeftPupil.Value + rUp.Cells(1, cInterpLeftCol).Value
NextRowLeft:
Next iRow
'interpolate right
iStartRow = ws.Cells(1, cPupilRightCol).End(xlDown).Row
For iRow = iStartRow To iLastRow
If ws.Cells(iRow, cPupilRightCol).Value > 0# Then GoTo NextRowRight
Set rUp = ws.Cells(iRow, cPupilRightCol).End(xlUp).EntireRow
If rUp.Row < 2 Then GoTo NextRowRight
Set rDown = ws.Cells(iRow, cPupilRightCol).End(xlDown).EntireRow
If rDown.Row > iLastRow Then GoTo NextRowRight
Set rCurrent = ws.Rows(iRow)
Set rRightPupil = rCurrent.Cells(1, cInterpRightCol)
dDown = pvtMakeDateTime(rDown.Cells(1, cDateCol).Value, rDown.Cells(1, cTimeCol).Value)
dUp = pvtMakeDateTime(rUp.Cells(1, cDateCol).Value, rUp.Cells(1, cTimeCol).Value)
dCurrent = pvtMakeDateTime(rCurrent.Cells(1, cDateCol).Value, rCurrent.Cells(1, cTimeCol).Value)
rRightPupil.Value = dCurrent - dUp
rRightPupil.Value = rRightPupil * (rDown.Cells(1, cInterpRightCol).Value - rUp.Cells(1, cInterpRightCol).Value)
rRightPupil.Value = rRightPupil.Value / (dDown - dUp)
rRightPupil.Value = rRightPupil.Value + rUp.Cells(1, cInterpRightCol).Value
NextRowRight:
Next iRow
End Sub
Private Function pvtMakeDateTime(D As String, T As String) As Double
Dim H As Long, M As Long
Dim S As Double
'123456789012
'15:04:27.205
H = CDbl(Left(T, 2))
M = CDbl(Mid(T, 4, 2))
S = CDbl(Right(T, 6))
pvtMakeDateTime = CDbl(DateValue(D) + (H / 24#) + (M / 24# / 60#) + S)
End Function