1. Collection Nedir?
Collection’lar da, dizi değişkenleri gibi, farklı değişkenleri bir arada tutmak için kullanılan yapılardır. Bu sayede geniş bir aralıktaki değişkenleri bir araya getirip üzerilerinde daha rahat çalışabilirsiniz. Öncelikle İngilizce terimleri kullanmayı pek sevmem. Ancak Collection için tam bir karşılık bulamadın, Türkçe’de en yakın karşılığı olarak yığın kullanılabilir. Bana göre de en uygun anlamı bu.
Excel’de az biraz daha olsa makro yazdı iseniz Collection’ları bir şekilde kullanmışsınızdır. Excel’de açtığınız tüm çalışma kitapları, çalışma sayfaları ve hücreler birer collection nesnesidir. Dikkat ederseniz nesne dedim, dizi değişkenlerinden en büyük farkı nesne olmalarıdır. Bu sayede kendilerine ait işlevler ve yöntemlere sahiptir.
Collection nesnesi oldukça eski bir nesnedir. Bu nesne önce Sözlük (Dictionary) nesnesine dönüştü, daha sonrasında ise Liste nesnesine. VBA yerine Visual Studio kullanıyorsanız Liste nesneleri çok daha fazla yeteneğe sahiptir.
2. Dizilerden Farkı Nedir?
a. Kolaylıkları
Bildiğiniz gibi diziler belli bir alt ve üst sınıra sahipti. Siz eğer belirli boyutlu bir dizi oluşturursanız üst sınırını değiştiremiyordunuz, eğer değişken boyutlu bir dizi oluşturdu iseniz sadece tanımladığınız en son boyutunu değiştirebiliyordunuz ve bunu değer atamadan önce her seferinde yapmanız gerekiyordu ve tabii daha önce atanan değerleri korumak için de ek bir kod yazmanız gerekli idi.
Collection nesnesinde alt sınır sabittir ve her zaman 1’dir. Yani nesnenin ilk öğesi her zaman 1. eğedir. Üst sınır ise her zaman değişkendir ve siz herhangi bir işlem yapmak zorunda bırakmaz. Collection nesnesine yeni bir eleman eklediğinizde üst sınır otomatik olarak değişir ve bu değere hızlıca erişebilirsiniz.
Dizi nesnelerinde yer alan elemanların sıralamasını değiştirmek ve aralarına yeni değerler eklemek oldukça zahmetlidir. Collection nesnesinde ise istediğiniz elemanı, mevcut elemanlardan istediğinizin önüne veya arkasına yerleştirebilirsiniz.
Dizi değişkenlerinde girilmiş elemanlardan birini silmek ve üst sınırı da buna göre güncellemek yine ek kod ister ve biraz zahmetlidir. Collection nesnesinde ise eleman silmek için bir yordam mevcuttur ve kolayca yapılabilir.
Sürekli yeni elemanlar ekliyor, mevcutları çıkartıyor iseniz dizi değişkenleri ile bunu yapmak biraz zahmetli olacaktır. Collection nesnesi bu konuda çok daha avantajlı.
b. Zorlukları
Collection nesnesi tek boyutludur. Diziler gibi birden fazla değeri tek bir girdi olarak tutmak isterseniz Collection içinde bunu yapmak mümkün değil. Ya bu değerleri bir metin olarak aralarına bir ayraç koyarak birleştireceksiniz ya da her bir ayrı değeri ayrı Collection’lar içinde tutup sonradan bir ana Collection nesnesinde tutacaksınız ki her ikisinde de ek programlama adımlarına ihtiyacınız var.
Dizi değişkenlerinde olduğu gibi bir Collection’a bir değeri daha önce ekleyip eklemediğinizi bulmak için ek programlama adımlarına ihtiyacınız vardır. Bu eksiklikler Sözlük (Dictionary) nesnesi ile bir nebze iyileştirildi ancak belli değerden küçük tüm değerleri bul gibi bir ifade kullanamıyorsunuz.
Collection’lar içindeki tam sayı, metin gibi temel değişkenlerin değerlerini değiştiremezsiniz. Yani daha önce eklediğiniz bir değeri daha sonra değiştirmek isterseniz önce o değeri kaldırmalı ve yeni değere sahip bir şekilde aynı konuma eklemelisiniz.
Collection içinde tuttuğunuz nesnelerde ise bir yukarıda anlattığım kısıtlama geçerli değil. Nesneler, Collection içinde başvuru olarak yer alır. C kullananlar için bu işaretçi gibi düşünülebilir.
Collection nesnesinin en gıcık olduğum hatta bana göre en büyük eksikliği Kullanıcı Tanımlı Türleri ekleyemiyor olmanız. Collection nesnesinin tek boyutlu olması da bu sorunu daha da bela haline getiriyor. Bunu aşmanın tek yolu Kullanıcı Tanımlı Türlerinizi nesneye çevirmek.
3. Kullanımı
a. Tanımlama
Collection bir nesne olduğu için nesne olarak tanımlanmalıdır.
Dim cYigin As Collection
Set cYigin = New Collection
veya:
Dim cYigin as New Collection
şeklinde bunu tek satırda yapabilirsiniz.
b. Count Sınıf Mülkü
Bir Collection nesnesi içinde herhangi bir anda toplamda kaç tane öğe olduğunu gösteren değerdir. Bu değere sizin dışarıdan müdahale etmeniz mümkün değildir. Nesneye yeni öğeler eklediğinizde veya mevcut öğeyi çıkardığınızda bu değer otomatik olarak güncellenir. Eğer hiç bir öğe yok ise 0 değerini döndürür.
dim cYigin as new Collection
debug.print cYigin.Count
cYigin.Add item:=80, key:= “Ahmet Demir”
cYigin.Add item:=100, key:= “Deniz Yıldız”
cYigin.Add item:= 95, key:=”Mehmet Sefir”
cYigin.Add item:=85, key:=”Ceren Şen”
debug.print cYigin.Count
Yukarıdaki kodu çalıştırdığınızda sırası ile 0 ve 4 değerlerini çıktı olarak verecektir.
c. Yeni Öğe Ekleme
Bir Collection nesnesine değer eklemek için Add (Ekle) anahtar kelimesini kullanıyoruz.
Sub Ana()
Dim cYigin As New Collection
cYigin.Add “Elma”
End Sub
Aynı Collection içinde farklı değişken türlerini tutabilirsiniz.
Dim cYigin As New Collection
cYigin.Add “Elma”
cYigin.Add 10
cYigin.Add #20/10/2020#
Yukarıdaki kod ile aynı Collection içine metin, tam sayı ve tarih değerini ekledik.
Collection nesnelerinde daha önce eklediğimiz bir elemanın öncesine veya sonrasına değer eklemek te mümkün. Bunun için sırası ile before (önce) ve after (sonra) anahtar kelimelerini kullanıyoruz.
Dim cYigin As New Collection
cYigin.Add “Elma”
cYigin.Add “Armut”
cYigin.Add “Erik”, before:=1
cYigin.Add “İğde”, after:=1
Yukarıdaki kodu adım adım çalıştırdığınızda “Elma”, “Armut” değerleri ilk olarak eklenir sonrasında ilk elemanın önüne Erik ve arkasına da “İğde” eklenecektir.
d. Item ve Key Anahtar Kelimeleri
Collection nesnelerine eklediğiniz her elemana, kolay erişim için bir de anahtar ekleyebilirsiniz. Bu sayede sadece anahtar kullanarak istediğiniz elemanı çekebilirsiniz. Anahtar olarak sadece metin değerleri girebilirsiniz. Bu sayede örnek olarak öğrenci isimlerini anahtar, öğrencinin puanını değer olarak kullanabilir ve 2 boyutlu bir dizi gibi kullanabilirsiniz. Tabii bunu yaparken değeri de Item (Öğe) anahtar kelimesi ile tanımlamanız gerek.
cYigin.Add item:=80, key:= “Ahmet Demir”
cYigin.Add item:=100, key:= “Deniz Yıldız”
Debug.Print cYigin(“Ahmet Demir”)
Yukarıdaki kodu çalıştırdığınızda Ahmet Demir öğesinin sahip olduğu değer olan 80 rakamını Immediate penceresinde görebilirsiniz.
e. Item Yordamı
Collection nesnesine eklediğiniz öğelere erişmek için iki yol mevcut. Bir tanesini Collection nesnesinin sonuna bulmak istediğinin öğenin sırasını ya da anahtarını girmek:
=cYigin(1)
=cYigin(“anahtar”)
İkinci yöntem ise Item yordamını kullanmak.
=cYigin.Item(1)
=cYigin.Item(“anahtar”)
Örnek olarak
cYigin.Add item:=80, key:= “Ahmet Demir”
cYigin.Add item:=100, key:= “Deniz Yıldız”
cYigin.Add item:= 95, key:=”Mehmet Sefir”
cYigin.Add item:=85, key:=”Ceren Şen”
Debug.Print cYigin.item(2)
Debug.Print cYigin.Item(“Mehmet Sefir”)
yukarıdaki kodun son iki satırı Collection nesnesinin 3. öğesi olan Mehmet Sefir’in değerini Immediate penceresine yazdıracaktır. Bazı eski sürümlerde ilk kullanım hataya sebep olabilir. O yüzden kullanırken dikkatli olmanızda fayda var.
f. Öğe Silme
Collection nesnesine eklediğiniz öğeleri remove (kaldır) anahtar kelimesi ile kaldırabilirsiniz. Bunun için ya kaldırmak istediğiniz öğenin değerini ya da anahtarını bilmeniz ve parametre olarak girmeniz gereklidir. Kaldırma işlemini Remove yordamı kullanarak yapıyoruz:
cYigin.Add item:=80, key:= “Ahmet Demir”
cYigin.Add item:=100, key:= “Deniz Yıldız”
cYigin.Add item:= 95, key:=”Mehmet Sefir”
cYigin.Add item:=85, key:=”Ceren Şen”
‘bu aşamada cYigin 4 adet öğe barındırmakta
cYigin.Remove(1) ‘ Yığındaki ile öğe olan Ahmet Demir girdisini siler. toplam öğe: 3
cYigin.Remove(“Deniz Yıldız”) ‘Deniz Yıldız girdisini siler. toplam öğe: 2
cYigin.Remove.Item(3) ‘toplam öğe adeti 2 olduğundan hata verir.
Burda dikkat edeceğiniz husus her bir öğeyi kaldırdığınızda, Collection nesnesinde bulunan toplam öğe sayısının azalmasıdır. Bu nedenle 4 öğeye sahip bir Collection’da, ilk öğeyi kaldırıp ardından 4. öğeyi kaldırmak isterseniz bu öğe artık 3. sırada olacağından hata alırsınız. Collection nesnesindeki en son elemanı silmek için Count mülkünü kullanabilirsiniz.
cYigin.Remove(cYigin.Count)
Eğer bir Collection nesnesindeki tüm öğeleri hızlıca silmek isterseniz bunu bir döngü ile yapmak yerine Collection nesnesini yeniden tanımlayarak yapabilirsiniz.
Set cYigin = New Collection
Yukarıdaki kod ile yigin nesnesi yeniden oluşturulacağından hafızadaki veriler silinir ve en baştan hafızada yer ayrılır.
g. Öğe Mevcut mu Kontrol Etme
Collection nesnesinde belirli bir öğenin mevcut olup olmadığını kontrol etmek için bir yordam mevcut değil. Ancak bunun için basit bir kod yazılabilir:
Function Mevcutmu(cYigin As Collection, Anahtar As String) As Boolean
On Error GoTo Hata
IsObject (cYigin(Anahtar))
Mevcutmu = True
Hata:
End Function
Eğer girdiğiniz anahtara sahip öğe collectiom nesnesi içinde mevcut ise bu işlev Doğru değerini döndürecektir.