Final option (maybe) using arrays:
Sub TMS()
Dim shIn As Worksheet: Set shIn = Sheets("Input")
Dim shOut As Worksheet: Set shOut = Sheets("TMS")
Dim rIn As Range, rOut As Range
Dim vIn, vInR, vInC, vOut
Dim i As Long
Dim sPupil As String, vGat8, vGat11
Dim lRIndex As Long, lCIndex As Long
Dim awf As WorksheetFunction: Set awf = WorksheetFunction
Application.ScreenUpdating = True
' store the data from the input sheet
With shIn
vIn = .Range(.Range("B4"), _
.Range("B4").End(xlDown)) _
.Resize(, 3)
End With
' set the range(s) from the output sheet
With shOut
' use for lookup
Set rIn = .Range(.Range("C9"), _
.Range("C9").End(xlDown))
' where the output is going
Set rOut = rIn.Offset(0, 1).Resize(, rIn.Rows.Count)
End With
vInR = awf.Transpose(rIn) ' row lookup, Grade at 11
vInC = awf.Transpose(rIn) ' just to get the size
' column lookup, Grade at 8 (reverse row values)
For i = LBound(vInR) To UBound(vInR)
vInC(i) = vInR(UBound(vInR) - i + 1)
Next i
' prepare the output matrix
ReDim vOut(LBound(vInR) To UBound(vInR), _
LBound(vInC) To UBound(vInC))
' loop through the input data and store in output matrix
For i = LBound(vIn, 1) To UBound(vIn, 1)
sPupil = vIn(i, 1): vGat8 = vIn(i, 2): vGat11 = vIn(i, 3)
lRIndex = awf.Match(vGat11, vInR, 0)
lCIndex = awf.Match(vGat8, vInC, 0)
If vOut(lRIndex, lCIndex) = "" Then
vOut(lRIndex, lCIndex) = sPupil
Else
vOut(lRIndex, lCIndex) = _
vOut(lRIndex, lCIndex) & ", " & _
sPupil
End If
Next 'i
' clear/format the output range
With rOut
.ClearContents
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlTop
.WrapText = True
End With
' move output matrix to worksheet
rOut = vOut
Application.ScreenUpdating = True
End Sub
Regards, TMS
Bookmarks