Hi all.
I hope someone can help me out.
I have an Excel worksheet with 2 columns: 'Client #' and 'Invoice #'.
Every time the accounting dept. generates an invoice, a new row is
added in this worksheet.
Obviously this is chronological not per Client #.
But for the sake of simplicity, let's assume the worksheet is already
sorted by Client #, like so:
A B
Client # Invoice #
231 5929
231 4358
231 2185
231 6234
464 1166
464 1264
464 3432
464 1720
464 9747
791 1133
791 4930
791 5496
791 6291
989 8681
989 3023
989 7935
989 8809
989 8873
My goal is to achieve this:
Client # Invoice #
231 5929, 4358, 2185, 6234
464 1166, 1264, 3432, 1720, 9747
791 1133, 4930, 5496, 6291
989 8681, 3023, 7935, 8809, 8873
In order to create a (Word) mail-merge, where I can write to each
Client:
"Dear ABC,
You have the following invoices are still open: <column B from the
optimised version>..."
Anyone have an idea how to achieve this without external software or
VB programming?
Any help greatly appreciated.
==
M.T.
It occurs to me that you might want to also have the invoices be listed in sorted order. If that is the case, try this version which sorts on both dimensions before creating the result:
====================
Option Explicit
Sub MakeList()
Dim vData As Variant
Dim vRes() As Variant
Dim vTemp As Variant
Dim lRows As Long
Dim i As Long, j As Long
Dim coll As Collection 'to get unique list of ID's
'Rows of data:
lRows = Range("A1", Cells(Cells.Rows.Count, "A").End(xlUp)).Rows.Count
'Read data into a VBA variable
vData = Range("A1", Cells(Cells.Rows.Count, "B").End(xlUp)) _
.Offset(rowoffset:=1).Resize(rowsize:=lRows - 1)
'Sort it
vData = WorksheetFunction.Transpose(vData)
MyQuickSort_Two vData, LBound(vData, 2), UBound(vData, 2), 1, 2, True
'get unique list of ID's
Set coll = New Collection
On Error Resume Next
For i = 1 To UBound(vData, 2)
coll.Add vData(1, i), CStr(vData(1, i))
Next i
On Error GoTo 0
'set up results array
ReDim vRes(1 To 2, 1 To coll.Count)
i = 1
For j = 1 To coll.Count
vRes(1, j) = coll(j)
Do
vRes(2, j) = vRes(2, j) & ", " & vData(2, i)
i = i + 1
If i > UBound(vData, 2) Then Exit Do
Loop Until vData(1, i) <> coll(j)
vRes(2, j) = Mid(vRes(2, j), 3)
Next j
vRes = WorksheetFunction.Transpose(vRes)
With Range("F1", Cells(coll.Count, "G"))
.Value = vRes
.EntireColumn.AutoFit
End With
End Sub
' ************************************************
' Multidimensional Array sort on 2 dimensions
' ************************************************
Sub MyQuickSort_Two(ByRef SortArray As Variant, ByVal First As Long, ByVal Last As Long, _
ByVal PrimeSort As Integer, ByVal SecSort As Integer, ByVal Ascending As Boolean)
Dim Low As Long, High As Long
Dim Temp As Variant
Dim List_Separator1 As Variant, List_Separator2 As Variant
Dim TempArray() As Variant
Dim i As Long
ReDim TempArray(UBound(SortArray, 1))
Low = First
High = Last
List_Separator1 = SortArray(PrimeSort, (First + Last) / 2)
List_Separator2 = SortArray(SecSort, (First + Last) / 2)
Do
If Ascending = True Then
Do While (SortArray(PrimeSort, Low) < List_Separator1) Or _
((SortArray(PrimeSort, Low) = List_Separator1) And (SortArray(SecSort, Low) < List_Separator2))
Low = Low + 1
Loop
Do While (SortArray(PrimeSort, High) > List_Separator1) Or _
((SortArray(PrimeSort, High) = List_Separator1) And (SortArray(SecSort, High) > List_Separator2))
High = High - 1
Loop
Else
Do While (SortArray(PrimeSort, Low) > List_Separator1) Or _
((SortArray(PrimeSort, Low) = List_Separator1) And (SortArray(SecSort, Low) > List_Separator2))
Low = Low + 1
Loop
Do While (SortArray(PrimeSort, High) < List_Separator1) Or _
((SortArray(PrimeSort, High) = List_Separator1) And (SortArray(SecSort, High) < List_Separator2))
High = High - 1
Loop
End If
If (Low <= High) Then
For i = LBound(SortArray, 1) To UBound(SortArray, 1)
TempArray(i) = SortArray(i, Low)
Next
For i = LBound(SortArray, 1) To UBound(SortArray, 1)
SortArray(i, Low) = SortArray(i, High)
Next
For i = LBound(SortArray, 1) To UBound(SortArray, 1)
SortArray(i, High) = TempArray(i)
Next
Low = Low + 1
High = High - 1
End If
Loop While (Low <= High)
If (First < High) Then MyQuickSort_Two SortArray, First, High, PrimeSort, SecSort, Ascending
If (Low < Last) Then MyQuickSort_Two SortArray, Low, Last, PrimeSort, SecSort, Ascending
End Sub
=====================================