UDF
Use in cell like
=FilterUniq(Sheet1!$A$1:$C$7,1,ROW(A1),COLUMN(A1),2,3)
then copy right/down
Where;
Sheet1!$A$1:$D$7 is a source range incl headings
1 is a unique key col
2 is a column for Sum
3 is a column to be joined
You can use Array when any of above 3 arguments consists of multiple columns
e.g
=FilterUniq(Sheet1!$A$1:$D$7,1,ROW(A1),COLUMN(A1),{2,4},3)
ROW(A1),COLUMN(A1) MUST not be changed in the first cell, so that it increments as you copy.
Function FilterUniq(ByVal rng As Range, ByVal keyCols, ByVal rowRef, _
ByVal colRef, Optional sumCols, Optional JoinCols)
Dim a, e, i As Long, ii As Long, txt
Static dic As Object
If dic Is Nothing Then Set dic = CreateObject("Scripting.Dictionary")
dic.RemoveAll
a = rng.Value
For i = 1 To UBound(a, 1)
If IsArray(keyCols) Then
For Each e In keyCols
txt = txt & Chr(2) & a(i, e)
Next
Else
txt = a(i, keyCols)
End If
If Not dic.exists(txt) Then
dic(txt) = dic.Count + 1
For ii = 1 To UBound(a, 2)
a(dic.Count, ii) = a(i, ii)
Next
Else
If Not IsMissing(sumCols) Then
If IsArray(sumCols) Then
For Each e In sumCols
a(dic(txt), e) = a(dic(txt), e) + a(i, e)
Next
Else
a(dic(txt), sumCols) = a(dic(txt), sumCols) + a(i, sumCols)
End If
End If
If Not IsMissing(JoinCols) Then
If IsArray(JoinCols) Then
For Each e In JoinCols
If a(i, e) <> "" Then
a(dic(txt), e) = a(dic(txt), e) & _
IIf(a(dic(txt), e) <> "", ", ", "") & a(i, e)
End If
Next
Else
If a(i, JoinCols) <> "" Then
a(dic(txt), JoinCols) = a(dic(txt), JoinCols) & _
IIf(a(dic(txt), JoinCols) <> "", ", ", "") & a(i, JoinCols)
End If
End If
End If
End If
txt = ""
Next
If rowRef <= dic.Count Then
FilterUniq = a(rowRef, colRef)
Else
FilterUniq = ""
End If
End Function
Bookmarks