VBA
Scripting.Diction-objekt
Sök…
Anmärkningar
Du måste lägga till Microsoft Scripting Runtime till VBA-projektet via VBE: s verktyg → Referenser-kommandot för att implementera tidig bindning av Scripting Dictionary-objektet. Denna bibliotekreferens tas med projektet; det behöver inte hänvisas till när VBA-projektet distribueras och körs på en annan dator.
Egenskaper och metoder
Ett Scripting Dictionary-objekt lagrar information i nyckel- / objektpar. Nycklarna måste vara unika och inte en matris men de tillhörande artiklarna kan upprepas (deras unikhet hålls av ledsagarnyckeln) och kan vara av alla typer av varianter eller objekt.
En ordbok kan betraktas som en tvåfält i minnesdatabas med ett primärt unikt index på det första 'fältet' ( nyckeln ). Det här unika indexet för Keys-egenskapen tillåter mycket snabba "sökningar" att hämta en nyckels tillhörande objektvärde.
Egenskaper
namn | läsa skriva | typ | beskrivning |
---|---|---|---|
CompareMode | läsa skriva | CompareMode konstant | Inställning av CompareMode kan endast utföras i en tom ordlista. Accepterade värden är 0 (vbBinaryCompare), 1 (vbTextCompare), 2 (vbDatabaseCompare). |
Räkna | läs bara | osignerat långt heltal | Ett enbaserat antal av nyckel- / objektpar i skriptordbokobjektet. |
Nyckel | läsa skriva | icke-matrisvariant | Varje enskild unik nyckel i ordboken. |
Objekt ( nyckel ) | läsa skriva | vilken variant som helst | Standardegenskap. Varje enskilt objekt associerat med en nyckel i ordboken. Observera att om du försöker hämta ett objekt med en nyckel som inte finns i ordboken implicit lägger till den passerade nyckeln. |
metoder
namn | beskrivning |
---|---|
Lägg till ( nyckel , artikel ) | Lägger till en ny nyckel och objekt i ordboken. Den nya nyckeln får inte finnas i ordlistans nuvarande nyckelsamling men ett objekt kan upprepas bland många unika nycklar. |
Finns ( nyckel ) | Boolesktest för att avgöra om en nyckel redan finns i ordboken. |
Keys | Returnerar matrisen eller samlingen av unika nycklar. |
artiklar | Returnerar arrayen eller samlingen av tillhörande objekt. |
Ta bort ( nyckel ) | Tar bort en enskild ordboksknapp och dess tillhörande objekt. |
Ta bort alla | Rensar alla nyckelord och objekt för ett ordbokobjekt. |
Exempelkod
'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
Samla data med Scripting.Diction (Maximum, Count)
Ordböcker är bra för att hantera information där flera poster inträffar, men du är bara upptagen med ett enda värde för varje uppsättning poster - det första eller sista värdet, mininmum eller maximivärde, ett genomsnitt, en summa etc.
Tänk på en arbetsbok som innehåller en logg över användaraktivitet, med ett skript som sätter in användarnamn och redigeringsdatum varje gång någon redigerar arbetsboken:
Log
kalkylbladet
EN B guppa 10/12/2016 9:00 alice 10/13/2016 13:00 guppa 10/13/2016 13:30 alice 10/13/2016 14:00 alice 10/14/2016 13:00
Låt oss säga att du vill mata ut den senaste redigeringstiden för varje användare i ett kalkylblad som heter Summary
.
Anmärkningar:
1. ActiveWorkbook
antas vara i ActiveWorkbook
.
2. Vi använder en matris för att dra värdena från kalkylbladet; detta är mer effektivt än att iterera över varje cell.
3. Dictionary
skapas med tidig bindning.
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
och utgången ser ut så här:
Summary
kalkylblad
EN B guppa 10/13/2016 13:30 alice 10/14/2016 13:00
Om du å andra sidan vill skriva ut hur många gånger varje användare redigerade arbetsboken, ska kroppen på For
slingan se ut så här:
'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
och utgången ser ut så här:
Summary
kalkylblad
EN B guppa 2 alice 3
Få unika värden med Scripting.Diction
Dictionary
gör det möjligt att få en unik uppsättning värden mycket enkelt. Tänk på följande funktion:
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
som du då kan kalla så här:
Dim duplicates() As Variant
duplicates = Array(1, 2, 3, 1, 2, 3)
Dim uniqueVals() As Variant
uniqueVals = Unique(duplicates)
och uniqueVals
skulle innehålla endast {1,2,3}
.
Obs: Denna funktion kan användas med valfritt antal objekt.