VBA question regarding multiple instances of strings

rmfrase

Board Regular
Joined
Jul 6, 2006
Messages
132
Office Version
  1. 365
Platform
  1. Windows
I'm working on a Macro but I'm struggling.
I'm needing to count each instance of unique text strings in a column. (Has a column header "Status".)
The number of each unique text strings will vary from 2 to about 30, but the spreadsheet will have up to several hundred rows with multiples of each. So it's possible to have close to 100 different unique text strings.
The macro starts counting from Row 2 and goes to the last row.
I will then need to display the results in an Alpha order in one column along with the quantity of each in the next.
I tried doing a Pivot Table macro, but kept running into an error 5 as the export constantly has variable row counts.
Any suggestions?

I wanted to try a 2D array (if that's the correct term) like Stat(x,y) where the x was "string" and y the number of instances of x, But couldn't figure how to increment y.
 

Excel Facts

Whats the difference between CONCAT and CONCATENATE?
The newer CONCAT function can reference a range of cells. =CONCATENATE(A1,A2,A3,A4,A5) becomes =CONCAT(A1:A5)
What version of Excel are you using and are you on Windows ?
(Please update your profile to show which version)
If you have MS365 or O2021 do you really need to use VBA to do that, they have easy to use functions that could do that.
You could also leverage off these functions in VBA as opposed to using a data dictionary which is a common way of getting unique value in VBA and also for counting or summing values for them.

Power Query would be another option.
 
Upvote 0
I suggest that you update your Account details (or click your user name at the top right of the forum) so helpers always know what Excel version(s) & platform(s) you are using as the best solution often varies by version. (Don’t forget to scroll down & ‘Save’)

You could probably do this with formulas rather than a macro. Would that be a suitable option?

If you do want a macro, see if you can adapt this. My Status column is column A and the results go into columns F:G

VBA Code:
Sub Count_Strings()
  Dim d As Object
  Dim a As Variant
  Dim i As Long
  
  a = Range("A2", Range("A" & Rows.Count).End(xlUp)).Value
  Set d = CreateObject("Scripting.Dictionary")
  For i = 1 To UBound(a)
    d(a(i, 1)) = d(a(i, 1)) + 1
  Next i
  With Range("F2:G2").Resize(d.Count)
    .Value = Application.Transpose(Array(d.Keys, d.Items))
    .Sort Key1:=.Cells(1, 1), Order1:=xlAscending, Header:=xlNo
  End With
End Sub
 
Upvote 0
Solution
Your macro example worked perfectly!
Good news! Thanks for the confirmation. :)

.. and thanks for updating your version information. (y)

So, with my sample data in column A below, the code I suggested produced the values in columns F:G but note that the formula in cell J2 produces identical results.

rmfrase.xlsm
ABCDEFGHIJK
1Status
2aa1a1
3bb1b1
4gd4d4
5fe4e4
6rf4f4
7gg3g3
8fr2r2
9ds1s1
10esw1sw1
11dt1t1
12fw7w7
13gx1x1
14t
15r
16f
17d
18d
19e
20e
21e
22s
23x
24sw
25w
26w
27w
28w
29w
30w
31w
Sheet1
Cell Formulas
RangeFormula
J2:K13J2=LET(u,SORT(UNIQUE(A2:A31)),HSTACK(u,COUNTIF(A2:A31,u)))
Dynamic array formulas.
 
Last edited:
Upvote 0
Thanks. I'm working to have the macro find the column header by name as it's possible that my teams exports may have the status column in a different spot.
Instead of 'A', it may be in 'R'
 
Upvote 0
You have not said where the results should go. This code puts them on the same sheet to the right of any other data on the sheet.
The code assumes that there will always be a cell in row 1 with a value of "Status".

VBA Code:
Sub Count_Strings_v2()
  Dim d As Object
  Dim a As Variant
  Dim i As Long, MyCol As Long, LastCol As Long
  
  MyCol = Rows(1).Find(What:="Status", LookAt:=xlWhole, MatchCase:=False).Column
  LastCol = Cells.Find(What:="*", LookIn:=xlValues, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
  a = Cells(1, MyCol).Resize(Cells(Rows.Count, MyCol).End(xlUp).Row).Value
  Set d = CreateObject("Scripting.Dictionary")
  For i = 1 To UBound(a)
    d(a(i, 1)) = d(a(i, 1)) + 1
  Next i
  With Cells(1, LastCol + 2).Resize(d.Count, 2)
    .Value = Application.Transpose(Array(d.Keys, d.Items))
    .Cells(1, 2).Value = "Count"
    .Sort Key1:=.Cells(1, 1), Order1:=xlAscending, Header:=xlYes
  End With
End Sub
 
Upvote 0
Thank you very much! I was actually able to have a [Tab] added and the results are sent there. I then add in column headers for the rows as well as Percent calculations for the rows and a Total amount (in order to obtain the "% to Total".
The end result looks like what I would have done with a pivot table. Had it not been a pain.
 
Upvote 0
You're welcome. Thanks for the additional information - it seems you are closing in on what you are after. :)
 
Upvote 0

Forum statistics

Threads
1,223,869
Messages
6,175,088
Members
452,611
Latest member
bls2024

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top