Wybór niepowtarzających się elementów przy pomocy kolekcji (zbiorów)

by Marcin

Przygotowując formularz do obsługi magazynu potrzebowałem wygenerować i umieścić w kontrolce ListBox listę niepowtarzających się elementów pobieranych z komórek jednego ze skoroszytów. Mam tam listę wszystkich producentów oraz waluty, w jakich rozliczane są zakupy. Poniżej fragment wspomnianego skoroszytu (przechowywane są w nim ustawienia aplikacji). Ponieważ jest to „żywy organizm” postanowiłem poukrywać informacje, które niekoniecznie są nam potrzebne.

Niepowtarzające się elementy na liście przy pomocy kolekcji (zbiorów)

To, co chciałem zrobić to wyświetlić w kontrolce ListBox listę (bez powtórzeń) używanych walut. Mniej więcej tak jak na rysunku poniżej.

Niepowtarzające się elementy na liście ListBox przy pomocy kolekcji (zbiorów)

Jak to w Excelu, problem można rozwiązać na kilka sposobów. Osobiście, z reguły, wykorzystuję kolekcje (zwane także zbiorami). Głównie dlatego, że rozwiązanie to wydaje mi się najprostsze.

Czym zatem jest kolekcja ?

Pomijam fachowe definicje – jeżeli takich szukasz bez problemów znajdziesz je w książkach o programowaniu. Z praktycznego punktu widzenia kolekcja, podobnie jak tablica, jest zmienną „w której” możesz przechowywać wiele informacji na raz.

W przeciwieństwie do tablic nie jesteś ograniczony tylko do jednego typu danych, nie musisz także deklarować rozmiaru kolekcji. Pamięć jest rezerwowana dynamicznie, za każdym razem kiedy dodajesz nowy element do kolekcji. Warto także dodać, że elementy w kolekcji numerowane są od „1”, w przeciwieństwie do tablic gdzie (o ile nie określisz inaczej) elementy numerowane są od „0”.

Kolekcje posiadają cztery metody – Add, Item, Remove oraz Count. Nazwy metod wyjaśniają w zasadzie ich działanie. W przypadku, o którym piszę interesuje nasz metoda Add.

Składnia metody Add jest następująca:

NazwaKolekcji.Add Item [, Key] [, Before,] [, After], gdzie Item to oczywiście element dodawany do kolekcji, Key(klucz) to coś na kształt identyfikatora, przypisanego do elementu, pozwalającego w bardziej przyjazny sposób odwoływać się do elementu. Before i After umożliwiają precyzyjne umieszczenie elementu wśród innych elementów znajdujących się już w kolekcji.

Kluczowe znaczenie w omawianym przypadku ma argument KEY (klucz). Kiedy korzystasz z tego argumentu, dla każdego dodawanego elementu musisz użyć INNEGO klucza. Jeżeli więc jako klucza użyjesz wartości dodawanego elementu (np. kiedy dodawany element to ciąg „marcin”, kluczem byłby także ciąg tekstowy„marcin”) to metoda zaakceptuje tylko niepowtarzające się elementy. W przypadku powtórzeń zwróci błąd, taki jak na rysunku poniżej.

Niepowtarzające się elementy na liście ListBox przy pomocy kolekcji (zbiorów)

Oczywiście nie chcemy, aby wykonywanie kodu przerwane zostało przez błędy. Dlatego przed rozpoczęciem wypełniania kolekcji dobrze jest chwilowo wyłączyć obsługę błędów i włączyć ja ponownie po zakończeniu.

Poniżej kod, jaki zastosowałem w swoim przykładzie.

Private Sub UserForm_Initialize()Dim WalutyBezPowtorzen As Collection   '  deklaracja zmiennej użytej później jako kolekcja

Dim waluty As Range	 '  zakres komórek z nazwami walut

Dim waluta As Variant	  '  zmienna pomocnicza, użyta w pętli wypełniającej ListBox

Set WalutyBezPowtorzen = New Collection   ' inicjowanie kolekcji

' wyłączam obsługę błędów, aby pomijać błędy wygenerowane w przypadku dodania powtarzającej się wartości

On Error Resume Next

'  dla każdej komórki(symbolu) waluty w nazwanym zakresie

For Each waluty In Range("wksUstawienia_waluty")

' dodaję element do kolekcji.

 WalutyBezPowtorzen.Add waluty.Value, waluty.Value

Next waluty

On Error GoTo 0  ' wyłączam obsługę błędów

'  Wypelniam listox wartosciami przechowywanymi w kolekcji

For Each waluta In WalutyBezPowtorzen

  	Me.CboxWaluty.AddItem waluta

Next waluta

End sub

Chciałbym jeszcze zwrócić Twoją uwagę na fakt, że argument KEY (klucz) metody Add MUSI być ciągiem tekstowym. W moim przypadku waluty są przechowywane jako ciągi tekstowe, więc wszystko zadziałało poprawnie. Gdybyś jednak nie miał pewności, lub po prostu chciał całość zapisać poprawnie (na wszelki wypadek), tak jak ja to później zrobię, mógłbyś wykorzystać funkcję CStr, zamieniającą podany argument na ciąg tekstowy.

Zamiast

WalutyBezPowtorzen.Add waluty.Value, waluty.Value

możesz użyć więc

WalutyBezPowtorzen.Add waluty.Value, CStr(waluty.Value)

i zapomnieć o problemie.

Oczywiście w moim przypadku lista elementów do „odfiltrowania” była niewielka. Śmiało jednak możesz wyobrazić sobie sytuacje i wykorzystać kolekcje do tworzenia list niepowtarzających się elementów w bardziej złożonych przypadkach.

{ 4 comments… read them below or add one }


Fatal error: Cannot assign by reference to overloaded object in /home/klient.dhosting.pl/antiquus/excelblog.pl/public_html/wp-content/themes/thesis_182/lib/classes/comments.php on line 176