SCRIPTING DICTIONARY NESNESİ

SCRIPTING DICTIONARY

Scripting Dictionary bir koleksiyon nesnedir. Sözlük olarak adlandırılır.
İçerisine sayı, metin, tarih, dizi, aralık gibi her türlü veriyi alabilir.
Sözlük’teki her öğe kendi benzersiz anahtarını alır.
Sözlük, bir Collection kullanımına kıyasla avantajlı olabilecek, .Keys.Items ve .RemoveAll gibi bazı özelliklere, fonksiyonlara ve metotlara sahiptir.

Geçici olarak bellekte depolandığından, verilere kolay ve hızlı erişim sağlamak için her türlü veriyi bir Sözlükte gruplayabilirsiniz.
Hiçbir ekran tazelemesi ve otomatik hesaplama yapmadığı için arka plan yedeği gerekli değildir, bu nedenle kodunuzu önemli ölçüde hızlandıracaktır. Genel olarak, ortak bir özelliği ( key ) olan verileri depolamak/gruplamak için Sözlük nesnesini kullanabilirsiniz. Dağınık verileri de kolayca birleştirebilirsiniz. .keys benzersiz dizeler, sayılar veya tarihlerin bir listesini oluşturmak için tasarlanmamış olsa da, kullanım özelliği bakımından güzel bir fonksiyondur.

Sözlük standart VBA kitaplığının bir parçası değildir.
Microsoft Scripting Runtime kitaplığındaki bir sınıftır.
Yani kütüphane bu dosyada (C:\Windows\system32\scrrun.dll) veya benzer dizinde bulunur.
Microsoft Scripting Runtime referansı etkinleştirerek bu kitaplığa bir başvuru yapabilirsiniz.

NotCollection nesnesi ve Dictionary nesnesi arasındaki önemli bir fark, Item özelliğinin davranışıdır.
Collection nesnesinde var olmayan bir anahtarı referans almak için Item özelliğini kullanırsanız, bir hata alırsınız.
Dictionary‘de var olmayan bir anahtarı referans almak için Item özelliğini kullanırsanız, sözlüğe bu anahtar eklenir.
Bir anahtarın bir sözlükte bulunup bulunmadığını belirlemek için ise Exists yöntemini kullanırız.

Scripting Dictionary nesnesini üç farklı yöntemle başlatabiliriz.

  • Late Binding yöntemiyle, yani geç bağlanma yöntemiyle referans eklemeye gerek kalmadan.
  • Early Binding yöntemiyle, yani erken bağlanma yöntemiyle referans ekleyerek.
  • Late Binding yöntemiyle, ama herhangi bir tanımlama yapmadan sadece With ile başlayarak.

Şimdi bu tanımlama işlemlerine bir bakalım.
Late Binding yöntemiyle bu şekilde sözlüğü tanımlayabiliriz;

Dim sozluk as Object
Set sozluk = CreateObject("Scripting.Dictionary")

Early Binding yöntemiyle bu şekilde sözlüğü tanımlayabiliriz;

Dim sozluk As Scripting.Dictionary
Set sozluk = New Scripting.Dictionary

Bu kodla Microsoft Scripting Runtime referansını seçtirebilir ve kullanabilirsiniz.

Sub Scripting_Referansını_Sec()
On Error Resume Next
ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\scrrun.dll"
End Sub

With ifadesiyle başlayarak bu şekilde sözlüğü tanımlayabiliriz;

With CreateObject("Scripting.Dictionary")
'kodlar'
End With

Scripting Dictionary nesnesini kodlarımızda kullanmanın en kolay biçimi budur.

Metotlar/Fonksiyonlar Özellikler
Add CompareMode
Exists Count
Items Key
Keys Item
Remove
RemoveAll

Şimdi bu metot ve özellikleri görelim;..

Add Metodu
Sözlüğe yeni bir anahtar ve öğe eklemek için kullanılır.
sozluk.Add Key, Item

.Add "Tarih", Date

Exists Metodu
Bir anahtarın var olup olmadığını belirlemek için kullanılır.
If sozluk.Exists(Key) Then

Eğer anahtar yoksa demek için If Not ile başlayabilirsiniz.
If Not sozluk.Exists(Key) Then

Items Metodu
Add 
metoduyla eklenen tüm öğeleri taşır.
Gerektiğinde sozluk.Items ile dışarıya aktarılır veya içindeki öğeler döndürülür.

Keys Metodu
Add 
metoduyla eklenen tüm anahtarları taşır.
Gerektiğinde sozluk.Keys ile dışarıya aktarılır veya içindeki anahtarlar döndürülür.

Remove Metodu
Anahtarları sözlük koleksiyonundan kaldırmak için kullanılır.
sozluk.Remove Key

sozluk.Add "PEAKUP", "TEKNOLOJİ"
sozluk.Add "Murat", "OSMA"
sozluk.Remove "Murat"

RemoveAll Metodu
Tüm anahtarları sözlük koleksiyonundan kaldırır.
sozluk.RemoveAll

sozluk.Add "PEAKUP", "TEKNOLOJİ"
sozluk.Add "Murat", "OSMA"
sozluk.RemoveAll

CompareMode Özelliği
Anahtar karşılaştırması yaparken küçük büyük harf duyarlılığını belirtmek için kullanılır.
Bu özellik belirtilmezse ‘Büyük/Küçük Harfe Duyarlı’ olarak verileri alır.
sozluk.CompareMode = vbBinaryCompare ‘Büyük/Küçük Harfe Duyarlı
sozluk.CompareMode = vbTextCompare ‘Büyük/Küçük Harfe Duyarsız

Count Özelliği
Sözlük koleksiyonundaki anahtarların sayısını verir.
sozluk.Count

sozluk.Add "PEAKUP", "TEKNOLOJİ"
sozluk.Add "Murat", "OSMA"
MsgBox sozluk.Count

Key Özelliği
Sözlüğe eklenen anahtarı ifade eder.
sozluk.Add "PEAKUP", "TEKNOLOJİ" buradaki PEAKUP kelimesi Key olarak alınır, TEKNOLOJİ kelimesi de Item olarak alınır.

Item Özelliği
Sözlüğe eklenen her bir anahtar için belirtilen öğeyi ifade eder.
sozluk.Item("TEKNOLOJİ") = Date

sozluk.Add "PEAKUP", "TEKNOLOJİ"
sozluk.Item("TEKNOLOJİ") = Date
MsgBox sozluk.Item("TEKNOLOJİ")

Şimdiye kadar öğrendiklerimizle şöyle bir örnek yapalım; A1:B10 hücre aralığında birtakım verilerimiz olsun, A sütunundaki verileri Dictionarynesnesinin Key özelliğine, sütunundakileri de Item özelliğine alalım ve Key‘de oluşan benzersiz verilerimize göre C1 ve D1‘den itibaren koleksiyondaki verileri aktaralım.

Sub PEAKUP()
Dim a&, sayi&
With CreateObject("Scripting.Dictionary")
For a = 1 To 10
sayi = Cells(a, 1).Value
If Not .Exists(sayi) Then
.Add sayi, Cells(a, 2).Value
End If
Next a
Range("C1").Resize(.Count, 1).Value = Application.Transpose(.Keys)
Range("D1").Resize(.Count, 1).Value = Application.Transpose(.Items)
End With
sayi = Empty: a = Empty
End Sub

Evet.. gördüğünüz gibi A sütunundaki benzersiz verilere göre bir liste oluşturup başka bir yerde listelenmesini sağladık.
Benzersiz verileri başka bir yerde listeleyecekseniz Sözlük nesnesini kullanmanızı öneririm. Yukarıda bu nesnenin yapılacak işlemi, hızlandıracağından bahsetmiştim. Diğer standart döngülere göre çok daha hızlı dönüş alırsınız.

Şimdi benzer kodları kullanıp, Item özelliğinde aynı olan verilerin toplanmasını sağlayarak hücrelere aktarma ile ilgili bir örnek yapalım.
sütununda mükerrer biçimde Ay isimlerinin olduğunu, yani; aynı ay isimlerinden birden fazla olabildiğini düşünün.
sütununda da o aylara ait bazı satış tutarlarımız olsun.

Yapacağımız iş; sütunundaki ay isimlerinin benzersiz bir listesini oluşturup B sütunundaki satış tutarlarını da toplamını almak olacak.
Bir nevi özet tablo oluşturacağız.

Bu tabloyu kopyalayıp A1 hücresine yapıştırın.

Aylar Tutar
Ocak 331
Şubat 449
Şubat 342
Nisan 210
Ocak 284
Haziran 449
Temmuz 230
Mart 449
Eylül 320
Nisan 301
Kasım 114
Aralık 164

Bahsettiğimiz işi yapabilmemiz için bu kodları kullanabilirsiniz. Bu işte, yukarıda kullandığımız kodlara ek olarak sadece bu iki satırı ilave ettik.
Else
.Item(sayi) = .Item(sayi) + Cells(a, 2).Value

Sub PEAKUP()
Dim a&, sayi$
With CreateObject("Scripting.Dictionary")
For a = 1 To 12
sayi = Cells(a, 1).Value
If Not .Exists(sayi) Then
.Add sayi, Cells(a, 2).Value
Else
.Item(sayi) = .Item(sayi) + Cells(a, 2).Value
End If
Next a
Range("D1").Resize(.Count, 1).Value = Application.Transpose(.Keys)
Range("E1").Resize(.Count, 1).Value = Application.Transpose(.items)
End With
sayi = Empty: a = Empty
End Sub

F8 ile adım adım giderek Locals Window‘dan gözlemleyebilirsiniz.

Sonuç olarak bu tablonun oluştuğunu göreceksiniz.

Aylar Tutar
Ocak 615
Şubat 791
Nisan 511
Haziran 449
Temmuz 230
Mart 449
Eylül 320
Kasım 114

Şimdi başka bir konuya geçelim..

Verileri koleksiyon içine alırken önemli bir ayrıntı da küçük/büyük harf eşleşmesi/duyarlılığıdır.
Karşılaştırma modu (Compare Mode) kullanılmazsa, aynı veri büyük ve küçük harfle ayrı ayrı yazılmışsa, 2 ayrı veri olacak şeklinde koleksiyona alınır. Bu bazı hatalara veya istemediğimiz durumlara yol açabilir. Bu özelliğin sabitlerini yukarıda görmüştük. Şimdi nasıl çalıştığını anlamanız için üç örnek yapacağız.

İlk örnekte CompareMode özelliğini kullanmadan sonucu görelim.

Sub PEAKUP()
With CreateObject("Scripting.Dictionary")
For Each bak In Array("aa1", "AA1", "Aa1", "aA1", "bb1", "BB1", "Bb1", "bB1")
al = .Item(bak)
Next bak
MsgBox .Count
MsgBox Join(.Keys, vbLf)
End With
End Sub

İkinci örnekte CompareMode özelliğini yani BinaryCompare şeklinde kullanarak sonucu görelim.

Sub PEAKUP()
With CreateObject("Scripting.Dictionary")
.CompareMode = 0
For Each bak In Array("aa1", "AA1", "Aa1", "aA1", "bb1", "BB1", "Bb1", "bB1")
al = .Item(bak)
Next bak
MsgBox .Count
MsgBox Join(.Keys, vbLf)
End With
End Sub

Bu iki örneğin de aynı sonucu verdiğini görmüş olmalısınız. Yani bu özellik belirtilmez ise varsayılan olarak kabul edilir.

Üçünü örnekte CompareMode özelliğini 1 yani TextCompare şeklinde kullanarak sonucu görelim.

Sub PEAKUP()
With CreateObject("Scripting.Dictionary")
.CompareMode = 1
For Each bak In Array("aa1", "AA1", "Aa1", "aA1", "bb1", "BB1", "Bb1", "bB1")
al = .Item(bak)
Next bak
MsgBox .Count
MsgBox Join(.Keys, vbLf)
End With
End Sub

Kodları denediyseniz, gördüğünüz gibi .CompareMode = 1 ifadesi ile küçük/büyük harf ayırımı olmaksızın, yani büyük de yazılsa küçük de yazılsa tek bir metin olarak kabul edilip koleksiyon içerisinde aldı.

IndexNumber

Key ve Item‘larda indeks numaraları belirtilerek istenilen Key ve Item değeri de alınabilir.
Key ve Item özelliğine alına verilerin indeks değeri 0‘dan başlar.
Bununla ilgili bir örnek vereyim.

Sub PEAKUP()
With CreateObject("Scripting.Dictionary")
For Each bak In Array("aa1", "aa2", "aa1", "aa3", "aa4", "aa2")
.Item(bak) = bak & "_Excel"
Next bak
MsgBox .Item(.Keys()(1)) ' 2. key değeri
MsgBox .Item(.Keys()(2)) '
3. key değeri
MsgBox .Item(.Keys()(.Count - 1)) ' Son key değeri
End With
End Sub
Sub PEAKUP()
With CreateObject("Scripting.Dictionary")
For Each bak In Array("aa1", "aa2", "aa1", "aa3", "aa4", "aa2")
.Item(bak) = bak & "_Excel"
Next bak
MsgBox .Items()(0) ' 1. Item değeri
MsgBox .Items()(2) '
3. Item değeri
MsgBox .Items()(.Count - 1) ' Son Item değeri
End With
End Sub

Bir de şöyle bir örnek yapalım; yukarıda kullandığımız bir aylar/tutar tablomuz vardı, o verileri kullanarak tablodaki benzersiz verilerin son kayıtlarını alıp listeleyelim. Bu örneği nerede kullanabiliriz derseniz, örneğin; müşterilere kesilen son faturaları, son ürün gönderilerini vs. gibi müşteri, ürün, fatura, stok vs. işlerindeki son kayıtların bir listesini almak istediğinizde kullanabilirsiniz..

Örnek tablomuz bu, yanda da sonuç olarak elde edeceğimiz tablomuzu görüyorsunuz.

Ocak 331 ……….. Ocak 284
Şubat 449 Şubat 342
Şubat 342 Nisan 301
Nisan 210 Haziran 449
Ocak 284 Temmuz 230
Haziran 449 Mart 449
Temmuz 230 Eylül 320
Mart 449 Kasım 114
Eylül 320 Aralık 164
Nisan 301
Kasım 114
Aralık 164

Bu kodlar da istediğimiz işi yapmamız için gereken kodlarımız..

Sub Benzersiz_Son_Kayıtları_Listele()
dizi = Cells(1).CurrentRegion.Resize(, 2).Value
With CreateObject("Scripting.Dictionary")
For sat = 1 To UBound(dizi)
.Item(dizi(sat, 1)) = WorksheetFunction.Index(dizi, sat, 0)
Next sat
Range("F1").Resize(.Count, UBound(dizi, 2)) = WorksheetFunction.Index(.Items, 0, 0)
End With
End Sub
Sonuçları bu gif resim görebilirsiniz. 

Makalemizi beğendiyseniz çevrenizle de paylaşmayı ihmâl etmeyiniz.

Start typing and press Enter to search

X