VBA: apply dictionary to count

Nelson78

Well-known Member
Joined
Sep 11, 2017
Messages
526
Office Version
  1. 2007
Hello everybody.

I would like to improuve my ability to use dictionary, but unfortunately I have problem in understanding how they work.

For example, in the case below, the result in column C has to be the number of different values in column B for each value in column A. (You can see the result on column C in gray).

https://imgur.com/a/sHEh2Uc

I've tried this way:

Code:
Sub count()

Dim s1
Dim lr As Long, i As Long, n As Long
Dim rng As Range
Dim x, dict, it

Set s1 = Sheets("Sheet 1")

s1.AutoFilterMode = False
lr = s1.Cells(Rows.count, 1).End(xlUp).Row
x = s1.Range("A2:A" & lr)

Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(x, 1)
    dict.Item(x(i, 1)) = ""
Next i

For Each it In dict.keys

and then?
Something like

Code:
.AutoFilter 1, it

?
 
@Peter_SSs
You are quite right, it is.

Here is an modified version
Code:
Sub DicCount()
   Dim Ary As Variant
   Dim i As Long
   Dim Dic As Object
   
   Set Dic = CreateObject("scripting.dictionary")
   Ary = Range("A1", Range("A" & Rows.count).End(xlUp).Offset(, 2))
   For i = 2 To UBound(Ary)
      If Not Dic.exists(Ary(i, 1)) Then Dic.Add Ary(i, 1), CreateObject("scripting.dictionary")
      Dic(Ary(i, 1))(Ary(i, 2)) = Dic(Ary(i, 1))(Ary(i, 2)) + 1
   Next i
   For i = 2 To UBound(Ary)
      Ary(i, 3) = Dic(Ary(i, 1)).count
   Next i
   Range("C1").Resize(UBound(Ary)).Value = Application.Index(Ary, 0, 3)
End Sub

I'm trying to work with one more discriminating factor.

Something like this:

Code:
Sub DicCount2()

   Dim Ary As Variant
   Dim i As Long
   Dim dic As Object

   Set dic = CreateObject("scripting.dictionary")
   Ary = Range("A1", Range("A" & Rows.Count).End(xlUp).Offset(, 3))
   For i = 2 To UBound(Ary)
   
      If Not dic.exists(Ary(i, 1)) Then dic.Add Ary(i, 1), CreateObject("scripting.dictionary")
      dic(Ary(i, 1))(Ary(i, 2)) = dic(Ary(i, 1))(Ary(i, 2)) + 1
   
     [COLOR="#FF0000"] If Not dic.exists(Ary(i, 1))(Ary(i, 2)) Then[/COLOR] dic.Add Ary(i, 3), CreateObject("scripting.dictionary")
      dic(Ary(i, 1))(Ary(i, 2))(Ary(i, 3)) = dic(Ary(i, 1))(Ary(i, 2))(Ary(i, 3)) + 1
    
   Next i
   

   For i = 2 To UBound(Ary)
      Ary(i, 4) = dic(Ary(i, 1))(Ary(i, 2))(Ary(i, 3))
   Next i

   Range("D1").Resize(UBound(Ary)).Value = Application.Index(Ary, 0, 4)

End sub

error run-time '13' type mismatch in the red line
 
Last edited:
Upvote 0

Excel Facts

Test for Multiple Conditions in IF?
Use AND(test, test, test, test) or OR(test, test, test, ...) as the logical_test argument of IF.
Can you please explain what you are trying to do?
 
Upvote 0
How about
Code:
Sub DicCount2()

   Dim Ary As Variant
   Dim i As Long
   Dim dic As Object

   Set dic = CreateObject("scripting.dictionary")
   Ary = Range("A1", Range("A" & Rows.Count).End(xlUp).Offset(, 3))
   For i = 2 To UBound(Ary)
   
      If Not dic.exists(Ary(i, 1)) Then
         dic.Add Ary(i, 1), CreateObject("scripting.dictionary")
         dic(Ary(i, 1)).Add Ary(i, 2), CreateObject("scripting.dictionary")
         dic(Ary(i, 1))(Ary(i, 2)).Add Ary(i, 3), 1
      ElseIf Not dic(Ary(i, 1)).exists(Ary(i, 2)) Then
         dic(Ary(i, 1)).Add Ary(i, 2), CreateObject("scripting.dictionary")
         dic(Ary(i, 1))(Ary(i, 2)).Add Ary(i, 3), 1
      ElseIf Not dic(Ary(i, 1))(Ary(i, 2)).exists(Ary(i, 3)) Then
         dic(Ary(i, 1))(Ary(i, 2)).Add Ary(i, 3), 1
      Else
         dic(Ary(i, 1))(Ary(i, 2))(Ary(i, 3)) = dic(Ary(i, 1))(Ary(i, 2))(Ary(i, 3)) + 1
      End If
   Next i
   

   For i = 2 To UBound(Ary)
      Ary(i, 4) = dic(Ary(i, 1))(Ary(i, 2))(Ary(i, 3))
   Next i

   Range("D1").Resize(UBound(Ary)).Value = Application.Index(Ary, 0, 4)

End Sub
 
Upvote 0
.. or if your columns are still disjoint (I've used columns C, F and AQ - with results in column AR) & again just using a single dictionary:
Code:
Sub Dict_Count_v3()
  Dim lr As Long, i As Long
  Dim dict As Object
  Dim x As Variant
  
  ActiveSheet.AutoFilterMode = False
  lr = Cells(Rows.Count, "C").End(xlUp).Row
  x = Application.Index(Range("C1:AQ" & lr).Value, Evaluate("row(2:" & lr & ")"), Array(1, 4, 41))
  Set dict = CreateObject("Scripting.Dictionary")
  dict.CompareMode = 1
  For i = 1 To UBound(x, 1)
    dict(x(i, 1) & "|" & x(i, 2) & "|" & x(i, 3)) = dict(x(i, 1) & "|" & x(i, 2) & "|" & x(i, 3)) + 1
  Next i
  For i = 1 To UBound(x, 1)
    x(i, 1) = dict(x(i, 1) & "|" & x(i, 2) & "|" & x(i, 3))
  Next i
  Range("AR2:AR" & lr).Value = Application.Index(x, 0, 1)
End Sub

Excel Workbook
CFAQAR
1DateColourCodeResults
224/09/2017REDAAAAA2
324/09/2017GREENAAAAA2
424/09/2017YELLOWAAAAA1
524/09/2017REDEE1
624/09/2017GREENAAAAA2
724/09/2017YELLOWZZ1
824/09/2017REDAAAAA2
924/09/2017YELLOWBBB1
1024/09/2017GREENBBB2
1124/09/2017REDBBB1
1224/09/2017GREENBBB2
1324/09/2017YELLOWEE1
1425/09/2017REDBBB2
1525/09/2017REDBBB2
1625/09/2017REDCCCCCCCC4
1725/09/2017REDCCCCCCCC4
1825/09/2017REDCCCCCCCC4
1925/09/2017REDCCCCCCCC4
2025/09/2017YELLOWXXXXXXXXXX1
2125/09/2017GREENAAAAA3
2225/09/2017GREENAAAAA3
2325/09/2017GREENAAAAA3
Sheet2
 
Last edited:
Upvote 0

Forum statistics

Threads
1,216,075
Messages
6,128,657
Members
449,462
Latest member
Chislobog

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