6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
1 |
|
словарь словарей30.03.2017, 00:58. Показов 13674. Ответов 30
Здравствуйте.
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
30.03.2017, 00:58 |
30 |
Alex77755 11482 / 3773 / 677 Регистрация: 13.02.2009 Сообщений: 11,145 |
||||||||
30.03.2017, 02:15 |
2 |
|||||||
Сообщение было отмечено kronos_o_0 как решение Решение
Добавлено через 58 секунд Добавлено через 1 минуту
1 |
Hugo121 6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
||||
30.03.2017, 08:43 |
3 |
|||
Сообщение было отмечено kronos_o_0 как решение РешениеЯ так делал в другой задаче:
1 |
kronos_o_0 6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
||||
30.03.2017, 09:32 [ТС] |
4 |
|||
Alex77755, я пытался сделать на подобие первого, но не совсем понял, там второй словарь вкладывают в коллекцию?
.Item(t).Item(a(i, 2) & «|» & a(i, 3) & «|» & i) = 0& вот что у меня получилось, но я не могу обратится к Dic через .item
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 09:46 |
5 |
У меня на итем не ругается, да и у Вас скорее всего ругается на выход за пределы массива.
0 |
kronos_o_0 6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
||||
30.03.2017, 09:50 [ТС] |
6 |
|||
вставил эту часть, показало что словарь заполнен ключ[ключ, но итем второго словаря пуст]
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 10:00 |
7 |
как проверить заполненность словаря-словарей тут что пишет?
Debug.Print «Ищем данные » & col
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 10:07 [ТС] |
8 |
тут что пишет? Открываем файл литий
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 10:13 |
9 |
Ну так вот же — у лития в словаре 1, 2 и 8, у аммония 2, 1, 6 и т.д. Добавлено через 2 минуты
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 10:13 [ТС] |
10 |
Ну так вот же — у лития в словаре 1, 2 и 8, у аммония 2, 1, 6 и т.д. да тут все правильно, но нет значений у 1,2,8 и т.д., у них должны быть еще
0 |
Hugo121 6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
||||
30.03.2017, 10:27 |
11 |
|||
Да, в той реализации у всех внутренних значение 0, но можно изменить как угодно, а вывести можно если убрать апостроф в строке
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 10:35 [ТС] |
12 |
Hugo121, Спасибо большое, действительно все работало
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 10:51 |
13 |
Да, по тому же принципу можно, только выводите в ячейки.
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 11:04 [ТС] |
14 |
Hugo121, а можете сказать, я видел на одном сайте они выгружают словарь вот таким способом
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 11:10 |
15 |
Так и тут можно так выгружать внутренние словари (для внешнего итемы — это не значения, а объекты, поэтому так не пойдёт).
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 11:16 [ТС] |
16 |
Hugo121, все большое спасибо
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 11:32 |
17 |
Можно выгрузить ключи в массив, его процедурой отсортировать (есть уже готовые разные), затем перебором этого массива извлекать итемы и всё писать на лист, или куда угодно.
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 11:44 [ТС] |
18 |
Hugo121, а сортировать сам словарь это сложнее?
0 |
6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
|
30.03.2017, 11:55 |
19 |
Словарь несортируется, там нельзя поменять позицию элементу. Да и как выше я уже говорил — эта позиция не гарантируется. Добавлено через 6 минут
0 |
6 / 6 / 0 Регистрация: 02.06.2014 Сообщений: 65 |
|
30.03.2017, 12:50 [ТС] |
20 |
Hugo121, т.е. порядка в словаре нет? я думал они стоят в порядке их добавления
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
30.03.2017, 12:50 |
20 |
“The greatest masterpiece in literature is only a dictionary out of order.” – Jean Cocteau
A Quick Guide to the VBA Dictionary
Function | Example |
---|---|
Early binding reference | “Microsoft Scripting Runtime” (Add using Tools->References from the VB menu) |
Declare (early binding) | Dim dict As Scripting.Dictionary |
Create(early binding) | Set dict = New Scripting.Dictionary |
Declare (late binding) | Dim dict As Object |
Create(late binding) | Set dict = CreateObject(«Scripting.Dictionary») |
Add item (key must not already exist) | dict.Add Key, Value e.g. dict.Add «Apples», 50 |
Change value at key. Automatically adds if the key does not exist. | dict(Key) = Value e.g. dict(«Oranges») = 60 |
Get a value from the dictionary using the key | Value = dict(Key) e.g. appleCount = dict(«Apples») |
Check if key exists | dict.Exists(Key) e.g. If dict.Exists(«Apples») Then |
Remove item | dict.Remove Key e.g. dict.Remove «Apples» |
Remove all items | dict.RemoveAll |
Go through all items (for each loop) | Dim key As Variant For Each key In dict.Keys Debug.Print key, dict(key) Next key |
Go through all items (for loop — early binding only) | Dim i As Long For i = 0 To dict.Count — 1 Debug.Print dict.Keys(i), dict.Items(i) Next i |
Go through all items (for loop — early and late binding) | Dim i As Long For i = 0 To dict.Count — 1 Debug.Print dict.Keys()(i), dict.Items()(i) Next i |
Get the number of items | dict.Count |
Make key case sensitive (the dictionary must be empty). | dict.CompareMode = vbBinaryCompare |
Make key non case sensitive (the dictionary must be empty). | dict.CompareMode = vbTextCompare |
What is the VBA Dictionary?
In VBA we use Arrays and Collections to store groups of values. For example, we could use them to store a list of customer names, student marks or a list of values from a range of cells.
A Dictionary is similar to a Collection. Using both types, we can name an item when we add it. Imagine we are storing the count of different fruit types.
We could use both a Collection and a Dictionary like this
' Add to Dictionary dict.Add Key:="Apple", Item:=5 ' Add to Collection coll.Add Item:=5, Key:="Apple"
Example of Key, Value pairs
In both cases, we are storing the value 5 and giving it the name “Apple”. We can now get the value of Apple from both types like this
' Get value from Dictionary Total = dict("Apple") ' Get value from Collection Total = coll("Apple")
So far so good. The Collection however, has two major faults
- We cannot check if the key already exists.
- We cannot change the value of an existing item.
The first issue is pretty easy to get around: Check Collection Key exists. The second is more difficult.
The VBA Dictionary does not have these issues. You can check if a Key exists and you can change the Item and the Key.
For example, we can use the following code to check if we have an item called Apple.
If dict.Exists("Apple") Then dict("Apple") = 78
These may seem very simple differences. However, it means that the Dictionary is very useful for certain tasks. Particularly when we need to retrieve the value of an item.
Download the Source Code
Dictionary Webinar
If you are a member of the VBA Vault, then click on the image below to access the webinar and the associated source code.
(Note: Website members have access to the full webinar archive.)
A Dictionary in real world terms
If you are still not clear about a Dictionary then think of it this way. A real-world dictionary has a list of keys and items. The Keys are the words and the Items are the definition.
When you want to find the definition of a word you go straight to that word. You don’t read through every item in the Dictionary.
A second real world example is a phone book(remember those?). The Key in a phone book is the nameaddress and the Item is the phone number. Again you use the nameaddress combination to quickly find a phone number.
In Excel the VLookup function works in a similar way to a Dictionary. You look up an item based on a unique value.
A Simple Example of using the VBA Dictionary
The code below give a simple but elegant example of using the Dictionary. It does the following
- Adds three fruit types and a value for each to a Dictionary.
- The user is asked to enter the name of a fruit.
- The code checks if this fruit is in the Dictionary.
- If yes then it displays the fruit name and the value.
- If no then it informs the user the fruit does not exist.
' https://excelmacromastery.com/ Sub CheckFruit() ' Select Tools->References from the Visual Basic menu. ' Check box beside "Microsoft Scripting Runtime" in the list. Dim dict As New Scripting.Dictionary ' Add to fruit to Dictionary dict.Add key:="Apple", Item:=51 dict.Add key:="Peach", Item:=34 dict.Add key:="Plum", Item:=43 Dim sFruit As String ' Ask user to enter fruit sFruit = InputBox("Please enter the name of a fruit") If dict.Exists(sFruit) Then MsgBox sFruit & " exists and has value " & dict(sFruit) Else MsgBox sFruit & " does not exist." End If Set dict = Nothing End Sub
This is a simple example but it shows how useful a Dictionary is. We will see a real world example later in the post. Let’s look at the basics of using a Dictionary.
Creating a Dictionary
To use the Dictionary you need to first add the reference.
- Select Tools->References from the Visual Basic menu.
- Find Microsoft Scripting Runtime in the list and place a check in the box beside it.
We declare a dictionary as follows
Dim dict As New Scripting.Dictionary
or
Dim dict As Scripting.Dictionary Set dict = New Scripting.Dictionary
Creating a Dictionary in this way is called “Early Binding”. There is also “Late Binding”. Let’s have a look at what this means.
Early versus Late Binding
To create a Dictionary using Late binding we use the following code. We don’t need to add a reference.
Dim dict As Object Set dict = CreateObject("Scripting.Dictionary")
In technical terms Early binding means we decide exactly what we are using up front. With Late binding this decision is made when the application is running. In simple terms the difference is
- Early binding requires a reference. Late binding doesn’t.
- Early binding allows access to *Intellisense. Late binding doesn’t.
- Early binding may require you to manually add the Reference to the “Microsoft Scripting Runtime” for some users.
(*Intellisense is the feature that shows you the available procedures and properties of an item as you are typing.)
While Microsoft recommends that you use early binding in almost all cases I would differ. A good rule of thumb is to use early binding when developing the code so that you have access to the Intellisense. Use late binding when distributing the code to other users to prevent various library conflict errors occurring.
Adding Items to the Dictionary
Function | Params | Example |
---|---|---|
Add | Key, Item | dict.Add «Apples», 50 |
We can add items to the dictionary using the Add function. Items can also be added by assigning a value which we will look at in the next section.
Let’s look at the Add function first. The Add function has two parameters: Key and Item. Both must be supplied
dict.Add Key:="Orange", Item:=45 dict.Add "Apple", 66 dict.Add "12/12/2015", "John" dict.Add 1, 45.56
In the first add example above we use the parameter names. You don’t have to do this although it can be helpful when you are starting out.
The Key can be any data type. The Item can be any data type, an object, array, collection or even a dictionary. So you could have a Dictionary of Dictionaries, Array and Collections. But most of the time it will be a value(date, number or text).
If we add a Key that already exists in the Dictionary then we will get the error
The following code will give this error
dict.Add Key:="Orange", Item:=45 ' This line gives an error as key exists already dict.Add Key:="Orange", Item:=75
Assigning a Value
Operation | Format | Example |
---|---|---|
Assign | Dictionary(Key) = Item | dict(«Oranges») = 60 |
We can change the value of a key using the following code
dict("Orange") = 75
Assigning a value to Key this way has an extra feature. If the Key does not exist it automatically adds the Key and Item to the dictionary. This would be useful where you had a list of sorted items and only wanted the last entry for each one.
' Adds Orange to the dictionary dict("Orange") = 45 ' Changes the value of Orange to 100 dict("Orange") = 100
Don’t forget that you can download all the VBA code used in this post from the top or bottom of the post.
Checking if a Key Exists
Function | Parameters | Example |
---|---|---|
Exists | Key | If dict.Exists(«Apples») Then |
We can use the Exists function to check if a key exists in the dictionary
' Checks for the key 'Orange' in the dictionary If dict.Exists("Orange") Then MsgBox "The number of oranges is " & dict("Orange") Else MsgBox "There is no entry for Orange in the dictionary." End If
Storing Multiple Values in One Key
Take a look at the sample data below. We want to store the Amount and Items for each Customer ID.
The Dictionary only stores one value so what can we do?
We could use an array or collection as the value but this is unnecessary. The best way to do it is to use a Class Module.
The following code shows how we can do this
' clsCustomer Class Module Code Public CustomerID As String Public Amount As Long Public Items As Long
' Create a new clsCustomer object Set oCust = New clsCustomer ' Set the values oCust.CustomerID = rg.Cells(i, 1).Value oCust.Amount = rg.Cells(i, 2).Value oCust.Items = rg.Cells(i, 3).Value ' Add the new clsCustomer object to the dictionary dict.Add oCust.CustomerID, oCust
You can see that by using the Class Module we can store as many fields as we want. Examples 2 and 3 at the bottom of the post show how to use a class module with a Dictionary
Other useful functions
Function | Parameters | Example |
---|---|---|
Count | N/A | dict.Count |
Remove | Key | dict.Remove «Apples» |
RemoveAll | N/A | dict.RemoveAll |
The three functions in the above table do the following:
- Count – returns the number of items in the Dictionary.
- Remove – removes a given key from the Dictionary.
- RemoveAll – removes all items from the Dictionary
The following sub shows an example of how you would use these functions
' https://excelmacromastery.com/ Sub AddRemoveCount() Dim dict As New Scripting.Dictionary ' Add some items dict.Add "Orange", 55 dict.Add "Peach", 55 dict.Add "Plum", 55 Debug.Print "The number of items is " & dict.Count ' Remove one item dict.Remove "Orange" Debug.Print "The number of items is " & dict.Count ' Remove all items dict.RemoveAll Debug.Print "The number of items is " & dict.Count End Sub
Remember that you can download all the code examples from the post. Just go to the download section at the top.
The Key and Case Sensitivity
Some of the string functions in VBA have a vbCompareMethod. This is used for functions that compare strings. It is used to determine if the case of the letters matter.
© BigStockPhoto.com
The Dictionary uses a similar method. The CompareMode property of the Dictionary is used to determine if the case of the key matters. The settings are
vbTextCompare: Upper and lower case are considered the same.
vbBinaryCompare: Upper and lower case are considered different. This is the default.
With the Dictionary we can use these settings to determine if the case of the key matters.
' https://excelmacromastery.com/ Sub CaseMatters() Dim dict As New Scripting.Dictionary dict.CompareMode = vbBinaryCompare dict.Add "Orange", 1 ' Prints False because it considers Orange and ORANGE different Debug.Print dict.Exists("ORANGE") Set dict = Nothing End Sub
This time we use vbTextCompare which means that the case does not matter
' https://excelmacromastery.com/ Sub CaseMattersNot() Dim dict As New Scripting.Dictionary dict.CompareMode = vbTextCompare dict.Add "Orange", 1 ' Prints true because it considers Orange and ORANGE the same Debug.Print dict.Exists("ORANGE") Set dict = Nothing End Sub
Note: The Dictionary must be empty when you use the CompareMode property or you will get the error: “Invalid procedure call or argument”.
Things to Watch Out For
vbBinaryCompare (the case matters) is the default and this can lead to subtle errors. For example, imagine you have the following data in cells A1 to B2.
Orange, 5
orange, 12
The following code will create two keys – on for “Orange” and one for “orange”. This is subtle as the only difference is the case of the first letter.
' https://excelmacromastery.com/ Sub DiffCase() Dim dict As New Scripting.Dictionary dict.Add Key:=(Range("A1")), Item:=Range("B1") dict.Add Key:=(Range("A2")), Item:=Range("B2") End Sub
If you do use vbTextCompare for the same data you will get an error when you try to add the second key as it considers “Orange” and “orange” the same.
' https://excelmacromastery.com/ Sub UseTextcompare() Dim dict As New Scripting.Dictionary dict.CompareMode = vbTextCompare dict.Add Key:=(Range("A1")), Item:=Range("B1") ' This line will give an error as your are trying to add the same key dict.Add Key:=(Range("A2")), Item:=Range("B2") End Sub
If you use the assign method then it does not take the CompareMode into account. So the following code will still add two keys even though the CompareMode is set to vbTextCompare.
' https://excelmacromastery.com/ Sub Assign() Dim dict As New Scripting.Dictionary dict.CompareMode = vbTextCompare ' Adds two keys dict(Range("A1")) = Range("B1") dict(Range("A2")) = Range("B2") ' Prints 2 Debug.Print dict.Count End Sub
Reading through the Dictionary
We can read through all the items in the Dictionary. We can go through the keys using a For Each loop. We then use the current key to access an item.
Dim k As Variant For Each k In dict.Keys ' Print key and value Debug.Print k, dict(k) Next
We can also loop through the keys although this only works with Early Binding(Update Feb 2020: In Office 365 this now works with both versions):
Dim i As Long For i = 0 To dict.Count - 1 Debug.Print dict.Keys(i), dict.Items(i) Next i
This method works with both Early and Late binding:
Dim i As Long For i = 0 To dict.Count - 1 Debug.Print dict.Keys()(i), dict.Items()(i) Next i
Sorting the Dictionary
Sometimes you may wish to sort the Dictionary either by key or by value.
The Dictionary doesn’t have a sort function so you have to create your own. I have written two sort functions – one for sorting by key and one for sorting by value.
Sorting by keys
To sort the dictionary by the key you can use the SortDictionaryByKey function below
' https://excelmacromastery.com/ Public Function SortDictionaryByKey(dict As Object _ , Optional sortorder As XlSortOrder = xlAscending) As Object Dim arrList As Object Set arrList = CreateObject("System.Collections.ArrayList") ' Put keys in an ArrayList Dim key As Variant, coll As New Collection For Each key In dict arrList.Add key Next key ' Sort the keys arrList.Sort ' For descending order, reverse If sortorder = xlDescending Then arrList.Reverse End If ' Create new dictionary Dim dictNew As Object Set dictNew = CreateObject("Scripting.Dictionary") ' Read through the sorted keys and add to new dictionary For Each key In arrList dictNew.Add key, dict(key) Next key ' Clean up Set arrList = Nothing Set dict = Nothing ' Return the new dictionary Set SortDictionaryByKey = dictNew End Function
The code below, shows you how to use SortDictionaryByKey
' https://excelmacromastery.com/ Sub TestSortByKey() Dim dict As Object Set dict = CreateObject("Scripting.Dictionary") dict.Add "Plum", 99 dict.Add "Apple", 987 dict.Add "Pear", 234 dict.Add "Banana", 560 dict.Add "Orange", 34 PrintDictionary "Original", dict ' Sort Ascending Set dict = SortDictionaryByKey(dict) PrintDictionary "Key Ascending", dict ' Sort Descending Set dict = SortDictionaryByKey(dict, xlDescending) PrintDictionary "Key Descending", dict End Sub Public Sub PrintDictionary(ByVal sText As String, dict As Object) Debug.Print vbCrLf & sText & vbCrLf & String(Len(sText), "=") Dim key As Variant For Each key In dict.keys Debug.Print key, dict(key) Next End Sub
Sorting by values
To sort the dictionary by the values you can use the SortDictionaryByValue function below.
' https://excelmacromastery.com/ Public Function SortDictionaryByValue(dict As Object _ , Optional sortorder As XlSortOrder = xlAscending) As Object On Error GoTo eh Dim arrayList As Object Set arrayList = CreateObject("System.Collections.ArrayList") Dim dictTemp As Object Set dictTemp = CreateObject("Scripting.Dictionary") ' Put values in ArrayList and sort ' Store values in tempDict with their keys as a collection Dim key As Variant, value As Variant, coll As Collection For Each key In dict value = dict(key) ' if the value doesn't exist in dict then add If dictTemp.exists(value) = False Then ' create collection to hold keys ' - needed for duplicate values Set coll = New Collection dictTemp.Add value, coll ' Add the value arrayList.Add value End If ' Add the current key to the collection dictTemp(value).Add key Next key ' Sort the value arrayList.Sort ' Reverse if descending If sortorder = xlDescending Then arrayList.Reverse End If dict.RemoveAll ' Read through the ArrayList and add the values and corresponding ' keys from the dictTemp Dim item As Variant For Each value In arrayList Set coll = dictTemp(value) For Each item In coll dict.Add item, value Next item Next value Set arrayList = Nothing ' Return the new dictionary Set SortDictionaryByValue = dict Done: Exit Function eh: If Err.Number = 450 Then Err.Raise vbObjectError + 100, "SortDictionaryByValue" _ , "Cannot sort the dictionary if the value is an object" End If End Function
The code below shows you how to use SortDictionaryByValue
' https://excelmacromastery.com/ Sub TestSortByValue() Dim dict As Object Set dict = CreateObject("Scripting.Dictionary") dict.Add "Plum", 99 dict.Add "Apple", 987 dict.Add "Pear", 234 dict.Add "Banana", 560 dict.Add "Orange", 34 PrintDictionary "Original", dict ' Sort Ascending Set dict = SortDictionaryByValue(dict) PrintDictionary "Value Ascending", dict ' Sort Descending Set dict = SortDictionaryByValue(dict, xlDescending) PrintDictionary "Value Descending", dict End Sub Public Sub PrintDictionary(ByVal sText As String, dict As Object) Debug.Print vbCrLf & sText & vbCrLf & String(Len(sText), "=") Dim key As Variant For Each key In dict.keys Debug.Print key, dict(key) Next key End Sub
Troubleshooting the Dictionary
This section covers the common errors you may encounter using the Dictionary.
Missing Reference
Issue: You get the error message “User-defined type not defined”
This normally happens when you create the Dictionary but forget to add the reference.
Dim dict As New Scripting.Dictionary
Resolution: Select Tools->Reference from the Visual Basic menu. Place a check in the box beside “Microsoft Scripting Runtime”.
See Section: Creating a Dictionary
Exists is not Working
Issue: You have added a key to the Dictionary but when you use the Exists function it returns false
This is normally an issue with Case Sensitivity(see above).
The following code adds “Apple” as a key. When we check for “apple” it returns false. This is because it takes the case of the letters into account:
dict.Add "Apple", 4 If dict.Exists("apple") Then MsgBox "Exists" Else MsgBox "Does not Exist" End If
You can set the CompareMode property to vbTextCompare and this will ignore the case:
Dim dict As New Scripting.Dictionary dict.CompareMode = vbTextCompare
Resolution: Set the CompareMode to vbTextCompare to ignore case or ensure your data has the correct case.
See Section: The Key and Case Sensitivity
Object Variable Error
Issue: You get the error message “Object variable or With block variable not set” when you try to use the Dictionary.
The normally happens when you forget to use New before you use the Dictionary. For example, the following code will cause this error
Dim dict As Scripting.Dictionary ' This line will give "Object variable..." error dict.Add "Apple", 4
Resolution: Use the New keyword when creating the Dictionary
Dim dict As New Scripting.Dictionary
Or
Dim dict As Scripting.Dictionary Set dict = New Scripting.Dictionary
See Section: Creating a Dictionary
Useful Tips for Troubleshooting the Dictionary
If you are investigating an issue with the Dictionary it can be useful to see the contents.
Use the following sub to Print each Key and Item to the Immediate Window(Ctrl + G).
' https://excelmacromastery.com/ Sub PrintContents(dict As Scripting.Dictionary) Dim k As Variant For Each k In dict.Keys ' Print key and value Debug.Print k, dict(k) Next End Sub
You can use it like this
Dim dict As Scripting.Dictionary Set dict = New Scripting.Dictionary ' Add items to Dictionary here ' Print the contents of the Dictionary to the Immediate Window PrintContents dict
If you are stepping through the code you can also add dict.Count to the Watch Window to see how many items are currently in the Dictionary. Right-click anywhere in the code window and select Add Watch. Type dict.Count into the text box and click Ok.
You can also use the Dictionary itself as a Watch. Add Dict to the Watch window. If you click on the plus sign you will see the contents of the Dictionary. This can be useful but it only shows the key and not the item.
Note: You can only view Watches when the code is running.
Remember that you can download all the code examples from the post. Just go to the download section at the top.
Copying the Dictionary to an Array
As we know the dictionary is made up of Key and Value pairs. The dictionary has a Keys property which is an array of all the keys and an Items property which is an array of all the items(i.e. values).
As both of these properties are arrays, we can write them directly to a worksheet as we will see in the next section.
If we want to copy either the Keys or Items array to a new array then we can do it very easily like this:
Dim arr As Variant arr = dict.Keys
The following example copies the Keys and Items arrays to new arrays. Then the contents of the new arrays are printed to the Immediate Window:
Sub DictionaryToArray() ' Create dictionary and add entries Dim dict As New Dictionary dict.Add "France", 56 dict.Add "USA", 23 dict.Add "Australia", 34 ' Declare variant to use as array Dim arr As Variant ' Copy keys to array arr = dict.Keys ' Print array to Immediate Window(Ctrl + G to View) Call PrintArrayToImmediate(arr, "Keys:") ' Copy items to array arr = dict.Items ' Print array to Immediate Window(Ctrl + G to View) Call PrintArrayToImmediate(arr, "Items:") End Sub ' Prints an array to the Immediate Window(Ctrl + G to View) Sub PrintArrayToImmediate(arr As Variant, headerText As String) Debug.Print vbNewLine & headerText Dim entry As Variant For Each entry In arr Debug.Print entry Next End Sub
When you run the code you wil get the following output:
Note that you can only copy the Items array when it contains basic data types like string, long, date, double etc. If the items are objects then you can not copy them to an array. You’ll need to read through the dictionary using a loop instead.
Writing the Dictionary to the Worksheet
We can write the Dictionary keys or items to the worksheet in one line of code.
When you write out the keys or items they will be written to a row. If you want to write them to a column you can use the WorksheetFunction.Transpose function.
The code below shows examples of how to write the Dictionary to a worksheet:
Sub DictionaryToWorksheet() Dim dict As New Dictionary dict.Add "France", 56 dict.Add "USA", 23 dict.Add "Australia", 34 Dim sh As Worksheet Set sh = ThisWorkbook.Worksheets("Sheet1") ' Write keys to range A1:C1 sh.Range("A1:C1").Value = dict.Keys ' Write items to range A2:C2 sh.Range("A2:C2").Value = dict.Items ' Write keys to range E1:E3 sh.Range("E1:E3").Value = WorksheetFunction.Transpose(dict.Keys) ' Write items to range F1:F3 sh.Range("F1:F3").Value = WorksheetFunction.Transpose(dict.Items) End Sub
Useful Dictionary Examples
The easiest way to see the benefits of the Dictionary is to see some real-world examples of it’s use. So in this section we are going to look at some examples. You can get workbooks and code for these examples by entering your email below:
Example 1 – Summing Single Values
Let’s have a look at a real-world example of using a dictionary. Our data for this example is the World Cup Final matches from 2014.
Our task here is to get the number of goals scored by each team.
The first thing we need to do is to read all the data. The following code reads through all the matches and prints the names of the two teams involved.
' https://excelmacromastery.com/vba-dictionary ' Reads the World Cup data from the 2014 Worksheet ' View the results in the Immediate Window(Ctrl + G) Sub GetTotals() ' Get worksheet Dim wk As Worksheet Set wk = ThisWorkbook.Worksheets("2014") ' Get range for all the matches Dim rg As Range Set rg = wk.Range("A1").CurrentRegion Dim Team1 As String, Team2 As String Dim Goals1 As Long, Goals2 As Long Dim i As Long For i = 2 To rg.Rows.Count ' read the data from each match Team1 = rg.Cells(i, 5).Value Team2 = rg.Cells(i, 9).Value Goals1 = rg.Cells(i, 6).Value Goals2 = rg.Cells(i, 7).Value ' Print each teams/goals to Immediate Window(Ctrl + G) Debug.Print Team1, Team2, Goals1, Goals2 Next i End Sub
What we want to do now is to store each team and the goals they scored. When we meet a team for the first time we add the name as a Key and the number of goals as the Item.
Celebrating a Goal | © BigStockPhoto.com
If the team has already been added then we add the goals they scored in the current match to their total.
We can use the following line to add goals to the current team:
dict(Team1) = dict(Team1) + Goals1
This line is very powerful.
If the teams exists in the Dictionary, the current goals are added to the current total for that team.
If the team does not exist in the Dictionary then it will automatically add the team to the Dictionary and set the value to the goals.
For example, imagine the Dictionary has one entry
Key, Value
Brazil, 5
Then
dict("Brazil") = dict("Brazil") + 3
will update the dictionary so it now looks like this
Key, Value
Brazil, 8
The line
dict("France") = dict("France") + 3
will update the dictionary so it now looks like this
Key, Value
Brazil, 8
France, 3
This saves us having to write code like this:
If dict.Exists(Team1) Then ' If exists add to total dict(Team) = dict(Team) + Goals1 Else ' if doesn't exist then add dict(Team) = Goals1 End If
We write out the values from the Dictionary to the worksheet as follows:
' Write the data from the dictionary to the worksheet ' https://excelmacromastery.com/vba-dictionary Private Sub WriteDictionary(dict As Scripting.Dictionary _ , shReport As Worksheet) ' Write the keys shReport.Range("A1").Resize(dict.Count, 1).Value = WorksheetFunction.Transpose(dict.Keys) ' Write the items shReport.Range("B1").Resize(dict.Count, 1).Value = WorksheetFunction.Transpose(dict.Items) End Sub
We obviously want the scores to be sorted. It is much easier to read this way. There is no easy way to sort a Dictionary. The way to do it is to copy all the items to an array. Sort the array and copy the items back to a Dictionary.
What we can do is sort the data once it has been written to the worksheet. We can use the following code to do this:
' Sort the data on the worksheet ' https://excelmacromastery.com/vba-dictionary Public Sub SortByScore(shReport As Worksheet _ , Optional sortOrder As XlSortOrder = xlDescending) Dim rg As Range Set rg = shReport.Range("A1").CurrentRegion rg.Sort rg.Columns("B"), sortOrder End Sub
Our final GetTotals sub looks like this:
' https://excelmacromastery.com/vba-dictionary Sub GetTotalsFinal() ' Create dictionary Dim dict As New Scripting.Dictionary ' Get worksheet Dim sh As Worksheet Set sh = ThisWorkbook.Worksheets("2014") ' Get range Dim rgMatches As Range Set rgMatches = sh.Range("A1").CurrentRegion Dim team1 As String, team2 As String Dim goals1 As Long, goals2 As Long Dim i As Long ' Read through the range of data For i = 2 To rgMatches.Rows.Count ' read the data to variables team1 = rgMatches.Cells(i, 5).Value team2 = rgMatches.Cells(i, 9).Value goals1 = rgMatches.Cells(i, 6).Value goals2 = rgMatches.Cells(i, 7).Value ' Add the totals for each team to the dictionary. ' If the team doesn't exist it will be automatically added dict(team1) = dict(team1) + goals1 dict(team2) = dict(team2) + goals2 Next i ' Get the report worksheet Dim shReport As Worksheet Set shReport = ThisWorkbook.Worksheets("2014 Report") ' Write the teams and scores to the worksheet WriteDictionary dict, shReport ' Sort the range ' Change to xlAscending to reverse the order SortByScore shReport, xlDescending ' Clean up Set dict = Nothing shReport.Activate End Sub
When you run this code you will get the following results
Teams ordered by number of goals scored
Example 2 – Dealing with Multiple Values
We are going to use the data from the Multiple Values section above
Imagine this data starts at cell A1. Then we can use the code below to read to the dictionary.
The code includes two subs for displaying the data:
- WriteToImmediate prints the contents of the dictionary to the Immediate Window.
- WriteToWorksheet writes the contents of the dictionary to the worksheet called Output.
To run this example:
- Create a worksheet called Customers.
- Add the above data to the worksheet starting at cell A1.
- Create a worksheet called Output and leave it blank.
- Go to the Visual Basic Editor(Alt + F11).
- Select Tools->Reference and then check “Microsoft Scripting Runtime” from the list.
- Create a new class module and add the first piece of code from below.
- Create a new standard module and add the second piece of code from below.
- Press F5 to run and select Main from the menu.
- Check the ImmediateWindow(Ctrl + G) and the Output worksheet to see the results.
' clsCustomer Class Module Code Public CustomerID As String Public Amount As Long Public Items As Long
' Standard module Code ' https://excelmacromastery.com/ Sub Main() Dim dict As Dictionary ' Read the data to the dictionary Set dict = ReadMultiItems ' Write the Dictionary contents to the Immediate Window(Ctrl + G) WriteToImmediate dict ' Write the Dictionary contents to a worksheet WriteToWorksheet dict, ThisWorkbook.Worksheets("Output") End Sub Private Function ReadMultiItems() As Dictionary ' Declare and create the Dictionary Dim dict As New Dictionary ' Get the worksheet Dim sh As Worksheet Set sh = ThisWorkbook.Worksheets("Customers") ' Get the range of all the adjacent data using CurrentRegion Dim rg As Range Set rg = sh.Range("A1").CurrentRegion Dim oCust As clsCustomer, i As Long ' read through the data For i = 2 To rg.Rows.Count ' Create a new clsCustomer object Set oCust = New clsCustomer ' Set the values oCust.CustomerID = rg.Cells(i, 1).Value oCust.Amount = rg.Cells(i, 2).Value oCust.Items = rg.Cells(i, 3).Value ' Add the new clsCustomer object to the dictionary dict.Add oCust.CustomerID, oCust Next i ' Return the dictionary to the Main sub Set ReadMultiItems = dict End Function ' Write the Dictionary contents to the Immediate Window(Ctrl + G) ' https://excelmacromastery.com/ Private Sub WriteToImmediate(dict As Dictionary) Dim key As Variant, oCust As clsCustomer ' Read through the dictionary For Each key In dict.Keys Set oCust = dict(key) With oCust ' Write to the Immediate Window (Ctrl + G) Debug.Print .CustomerID, .Amount, .Items End With Next key End Sub ' Write the Dictionary contents to a worksheet ' https://excelmacromastery.com/ Private Sub WriteToWorksheet(dict As Dictionary, sh As Worksheet) ' Delete all existing data from the worksheet sh.Cells.ClearContents Dim row As Long row = 1 Dim key As Variant, oCust As clsCustomer ' Read through the dictionary For Each key In dict.Keys Set oCust = dict(key) With oCust ' Write out the values sh.Cells(row, 1).Value = .CustomerID sh.Cells(row, 2).Value = .Amount sh.Cells(row, 3).Value = .Items row = row + 1 End With Next key End Sub
Example 3 – Summing Multiple Values
In this example were are going to make a small update to Example 2. In that example there was only one entry per customer in the data.
This time there will be multiple entries for some customers and we want to sum the total Amount and total Items for each customer.
See the updated dataset below:
Note: If you run the “Example 2” code on data with multiple copies of the CustomerID, it will give the “Key already exists error”.
' clsCustomer Class Module Code Public CustomerID As String Public Amount As Long Public Items As Long
' Read from worksheet: CustomerSum ' Write to worksheet: CustomerRepSum ' https://excelmacromastery.com/vba-dictionary Sub MainSum() Dim dict As Dictionary ' Read the data to the dictionary Set dict = ReadMultiItemsSum ' Write the Dictionary contents to the Immediate Window(Ctrl + G) WriteToImmediate dict ' Write the Dictionary contents to a worksheet WriteToWorksheet dict, ThisWorkbook.Worksheets("CustomerRepSum") End Sub ' Read multiple items but this time sums the items ' https://excelmacromastery.com/ Private Function ReadMultiItemsSum() As Dictionary ' Declare and Create the Dictionary Dim dict As New Dictionary ' Get the worksheet Dim sh As Worksheet Set sh = ThisWorkbook.Worksheets("CustomerSum") ' Get the range of all the adjacent data using CurrentRegion Dim rg As Range Set rg = sh.Range("A1").CurrentRegion Dim oCust As clsCustomer, i As Long, customerID As String ' read through the data For i = 2 To rg.Rows.Count customerID = rg.Cells(i, 1).Value ' check if the customerID has been added already If dict.Exists(customerID) = True Then ' Get the existing customer object Set oCust = dict(customerID) Else ' Create a new clsCustomer object Set oCust = New clsCustomer ' Add the new clsCustomer object to the dictionary dict.Add customerID, oCust End If ' Set the values oCust.Amount = oCust.Amount + rg.Cells(i, 2).Value oCust.Items = oCust.Items + rg.Cells(i, 3).Value Next i ' Return the dictionary to the Main sub Set ReadMultiItemsSum = dict End Function ' Write the Dictionary contents to the Immediate Window(Ctrl + G) ' https://excelmacromastery.com/vba-dictionary Private Sub WriteToImmediate(dict As Dictionary) Dim key As Variant, oCust As clsCustomer ' Read through the dictionary For Each key In dict.Keys Set oCust = dict(key) With oCust ' Write to the Immediate Window (Ctrl + G) Debug.Print key, .Amount, .Items End With Next key End Sub ' Write the Dictionary contents to a worksheet ' https://excelmacromastery.com/ Private Sub WriteToWorksheet(dict As Dictionary, sh As Worksheet) ' Delete all existing data from the worksheet sh.Cells.ClearContents Dim row As Long row = 1 Dim key As Variant, oCust As clsCustomer ' Read through the dictionary For Each key In dict.Keys Set oCust = dict(key) With oCust ' Write out the values sh.Cells(row, 1).Value = key sh.Cells(row, 2).Value = .Amount sh.Cells(row, 3).Value = .Items row = row + 1 End With Next key End Sub
When To Use The Dictionary
So when should you use the VBA Dictionary? When you have a task where:
- You have a list of unique items e.g. countries, invoice numbers, customer name and addresses, project ids, product names etc.
- You need to retrieve the value of a unique item.
Key/Values of Countries and Land area in Km2
What’s Next?
Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.
Related Training: Get full access to the Excel VBA training webinars and all the tutorials.
(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)
Василий Пользователь Сообщений: 29 |
Коллеги, Подскажите, есть ли возможность добавления словаря в качестве значения в другой словарь? К примеру есть основной словарь: ГЛ_СЛОВАРЬ (Ключ1: Значение1; Ключ2 : Значение2; …) Вместо Значение1, Значение2, … должны быть словари. В итоге хотелось бы увидеть следующее: ГЛ_СЛОВАРЬ (Ключ1: ВЛ_СЛОВАРЬ(Ключ1_1: Значение 1, …); Ключ2 : ВЛ_СЛОВАРЬ(Ключ2_2: Значение 1, …); …) Если есть такая возможность, то каким образом можно заполнить такую структуру и как к ней обращаться? |
что мешает? добавляйте Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете! |
|
Василий Пользователь Сообщений: 29 |
#3 27.04.2022 07:23:10 Примерно получается такой кусочек кода, но он не рабочий:
|
||
Василий Пользователь Сообщений: 29 |
Т.е. я не совсем понимаю, как правильно вложить словарь во внутрь и как его при необходимости оттуда взять… |
но вы хоть понимаете что вы хотите вложить в словари? Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете! |
|
Jack Famous Пользователь Сообщений: 10848 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
Василий, файл с кодом и данными Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
Бахтиёр Пользователь Сообщений: 1930 Excel 365 |
#7 27.04.2022 09:46:26
Прикрепленные файлы
Изменено: Бахтиёр — 27.04.2022 09:47:16 |
||
Jack Famous Пользователь Сообщений: 10848 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
Ну раз решение есть, то добавлю, что иногда может быть удобнее использовать массив словарей aDic() As Dictionary Изменено: Jack Famous — 27.04.2022 10:20:37 Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
Василий Пользователь Сообщений: 29 |
#9 27.04.2022 14:20:16 Коллеги, Спасибо за Ваш труд. В итоге остановился на варианте, который я описал в самом начале. Меня интересовало как именно в словарь, в значение его ключа включить еще один словарь. Почему не массив, потому что со словарем проще работать, там не нужно делать циклы для перебора значений. Оказалось, что код, который я написал не корректно работал из-за разницы в типах данных.
Так вот, проблема была в том, что значение ключа в словарь нужно было вставлять, предварительно преобразовав его в текстовый формат. После этого все завелось |
||
New Пользователь Сообщений: 4581 |
#10 27.04.2022 20:34:44
— скажите любое слово из русского языка? Изменено: New — 27.04.2022 23:25:37 |
||
Василий Пользователь Сообщений: 29 |
New, А Вы просто флудите. |
Msi2102 Пользователь Сообщений: 3137 |
#12 28.04.2022 07:12:58
Ну давайте начнём с того, что заморочиться должны были Вы, а не помогающий. Вы правила форума для начала почитайте и подумайте, почему у вас так мало ответов с решениями. И вообще удивительно, что эта тема просуществовала так долго. С таким названием, модераторы, как правило их удаляют.
Оно конечно может подходить, но в данной ветке должен быть поставлен конкретный вопрос, что именно не получается, и это также должно быть отражно в названии темы (что кстати тоже описано в правилах форума и модераторы за этим строго следят) , а не задавать филосовские вопросы, о проблемах словаря в словаре. |
||||
БМВ Модератор Сообщений: 21378 Excel 2013, 2016 |
Все остановились! По вопросам из тем форума, личку не читаю. |
Jack Famous Пользователь Сообщений: 10848 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
Msi2102, пусть сидит теперь и ждёт помогающих, которые всё за него сделают Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
Александр Моторин Пользователь Сообщений: 958 |
#15 02.05.2022 08:06:03
кусок кода из моей программы |
||
I found an old method http://www.techbookreport.com/tutorials/vba_dictionary2.html to perform a dictionary inside a dictionary in VBA but in Excel 2013 modification in the Scripting library, I can’t make the nesting work the same way.
Or is there?
Sub dict()
Dim ws1 As Worksheet: Set ws1 = Sheets("BM")
Dim family_dict As New Scripting.Dictionary
Dim bm_dict As New Scripting.Dictionary
Dim family As String, bm As String
Dim i
Dim ws1_range As Range
Dim rng1 As Range
With ws1
Set ws1_range = .Range(Cells(2, 1).Address & ":" & Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1).Address)
End With
For Each rng1 In ws1_range
family = ws1.Cells(rng1.Row, 1)
bm = ws1.Cells(rng1.Row, 2)
If family_dict.Exists(family) Then
Set bm_dict = family_dict(family)("scripting.dictionary")
If bm_dict.Exists(bm) Then
Else
bm_dict.Add bm, Empty
End If
Else
family_dict.Add family, Empty
Set bm_dict = family_dict(family)("scripting.dictionary")
If bm_dict.Exists(bm) Then
Else
bm_dict.Add bm, Empty
End If
End If
For Each i In family_dict.Keys: Debug.Print i: Next
For Each i In bm_dict.Keys: Debug.Print i: Next
For Each i In bm_dict.Items: Debug.Print i: Next
Debug.Print bm_dict.Count
Next
End Sub
pnuts
58k11 gold badges85 silver badges137 bronze badges
asked Sep 17, 2015 at 1:25
3
Working code for my Sheet:
Sub dict()
Dim ws1 As Worksheet: Set ws1 = Sheets("BM")
Dim family_dict As Dictionary, bm_dict As Dictionary
Dim i, j
Dim ws1_range As Range
Dim rng1 As Range, rng2 As Range
With ws1
Set ws1_range = .Range(Cells(2, 1).Address & ":" & Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1).Address)
End With
Set family_dict = New Dictionary
For Each rng1 In ws1_range
If Not family_dict.Exists(Key:=ws1.Cells(rng1.Row, 1).Value2) Then
Set bm_dict = New Dictionary
For Each rng2 In ws1_range
If rng2 = rng1 Then
If Not bm_dict.Exists(Key:=ws1.Cells(rng2.Row, 2).Value2) Then
bm_dict.Add Key:=ws1.Cells(rng2.Row, 2).Value2, Item:=Empty
End If
End If
Next
family_dict.Add Key:=ws1.Cells(rng1.Row, 1).Value2, Item:=bm_dict
Set bm_dict = Nothing
End If
Next
'---test---immediate window on---
For Each i In family_dict.Keys: Debug.Print i: For Each j In family_dict(i): Debug.Print j: Next: Next
End Sub
answered Sep 17, 2015 at 14:07
Dictionary of dictionaries:
Late binding is slow: CreateObject(«Scripting.Dictionary»)
Early binding is fast: VBA Editor -> Tools -> References -> Add Microsoft Scripting Runtime
Option Explicit
Public Sub nestedList()
Dim ws As Worksheet, i As Long, j As Long, x As Variant, y As Variant, z As Variant
Dim itms As Dictionary, subItms As Dictionary 'ref to "Microsoft Scripting Runtime"
Set ws = Worksheets("Sheet1")
Set itms = New Dictionary
For i = 2 To ws.UsedRange.Rows.Count
Set subItms = New Dictionary '<-- this should pick up a new dictionary
For j = 2 To ws.UsedRange.Columns.Count
' Key: "Property 1", Item: "A"
subItms.Add Key:=ws.Cells(1, j).Value2, Item:=ws.Cells(i, j).Value2
Next
' Key: "Item 1", Item: subItms
itms.Add Key:=ws.Cells(i, 1).Value2, Item:=subItms
Set subItms = Nothing '<-- releasing previous object
Next
MsgBox "Row 5, Column 4: ---> " & itms("Row 5")("Column 4")
End Sub
answered Sep 17, 2015 at 2:10
paul bicapaul bica
10.5k4 gold badges22 silver badges41 bronze badges
1
Создание объекта Dictionary с помощью кода VBA Excel. Раннее и позднее связывание. Методы и свойства словаря и синтаксис выражений с ними. Примеры кода.
Dictionary – это объект, предназначенный для записи, хранения и использования пар, состоящих из ключа и элемента данных.
Раннее связывание:
Dim myDict As Dictionary Set myDict = New Dictionary |
или
Dim myDict As New Dictionary |
Позднее связывание:
Dim myDict As Object Set myDict = CreateObject(«Scripting.Dictionary») |
Чтобы использовать раннее связывание, необходимо подключить в редакторе VBA ссылку на библиотеку Microsoft Scripting Runtime, если она еще не подключена (в меню Tools–>References…):
Раннее связывание позволяет использовать при написании кода VBA Excel лист выбора и вставки свойств и методов объекта Dictionary (лист подсказок):
Лист подсказок отображается автоматически после ввода точки или, в иных случаях, вызывается сочетанием клавиш «Ctrl+Пробел».
Методы и свойства словаря
Методы объекта Dictionary
Метод Add
Метод Add добавляет в словарь новую пару ключ–элемент.
Dictionary.Add Ключ, Элемент |
- Ключ – обязательный аргумент, представляющий ключ добавляемой пары.
- Элемент – обязательный аргумент, представляющий элемент добавляемой пары.
Если добавляемый ключ в словаре уже есть, VBA Excel сгенерирует ошибку.
Метод Exists
Метод Exists возвращает логическое значение, указывающее, существует ли в словаре указанный ключ. True – указанный ключ существует, False – указанный ключ не существует.
Метод Items
Метод Items возвращает массив всех элементов в словаре.
Метод Keys
Метод Keys возвращает массив всех ключей в словаре.
Метод Remove
Метод Remove удаляет из словаря одну пару ключ–элемент.
Если указанный ключ не существует, произойдет ошибка.
Метод RemoveAll
Метод RemoveAll удаляет из словаря все пары ключей и элементов.
Свойства объекта Dictionary
Свойство CompareMode
Свойство CompareMode задает или возвращает режим сравнения ключей в словаре. Используется для чтения и записи.
Dictionary.CompareMode [Сравнение] |
Необязательный аргумент Сравнение используется только при записи и может принимать следующие значения:
- –1 (vbUseCompareOption) – выполняется сравнение, заданное оператором Option Compare.
- 0 (vbBinaryCompare) – выполняется двоичное сравнение.
- 1 (vbTextCompare) – выполняется текстовое сравнение.
По умолчанию выполняется двоичное сравнение, при котором значение свойства CompareMode равно 0 (vbBinaryCompare).
Свойство Count
Свойство Count возвращает количество элементов в словаре. Только для чтения.
Свойство Item
Свойство Item задает или возвращает элемент для указанного ключа в словаре. Используется для чтения и записи.
Dictionary.Item(Ключ) [= Элемент] |
- Ключ – обязательный аргумент, представляющий из себя существующий ключ для чтения или изменения существующего элемента, или новый ключ для создания новой пары ключ–элемент.
- Элемент – необязательный аргумент, представляющий выражение, которое заменяет существующий элемент с существующим ключом или добавляет новый элемент в пару ключ–элемент с новым ключом.
Если при создании с новым ключом новой пары ключ–элемент аргумент Элемент не указан, значение элемента будет пустым (Empty).
Свойство Key
Свойство Key задает новое значение ключа для существующего ключа в словаре.
Dictionary.Key(Ключ) = НовыйКлюч |
- Ключ – обязательный аргумент, представляющий из себя существующий ключ.
- НовыйКлюч – обязательный аргумент, представляющий выражение, значение которого заменяет существующий ключ.
Если указанный ключ отсутствует в словаре, произойдет ошибка.
Примеры кода с Dictionary
Пример 1
Заполнение словаря парами ключ-элемент и извлечение элементов с помощью свойства Item:
Sub Primer1() Dim myDict As New Dictionary ‘Добавляем три пары ключ-элемент myDict.Add «№1», «Ананас» myDict.Add 2, «Апельсин» myDict.Add «Три», «Мандарин» ‘Смотрим количество записей в словаре MsgBox myDict.Count ‘Извлекаем элементы по ключам MsgBox myDict.Item(«№1») MsgBox myDict.Item(2) MsgBox myDict.Item(«Три») End Sub |
Пример 2
Замена элемента в существующей паре ключ-элемент, добавление новой пары ключ-элемент и добавление нового ключа без указания элемента с помощью свойства Item:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Sub Primer2() Dim myDict As New Dictionary, _ i As Integer ‘Добавляем три пары ключ-элемент myDict.Add 1, «Январь» myDict.Add 2, «Вторник» myDict.Add 3, «Среда» ‘Меняем элемент в паре с ключом 1 myDict.Item(1) = «Понедельник» ‘Добавляем новую пару ключ-элемент myDict.Item(4) = «Четверг» ‘Извлекаем элементы по ключам For i = 1 To 4 MsgBox myDict.Item(i) Next ‘Добавляем новый ключ без элемента, ‘MsgBox покажет пустую строку MsgBox myDict.Item(5) ‘Убеждаемся, что теперь в словаре ‘не 4, а 5 записей MsgBox myDict.Count End Sub |
Обратите внимание, добавить новый ключ без указания элемента можно только путем присвоения значения выражения переменной или, как во втором примере, функции MsgBox:
‘Так работает: a = myDict.Item(НовыйКлюч) ‘Так работает: MsgBox myDict.Item(НовыйКлюч) ‘Так не работает, вызывает ошибку: myDict.Item(НовыйКлюч) |
Пример 3
Извлечение ключей и элементов в массив:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Sub Primer3() Dim myDict As New Dictionary, _ a As Variant, b As String, _ i As Integer myDict.Add «з», «Зима» myDict.Add «в», «Весна» myDict.Add «л», «Лето» myDict.Add «о», «Осень» ‘Извлекаем ключи в массив a a = myDict.Keys ‘Записываем извлеченные ключи ‘в переменную b b = «Ключи:» & vbNewLine For i = 1 To myDict.Count b = b & vbNewLine & a(i — 1) Next ‘Смотрим список ключей MsgBox b ‘Извлекаем элементы в массив a a = myDict.Items ‘Записываем извлеченные ‘элементы в переменную b b = «Элементы:» & vbNewLine For i = 1 To myDict.Count b = b & vbNewLine & a(i — 1) Next ‘Смотрим список элементов MsgBox b End Sub |