VBA Dictionary Objects

Innholdsfortegnelse

Bruke en VBA -ordbok

En VBA -ordbok fungerer på lignende måte som et samleobjekt, men den har flere egenskaper og metoder, og gir mer fleksibilitet

Ordboken lagrer dataene i minnet og kan enkelt manipuleres. Det er ingen automatisk beregning, bakgrunnssikkerhetskopiering og skjermoppfriskning nødvendig, så koden din vil kjøre betydelig raskere.

Ordbokobjektet fungerer på samme måte som en vanlig ordbok som du vil bruke hvis du vil finne betydningen av et ord. Hver oppføring i ordbokobjektet har en "nøkkel" -verdi og en "element" -verdi. Du bruker ‘nøkkelen’ nøkkelverdien til å slå opp elementverdien i ordbokobjektet, på samme måte som du ville brukt en konvensjonell ordbok.

På grunn av måten ordboksobjektet fungerer på, må nøkkelverdiene alle være unike, på samme måte som i en konvensjonell ordbok. Tenk hvis du åpnet den konvensjonelle ordboken for å slå opp betydningen av et ord, og fant ordet som er oppført mer enn én gang med to helt forskjellige definisjoner. Du ville bli veldig forvirret!

Nøkkelverdier er vanligvis tekst eller tall, eller begge deler. Brukere synes ofte det er lettere å huske navn på nøkler som tekst i stedet for bare tall.

I sammenligning med et samlingsobjekt er samlingsobjektet skrivebeskyttet. Den har bare to metoder (Legg til og fjern) og to egenskaper (Count og Item). Når et element er lagt til i et samleobjekt, kan det bare fjernes, men ikke redigeres, noe som er en tungvint prosedyre hvis verdien av et element må endres.

Et ordbokobjekt endres automatisk i størrelse for å passe til antallet elementer i det. Det trenger ikke å være definert i størrelse, som en konvensjonell matrise

Ordbokobjektet er endimensjonalt og datatypen er ‘Variant’, så enhver datatype kan legges inn i den f.eks. numerisk, tekst, dato

VBA -ordboken er ikke hjemmehørende i Excel, og må nås enten ved tidlig eller sen binding når du definerer ordbokobjektet

123 Sub EarlyBindingExample ()Dim MyDictionary As New Scripting.DictionarySlutt Sub
1234 Sub LateBindingExample ()Dim MyDictionary Som objektSett MyDictionary = CreateObject ("Scripting.Dictionary")Slutt Sub

Hvis du bruker den tidlige bindingen, må du legge til en referanse til biblioteket "Microsoft Scripting Runtime"

Du gjør dette ved å velge ‘Verktøy | Referanser på menylinjen i Visual Basic Editor (VBE) -vinduet og et popup-vindu vil vises med en liste over tilgjengelige biblioteker.

Rull ned til ‘Microsoft Scripting Runtime’ og merk av i boksen ved siden av. Klikk OK, og dette biblioteket er nå en del av ditt VBA -prosjekt og kan refereres til ved hjelp av tidlig binding. Alle eksempler på kode i denne artikkelen vil bruke tidlig binding.

Koden din vil kjøre betydelig raskere med tidlig binding, fordi den er samlet på forhånd. Ved sen binding må objektet kompileres mens koden kjører

Scripting Runtime -biblioteket har ‘Intellisense’. Når du skriver koden din, vil du se lister over tilgjengelige metoder og egenskaper som hjelper deg med å forhindre feil i stavemåten, noe som vil forårsake feil i programmet

Hvis du også trykker på F2 i VBE, og velger "Scripting" -biblioteket, vil du se alle tilgjengelige metoder og egenskaper og parametrene som kreves for hver

Distribuere Excel -applikasjonen din som inneholder en ordbok

Som allerede påpekt, er Scripting Runtime -biblioteket ikke en del av Excel VBA, så hvis du distribuerer applikasjonen din til andre brukere, må de ha tilgang til Scripting Runtime -biblioteket på datamaskinen. Hvis de ikke har det, vil det oppstå en feil.

Det er en god idé å inkludere noen VBA -kode for å kontrollere at dette biblioteket er tilstede når Excel -programmet er lastet. Du kan bruke "Dir" -kommandoen til å gjøre dette på "Workbook Open" -hendelsen

Plasseringen av filen er C: \ Windows \ SysWOW64 \ scrrun.dll

Omfang av et ordbokobjekt

Ordbok -objektet er bare tilgjengelig mens Excel -arbeidsboken er åpen. Den blir ikke lagret når arbeidsboken er lagret.

Hvis ordboken din skal være tilgjengelig for alle rutinene i modulen din, må du deklarere den (Dim) i delen Deklarere helt øverst i modulen

Du definerer det som et globalt objekt hvis du vil at ordboken skal brukes i hele koden.

1 Global My Dictionary som ny ordbok

Befolkning og lesing fra ordboken din

Til å begynne med må du opprette en ordbok, fylle den med noen data, og deretter gjenta den for å bevise at dataene eksisterer

1234567891011 Sub PopulateReadDictionary ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Legg til "MyItem1", 10MyDictionary.Legg til "MyItem2", 20MyDictionary.Legg til "MyItem3", 30For n = 0 til MyDictionary.Count - 1MsgBox MyDictionary.Keys (n) & "" & MyDictionary.Items (n)Neste nSlutt Sub

Denne koden oppretter et nytt ordbokobjekt kalt 'MyDictionary' og fyller det deretter ut med tre elementer. Add -metoden har to parametere - nøkkel og element, og de er begge påkrevde

Datatypene for nøkkel og element er begge varianter, så de godtar alle typer data - numerisk, tekst, dato osv

Det første elementet i ordlisten kan legges til som:

1 MyDictionary.Add 10, "MyItem1"

Verdiene er reversert mellom nøkkel og element, men dette vil fortsatt fungere, selv om søketasten nå ville bli 10.

Det er imidlertid viktig å forstå at nøkkelverdien er oppslagsverdien i ordboken. Det fungerer på en veldig lignende måte som VLOOKUP -funksjonen i Excel. Fordi alle nøklene må ha unike verdier, kan du angi en nøkkelverdi og umiddelbart returnere varen for denne nøkkelen.

Vær oppmerksom på at ordbokindeksen starter på 0, så du må trekke 1 fra ordlistetellingen som brukes i For… Next -løkken

Du kan også bruke en For … Hver sløyfe til å lese verdiene i ordboken:

1234567891011 Sub PopulateReadDictionary ()Dim MyDictionary As New Scripting. Dictionary, I As VariantMyDictionary.Legg til "MyItem1", 10MyDictionary.Legg til "MyItem2", 20MyDictionary.Legg til "MyItem3", 30For hver I In MyDictionary.KeysMsgBox I & "" & MyDictionary (I)Neste jegSlutt Sub

Denne koden går gjennom hvert element og viser varenøkkelen og varens verdi

Bruke vareindeksnummeret

Du kan bruke indeksnummeret til en nøkkel eller et element for å lese verdien

123456789101112 DelindeksNumre ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.CompareMode = TextCompareMyDictionary.Legg til "Item1", 10MyDictionary.Legg til "Item2", 20MyDictionary.Legg til "Item3", 30MsgBox MyDictionary.Keys (2)MsgBox MyDictionary.Items (1)Slutt Sub

Denne koden returnerer nøkkelen ‘item3’ ettersom indeksen starter på 0, og elementverdien 20

Du kan referere til individuelle nøkkel- eller elementverdier i nøklene eller elementene ved å bruke indeksnumrene.

Filtrering av ordboken

Det er ikke en direkte metode for å gjøre dette, men det er ganske enkelt å skrive kode for å gjøre det:

1234567891011 Sub FilterDiction ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Legg til "AAItem1", 10MyDictionary.Legg til "BBItem2", 20MyDictionary.Legg til "BBItem3", 30For hvert I In Filter (MyDictionary.Keys, "BB")MsgBox MyDictionary.Item (I)Neste jegSlutt Sub

Filterverdien fungerer bare fra begynnelsen av nøkkelverdien. Du kan ikke bruke jokertegn i filteret. Denne koden returnerer de to elementverdiene med nøkkelnavn som begynner med 'BB'

Dette vil gi deg et delsett av ordlisten basert på filterverdien din, som du deretter kan overføre til en annen ordbok eller et regneark. Med nøye planlegging av viktige navn, og sørg for at det er et meningsfullt prefiks for hver, ville du enkelt kunne dele ordboken i forskjellige komponentdeler.

Endre en varens verdi for en nøkkel

Ordbokobjektet har en stor fordel i forhold til en samling ved at vareverdien kan endres f.eks.

1 MyDictionary ("MyItem4") = "40"

I samlingen må du slette den oppføringen og deretter lage den på nytt.

Her er et kodeeksempel:

12345678910111213 Sub PopulateReadDictionary ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Legg til "MyItem1", 10MyDictionary.Legg til "MyItem2", 20MyDictionary.Legg til "MyItem3", 30MyDictionary ("MyItem2") = "25"MyDictionary ("MyItem4") = "40"For n = 0 til MyDictionary.Count - 1MsgBox MyDictionary.Keys (n) & "" & MyDictionary.Items (n)Neste nSlutt Sub

Koden ovenfor setter opp tre elementer i ordlisten, og endrer deretter verdien til ‘MyItem2’ fra 20 til 25.

Det endrer også verdien av ‘MyItem4’ til 40. Vær oppmerksom på at det ikke ble lagt til ‘MyItem4’ i tilleggsetningene i koden. Når du endrer verdien til en nøkkel som ikke eksisterer, opprettes den automatisk. Dette er ekstremt praktisk, siden ingen feil utløses, men det betyr at du må være forsiktig med nøkkelnavnene dine. En utilsiktet stavefeil i nøkkelnavnet vil bety at en ny nøkkel opprettes, og det opprinnelige nøkkelnavnet vil fortsatt ha den gamle verdien.

Dette kan lett føre til integritetsproblemer i ordbokobjektet.

Test om det finnes en nøkkel

Du kan kontrollere om det finnes en nøkkelverdi i ordlisten

123456789 Sub CheckExistsDictionary ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Legg til "MyItem1", 10MyDictionary.Legg til "MyItem2", 20MyDictionary.Legg til "MyItem3", 30MsgBox MyDictionary.Exists ("MyItem8")Slutt Sub

Koden legger til tre elementer i et nytt ordbokobjekt, og tester deretter for en nøkkel ('MyItem8') som ikke er i ordlisten. Dette returnerer False, men hadde en av de eksisterende nøklene blitt brukt, ville det returnere True

Jokertegn godtas ikke. Søketekst er også skift mellom store og små bokstaver, men dette kan endres (se senere i artikkelen)

Bruke flere verdier i en ordbok

I motsetning til en matrise er ordboksobjektet bare en dimensjonal. Dette kan føre til problemer hvis du har flere verdier du vil sette mot en nøkkel.

En vei rundt dette er å sammenkoble hver elementverdi ved å bruke et skilletegn mellom hver verdi f.eks. '|'

12345678910111213141516171819202122232425262728293031323334 Sub MultipleValues ​​()'Lag ordlisteobjekt og variablerDim MyDictionary As New Scripting.Dictionary, V1 As Integer, V2 As StringDim V3 As Date, Temp As String, N As Integer'Fyll ut 3 variabler for å demonstrere flere verdierV1 = 5V2 = "Eksempel på flere verdier"V3 = "22. juli 2020"'Legg til den sammenkoblede verdien i ordlisten ved å bruke "|" avgrensningMyDictionary.Add "MyMultipleItem", V1 & "|" & V2 & "|" & V3 & "|"'Fang den sammenkoblede ordbokverdien fra ordlisten til en variabelTemp = MyDictionary ("MyMultipleItem")'Skift gjennom den sammenkoblede strengen for å skille de enkelte verdieneGjøre'Finn posisjonen til en skilletegnN = InStr (Temp, "|")'Hvis det ikke er flere avgrensere, må du gå ut av sløyfenHvis N = 0, avslutter du Do'Vis tekst i forhold til plasseringen av skilletegn funnetMsgBox Venstre (Temp, N - 1)'Avkort den sammenkoblede strengen til neste tegn etter at skilletegnet er funnetTemp = Midt (Temp, N + 1)LøkkeSlutt Sub

En annen vei rundt dette problemet er å designe ditt eget underskriptsystem for viktige navn. Det er ingen grunn til at du ikke skal bruke parenteser og tall i nøkkelnavn

1234567891011 Sub MultipleValues ​​()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Add "Multiple (1)", 5MyDictionary.Add "Multiple (2)", "Eksempel på flere verdier"MyDictionary.Add "Multiple (3)", "22-Jul-2020"For N = 1 til 3MsgBox MyDictionary ("Multiple (" & N & ")")Neste NSlutt Sub

Denne koden legger til tre nøkler i ordlisten, men hvert tastenavn inneholder et underskriptnummer i parentes. Du kan deretter referere til nøkkelenavnet, men ved å bruke subskriptnummeret sammenkoblet. Dette ligner veldig på å bruke et matriseobjekt

Sletter elementer

Du kan fjerne individuelle elementer ved å referere til nøkkelverdien

1 MyDictionary.Remove ("MyItem2")

Vær oppmerksom på at fordi nøkkelenavn er unike, fjerner dette bare den bestemte nøkkelen og elementverdien

Du kan også slette ordboken helt

1 MyDictionary.RemoveAll

Her er et eksempel på bruk av ‘Fjern’ i VBA:

12345678910111213141516 Sub RemoveValues ​​()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Legg til "Item1", 10MyDictionary.Legg til "Item2", 20MyDictionary.Legg til "Item3", 30MyDictionary.Remove ("Item2")For N = 0 Til MyDictionary.Count - 1MsgBox MyDictionary.Keys (N) & "" & MyDictionary.Items (N)Neste NMyDictionary.RemoveAllMsgBox MyDictionary.CountSlutt Sub

Koden legger til tre elementer i ordlisten, og fjerner deretter "Item2". Deretter går det gjennom ordboken for å bevise at "Item2" ikke lenger eksisterer

Til slutt fjerner koden alle elementene i ordlisten og viser ordboktallet, som nå er null.

Endre saksfølsomhet for søk

Hvis du søker etter en nøkkel, er den skiftende mellom store og små bokstaver. Du kan imidlertid bruke egenskapen ‘CompareMode’ til å endre dette.

Vær oppmerksom på at dette må gjøres umiddelbart i koden etter at du har opprettet ordbokobjektet, men før du legger til data i ordlisten. Når sammenligningsmodusen er angitt, kan den ikke endres i ordlisten.

12345678910 Sub ChangeCaseSensitivity ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.CompareMode = TextCompareMyDictionary.Legg til "Item1", 10MyDictionary.Legg til "Item2", 20MyDictionary.Legg til "Item3", 30MsgBox MyDictionary.Exists ("item2")Slutt Sub

I dette eksemplet er sammenligningsmodusen satt til ‘TextCompare’, noe som betyr at den ikke er store og små bokstaver. 'Eksisterer' -utsagnet på slutten av eksemplet vil returnere True, til tross for at søketeksten er liten.

I Excel er det bare to verdier som kan brukes til sammenligningsmodus. Binær sammenligning er store og små bokstaver

Hvis du har sammenligningsmodus satt til Binær sammenligning, må du være forsiktig når du navngir nøklene dine. Hvis du angir et navn for å ha en stor bokstav som det første tegnet, må du sørge for at du fortsatt gjør det første tegnet til store bokstaver når du endrer verdien. Hvis du starter med små bokstaver, blir dette tolket som en ny nøkkel, og kan lett føre til forvirring og feil i ordlisten din

Husk at hvis du endrer en verdi for en nøkkel og nøkkelnavnet ikke eksisterer på grunn av at en binær sammenligning brukes, vil en ny nøkkel og verdi bli lagt til i ordlisten.

Hvis du bruker Text Compare i stedet, vil eventuelle verdiendringer gå til nøkkelen uavhengig av bokstav. Hvis du prøver å legge til det samme elementet, men stavet med et annet sakstegn, får du en feil fordi det allerede eksisterer.

Sortering av ordboken

Som med samleobjektet, er det ingen metode for å kunne sortere ordlisten, verken ved hjelp av nøkler eller elementverdier.

Siden VBA -koden sitter i en Excel -arbeidsbok, kan imidlertid ordbokdataene overføres til Excel i tabellform, og deretter kan Excel -sorteringsfunksjonen brukes på den. Ordlisten kan deretter tømmes ved hjelp av ‘RemoveAll’ og de sorterte verdiene som legges til fra regnearket.

Denne koden vil sortere både nøklene og elementverdiene

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 Sub SortMyDictionary ()Dim MyDictionary As New DictionaryDim Counter As Long'Bygg ordbok med tilfeldige rekkefølgeelementerMyDictionary.Legg til "Item5", 5MyDictionary.Legg til "Item2", 15MyDictionary.Legg til "Item4", 11MyDictionary.Legg til "Item1", 2MyDictionary.Legg til "Item3", 19'Fang antall elementer i ordboken for fremtidig brukTeller = MyDictionary.Count'Gjenta gjennom ordlisten og kopier hver nøkkel og element til en påfølgende celle på' Ark1 '(kolonne A)For N = 0 Til MyDictionary.Count - 1Sheets ("Sheet1"). Celler (N + 1, 1) = MyDictionary.Keys (N)Sheets ("Sheet1"). Celler (N + 1, 2) = MyDictionary.Items (N)Neste N'Aktiver Sheet1 og bruk Excel -sorteringsrutinen for å sortere dataene i stigende rekkefølgeArk ("Ark1"). AktiverOmråde ("A1: B" og MyDictionary.Count) .VelgActiveWorkbook.Worksheets ("Sheet1"). Sort.SortFields.ClearActiveWorkbook.Worksheets ("Sheet1"). Sort.SortFields.Add2 Key: = Range (_"A1: A5"), SortOn: = xlSortOnValues, Order: = xlAscending, DataOption: = _xlSortNormalMed ActiveWorkbook.Worksheets ("Ark1"). Sorter.SetRange -område ("A1: A5").Header = xlGuess.MatchCase = Falsk.Orientation = xlTopToBottom.SortMethod = xlPinYin.Søke omSlutt med'Fjern alle elementene fra ordlistenMyDictionary.RemoveAll'Kopier celleverdiene tilbake til det tomme ordbokobjektet ved å bruke den lagrede verdien (telleren) for' loop 'For N = 1 å telleMyDictionary.Add Sheets ("Sheet1"). Celler (N, 1) .Value, Sheets ("Sheet1"). Cells (N, 2) .ValueNeste N'Skift gjennom ordboken for å bevise rekkefølgen elementene nå er iFor N = 0 Til MyDictionary.Count - 1MsgBox MyDictionary.Keys (N) & "" & MyDictionary.Items (N)Neste N'Fjern regnearket (ark1) - slett det om nødvendig ogsåArk ("Ark1"). Rekkevidde (celler (1, 1), celler (teller, 2)). FjernSlutt Sub

Denne koden oppretter en ordbok med fem tilfeldige rekkefølgeverdier lagt til. Den registrerer antall elementer i en variabel, og går deretter gjennom ordlisten og overfører nøkkel- og elementverdiene til separate kolonner i et regneark.

Den sorterer deretter det nedlastede området, ved hjelp av kolonne A som sorteringsfelt. Ordlisten tømmes fullstendig ved hjelp av "RemoveAll" -metoden, og koden går deretter gjennom celleverdiene i regnearket og legger dem tilbake til ordlisten.

Til slutt gjentar koden seg gjennom ordlisten, og viser nøkkel- og elementverdiene sammenkoblet for å bevise at sorteringen har fungert.

Ved å endre parametrene i sorteringskoden, kan dataene sorteres etter elementverdier.

Kopiere en liste over nøkler til et regneark

Du kan kopiere en liste over alle nøkkelverdier til et regneark ved å bruke følgende kode:

12345678910 Sub CopyKeyList ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.CompareMode = TextCompareMyDictionary.Legg til "Item1", 10MyDictionary.Legg til "Item2", 20MyDictionary.Legg til "Item3", 30Ark ("Ark1"). Område ("A1"). Verdi = Bli med (MyDictionary.Keys, vbLf)Slutt Sub

Dette gir resultatet i regnearket ditt:

Du kan kopiere en hel ordbok til et regneark ved å bruke denne koden:

12345678910 UnderkopiIntoWorksheet ()Dim MyDictionary As New Scripting.DictionaryMyDictionary.Legg til "Item1", 10MyDictionary.Legg til "Item2", 20MyDictionary.Legg til "Item3", 30Område ("A1"). Endre størrelse (MyDictionary.Count, 1) = WorksheetFunction.Transpose (MyDictionary.Keys)Område ("B1"). Endre størrelse (MyDictionary.Count, 1) = WorksheetFunction.Transpose (MyDictionary.Items)Slutt Sub

Regnearket ditt vil se slik ut:

Sammenligning av en ordbok med en samling

Ordboken er raskere enn en samling.

En samling er allerede innenfor VBA. En ordbok trenger en referanse til Microsoft Scripting Dictionary for å legges til eller et objekt opprettes ved hjelp av sen binding

Et samleobjekt kan bare skrives én gang og leses mange ganger. I en ordbok kan elementverdien endres. Med en samling må elementet fjernes og det endrede elementet legges tilbake.

Samlingen jobber med indeksverdier, noe som kan være vanskelig å finne ut hvilken indeksverdi som hører hjemme. Ordboken jobber med unike nøkkelverdier som brukes til å finne et element

Å hente et enkelt element er tregere i en stor samling enn i en ordbok

I en samling brukes nøklene bare til å slå opp data og kan ikke hentes. I en ordbok kan nøkler testes for eksistens, og kan brukes til å finne et bestemt element.

Samlinger er store og små bokstaver, og dette kan ikke endres. I en ordbok kan sammenligningsmodus settes til å gi store eller små bokstaver

I en samling må nøkkelverdiene være strenger. I en ordbok kan de være hvilken som helst datatype f.eks. numerisk, dato osv

Hvis du fjerner alle elementene i en samling, må du definere samlingsobjektet på nytt. Ordboken har "RemoveAll" -metoden for dette.

Du vil bidra til utvikling av området, dele siden med vennene dine

wave wave wave wave wave