Obiekty słownika VBA

Korzystanie ze słownika VBA

Słownik VBA działa podobnie do obiektu kolekcji, ale ma więcej właściwości i metod oraz oferuje większą elastyczność

Słownik przechowuje dane w pamięci i można nim łatwo manipulować. Nie jest wymagane automatyczne obliczanie, tworzenie kopii zapasowych w tle ani odświeżanie ekranu, dzięki czemu Twój kod będzie działał znacznie szybciej.

Obiekt słownika działa w sposób podobny do zwykłego słownika, którego można użyć do poznania znaczenia słowa. Każdy wpis w obiekcie słownika ma wartość „klucz” i wartość „elementu”. Używasz „klucza” jako wartości klucza, aby wyszukać wartość elementu w obiekcie słownika, w podobny sposób, jak w zwykłym słowniku.

Ze względu na sposób działania obiektu słownika wszystkie wartości klucza muszą być unikatowe, w taki sam sposób jak w konwencjonalnym słowniku. Wyobraź sobie, że otworzyłeś swój konwencjonalny słownik, aby sprawdzić znaczenie słowa i znalazłeś to słowo wymienione więcej niż raz w dwóch całkowicie różnych definicjach. Byłbyś bardzo zdezorientowany!

Kluczowe wartości to zazwyczaj tekst lub liczby, albo obie te wartości. Użytkownikom często łatwiej jest zapamiętać nazwy kluczy jako tekst, a nie tylko liczby.

W porównaniu z obiektem kolekcji obiekt kolekcji jest tylko do odczytu. Ma tylko dwie metody (Add i Remove) oraz dwie właściwości (Count i Item). Po dodaniu elementu do obiektu kolekcji można go tylko usunąć, ale nie można go edytować, co jest kłopotliwą procedurą w przypadku konieczności zmiany wartości elementu.

Obiekt słownika zmieni rozmiar automatycznie, aby dopasować się do liczby elementów w nim zawartych. Nie trzeba określać rozmiaru, jak w przypadku konwencjonalnej tablicy

Obiekt słownika jest jednowymiarowy, a typ danych to „Wariant”, więc można w nim wprowadzić dowolny typ danych, np. numeryczna, tekstowa, data

Słownik VBA nie jest natywny dla programu Excel i wymaga dostępu przez wcześniejsze lub późne wiązanie podczas definiowania obiektu słownika

123 Sub Early BindingPrzykład()Dim MyDictionary jako nowy Scripting.DictionaryNapis końcowy
1234 Przykład późnego wiązania podrzędnego ()Przyciemnij mój słownik jako obiektUstaw MyDictionary = CreateObject("Scripting.Dictionary")Napis końcowy

Jeśli korzystasz z wczesnego wiązania, musisz dodać odwołanie do biblioteki „Microsoft Scripting Runtime”

Robisz to, wybierając „Narzędzia | References” na pasku menu okna Edytora Visual Basic (VBE) i pojawi się wyskakujące okienko z listą dostępnych bibliotek.

Przewiń w dół do „Microsoft Scripting Runtime” i zaznacz pole obok niego. Kliknij OK, a ta biblioteka jest teraz częścią projektu VBA i można się do niej odwoływać przy użyciu wczesnego wiązania. Wszystkie przykłady kodu w tym artykule będą używać wczesnego wiązania.

Twój kod będzie działał znacznie szybciej z wczesnym wiązaniem, ponieważ wszystko jest kompilowane z góry. W przypadku późnego wiązania obiekt musi być kompilowany podczas działania kodu

Biblioteka Scripting Runtime ma „Intellisense”. Podczas pisania kodu pojawiają się listy dostępnych metod i właściwości, co pomaga zapobiegać błędom w pisowni, które mogą powodować błędy w programie

Ponadto, jeśli naciśniesz F2 w VBE i wybierzesz bibliotekę „Skrypty”, zobaczysz wszystkie dostępne metody i właściwości oraz parametry wymagane dla każdego

Dystrybucja aplikacji Excel zawierającej słownik

Jak już wspomniano, biblioteka Scripting Runtime nie jest częścią Excel VBA, więc jeśli rozpowszechniasz swoją aplikację wśród innych użytkowników, muszą oni mieć dostęp do biblioteki Scripting Runtime na swoim komputerze. Jeśli nie, wystąpi błąd.

Dobrym pomysłem jest dołączenie kodu VBA, aby sprawdzić, czy ta biblioteka jest obecna podczas ładowania aplikacji Excel. Możesz użyć polecenia „Dir”, aby zrobić to w zdarzeniu „Workbook Open”

Lokalizacja pliku to C:\Windows\SysWOW64\scrrun.dll

Zakres obiektu słownika

Obiekt słownika jest dostępny tylko wtedy, gdy skoroszyt programu Excel jest otwarty. Nie jest zapisywany po zapisaniu skoroszytu.

Jeśli twój słownik ma być dostępny dla wszystkich procedur w twoim module, musisz go zadeklarować (Dim) w sekcji Declare na samej górze modułu

Definiujesz go jako obiekt globalny, jeśli chcesz, aby Twój słownik był używany w całym kodzie.

1 Globalny MyDictionary jako nowy słownik

Wypełnianie i czytanie z Twojego słownika

Na początek musisz utworzyć słownik, wypełnić go danymi, a następnie przejść przez niego, aby udowodnić, że dane istnieją

1234567891011 Sub PopulujPrzeczytajSłownik()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „MójElement1”, 10MójSłownik.Dodaj „MyItem2”, 20MyDictionary.Dodaj "MyItem3", 30Dla n = 0 Do MyDictionary.Count - 1MsgBox MyDictionary.Keys(n) & „ ” & MyDictionary.Items(n)Następna nNapis końcowy

Ten kod tworzy nowy obiekt słownika o nazwie „MyDictionary”, a następnie wypełnia go trzema elementami. Metoda Add ma dwa parametry - Key i Item, i oba są wymagane

Typy danych dla klucza i elementu są wariantami, więc akceptują każdy typ danych - numeryczne, tekstowe, daty itp

Pierwsza pozycja w słowniku mogłaby zostać dodana jako:

1 MyDictionary.Add 10, "MyItem1"

Wartości zostały zamienione między kluczem a elementem, ale to nadal działa, chociaż klucz wyszukiwania zmieni się teraz na 10.

Jednak ważne jest, aby zrozumieć, że wartość klucza jest wartością wyszukiwania w słowniku. Działa w bardzo podobny sposób do funkcji WYSZUKAJ.PIONOWO w programie Excel. Ponieważ wszystkie klucze muszą mieć unikatowe wartości, możesz określić wartość klucza i natychmiast zwrócić wartość elementu dla tego klucza.

Zauważ, że indeks słownika zaczyna się od 0, więc musisz odjąć 1 od licznika słownika użytego w pętli For… Next

Możesz również użyć pętli For… Each, aby odczytać wartości ze słownika:

1234567891011 Sub PopulujPrzeczytajSłownik()Dim MyDictionary jako nowy Scripting.Dictionary, ja jako wariantMójSłownik.Dodaj „MójElement1”, 10MyDictionary.Dodaj "MyItem2", 20MyDictionary.Dodaj „MyItem3”, 30Dla każdego I w MyDictionary.KeysMsgBox I & „ ” & MyDictionary(I)DalejNapis końcowy

Ten kod przejdzie przez każdą pozycję i wyświetli klucz pozycji oraz wartość pozycji

Korzystanie z numeru indeksu pozycji

Możesz użyć numeru indeksu klucza lub elementu, aby odczytać wartość

123456789101112 Numery indeksów podrzędnych ()Dim MyDictionary jako nowy Scripting.DictionaryMyDictionary.CompareMode = TekstPorównajMójSłownik.Dodaj „Pozycja1”, 10MójSłownik.Dodaj „Item2”, 20MójSłownik.Dodaj „Item3”, 30MsgBox MyDictionary.Keys(2)MsgBox MyDictionary.Items(1)Napis końcowy

Ten kod zwróci klucz „item3”, ponieważ indeks zaczyna się od 0, a wartość pozycji 20

Za pomocą numerów indeksu można odwoływać się do poszczególnych wartości klucza lub elementu w kolekcjach Keys lub Items.

Filtrowanie słownika

Nie ma na to bezpośredniej metody, ale napisanie odpowiedniego kodu jest dość proste:

1234567891011 Podrzędny słownik filtrów()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „AAItem1”, 10MójSłownik.Dodaj „BBItem2”, 20MójSłownik.Dodaj „BBItem3”, 30Dla każdego I In Filter (MyDictionary.Keys, "BB")MsgBox MójSłownik.Pozycja(I)DalejNapis końcowy

Wartość filtra działa tylko od początku wartości klucza. W filtrze nie można używać symboli wieloznacznych. Ten kod zwróci dwie wartości pozycji z nazwami kluczy zaczynającymi się od „BB”

W ten sposób otrzymasz podzbiór słownika oparty na wartości filtru, który możesz następnie przenieść do innego słownika lub arkusza roboczego. Dzięki starannemu planowaniu nazw kluczy, upewniając się, że każdy z nich ma sensowny przedrostek, możesz łatwo podzielić słownik na różne części składowe.

Zmiana wartości pozycji klucza

Obiekt słownika ma dużą przewagę nad kolekcją, ponieważ wartość elementu można zmienić, np.

1 MójSłownik("MyItem4") = "40"

W kolekcji musisz usunąć ten wpis, a następnie utworzyć go ponownie.

Oto przykład kodu:

12345678910111213 Sub PopulujPrzeczytajSłownik()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „MójElement1”, 10MyDictionary.Dodaj "MyItem2", 20MyDictionary.Dodaj "MyItem3", 30MójSłownik("MyItem2") = "25"MójSłownik("MyItem4") = "40"Dla n = 0 Do MyDictionary.Count - 1MsgBox MyDictionary.Keys(n) & „ ” & MyDictionary.Items(n)Następna nNapis końcowy

Powyższy kod konfiguruje trzy elementy w słowniku, a następnie zmienia wartość „MyItem2” z 20 na 25.

Zmienia również wartość „MyItem4” na 40. Zauważ, że w instrukcjach add kodu nie dodano „MyItem4”. Gdy zmienisz wartość klucza, który nie istnieje, zostanie on automatycznie utworzony. Jest to niezwykle wygodne, ponieważ nie jest wyzwalany żaden błąd, ale oznacza to, że musisz uważać na nazwy kluczy. Nieumyślny błąd pisowni w nazwie klucza oznaczałby, że zostanie utworzony nowy klucz, a oryginalna nazwa klucza nadal będzie miała starą wartość.

Może to łatwo prowadzić do problemów z integralnością w obiekcie słownika.

Sprawdź, czy klucz istnieje

Możesz sprawdzić, czy wartość klucza istnieje w słowniku

123456789 Sub CheckExistsDictionary()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „MójElement1”, 10MyDictionary.Dodaj "MyItem2", 20MyDictionary.Dodaj "MyItem3", 30MsgBox MyDictionary.Exists("MyItem8")Napis końcowy

Kod dodaje trzy elementy do nowego obiektu słownika, a następnie testuje klucz („MyItem8”), którego nie ma w słowniku. Zwraca False, ale gdyby został użyty jeden z istniejących kluczy, zwróciłby True

Symbole wieloznaczne nie są akceptowane. W wyszukiwanym tekście domyślnie rozróżniana jest również wielkość liter, ale można to zmienić (patrz dalej w artykule)

Używanie wielu wartości w słowniku

W przeciwieństwie do tablicy obiekt słownika jest tylko jednowymiarowy. Może to prowadzić do problemów, jeśli masz kilka wartości, które chcesz umieścić w kluczu.

Jednym ze sposobów jest łączenie wartości każdej pozycji za pomocą znaku ogranicznika pomiędzy każdą wartością, np. „|”

12345678910111213141516171819202122232425262728293031323334 Wiele wartości podrzędnych()'Utwórz obiekt i zmienne słownikaDim MyDictionary jako nowy Scripting.Dictionary, V1 jako liczba całkowita, V2 jako ciągDim V3 jako data, Temp jako ciąg, N jako liczba całkowita„Wypełnij 3 zmienne, aby zademonstrować wiele wartości”V1 = 5V2 = "Przykład wielu wartości"V3 = „22-lip-2020”'Dodaj połączoną wartość do słownika, używając "|" ogranicznikMyDictionary.Dodaj "MyMultipleItem", V1 i "|" & V2 & "|" & V3 & "|"'Przechwyć połączoną wartość słownikową ze słownika do zmiennejTemp = MyDictionary("MyMultipleItem")'Iterowanie przez połączony ciąg, aby oddzielić poszczególne wartościRobić„Znajdź pozycję ogranicznika”N = InStr(Temp, "|")'Jeśli nie ma więcej ograniczników, wyjściowa pętla WykonajJeśli N = 0, to zakończ Wykonaj'Wyświetl tekst względem znalezionej pozycji ogranicznikaMsgBox po lewej (Temp, N - 1)'Obetnij połączony ciąg do następnego znaku po znalezionym ogranicznikuTemp = Średnia (Temp, N + 1)PętlaNapis końcowy

Innym sposobem obejścia tego problemu jest zaprojektowanie własnego systemu skryptów podrzędnych dla nazw kluczy. Nie ma powodu, dla którego nie powinno się używać nawiasów i cyfr w nazwach kluczy

1234567891011 Wiele wartości podrzędnych()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „Wiele(1)”, 5MyDictionary.Add "Multiple(2)", "Przykład wielu wartości"MyDictionary.Add „Wiele(3)”, „22-lip-2020”Dla N = 1 do 3MsgBox MyDictionary("Wiele(" & N & ")")Następny NNapis końcowy

Ten kod dodaje do słownika trzy klucze, ale każda nazwa klucza zawiera numer skryptu podrzędnego w nawiasach. Następnie możesz odwołać się do nazwy klucza, ale używając numeru skryptu podrzędnego połączonego w. Jest to bardzo podobne do korzystania z obiektu tablicy

Usuwanie przedmiotów

Możesz usunąć poszczególne pozycje, odwołując się do wartości klucza

1 MyDictionary.Remove („MyItem2”)

Pamiętaj, że ponieważ nazwy kluczy są unikalne, usuwa to tylko jeden konkretny klucz i wartość pozycji

Możesz także całkowicie wyczyścić słownik

1 MójSłownik.UsuńWszystko

Oto przykład użycia „Usuń” w VBA:

12345678910111213141516 Sub UsuńWartości()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „Pozycja1”, 10MójSłownik.Dodaj „Item2”, 20MójSłownik.Dodaj „Item3”, 30MyDictionary.Remove ("Pozycja2")Dla N = 0 Do MyDictionary.Count - 1MsgBox MyDictionary.Keys(N) & „ ” & MyDictionary.Items(N)Następny NMójSłownik.UsuńWszystkoMsgBox MyDictionary.CountNapis końcowy

Kod dodaje trzy elementy do słownika, a następnie usuwa „Item2”. Następnie przechodzi przez słownik, aby udowodnić, że „Pozycja 2” już nie istnieje

Na koniec kod usuwa wszystkie elementy ze słownika i wyświetla licznik słownika, który teraz wynosi zero.

Zmiana rozróżniania wielkości liter w wyszukiwaniach

Jeśli szukasz klucza, domyślnie rozróżniana jest wielkość liter. Możesz jednak użyć właściwości „CompareMode”, aby to zmienić.

Należy zauważyć, że należy to zrobić natychmiast w kodzie po utworzeniu obiektu słownika, ale przed dodaniem jakichkolwiek danych do słownika. Po ustawieniu trybu porównywania nie można go zmienić w tym słowniku.

12345678910 Sub ChangeCase Sensitivity()Dim MyDictionary jako nowy Scripting.DictionaryMyDictionary.CompareMode = TekstPorównajMójSłownik.Dodaj „Pozycja1”, 10MójSłownik.Dodaj „Item2”, 20MójSłownik.Dodaj „Item3”, 30MsgBox MyDictionary.Exists("item2")Napis końcowy

W tym przykładzie tryb porównania jest ustawiony na „TextCompare”, co oznacza, że ​​wielkość liter nie jest rozróżniana. Wyrażenie „Exists” na końcu przykładu zwróci True, mimo że cały wyszukiwany tekst jest pisany małymi literami.

W programie Excel są tylko dwie wartości, których można użyć w trybie porównania. Porównanie binarne rozróżnia wielkość liter, a porównywanie tekstu nie rozróżnia wielkości liter

Jeśli masz ustawiony tryb porównania na Binary Compare, musisz być ostrożny przy nazywaniu kluczy. Jeśli ustawisz nazwę tak, aby jako pierwszy znak była wielka litera, to podczas zmiany wartości musisz upewnić się, że nadal pierwszy znak jest pisany wielką literą. Jeśli zaczniesz od małej litery, zostanie to zinterpretowane jako nowy klucz i może łatwo doprowadzić do zamieszania i błędów w słowniku

Pamiętaj, że jeśli zmienisz wartość klucza, a nazwa klucza nie istnieje z powodu użycia funkcji Binary Compare, do słownika zostanie dodany nowy klucz i wartość.

Jeśli zamiast tego użyjesz funkcji Text Compare, wszelkie zmiany wartości zostaną przeniesione do klucza, niezależnie od wielkości liter. Jeśli spróbujesz dodać ten sam element, ale pisany z inną literą wielkości liter, otrzymasz błąd, ponieważ już istnieje.

Sortowanie słownika

Podobnie jak w przypadku obiektu kolekcji, nie ma metody umożliwiającej sortowanie słownika za pomocą kluczy lub wartości pozycji.

Ponieważ jednak kod VBA znajduje się w skoroszycie Excela, dane ze słownika można przenieść do Excela w formie tabelarycznej, a następnie zastosować do niego funkcję sortowania Excela. Słownik można następnie wyczyścić za pomocą „Usuń wszystko”, a posortowane wartości dodać z arkusza roboczego.

Ten kod posortuje zarówno klucze, jak i wartości pozycji

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 Sub SortMySłownik()Przyciemnij mój słownik jako nowy słownikLicznik przyciemnienia tak długo'Zbuduj słownik z losowymi pozycjami zamówieniaMójSłownik.Dodaj „Pozycja5”, 5MójSłownik.Dodaj „Item2”, 15MójSłownik.Dodaj „Item4”, 11MójSłownik.Dodaj „Pozycja1”, 2MójSłownik.Dodaj „Pozycja3”, 19„Przechwyć liczbę pozycji w słowniku do wykorzystania w przyszłości”Licznik = MyDictionary.Count„Iteruj przez słownik, kopiując każdy klucz i element do kolejnej komórki w „Arkuszu1” (kolumna A)Dla N = 0 Do MyDictionary.Count - 1Arkusze("Arkusz1").Komórki(N + 1, 1) = MójSłownik.Klawisze(N)Arkusze("Arkusz1").Komórki(N + 1, 2) = MójSłownik.Items(N)Następny N'Aktywuj Arkusz1 i użyj procedury sortowania Excela, aby posortować dane w porządku rosnącymArkusze("Arkusz1").AktywujZakres("A1:B" & MyDictionary.Count).WybierzActiveWorkbook.Worksheets("Arkusz1").Sort.SortFields.ClearActiveWorkbook.Worksheets("Arkusz1").Sort.SortFields.Add2 Klucz:=Zakres( _"A1:A5"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _xlSortuj NormalnieZ ActiveWorkbook.Worksheets("Arkusz1").Sort.SetRange Range("A1:A5").Nagłówek = xlZgadnij.MatchCase = Fałsz.Orientacja = xlTopToBottom.Metoda sortowania = xlPinYin.ZastosowaćKończyć z'Wyczyść wszystkie pozycje ze słownikaMójSłownik.UsuńWszystko'Skopiuj wartości komórek z powrotem do pustego obiektu słownika, używając wartości przechowywanej (Licznik) dla 'pętliDla N = 1 Do LicznikaMójSłownik.Add Sheets("Arkusz1").Cells(N, 1).Value, Sheets("Arkusz1").Cells(N, 2).ValueNastępny N„Iteruj po słowniku, aby udowodnić kolejność, w jakiej są teraz elementy”Dla N = 0 Do MyDictionary.Count - 1MsgBox MyDictionary.Keys(N) & „ ” & MyDictionary.Items(N)Następny N'Wyczyść arkusz (Arkusz 1) - w razie potrzeby usuń go równieżArkusze("Arkusz1").Zakres(Komórki(1,1),Komórki(Licznik, 2)).WyczyśćNapis końcowy

Ten kod tworzy słownik z dodanymi pięcioma losowymi wartościami kolejności. Przechwytuje liczbę elementów do zmiennej, a następnie iteruje po słowniku, przenosząc wartości klucza i elementu do oddzielnych kolumn w arkuszu.

Następnie sortuje pobrany zakres, używając kolumny A jako pola sortowania. Słownik jest całkowicie czyszczony za pomocą metody „Usuń wszystko”, a następnie kod przechodzi przez wartości komórek w arkuszu, dodając je z powrotem do słownika.

Na koniec kod iteruje po słowniku, wyświetlając połączone wartości klucza i elementu, aby udowodnić, że sortowanie zadziałało.

Zmieniając parametry w kodzie sortowania, dane można sortować według wartości pozycji.

Kopiowanie listy kluczy do arkusza roboczego

Listę wszystkich wartości kluczy można skopiować do arkusza, korzystając z następującego kodu:

12345678910 Sub CopyKeyList()Dim MyDictionary jako nowy Scripting.DictionaryMyDictionary.CompareMode = TekstPorównajMójSłownik.Dodaj „Pozycja1”, 10MójSłownik.Dodaj „Item2”, 20MójSłownik.Dodaj „Item3”, 30Sheets("Arkusz1").Range("A1").Value = Dołącz(MójSłownik.Klucze, vbLf)Napis końcowy

To da wynik w twoim arkuszu:

Możesz skopiować cały słownik do arkusza za pomocą tego kodu:

12345678910 Sub Kopiuj do arkusza roboczego ()Dim MyDictionary jako nowy Scripting.DictionaryMójSłownik.Dodaj „Pozycja1”, 10MójSłownik.Dodaj „Item2”, 20MójSłownik.Dodaj „Item3”, 30Range("A1").Resize(MyDictionary.Count, 1) = WorksheetFunction.Transpose(MyDictionary.Keys)Range("B1").Resize(MyDictionary.Count, 1) = WorksheetFunction.Transpose(MyDictionary.Items)Napis końcowy

Twój arkusz będzie wyglądał tak:

Porównanie słownika z kolekcją

Słownik jest szybszy niż kolekcja.

Kolekcja jest już w VBA. Słownik wymaga odwołania do słownika Microsoft Scripting Dictionary lub obiektu utworzonego przy użyciu późnego wiązania

Element Kolekcji można zapisać tylko raz i przeczytać wiele razy. W Słowniku można zmienić wartość pozycji. W przypadku kolekcji element musi zostać usunięty, a następnie zmieniony element dodany z powrotem.

Kolekcja działa na wartościach indeksów, co może być trudne do ustalenia, która wartość indeksu należy do którego. Słownik działa na unikalnych wartościach kluczy, które są używane do zlokalizowania elementu

Pobieranie pojedynczego elementu jest wolniejsze w dużej kolekcji niż w słowniku

W kolekcji klucze są używane tylko do wyszukiwania danych i nie można ich odzyskać. W słowniku klucze mogą być testowane pod kątem istnienia i mogą być użyte do znalezienia konkretnego elementu.

W kolekcjach rozróżniana jest wielkość liter i nie można tego zmienić. W słowniku tryb porównania można ustawić tak, aby uwzględniał wielkość liter lub nie

W kolekcji wartości klucza muszą być ciągami. W słowniku mogą to być dane dowolnego typu, np. numeryczna, data itp.

Usunięcie wszystkich elementów w kolekcji wiąże się z ponownym zdefiniowaniem obiektu Collection. Słownik ma do tego metodę „RemoveAll”.

Będziesz pomóc w rozwoju serwisu, dzieląc stronę ze swoimi znajomymi

wave wave wave wave wave