Create dictionary of lists in vba Create dictionary of lists in vba vba vba

Create dictionary of lists in vba


Arrays in VBA are more or less like everywhere else with various peculiarities:

  • Redimensioning an array is possible (although not required).
  • Most of the array properties (e.g., Sheets array in a Workbook) are 1-based. Although, as rightly pointed out by @TimWilliams, the user-defined arrays are actually 0-based. The array below defines a string array with a length of 11 (10 indicates the upper position).

Other than that and the peculiarities regarding notations, you shouldn't find any problem to deal with VBA arrays.

Dim stringArray(10) As StringstringArray(1) = "first val"stringArray(2) = "second val"'etc.

Regarding what you are requesting, you can create a dictionary in VBA and include a list on it (or the VBA equivalent: Collection), here you have a sample code:

Set dict = CreateObject("Scripting.Dictionary")Set coll = New Collectioncoll.Add ("coll1")coll.Add ("coll2")coll.Add ("coll3")If Not dict.Exists("dict1") Then    dict.Add "dict1", collEnd IfDim curVal As String: curVal = dict("dict1")(3) '-> "coll3"Set dict = Nothing 


You can have dictionaries within dictionaries. No need to use arrays or collections unless you have a specific need to.

Sub FillNestedDictionairies()    Dim dcParent As Scripting.Dictionary    Dim dcChild As Scripting.Dictionary    Dim rCell As Range    Dim vaSplit As Variant    Dim vParentKey As Variant, vChildKey As Variant    Set dcParent = New Scripting.Dictionary    'Don't use currentregion if you have adjacent data    For Each rCell In Sheet2.Range("A1").CurrentRegion.Cells        'assume the text is separated by a space        vaSplit = Split(rCell.Value, Space(1))        'If it's already there, set the child to what's there        If dcParent.Exists(vaSplit(0)) Then            Set dcChild = dcParent.Item(vaSplit(0))        Else 'create a new child            Set dcChild = New Scripting.Dictionary            dcParent.Add vaSplit(0), dcChild        End If        'Assumes unique post-space data - text for Exists if that's not the case        dcChild.Add CStr(vaSplit(1)), vaSplit(1)    Next rCell    'Output to prove it works    For Each vParentKey In dcParent.Keys        For Each vChildKey In dcParent.Item(vParentKey).Keys            Debug.Print vParentKey, vChildKey        Next vChildKey    Next vParentKeyEnd Sub


I am not that familiar with C++ and Python (been a long time) so I can't really speak to the differences with VBA, but I can say that working with Arrays in VBA is not especially complicated.

In my own humble opinion, the best way to work with dynamic arrays in VBA is to Dimension it to a large number, and shrink it when you are done adding elements to it. Indeed, Redim Preserve, where you redimension the array while saving the values, has a HUGE performance cost. You should NEVER use Redim Preserve inside a loop, the execution would be painfully slow

Adapt the following piece of code, given as an example:

Sub CreateArrays()Dim wS As WorksheetSet wS = ActiveSheetDim Flanged_connections()ReDim Flanged_connections(WorksheetFunction.CountIf(wS.Columns(1), _    "Flanged_connections"))For i = 1 To wS.Cells(1, 1).CurrentRegion.Rows.Count Step 1    If UCase(wS.Cells(i, 1).Value) = "FLANGED_CONNECTIONS" Then   ' UCASE = Capitalize everything        Flanged_connections(c1) = wS.Cells(i, 2).Value    End IfNext iEnd Sub