vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest środa, 28 lipca 2021 roku.
Ustaw jako stronę startową Ulubione Napisz
Artykuły
Kolekcje w VBA
zamieszczony: 16 października 2003
przez: admin
czytany 49698 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