First and simplest, if you know that there aren't many different values in the column, you could just use countif():
=COUNTIF(A1:A6, "Cat")
Otherwise, if you've got tons of different items in a column and you want an automated solution, a VBA routine that scans the column, tallies the counts of each item, and deposits those counts in other columns seems reasonable.
Sub CountAll()
Dim searchCol, itemsCol, countCol, sheetName As String
Dim i, j, startRow As Integer
Dim aCounts() As Variant
Dim bAdded, bFound As Boolean
startRow = 1
searchCol = "A"
itemsCol = "B"
countCol = "C"
sheetName = "Sheet1"
ReDim aCounts(2, 1)
With Sheets(sheetName)
For i = 1 To .Range(searchCol & startRow).End(xlDown).Row
For j = 1 To UBound(aCounts, 2)
If (.Range(searchCol & i).Value) = aCounts(0, j) Then
bFound = True
Exit For
Else
bFound = False
End If
Next
If (bFound) Then
aCounts(1, j) = aCounts(1, j) + 1
Else
If (aCounts(1, UBound(aCounts, 2)) <> "") Then
ReDim Preserve aCounts(2, UBound(aCounts, 2) + 1)
End If
aCounts(0, UBound(aCounts, 2)) = .Range(searchCol & i).Value
aCounts(1, UBound(aCounts, 2)) = 1
End If
Next
i = 1
For i = 1 To UBound(aCounts, 2)
.Range(itemsCol & i).Value = aCounts(0, i)
.Range(countCol & i).Value = aCounts(1, i)
Next
End With
End Sub
If all your sheets are similar and you want it to run on each sheet, just change the With Sheets(sheetName)
to For Each Sheet in Sheets
, change End With
to Next
, add Sheet
before each .Range
, and reset the array with each iteration:
For Each Sheet In Sheets()
ReDim aCounts(2, 1)
For i = 1 To Sheet.Range(searchCol & startRow).End(xlDown).Row
For j = 1 To UBound(aCounts, 2)
If (Sheet.Range(searchCol & i).Value) = aCounts(0, j) Then
bFound = True
Exit For
Else
bFound = False
End If
Next
If (bFound) Then
aCounts(1, j) = aCounts(1, j) + 1
Else
If (aCounts(1, UBound(aCounts, 2)) <> "") Then
ReDim Preserve aCounts(2, UBound(aCounts, 2) + 1)
End If
aCounts(0, UBound(aCounts, 2)) = Sheet.Range(searchCol & i).Value
aCounts(1, UBound(aCounts, 2)) = 1
End If
Next
For i = 1 To UBound(aCounts, 2)
Sheet.Range(itemsCol & i).Value = aCounts(0, i)
Sheet.Range(countCol & i).Value = aCounts(1, i)
Next
Next