data-structures excel - Hat VBA eine Dictionary-Struktur?




auslesen for (9)

Hat VBA eine Wörterbuchstruktur? Wie Schlüssel <> value array?


Answers

Das Skript Laufzeit-Wörterbuch scheint einen Fehler zu haben, der Ihr Design in fortgeschrittenen Stadien ruinieren kann.

Wenn der Wörterbuchwert ein Array ist, können Sie die Werte der Elemente im Array nicht durch einen Verweis auf das Wörterbuch aktualisieren.


Aufbauend auf Cjrhs Antwort können wir eine Contains-Funktion erstellen, die keine Labels benötigt (ich mag keine Labels).

Public Function Contains(Col As Collection, Key As String) As Boolean
    Contains = True
    On Error Resume Next
        err.Clear
        Col (Key)
        If err.Number <> 0 Then
            Contains = False
            err.Clear
        End If
    On Error GoTo 0
End Function

Für ein Projekt von mir habe ich eine Reihe von Hilfsfunktionen geschrieben, damit sich eine Collection mehr wie ein Dictionary verhält. Es erlaubt immer noch rekursive Sammlungen. Sie werden feststellen, dass Key immer an erster Stelle steht, da dies bei der Implementierung zwingend erforderlich und sinnvoller war. Ich habe auch nur String Schlüssel verwendet. Sie können es zurück ändern, wenn Sie mögen.

einstellen

Ich habe dies umbenannt, weil es alte Werte überschreiben wird.

Private Sub cSet(ByRef Col As Collection, Key As String, Item As Variant)
    If (cHas(Col, Key)) Then Col.Remove Key
    Col.Add Array(Key, Item), Key
End Sub

Bekommen

Das err ist für Objekte, da Sie Objekte ohne set und Variablen übergeben würden. Ich denke, du kannst einfach nachsehen, ob es ein Objekt ist, aber ich wurde auf Zeit gedrückt.

Private Function cGet(ByRef Col As Collection, Key As String) As Variant
    If Not cHas(Col, Key) Then Exit Function
    On Error Resume Next
        err.Clear
        Set cGet = Col(Key)(1)
        If err.Number = 13 Then
            err.Clear
            cGet = Col(Key)(1)
        End If
    On Error GoTo 0
    If err.Number <> 0 Then Call err.raise(err.Number, err.Source, err.Description, err.HelpFile, err.HelpContext)
End Function

Hat

Der Grund für diesen Beitrag ...

Public Function cHas(Col As Collection, Key As String) As Boolean
    cHas = True
    On Error Resume Next
        err.Clear
        Col (Key)
        If err.Number <> 0 Then
            cHas = False
            err.Clear
        End If
    On Error GoTo 0
End Function

Löschen

Würfelt nicht, wenn es nicht existiert. Stellt nur sicher, dass es entfernt wurde.

Private Sub cRemove(ByRef Col As Collection, Key As String)
    If cHas(Col, Key) Then Col.Remove Key
End Sub

Schlüssel

Holen Sie sich eine Reihe von Schlüsseln.

Private Function cKeys(ByRef Col As Collection) As String()
    Dim Initialized As Boolean
    Dim Keys() As String

    For Each Item In Col
        If Not Initialized Then
            ReDim Preserve Keys(0)
            Keys(UBound(Keys)) = Item(0)
            Initialized = True
        Else
            ReDim Preserve Keys(UBound(Keys) + 1)
            Keys(UBound(Keys)) = Item(0)
        End If
    Next Item

    cKeys = Keys
End Function

VBA hat das Sammlungsobjekt:

    Dim c As Collection
    Set c = New Collection
    c.Add "Data1", "Key1"
    c.Add "Data2", "Key2"
    c.Add "Data3", "Key3"
    'Insert data via key into cell A1
    Range("A1").Value = c.Item("Key2")

Das Collection Objekt führt schlüsselbasierte Suchen mit einem Hash durch, damit es schnell geht.

Sie können eine Contains() Funktion verwenden, um zu überprüfen, ob eine bestimmte Sammlung einen Schlüssel enthält:

Public Function Contains(col As Collection, key As Variant) As Boolean
    On Error Resume Next
    col(key) ' Just try it. If it fails, Err.Number will be nonzero.
    Contains = (Err.Number = 0)
    Err.Clear
End Function

Bearbeiten 24. Juni 2015 : Kürzere Contains() dank @TWiStErRob.

Bearbeiten 25. September 2015 : Err.Clear() dank @scipilot hinzugefügt.


Wenn Sie aus irgendeinem Grund keine zusätzlichen Funktionen in Excel installieren können oder wollen, können Sie auch Arrays verwenden, zumindest für einfache Probleme. Als WhatisCapital stellst du den Namen des Landes ein und die Funktion gibt dir ihr Kapital zurück.

Sub arrays()
Dim WhatIsCapital As String, Country As Array, Capital As Array, Answer As String

WhatIsCapital = "Sweden"

Country = Array("UK", "Sweden", "Germany", "France")
Capital = Array("London", "Stockholm", "Berlin", "Paris")

For i = 0 To 10
    If WhatIsCapital = Country(i) Then Answer = Capital(i)
Next i

Debug.Print Answer

End Sub

Ein zusätzliches Wörterbuchbeispiel, das nützlich ist, um die Häufigkeit des Auftretens zu enthalten.

Außerhalb der Schleife:

Dim dict As New Scripting.dictionary
Dim MyVar as String

Innerhalb einer Schleife:

'dictionary
If dict.Exists(MyVar) Then
    dict.Item(MyVar) = dict.Item(MyVar) + 1 'increment
Else
    dict.Item(MyVar) = 1 'set as 1st occurence
End If

Frequenz überprüfen:

Dim i As Integer
For i = 0 To dict.Count - 1 ' lower index 0 (instead of 1)
    Debug.Print dict.Items(i) & " " & dict.Keys(i)
Next i

VBA verfügt nicht über eine interne Implementierung eines Wörterbuchs, aber von VBA können Sie weiterhin das Wörterbuchobjekt von MS Scripting Runtime Library verwenden.

Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "a", "aaa"
d.Add "b", "bbb"
d.Add "c", "ccc"

If d.Exists("c") Then
    MsgBox d("c")
End If

Ja.

Einen Verweis auf die MS Scripting-Laufzeit festlegen ('Microsoft Scripting Runtime')

Set dict = CreateObject("Scripting.Dictionary")

oder

Dim dict As New Scripting.Dictionary 

Anwendungsbeispiel:

If Not dict.Exists(key) Then 
    dict.Add key, value
End If 

Vergessen Sie nicht, das Wörterbuch auf " Nothing zu setzen, wenn Sie es nicht mehr verwenden.

Set dict = Nothing 


Ich denke du hast gemeint:

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

Dies würde so sortiert sein:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))




vba dictionary data-structures vb6