Selected Answer
Hello Kalil,
When I started writing this code I wanted to make things easier for you to identify, specify and modify columns. Now that it's done I don't think I succeeded :-) but the code will extract the data you want, and it is possible to identify, specify and modify columns. Count it as a partial success, please.
Option Explicit
Private Enum Nws ' worksheet navigation
' 280 ' change values to address other rows/columns
NwsFirstDataRow = 2
NwsSerial = 1 ' columns:
NwsGoods
NwsType
NwsPR ' enums without assigned value
NwsQty ' take the value of the previous + 1
NwsTarget = 7 ' 7 = column("G")
' leave 1 blank column between Tbl & NwsTarget
End Enum
Sub CreateSummary()
' 280
Dim Ws As Worksheet
Dim Tbl As Range ' table of original data
Dim Data As Variant ' value of Tbl
Dim Target As Range ' result area
Dim R As Long ' loop counter: rows
Set Ws = ThisWorkbook.Worksheets("Sheet1") ' change name to suit
Set Tbl = Ws.Range("A1").CurrentRegion.Offset(1)
Data = Tbl.Resize(Tbl.Rows.Count - 1).Value
Application.ScreenUpdating = False
Set Target = Ws.Cells(1, NwsTarget).CurrentRegion.Offset(1)
Target.ClearContents
Tbl.Columns(NwsGoods).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Target.Cells(1), Unique:=True
With Ws
For R = NwsFirstDataRow To .Cells(.Rows.Count, NwsTarget).End(xlUp).Row
.Cells(R, NwsTarget + NwsQty - 2).Value = WorksheetFunction.SumIfs( _
Tbl.Columns(NwsQty), _
Tbl.Columns(NwsGoods), _
.Cells(R, NwsTarget).Value)
.Cells(R, NwsTarget + NwsType - 2).Value = CSVString(.Cells(R, NwsTarget).Value, NwsType, Data)
.Cells(R, NwsTarget + NwsPR - 2).Value = CSVString(.Cells(R, NwsTarget).Value, NwsPR, Data)
Next R
End With
Target.Columns.AutoFit
Application.ScreenUpdating = True
End Sub
Private Function CSVString(ByVal Good As String, _
Clm As Nws, _
Data As Variant) As String
' 280
Dim Spike As String
Dim Itm As String
Dim R As Long ' loop counter: data rows
For R = 1 To UBound(Data)
If Data(R, NwsGoods) = Good Then
Itm = "," & Data(R, Clm) & ","
If InStr(1, Spike, Itm, vbTextCompare) = 0 Then
Spike = Spike & Itm
End If
End If
Next R
If Len(Spike) Then
Spike = Mid(Spike, 2, Len(Spike) - 2)
CSVString = Replace(Spike, ",,", ", ")
End If
End Function
Note that the Enum, here at the top of the code, must always be at the top of the module in which you keep it, preceded only by Option Explicit and before any procedures. Also note that the function CSVString will exclude duplicates. I'm not sure if this is a requirement but I suppose it can't do any harm.