VBA a-t-il une structure de dictionnaire?

VBA a-t-il une structure de dictionnaire? Comme la clé tableau de valeurs?

Oui.

Définissez une référence à l’environnement d’exécution MS Scripting («Microsoft Scripting Runtime»). Comme pour le commentaire de @ regjo, allez dans Outils-> Références et cochez la case “Microsoft Scripting Runtime”.

Fenêtre de références

Créez une instance de dictionnaire en utilisant le code ci-dessous:

Set dict = CreateObject("Scripting.Dictionary") 

ou

 Dim dict As New Scripting.Dictionary 

Exemple d’utilisation:

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

N’oubliez pas de définir le dictionnaire sur Nothing lorsque vous avez fini de l’utiliser.

 Set dict = Nothing 

VBA a l’object de collection:

  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") 

L’object Collection effectue des recherches basées sur des clés à l’aide d’un hachage rapide.


Vous pouvez utiliser une fonction Contains() pour vérifier si une collection particulière contient une clé:

 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 

Edit 24 juin 2015 : Shorter Contains() grâce à @TWiStErRob.

Éditer le 25 septembre 2015 : Ajout de Err.Clear() grâce à @scipilot.

VBA n’a pas d’implémentation interne d’un dictionnaire, mais depuis VBA, vous pouvez toujours utiliser l’object dictionnaire à partir de MS Scripting Runtime Library.

 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 

Un exemple de dictionnaire supplémentaire utile pour contenir la fréquence des occurrences.

En dehors de la boucle:

 Dim dict As New Scripting.dictionary Dim MyVar as Ssortingng 

Dans une boucle:

 '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 

Pour vérifier la fréquence:

 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 

En partant de la réponse de cjrh , nous pouvons créer une fonction Contains ne nécessitant aucun libellé (je n’aime pas utiliser les étiquettes).

 Public Function Contains(Col As Collection, Key As Ssortingng) 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 

Pour un de mes projets, j’ai écrit un ensemble de fonctions d’aide pour que la Collection se comporte plus comme un Dictionary . Il permet toujours des collections récursives. Vous remarquerez que Key vient toujours en premier car il était obligatoire et plus logique dans ma mise en œuvre. J’ai également utilisé uniquement des clés Ssortingng . Vous pouvez le changer si vous le souhaitez.

Ensemble

Je l’ai renommé pour qu’il remplace les anciennes valeurs.

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

Obtenir

L’ err est pour les objects puisque vous devez passer des objects en utilisant set et variables sans. Je pense que vous pouvez simplement vérifier si c’est un object, mais j’ai été pressé par le temps.

 Private Function cGet(ByRef Col As Collection, Key As Ssortingng) 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 

A

La raison de ce post …

 Public Function cHas(Col As Collection, Key As Ssortingng) 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 

Retirer

Ne jette pas s’il n’existe pas. Assurez-vous simplement qu’il est retiré.

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

Clés

Obtenez un tableau de clés.

 Private Function cKeys(ByRef Col As Collection) As Ssortingng() Dim Initialized As Boolean Dim Keys() As Ssortingng 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 

Le script d’exécution du script semble avoir un bogue qui peut ruiner votre conception à un stade avancé.

Si la valeur du dictionnaire est un tableau, vous ne pouvez pas mettre à jour les valeurs des éléments contenus dans le tableau via une référence au dictionnaire.

Oui. Pour VB6 , VBA (Excel) et VB.NET

Si, pour une raison quelconque, vous ne pouvez pas installer de fonctionnalités supplémentaires sur votre Excel ou si vous ne le souhaitez pas, vous pouvez également utiliser des baies, au moins pour les problèmes simples. Comme WhatIsCapital vous mettez le nom du pays et la fonction vous retourne son capital.

 Sub arrays() Dim WhatIsCapital As Ssortingng, Country As Array, Capital As Array, Answer As Ssortingng 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 

Tous les autres ont déjà mentionné l’utilisation de la version scripting.runtime de la classe Dictionary. Si vous ne parvenez pas à utiliser cette DLL, vous pouvez également utiliser cette version, ajoutez-la simplement à votre code.

https://github.com/VBA-tools/VBA-Dictionary/blob/master/Dictionary.cls

Il est identique à la version de Microsoft.