Try this, it doesn't use formulas so its definitely faster.
This Sub
will fill the Max for that group in column D.
Sub FillGroupsMax()
Application.ScreenUpdating = False
'stop screen updating makes vba perform better
Set last = Range("A:A").Find("*", Cells(1, 1), searchdirection:=xlPrevious)
'last cell with value in column A
Dim groupsArray As Variant
'array with all group infomation
Dim groupsSeen As Variant
'array with group infomation already seen
groupsArray = Range(Cells(1, 1), Cells(last.Row, 3))
'collect all the information on the Sheet into an array
'Improves performance by not visiting the sheet
For dRow = 1 To last.Row
'for each of the rows
'check if group as already been seen
If inArrayValue(Cells(dRow, 1).value, groupsSeen) > 0 Then
'if it has been seen/calculated attribute value
Cells(dRow, 4).value = inArrayValue(Cells(dRow, 1).value, groupsSeen)
Else
'if it hasn't been seen then find max
Cells(dRow, 4).value = getMax(Cells(dRow, 1).value, groupsArray)
'array construction from empty
If IsEmpty(groupsSeen) Then
ReDim groupsSeen(0)
groupsSeen(0) = Array(Cells(dRow, 1).value, Cells(dRow, 4).value)
'attribute value to array
Else
ReDim Preserve groupsSeen(0 To UBound(groupsSeen) + 1)
groupsSeen(UBound(groupsSeen)) = Array(Cells(dRow, 1).value, Cells(dRow, 4).value)
End If
End If
Next
'reactivate Screen updating
Application.ScreenUpdating = True
End Sub
Function getMax(group As String, groupsArray As Variant) As Double
'for each in array
For n = 1 To UBound(groupsArray)
'if its the same group the Max we seen so far the record
If groupsArray(n, 1) = group And groupsArray(n, 3) > maxSoFar Then
maxSoFar = groupsArray(n, 3)
End If
Next
'set function value
getMax = maxSoFar
End Function
Function inArrayValue(group As String, groupsSeen As Variant) As Double
'set function value
inArrayValue = 0
'if array is empty then exit
If IsEmpty(groupsSeen) Then Exit Function
'for each in array
For n = 0 To UBound(groupsSeen)
'if we find the group
If groupsSeen(n)(0) = group Then
'set function value to the Max value already seen
inArrayValue = groupsSeen(n)(1)
'exit function earlier
Exit Function
End If
Next
End Function