Ricerca…


Osservazioni

È necessario aggiungere Microsoft Scripting Runtime al progetto VBA tramite il comando Strumenti → Riferimenti di VBE per implementare l'associazione anticipata dell'oggetto Dizionario di script. Questo riferimento bibliografico è portato con il progetto; non deve essere rinviato quando il progetto VBA viene distribuito ed eseguito su un altro computer.

Proprietà e metodi

Un oggetto Scripting Dictionary memorizza le informazioni nelle coppie chiave / oggetto. Le chiavi devono essere uniche e non un array, ma gli articoli associati possono essere ripetuti (la loro unicità è detenuta dalla chiave companion) e possono essere di qualsiasi tipo di variante o oggetto.

Un dizionario può essere considerato come un database di due campi in memoria con un indice univoco primario sul primo 'campo' (la chiave ). Questo indice univoco sulla proprietà Keys consente "ricerche" molto rapide per recuperare il valore dell'articolo associato di una chiave.


Proprietà

nome leggere scrivere genere descrizione
CompareMode leggere scrivere CompareMode costante L'impostazione di CompareMode può essere eseguita solo su un dizionario vuoto. I valori accettati sono 0 (vbBinaryCompare), 1 (vbTextCompare), 2 (vbDatabaseCompare).
Contare sola lettura intero lungo senza segno Un conteggio basato su un singolo delle coppie chiave / articolo nell'oggetto del dizionario di scripting.
Chiave leggere scrivere variante non array Ogni singola chiave univoca nel dizionario.
Articolo ( chiave ) leggere scrivere qualsiasi variante Proprietà di default. Ogni singolo elemento associato a una chiave nel dizionario. Si noti che il tentativo di recuperare un elemento con una chiave che non esiste nel dizionario aggiungerà implicitamente la chiave passata.

metodi

nome descrizione
Aggiungi ( chiave , articolo ) Aggiunge una nuova chiave ed elemento al dizionario. La nuova chiave non deve esistere nella collezione Keys corrente del dizionario, ma un elemento può essere ripetuto tra molte chiavi univoche.
Esiste ( chiave ) Test booleano per determinare se una chiave esiste già nel dizionario.
chiavi Restituisce la matrice o la raccolta di chiavi univoche.
Elementi Restituisce la matrice o la raccolta di elementi associati.
Rimuovi ( chiave ) Rimuove una singola chiave del dizionario e il relativo oggetto associato.
Rimuovi tutto Cancella tutte le chiavi e gli oggetti di un dizionario.

Codice di esempio

'Populate, enumerate, locate and remove entries in a dictionary that was created
'with late binding
Sub iterateDictionaryLate()
    Dim k As Variant, dict As Object
    
    Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare          'non-case sensitive compare model
    
    'populate the dictionary
    dict.Add Key:="Red", Item:="Balloon"
    dict.Add Key:="Green", Item:="Balloon"
    dict.Add Key:="Blue", Item:="Balloon"
    
    'iterate through the keys
    For Each k In dict.Keys
        Debug.Print k & " - " & dict.Item(k)
    Next k

    'locate the Item for Green
    Debug.Print dict.Item("Green")
    
    'remove key/item pairs from the dictionary
    dict.Remove "blue"      'remove individual key/item pair by key
    dict.RemoveAll          'remove all remaining key/item pairs

End Sub

'Populate, enumerate, locate and remove entries in a dictionary that was created
'with early binding (see Remarks)
Sub iterateDictionaryEarly()
    Dim d As Long, k As Variant
    Dim dict As New Scripting.Dictionary
    
    dict.CompareMode = vbTextCompare          'non-case sensitive compare model
    
    'populate the dictionary
    dict.Add Key:="Red", Item:="Balloon"
    dict.Add Key:="Green", Item:="Balloon"
    dict.Add Key:="Blue", Item:="Balloon"
    dict.Add Key:="White", Item:="Balloon"
    
    'iterate through the keys
    For Each k In dict.Keys
        Debug.Print k & " - " & dict.Item(k)
    Next k

    'iterate through the keys by the count
    For d = 0 To dict.Count - 1
        Debug.Print dict.Keys(d) & " - " & dict.Items(d)
    Next d
    
    'iterate through the keys by the boundaries of the keys collection
    For d = LBound(dict.Keys) To UBound(dict.Keys)
        Debug.Print dict.Keys(d) & " - " & dict.Items(d)
    Next d
    
    'locate the Item for Green
    Debug.Print dict.Item("Green")
    'locate the Item for the first key
    Debug.Print dict.Item(dict.Keys(0))
    'locate the Item for the last key
    Debug.Print dict.Item(dict.Keys(UBound(dict.Keys)))
    
    'remove key/item pairs from the dictionary
    dict.Remove "blue"                         'remove individual key/item pair by key
    dict.Remove dict.Keys(0)                   'remove first key/item by index position
    dict.Remove dict.Keys(UBound(dict.Keys))   'remove last key/item by index position
    dict.RemoveAll                             'remove all remaining key/item pairs

End Sub

Dati aggregati con Scripting.Dictionary (Maximum, Count)

I dizionari sono grandi per la gestione delle informazioni in cui si verificano più voci, ma si è interessati solo a un singolo valore per ogni insieme di voci: il primo o l'ultimo valore, il mininmum o il valore massimo, una media, una somma, ecc.

Considera una cartella di lavoro che contiene un registro dell'attività dell'utente, con uno script che inserisce il nome utente e modifica la data ogni volta che qualcuno modifica la cartella di lavoro:

Log foglio di lavoro

UN B
peso 10/12/2016 9:00
alice 13/10/2016 13:00
peso 13/10/2016 13:30
alice 13/10/2016 14:00
alice 14/10/2016 13:00

Supponiamo di voler emettere l'ultima ora di modifica per ciascun utente in un foglio di lavoro denominato Summary .

Gli appunti:
1. Si presume che i dati siano in ActiveWorkbook .
2. Stiamo usando una matrice per estrarre i valori dal foglio di lavoro; questo è più efficiente di iterare su ogni cella.
3. Il Dictionary viene creato utilizzando l'associazione anticipata.

Sub LastEdit()
Dim vLog as Variant, vKey as Variant
Dim dict as New Scripting.Dictionary
Dim lastRow As Integer, lastColumn As Integer
Dim i as Long
Dim anchor As Range

With ActiveWorkbook
    With .Sheets("Log")
        'Pull entries in "log" into a variant array
        lastRow = .Range("a" & .Rows.Count).End(xlUp).Row
        vlog = .Range("a1", .Cells(lastRow, 2)).Value2

        'Loop through array
        For i = 1 to lastRow
            Dim username As String
            username = vlog(i, 1)
            Dim editDate As Date
            editDate = vlog(i, 2)

            'If the username is not yet in the dictionary:
            If Not dict.Exists(username) Then
                dict(username) = editDate
            ElseIf dict(username) < editDate Then
                dict(username) = editDate
            End If
        Next
    End With

    With .Sheets("Summary")
        'Loop through keys
        For Each vKey in dict.Keys
            'Add the key and value at the next available row
            Anchor = .Range("A" & .Rows.Count).End(xlUp).Offset(1,0)
            Anchor = vKey
            Anchor.Offset(0,1) = dict(vKey)
        Next vKey
    End With
End With
End Sub

e l'output sarà simile a questo:

Foglio di lavoro Summary

UN B
peso 13/10/2016 13:30
alice 14/10/2016 13:00

Se invece vuoi mostrare quante volte ogni utente ha modificato la cartella di lavoro, il corpo del ciclo For dovrebbe apparire così:

        'Loop through array
        For i = 1 to lastRow
            Dim username As String
            username = vlog(i, 1)

            'If the username is not yet in the dictionary:
            If Not dict.Exists(username) Then
                dict(username) = 1
            Else
                dict(username) = dict(username) + 1
            End If
        Next

e l'output sarà simile a questo:

Foglio di lavoro Summary

UN B
peso 2
alice 3

Ottenere valori univoci con Scripting.Dictionary

Il Dictionary consente di ottenere un insieme di valori unico in modo molto semplice. Considera la seguente funzione:

Function Unique(values As Variant) As Variant()
    'Put all the values as keys into a dictionary
    Dim dict As New Scripting.Dictionary
    Dim val As Variant
    For Each val In values
        dict(val) = 1 'The value doesn't matter here
    Next
    Unique = dict.Keys
End Function

che puoi chiamare così:

Dim duplicates() As Variant
duplicates = Array(1, 2, 3, 1, 2, 3)
Dim uniqueVals() As Variant
uniqueVals = Unique(duplicates)

e uniqueVals conterrebbe solo {1,2,3} .

Nota: questa funzione può essere utilizzata con qualsiasi oggetto enumerabile.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow