Create dictionary of lists in vba

后端 未结 3 1561
野趣味
野趣味 2020-12-15 07:07

I have worked in Python earlier where it is really smooth to have a dictionary of lists (i.e. one key corresponds to a list of stuff). I am struggling to achieve the same in

相关标签:
3条回答
  • 2020-12-15 07:48

    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 Worksheet
    Set wS = ActiveSheet
    
    Dim 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 If
    
    Next i
    
    End Sub
    
    0 讨论(0)
  • 2020-12-15 07:53

    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 vParentKey
    
    End Sub
    
    0 讨论(0)
  • 2020-12-15 07:54

    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 String
    stringArray(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 Collection
    coll.Add ("coll1")
    coll.Add ("coll2")
    coll.Add ("coll3")
    If Not dict.Exists("dict1") Then
        dict.Add "dict1", coll
    End If
    
    Dim curVal As String: curVal = dict("dict1")(3) '-> "coll3"
    
    Set dict = Nothing 
    
    0 讨论(0)
提交回复
热议问题