I do this all the time with vba. I am pretty sure I have used the same method since office 95', with minor changes made for column placement. It can be done with fewer lines if you don't define the variables. It can be done faster if you have a lot of lines to go through or more things that you need to define your group with.
I have run into situations where a 'group' is based on 2-5 cells. This example only looks at one column, but it can be expanded easily if anyone takes the time to play with it.
This assumes 3 columns, and you have to sort by the group_values column.
Before you run the macro, select the first cell you want to compare in the group_values column.
'group_values, some_number, empty_columnToHoldSubtotals
'(stuff goes here)
'cookie 1 empty
'cookie 3 empty
'cake 4 empty
'hat 0 empty
'hat 3 empty
'...
'stop
Sub subtotal()
' define two strings and a subtotal counter thingy
Dim thisOne, thatOne As String
Dim subCount As Double
' seed the values
thisOne = ActiveCell.Value
thatOne = ActiveCell.Offset(1, 0)
subCount = 0
' setup a loop that will go until it reaches a stop value
While (ActiveCell.Value <> "stop")
' compares a cell value to the cell beneath it.
If (thisOne = thatOne) Then
' if the cells are equal, the line count is added to the subcount
subCount = subCount + ActiveCell.Offset(0, 1).Value
Else
' if the cells are not equal, the subcount is written, and subtotal reset.
ActiveCell.Offset(0, 2).Value = ActiveCell.Offset(0, 1).Value + subCount
subCount = 0
End If
' select the next cell down
ActiveCell.Offset(1, 0).Select
' assign the values of the active cell and the one below it to the variables
thisOne = ActiveCell.Value
thatOne = ActiveCell.Offset(1, 0)
Wend
End Sub