przez:
admin
czytany 26003 razy.
Dziś na warsztat bierzemy kolekcje.
Czy wiecie co to jest kolekcja? Kolekcja to po prostu taka struktura danych.
W kolekcjach, inaczej niż w tablicach możemy przechowywać dane różnego typu,
mogą to być typy zarówno proste (String, Integer), typy obiektowe, w tym
również inne kolekcje.
Przykładowa deklaracja kolekcji może wyglądać tak:
Dim KolekcjaZnaczków As Collection
Jak wspomniałem powyżej kolekcja jest obiektową strukturą danych,
to znaczy przed wykorzystaniem kolekcji niezbędne jest jej utworzenie. Robi to
się tak:
Set KolekcjaZnaczków = New Collection
No i dopiero teraz można do takiej kolekcji dodawać elementy
składowe.. Do dodawania elementów służy metoda .Add, której składnia wygląda
następująco:
kolekcja.Add Item [, Key] [, Before,] [, After]
gdzie:
Key - klucz, czyli numer wstawianego elementu,
Before, After - określają, gdzie ma być wstawiony nowy element, za czy przed
określonym elementem.
A oto przykład, w którym do naszej kolekcji znaczków dodajemy
jakiś znaczek.
KolekcjaZnaczków.Add "Błękitny Mauritius"
Jeśli macie taki znaczek przypadkiem w domu, to nie naklejajcie
go na list, gdyż jest on nieważny w Polsce ;).
Załóżmy, że w naszej kolekcji wylądował rzeczony Błękitny Mauritius. Ale co
będzie jeżeli chcemy się go pozbyć, bo na przykład dostaniemy za niego
Zielonego Mauritiusa?
Proste: trzeba do usuniecia wykorzystać metodę .Remove:
KolekcjaZnaczków.Remove indeks
Indeks to numer naszego elementu w kolekcji. Pamiętać należy o
tym, że elementy kolekcji zawsze są numerowane od 1.
Dobrze, a jak można się dowiedzieć ile elementów znajduje się w
naszej kolekcjią Tu z odsieczą biegnie właściwość .Count.
ilosc = KolekcjaZnaczków.Count
I do zmiennej "ilosc" jest już przypisana ilość elementów w
naszej kolekcji.
|wietnie. A co należy zrobić, by w pętli "odwiedzić" wszystkie
elementy kolekcjią
Można to zrobić na dwa sposoby:
For i = 1 To KolekcjaZnaczków.Count
'[tu jakiś kod....]
Next el
Albo:
For Each el In
KolekcjaZnaczków
'[tu jakiś kod....]
Next el
Kolekcja wydaje się być więc bardzo wygodną dla programowania
strukturą danych, ale jak zbudować "wielowymiarowe" kolekcje (tak jak np.
wielowymiarowe tablice).
Przydałoby się one np. do przechowywania pełnych danych o znaczku z naszej
kolekcji, takich jak np. nazwa i cena.
Można to oczywiście zrobić, ale do tego potrzeba użyć klas.
Wyjaśnienie koncepcji klas - czyli innymi słowy koncepcji programowania
obiektowego wymaga dłuższej dygresji i odejścia od zasadniczego tematu tej
lekcji.
Klasy w VBA.
Po pierwsze musimy wiedzieć co to jest klasa.
Otóż klasą będziemy nazywać przepis na obiekt - a co to jest obiekt wiemy już z
kursu. Jeżeli będziemy mieli przepis na obiekt, będziemy mogli tworzyć w
oparciu o ten przepis nowe obiekty.
Zanim jednak utworzymy obiekt, musimy zdefiniować klasę. W VBA
robi to się tak:
Wstawiamy do naszego projektu moduł klasy. (Z menu "Insert" edytora VBA
wybieramy "Class Module", lub po kliknięciu prawym przyciskiem myszy na
eksplorator projektu wybieramy "Insert", a potem "Class Module").
Następnie w oknie właściwości nadajemy naszej klasie nazwę. Nasza przykładowa
klasa będzie się nazywać "Znaczek".
Po wejściu do modułu naszej klasy musimy zdefiniować właściwości
obiektu.
Polega to po prostu na zadeklarowaniu publicznych zmiennych.
Np.:
Public Nazwa As
String
Public Cena As Double
Tak zdefiniowane właściwości będą widoczne z dowolnego modułu
projektu VBA.
Mamy już zdefiniowana klasę "Znaczek". A jak utworzyć z niej
obiektą
Prosto, poprzez użycie operatorów Set i New:
Dim MojZnaczek as Znaczek
'Deklaracja zmiennej obiektowej MojZnaczek
Set MojZnaczek = New Znaczek
Zmienna MojZnaczek stanowi od tej pory referencję do obiektu.
Po utworzeniu nowego obiektu możemy nadać jego właściwościom, tzn. nazwie i
cenie odpowiednie wartości:
MojZnaczek.Nazwa = "Zielony Mauritius"
MojZnaczek.Cena= 100000
No, dobrze, a jeżeli chcielibyśmy, żeby jakaś nazwa i cena była
nadawana automatycznie w momencie tworzenia nowego obiektuą
Da to się zrobić poprzez wykorzystanie procedury, zwanej konstruktorem.
W module klasy piszemy więc:
Private Sub Class_Initialize()
Nazwa = "nazwa 1"
Cena = 10
End Sub
Jeżeli niszczymy obiekt (zwalniamy zmienną obiektową) :
Set MojZnaczek = Nothing
uruchomiona zostanie procedura, zwana destruktorem.
Private Sub Class_Terminate()
'[tu jakiś kod....]
End Sub
Powyższe procedury są w VBA (i VB też) predefiniowane dla każdej
klasy użytkownika. Można je wstawić do kodu także w sposób pokazany na
poniższych rysunkach:
Procedury te wydają się może w tej chwili niepotrzebne, a szczególnie
destruktor, ale docenicie je, jeśli w skład waszych klas wchodzić będą inne
obiekty (np. aplikacja). Wówczas zniszczenie obiektu, w skład którego wchodzi
aplikacja (np. Word), nie spowoduje automatycznego jej zamknięcia. Polecenie
zamykające Worda i zwalniające zmienną obiektową powinno się wówczas znaleĄć
się w destruktorze klasy.
Uff! Skomplikowane to trochę, więc wystarczy już o tym.
Do modułu klasy można wstawiać także procedury i funkcje. Funkcje
i procedury zawarte w module klasy nazywamy metodami tej klasy.
Omówienie sposobu tworzenia metod klasy w VBA to temat zbyt obszerny, żeby go
tutaj omówić, powracamy zatem to głównego tematu tej lekcji.
Jak utworzyć kolekcję znaczków zdefiniowanych jako obiektyą
Popatrzcie na poniższy przykład, a wszystko stanie się jasne:
Sub UtworzKolekcje()
'Deklaracje zmiennych
Dim KolekcjaZnaczków As Collection
Set KolekcjaZnaczków = New Collection
Dim MojZnaczek As Znaczek
Dim i As Integer
'W tej pętli tworzymy nowe obiekty, ustawiamy ich własciwości
'oraz dodajemy znaczki do kolekcji
For i = 1 To 10
Set MojZnaczek = New
Znaczek
MojZnaczek.Nazwa = "Mój znaczek nr " & i
MojZnaczek.Cena = i * 100
KolekcjaZnaczków.Add MojZnaczek
'Zwolnienie tej zmiennej obiektowej jest tutaj
konieczne,
'inaczej program nie będzie działał
prawidłowo!
Set MojZnaczek = Nothing
Next i
'**************************************************
'A teraz sprawdzimy, co "siedzi" w naszej kolekcji:
'**************************************************
Dim strKom1 As String
Dim strKom2 As String
Dim el As Znaczek
strKom1 = "Liczba znaczków w kolekcji: " & KolekcjaZnaczków.Count &
vbCrLf & vbCrLf
'W pętli tej "sklejamy" wszystkie informacje o znaczkach w naszej
kolekcji
For Each el In
KolekcjaZnaczków
strKom2 = strKom2 & el.Nazwa & " - " & el.Cena
& vbCrLf
Next el
'Wyświetlamy informację o naszej kolekcji
MsgBox strKom1 & strKom2, , "Kolekcja"
'Zwalniamy zmienną obiektową
Set KolekcjaZnaczków = Nothing
End Sub
Pozostaje jeszcze jeden temat to omówienia: jak sortować elementy
kolekcjią Nie da się tego zrobić tak prosto, jak przy tablicach.
Poniżej znajduje się przykładowa procedura sortująca, wykorzystująca sortowanie
bąbelkowe.
Przestawienie elementów odbywa się tutaj poprzez usunięcie rozpatrywanego
elementu kolekcji i wstawienie go z powrotem do kolekcji.
Sub Sortuj(ByRef Kolekcja As Collection)
If Kolekcja.Count = 0 Then Exit
Sub
Dim bSorted As Boolean
Dim el1 As Znaczek, el2
As Znaczek
Dim i As Integer
bSorted = False
Do Until bSorted
bSorted = True
For i = 2 To Kolekcja.Count
Set el1 = Kolekcja(i -
1)
Set el2 = Kolekcja(i)
If StrComp(el1.Nazwa,
el2.Nazwa, vbTextCompare) = 1 Then
bSorted = False
Kolekcja.Remove i - 1
Kolekcja.Add el1
End If
Next i
Loop
End Sub
wstecz