Здесь я использую словарь, который будет храниться каждый раз для каждого продукта, разделенного запятой, поэтому позже разделим его и примем первое и последнее вхождение:
Sub TimeTable()
'Declare an array variable to store the data
'change MySheet for your sheet name
arr = ThisWorkbook.Sheets("MySheet").UsedRange.Value 'this will store the whole worksheet, the used area.
'Declare a dictionary object
Dim Products As Object: Set Products = CreateObject("Scripting.Dictionary")
'Loop through the array
Dim i As Long
For i = 3 To UBound(arr) 'start from row 3 because of your screenshoot
If arr(i, 21) = vbNullString Then GoTo NextRow 'if column U is empty won't add anything
If Not Products.Exists(arr(i, 21)) Then '21 is the column index for column U
Products.Add arr(i, 21), arr(i, 1)
Else
Products(arr(i, 21)) = arr(i, 21) & "," & arr(i, 1)
End If
NextRow:
Next i
Erase arr
'Redim the array to fit your final data, 4 columns and as many rows as products
ReDim arr(1 To Products.Count + 1, 1 To 4)
'Insert the headers
arr(1, 1) = "Time"
arr(1, 4) = "Product / Error"
'Now loop through the dictionary
Dim Key As Variant, MySplit As Variant
i = 2
For Each Key In Products.Keys
MySplit = Split(Products(Key), ",")
arr(i, 1) = MySplit(LBound(MySplit))
arr(i, 2) = "-"
arr(i, 3) = MySplit(UBound(MySplit))
arr(i, 4) = Key
i = i + 1
Next Key
'I don't know where are you going to paste your data, so I'm making a new worksheet at the end of your workbook
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
With ws
.Range("A1").Resize(UBound(arr), UBound(arr, 2)).Value = arr
.Range("A1:C1").Merge
End With
End Sub