Here's one approach, which puts results on sheet2 (and assumes you have nothing in column P of your first sheet).
Sub x()
Dim rng As Range, oDic As Object, n As Long, i As Long
Sheet1.Activate
Sheet2.UsedRange.Clear
Range("D1", Range("D1").End(xlDown)).AdvancedFilter xlFilterCopy, copytorange:=Range("P1"), unique:=True
Range("P2", Range("P2").End(xlDown)).Copy
Sheet2.Range("E1").PasteSpecial Transpose:=True
Set oDic = CreateObject("Scripting.Dictionary")
For Each rng In Range("A2", Range("A2").End(xlDown))
i = Application.Match(rng.Offset(, 3).Value, Sheet2.Range("E1", Sheet2.Range("E1").End(xlToRight)), 0)
If Not oDic.Exists(rng.Value) Then
Sheet2.Cells(Rows.Count, 1).End(xlUp)(2) = rng.Value
Sheet2.Cells(Rows.Count, 4 + i).End(xlUp)(2) = "y"
n = n + 1
oDic.Add rng.Value, n
Else
Sheet2.Cells(oDic.Item(rng.Value) + 1, 1) = rng.Value
Sheet2.Cells(oDic.Item(rng.Value) + 1, 4 + i) = "y"
End If
Next rng
Sheet2.Range("E1").CurrentRegion.SpecialCells(xlCellTypeBlanks) = "n"
Columns("P").Clear
End Sub
EDIT: ok JBeaucaire has beaten me to it but at least you now have one of each.
Bookmarks