Esta macro faz o que você quer, mas só é testada com os dados que você deu (embora se continuar da mesma maneira, deve ficar bem, o problema será se você adicionar mais colunas, mas o código deve realmente ser fácil de atualizar)
Sub SortMeOut()
Dim previousOrderId As String
Dim row As Integer
row = 2
previousOrderId = Worksheets("Sheet1").Range("A2").Value
Dim offset As Integer
offset = 0
Do While (True)
If Worksheets("Sheet1").Range("A" & row).Value = "" Then
Exit Do
End If
Dim isHeader As Boolean
isHeader = True
Do While (True) 'loop through all columns with a match
If Worksheets("Sheet1").Range("A" & row).Value <> previousOrderId Then
Exit Do
End If
If Not isHeader Then
Worksheets("Sheet2").Range("A" & row + 1 + offset).Value = "ITM"
Worksheets("Sheet2").Range("B" & row + 1 + offset).Value = Worksheets("Sheet1").Range("B" & row).Value ' product num
Worksheets("Sheet2").Range("C" & row + 1 + offset).Value = Worksheets("Sheet1").Range("E" & row).Value ' product name
Worksheets("Sheet2").Range("D" & row + 1 + offset).Value = Worksheets("Sheet1").Range("F" & row).Value ' quantity
End If
If isHeader Then
Worksheets("Sheet2").Range("A" & row + offset).Value = "HDR"
Worksheets("Sheet2").Range("B" & row + offset).Value = Worksheets("Sheet1").Range("A" & row).Value 'order id
Worksheets("Sheet2").Range("C" & row + offset).Value = Worksheets("Sheet1").Range("D" & row).Value ' name of the dude
Worksheets("Sheet2").Range("D" & row + offset).Value = Worksheets("Sheet1").Range("C" & row).Value ' date
'we also have to do the first item as well...
Worksheets("Sheet2").Range("A" & row + 1 + offset).Value = "ITM"
Worksheets("Sheet2").Range("B" & row + 1 + offset).Value = Worksheets("Sheet1").Range("B" & row).Value ' product num
Worksheets("Sheet2").Range("C" & row + 1 + offset).Value = Worksheets("Sheet1").Range("E" & row).Value ' product name
Worksheets("Sheet2").Range("D" & row + 1 + offset).Value = Worksheets("Sheet1").Range("F" & row).Value ' quantity
isHeader = False
End If
row = row + 1
Loop
offset = offset + 1
previousOrderId = Worksheets("Sheet1").Range("A" & row).Value
Loop
End Sub
Ele assume que os dados estão no workseet1 e envia os resultados para worksheet2
Antes
Depois