Reeksen = Arrays, Hashtable, Dictionaries
Reeksen of in het Engels 'Arrays' worden ook in VBA en VB.net veelvuldig toegepast. Terwijl Dictionaries,Hashtables,ArrayList
niet van toepassing zijn in VBA.
Reeksen of Array
Een Array of reeks houdt data-waarden van dezelfde soort, de één na de andere. De array
class biedt nuttige methoden en eigenschappen, bijvoorbeeld voor het sorteren of het tellen van de elementen in de Array.
Met Arrays kan men tijdens het uitvoeren van een programma allerlei data bewaren, bewerken en opvragen.
Meest voorkomend zijn ééndimensionale en tweedimensionale Arrays terwijl ook meerdimensionale Arrays mogelijk zijn.
Een Array heeft een unieke Index (begint steeds met 0) waarmee de waarde kan opgevraag worden.
Declaren Array met Dim / Redim statement men moet de dimensie van de Array opgeven of wijzigen,
of onmiddellijk de waarden toekennen :
Dim strNamen() As String = {"Deblauwe", "Depoorter", "Verlinden", "Antheunis", "Brussens", "Carpentier", _
"Feyters", "Geenens", "Hofkens","Impens", "Justaert", "Vanmaele", "Waelkens", "Eerdekens"}
'ééndimensionale Array van het String data type.
'een element opvragen, vb respectievelijk eerste en vijfde
strNamen(0) geeft "Deblauwe"
strNamen(4) geeft "Brussens"
Ook zo kan men een Array Declaren (hier van 15 elementen) :
Dim strNamenAnder(14) As String
In een routine vult men dan de Array :
strNamenAnder(0) = "Deblauwe"
strNamenAnder(1) = "Depoorter"
.........
strNamenAnder(14) = "Verzele"
Tijdens het programma kan men de grote van de Array wijzigen met Redim
men kan de vorige waarden al dan niet behouden :
Redim strNamen(5) de oorspronkelijke waarden worden alle gewist
Redim Preserve strNamen(25) de oorspronkelijke namen worden behouden, de bijkomende toegevoegd in een
procedure
strNamen(14) = "Jensen"
strNamen(15) = "Fierens"
..........
strNamen(25) = "Debruyne"
Ondergrens en Bovengrens bepalen
met LBound en UBound functies :
intOnder As Integer = LBound(strNamen) geeft 0
intBoven As integer = UBound(strNamen) geeft 25
Interessante Methodes
van het Array object :
- Sort Array.Sort(strNamen) -> rangschikt alfabetisch of van klein naar groot
- ReverseArray.Reverse(strNamen) -> keert volgorde om
Declaren tweedimensionale Array met Dim statement, men moet de dimensie van de Array opgeven of
of onmiddellijk de waarden toekennen :
Public Sub TweeDim()
Dim getallenTweeDim(,) As Integer = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}'Let op accoladen
For i As Integer = 0 To 2
For j As Integer = 0 To 2
Debug.Print(String.Format("Waarde i {0} - Waarde j {1} - Waarde getallenTweeDim({2} {3}) is {4}", i, j, i, j, getallenTweeDim(i, j)))
Next j
Next i
End Sub
geeft als resultaat :
Waarde i 0 - Waarde j 0 - Waarde getallenTweeDim(0 0) is 1
Waarde i 0 - Waarde j 1 - Waarde getallenTweeDim(0 1) is 2
Waarde i 0 - Waarde j 2 - Waarde getallenTweeDim(0 2) is 3
Waarde i 1 - Waarde j 0 - Waarde getallenTweeDim(1 0) is 4
Waarde i 1 - Waarde j 1 - Waarde getallenTweeDim(1 1) is 5
Waarde i 1 - Waarde j 2 - Waarde getallenTweeDim(1 2) is 6
Waarde i 2 - Waarde j 0 - Waarde getallenTweeDim(2 0) is 7
Waarde i 2 - Waarde j 1 - Waarde getallenTweeDim(2 1) is 8
Waarde i 2 - Waarde j 2 - Waarde getallenTweeDim(2 2) is 9
'nog een voorbeeld
Public Sub TweeDim_1()
Dim strBord(9, 9) As String
For shtKol As Short = 0 To 9
For shtRij As Short = 0 To 9
strBord(shtKol, shtRij) = shtKol.ToString & shtRij.ToString
Next
Next
'grafisch weergeven
Dim strRij As String = ""
For shtrij = 0 To 9
For shtkol = 0 To 9
strRij += strBord(shtkol, shtrij) & " "
Next
Debug.Print(strRij)
strRij = ""
Next
End Sub
geeft als resultaat :
00 10 20 30 40 50 60 70 80 90
01 11 21 31 41 51 61 71 81 91
02 12 22 32 42 52 62 72 82 92
03 13 23 33 43 53 63 73 83 93
04 14 24 34 44 54 64 74 84 94
05 15 25 35 45 55 65 75 85 95
06 16 26 36 46 56 66 76 86 96
07 17 27 37 47 57 67 77 87 97
08 18 28 38 48 58 68 78 88 98
09 19 29 39 49 59 69 79 89 99
'Met een For Each constructie kan men ook door de Array heen stappen :
For Each strWaarde As String In strBord
Debug.Print(strWaarde)
Next
Hashtable.
Een hashtabel bewaart zijn data in paren van Sleutel(Key) en Waarde (Value).
Vooraf aanduiden hoeveel paren een hashtabel zal bevatten hoeft niet.De Sleutel is van het integer data-type.
Aan de hand van de Sleutel kan men snel de bijhorende waarde vinden.
Public Sub Test_Hash_1()
Dim mijnHash As New Hashtable
mijnHash.Add(1, "antoon") 'blijkbaar is key een integer
mijnHash.Add(2, "raymonde")
mijnHash.Add(3, "joke")
Dim shtAantal As Short = mijnHash.Count
MsgBox(shtAantal)
Dim strDum As String = Nothing
For intDum As Integer = 1 To 3
'met de ContainsKey methode weet men indien een bepaalde sleutel bestaat.
If mijnHash.ContainsKey(intDum) = True Then
strDum += mijnHash(intDum) & vbCrLf
End If
Next
MsgBox(strDum)
End Sub
Public Sub Test_Hash_2()
Dim mijnAndereHash As New Hashtable
Dim strDum As String = Nothing
Dim strArray() As String = {"Antoon", "Raymonde", "An", "Koen", "Joke", "Wolf", "Mickey", "Charlotte"}
For intDum As Integer = 0 To UBound(strArray)
mijnAndereHash.Add(intDum + 1, strArray(intDum))
Next
For intDum2 As Integer = 1 To mijnAndereHash.Count
strDum += mijnAndereHash(intDum2) & vbCrLf
Next
MsgBox(strDum)
Dim mijnDerdeHash As New Hashtable
mijnDerdeHash = mijnAndereHash.Clone'Met de Clone methode wordt als het ware een copie gemaakt
MsgBox(mijnDerdeHash(1))
mijnDerdeHash.Remove(1) ' met de Remove methode verwijdert men een paar
MsgBox(mijnDerdeHash.ContainsKey(1)) ' geeft False
MsgBox(mijnDerdeHash(4))
mijnDerdeHash.Remove(4)
MsgBox(mijnDerdeHash.Count) ' toont zes gezien er twee verwijderd zijn.
MsgBox(mijnDerdeHash(2)) ' raymonde
MsgBox(mijnDerdeHash(8)) 'charlotte
End Sub
Public Sub Test_Hash_3()
Dim mijnTabel As New Hashtable
mijnTabel(1) = "Eén"
mijnTabel(2) = "Twee"
mijnTabel(3) = "Drie"
mijnTabel(4) = "Vier"
mijnTabel(5) = "Vijf"
For Each element As DictionaryEntry In mijnTabel
Debug.Print("sleutel:" & element.Key & " Waarde:" & element.Value)
Next
' met de Contains en ContainsKey methodes nagaan indien de tabel een bepaalde sleutel bevat.
If mijnTabel.Contains(1) Then
MsgBox("met de methode contains: " & mijnTabel(1))
End If
If mijnTabel.ContainsKey(2) Then
MsgBox("met de methode ContainsKey: " & mijnTabel(2))
End If
' met de methode ContainsValue nagaan indien de tabel een bepaalde waarde bevat.
If mijnTabel.ContainsValue("Drie") Then
For Each element As DictionaryEntry In mijnTabel
If element.Value = "Drie" Then
MsgBox("met de methode ContainsValue :" & element.Key)
End If
Next
End If
'met de TypeOf en de Is operator kan men nagaan welk datatype de waarde van een item in de Hashtabel is
If TypeOf (mijnTabel(1)) Is String Then MsgBox("het is string")
'met de count property kan men het aantal sleutel waarde paren bekomen.
'met de clear methode kan men alle sleutel-waarde paren uit de tabel verwijderen.
End Sub
Public Sub Test_Hash_4()
' Eén HashTable kan verscillende datatypes bevatten.
Dim gemengdeHash As New Hashtable
gemengdeHash(1) = "Dit is een spring"
gemengdeHash(2) = 1000
gemengdeHash(3) = False
gemengdeHash(4) = 100 / 23
Dim intAant As Integer = gemengdeHash.Count
Dim sng As Single = gemengdeHash(4)
MsgBox("Deze tabel bevat " & intAant & "paren." _
& vbCrLf & "de vierde waarde is : " & sng)
End Sub
Dictionary
Het Dictionary-object vertoont veel analogieën met het Hashtable-object maar heeft ontegensprekelijk
voordelen vooral als het op performantie aankomt.
Bij de declaratie geeft men de data-waarden op van de Sleutel (Key) en de Waarden (Values). Daarna moeten deze bij het
gebruik van de dictionary gerespecteerd worden.
Voorbeeld van een Dictionary
Public Sub TestDictionary_av1()
Dim avDictionary As New Dictionary(Of Integer, String)
avDictionary.Add(1, "Antoon")
avDictionary.Add(2, "Raymonde")
avDictionary.Add(3, "An")
avDictionary.Add(4, "Koen")
avDictionary.Add(5, "Joke")
avDictionary.Add(6, "Arno")
avDictionary.Add(7, "Emiel")
avDictionary.Add(8, "Toor")
Dim intI As Integer = 0
For intI = 1 To 8
Debug.Print("Voor sleutel " & intI.ToString & " is de waarde {0}", avDictionary.Item(intI))
Next intI
' het zelfde als bovenstaande kan ook met onderstaande constructie
For Each slw As KeyValuePair(Of Integer, String) In avDictionary
Debug.Print("Voor sleutel {0} is de waarde {1}", slw.Key, slw.Value)
Next slw
' een waarde kan men opvragen aan de hand van de sleutel
Debug.Print("Voor sleutel 6 staat de waarde {0}", avDictionary(6))
Dim waardeKol As Dictionary(Of Integer, String).ValueCollection = avDictionary.Values
Debug.Print("avDictionary bevat volgende waarden : ")
For Each StrWaarde As String In waardeKol
Debug.Print("{0}", StrWaarde)
Next
End Sub
Public Sub TestDictionary_av2()
'Ziehier een dictionary waarvan zowel sleutel as waarde van hetzelfde datatype zijn.
Dim mijnDict As New Dictionary(Of String, String)
'Data voegt men toe met de Add methode
mijnDict.Add("A", "Deze waarde heeft A als sleutel")
mijnDict.Add("B", "Deze waarde heeft B als sleutel")
mijnDict.Add("C", "Deze waarde heeft C als sleutel")
mijnDict.Add("D", "Deze waarde heeft D als sleutel")
'Met de Count methode weet men hoeveel paren een Dictionary-object omvat
Debug.Print("Mijn directory-object bevat {0} paren", mijnDict.Count)
' De Add method geeft een waarschuwing indien de sleutel
' reeds bestaat
Try
mijnDict.Add("D", "Maar deze sleutel bevindt zich reeds in de Dictionary")
Catch ex As Exception
Debug.Print("De sleutel D bestaat reeds in deze dictionary")
End Try
'Een waarde opvragen kan met de Item property
Debug.Print("Waarde opvragen met Item property : {0} ", mijnDict.Item("A"))
'Gezien Item de standaard property is moet deze niet vermeld worden
Debug.Print("Om de waarde op te vragen mag de Item property weggelaten worden : {0}", mijnDict("B"))
'Met de Item property kan men ook de waarde wijzigen die met een sleutel
'geassocieerd is
mijnDict("D") = "De waarde was oorspronkelijk D"
Debug.Print("De gewijzigde waarde opvragen : {0}", mijnDict("D"))
'indien men de waarde probeert op te vragen van een niet bestaande sleutel
'krijgt men een foutbericht
Try
Debug.Print("Voor Sleutel X is de waarde {0} ", mijnDict("X"))
Catch ex As Exception
Debug.Print("Er is geen sleutel ""X""")
End Try
'Indien men twijfelt indien een sleutelwaarde wel aanwezig is
'gebruikt men beter de TryGetValue methode
Dim strTeZoekenWaarde As String = ""
If mijnDict.TryGetValue("X", strTeZoekenWaarde) Then
Debug.Print("De waarde voor sleutel X is {0}", strTeZoekenWaarde)
Else
Debug.Print("De sleutel X is niet gevonden")
End If
'En alvorens een sleutel/wwarde in te voeren kan men vooraf
'controleren met de ContainsKey methode
If Not mijnDict.ContainsKey("E") Then
mijnDict.Add("E", "Dit is de waarde voor E")
End If
Debug.Print("Voor de sleutel E werd de waarde : {0} toegevoegd", mijnDict("E"))
'bij het gebruik van een For Each constructie worden de elementen
'opgehaald als KeyValuePair objecten
For Each element As KeyValuePair(Of String, String) In mijnDict
Debug.Print("Sleutel = {0}, Waarde = {1}", _
element.Key, element.Value)
Next element
'wil men enkel de waarde ophalen maak dan gebruik van de Values property
Dim enkelWaarde As Dictionary(Of String, String).ValueCollection = mijnDict.Values
Debug.Print("Enkel waarden ophalen")
For Each str As String In enkelWaarde
Debug.Print("Waarde = {0}", str)
Next str
'wil men enkel de sleutels ophalen maak dan gebruik van de Keys property
Dim enkelSleutel As Dictionary(Of String, String).KeyCollection = mijnDict.Keys
Debug.Print("Enkel Sleutels ophalen")
For Each str As String In enkelSleutel
Debug.Print("Sleutel = {0}", str)
Next str
'met de Remove methode kan men een Sleutel/Waarde paar verwijderen
Debug.Print("Met de Remove methode een sleutel/waarde paar verwijderen")
mijnDict.Remove("E")
If Not mijnDict.ContainsKey("E") Then
Debug.Print("Sleutel ""E"" niet gevonden.")
End If
End Sub