Genel Bakış
Scripting Dictionary (Scripting.Dictionary nesnesi), anahtar ve değer çiftlerini bellekte tutan bir veri yapısıdır. Her anahtar yalnızca bir kez bulunabilir; bu sayede benzersiz liste çıkarma, gruplama, sayma ve DÜŞEYARA benzeri hızlı arama işlemleri VBA'da çok kısa kodla yapılır. Nesne Windows'taki Microsoft Scripting Runtime kitaplığından gelir ve Mac sürümlerinde bulunmaz.
Geç bağlama söz dizimi:
Parametreler:
Makro çalıştığında C sütununa beş benzersiz şehir adı, D sütununa her şehrin toplam satışı yazılır. Bu örnekte CreateObject kullanıldığı için makro sayfada otomatik çalıştırılmaz; kendi çalışma kitabınızda deneyin. Kodun püf noktası, var olmayan bir anahtarın okunduğunda boş (Empty) dönmesi ve boş değerin toplamada sıfır gibi davranmasıdır; böylece her şehir için ayrıca Exists denetimi yapmanız gerekmez.
Makro çalıştırıldığında E2 hücresine K-104 koduna ait Kulaklık adı ve fiyatı, E3 hücresine koşul sağlanmadığı için Bulunamadı yazılır; E4 hücresinde ise küçük harfle yazılan k-102 kodu da CompareMode sayesinde Fare ürünüyle eşleşir. CreateObject kullanıldığından bu örnek sayfada otomatik çalıştırılmaz. Sözlük yaklaşımı, aranacak kayıt sayısı çok olduğunda her aramada tabloyu baştan taramaktan çok daha hızlıdır.
Makro çalıştığında D sütununa Muhasebe, Satış, İnsan Kaynakları ve Üretim departmanları ilk görülme sırasıyla, E sütununa her departmandaki kişi sayısı yazılır. Bu örnek CreateObject içerdiğinden sayfada otomatik çalıştırılmaz. Application.Transpose, tek boyutlu Keys ve Items dizilerini dikey sütun haline getirir; bu sayede döngü kurmadan tek satırda hücrelere yazabilirsiniz. Transpose kullanımında dizi eleman sayısının sınırlı olabileceğini unutmayın; çok büyük sözlüklerde döngüyle yazmak daha güvenlidir.
Nesneyi oluşturma ve söz dizimi
Dictionary nesnesi iki yöntemle kullanılır. Geç bağlama (late binding) yönteminde herhangi bir başvuru eklemeye gerek yoktur ve kod başka bilgisayarlarda da sorunsuz çalışır. Erken bağlama (early binding) yönteminde ise VBA Düzenleyicisi > Araçlar > Başvurular (Tools > References) bölümünden Microsoft Scripting Runtime işaretlenir; bu durumda IntelliSense listesi açılır.Geç bağlama söz dizimi:
VBA
12 satır
Dim d As Object
Set d = CreateObject("Scripting.Dictionary")
' Erken bağlama (başvuru gerekir)
Dim d2 As Scripting.Dictionary
Set d2 = New Scripting.Dictionary
d.Add Key, Item
d.Exists(Key)
d.Remove Key
d.RemoveAll
d.Item(Key) = Value
- Key: Anahtar; zorunludur. Sayı, metin ya da tarih olabilir, ancak dizi olamaz. Her anahtar tekil olmalıdır.
- Item: Anahtara bağlı değer; Add yönteminde zorunludur. Sayı, metin, nesne ya da dizi olabilir.
- Value: Item özelliğine atanan yeni değer; anahtar yoksa anahtar oluşturulur.
Önemli özellikler
- Count: Sözlükteki anahtar sayısını verir; salt okunurdur.
- Item: Varsayılan özelliktir; d("Ankara") yazımı d.Item("Ankara") ile aynıdır. Var olmayan bir anahtara okuma amacıyla başvurursanız anahtar boş değerle sözlüğe eklenir.
- Key: Var olan bir anahtarın adını değiştirmek için kullanılır.
- CompareMode: Anahtar karşılaştırma biçimidir. vbBinaryCompare (0) varsayılandır ve büyük/küçük harfe duyarlıdır; vbTextCompare (1) harf duyarlılığını kapatır. Yalnızca sözlük boşken ayarlanabilir.
Önemli yöntemler
- Add: Yeni anahtar ve değer çifti ekler. Anahtar zaten varsa 457 numaralı çalışma zamanı hatası oluşur.
- Exists: Anahtarın var olup olmadığını True ya da False olarak döndürür; bu denetim sözlüğe yeni anahtar eklemez.
- Keys: Tüm anahtarları sıfırdan başlayan bir dizi olarak verir.
- Items: Tüm değerleri sıfırdan başlayan bir dizi olarak verir.
- Remove: Belirtilen anahtarı siler; anahtar yoksa hata verir.
- RemoveAll: Sözlüğün tüm içeriğini temizler.
Ne zaman kullanılır
Dictionary, özellikle büyük tablolarda hücre hücre arama yapmak yerine verileri bir kez belleğe alıp anahtarla erişmek istediğinizde kullanışlıdır. Tipik kullanım alanları şunlardır:- Benzersiz liste: Yinelenen değerleri ayıklamak.
- Gruplama ve toplama: Şehir, ürün ya da departman bazında toplam ve sayım almak.
- Hızlı arama: Kod karşılığı fiyat ya da ad bulmak.
- Karşılaştırma: İki listede ortak ya da eksik kayıtları belirlemek.
1. Şehir bazında toplam alma
A sütununda şehirler, B sütununda satış tutarları yer alıyor. Aşağıdaki kodu standart modüle yapıştırın. Makro her şehri sözlükte anahtar yapar, tutarları toplar ve benzersiz şehir listesini ile toplamları C ve D sütunlarına yazar.
VBA
25 satır
Option Explicit
Sub SehirToplamlari()
Dim d As Object
Dim ws As Worksheet
Dim son As Long, i As Long, r As Long
Dim k As Variant
Set d = CreateObject("Scripting.Dictionary")
Set ws = ActiveSheet
son = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' Her şehrin tutarını kendi anahtarında biriktir
For i = 2 To son
d(ws.Cells(i, 1).Value) = d(ws.Cells(i, 1).Value) + ws.Cells(i, 2).Value
Next i
' Sonuçları C ve D sütunlarına yaz
r = 2
For Each k In d.Keys
ws.Cells(r, 3).Value = k
ws.Cells(r, 4).Value = d(k)
r = r + 1
Next k
End Sub
Scripting Dictionary
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Şehir | Satış Tutarı | Benzersiz Şehir | Toplam |
| 2 | İstanbul | 12.500,00 | ||
| 3 | Ankara | 8.400,00 | ||
| 4 | İzmir | 9.600,00 | ||
| 5 | İstanbul | 7.300,00 | ||
| 6 | Bursa | 5.200,00 | ||
| 7 | Ankara | 6.100,00 | ||
| 8 | Antalya | 4.800,00 | ||
| 9 | İzmir | 3.900,00 | ||
| 10 | Bursa | 4.400,00 | ||
| 11 | İstanbul | 8.800,00 |
Şehir SatışlarıExcelDepo v1.0.0
2. DÜŞEYARA yerine sözlükle arama
A sütununda ürün kodları, B sütununda ürün adları, C sütununda birim fiyatlar var. D sütununa aranacak kodları yazdınız. Kodu standart modüle yapıştırın; makro kodları sözlüğe satır numarasıyla yükler ve E sütununa karşılık gelen ürün adı ile fiyatı yazar. CompareMode ayarı sayesinde küçük harfle yazılan kod da bulunur.
VBA
29 satır
Option Explicit
Sub UrunAra()
Dim d As Object
Dim ws As Worksheet
Dim son As Long, i As Long, sonAra As Long
Dim kod As String
Set ws = ActiveSheet
Set d = CreateObject("Scripting.Dictionary")
' Harf duyarlılığını kapat (sözlük boşken ayarlanmalı)
d.CompareMode = vbTextCompare
son = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 2 To son
kod = ws.Cells(i, 1).Value
If Not d.Exists(kod) Then d.Add kod, i
Next i
sonAra = ws.Cells(ws.Rows.Count, 4).End(xlUp).Row
For i = 2 To sonAra
kod = ws.Cells(i, 4).Value
If d.Exists(kod) Then
ws.Cells(i, 5).Value = ws.Cells(d(kod), 2).Value & " - " & ws.Cells(d(kod), 3).Value & " TL"
Else
ws.Cells(i, 5).Value = "Bulunamadı"
End If
Next i
End Sub
Scripting Dictionary
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ürün Kodu | Ürün Adı | Birim Fiyat | Aranan Kod | Sonuç |
| 2 | K-101 | Klavye | 450,00 | K-104 | |
| 3 | K-102 | Fare | 220,00 | K-999 | |
| 4 | K-103 | Monitör | 3.850,00 | k-102 | |
| 5 | K-104 | Kulaklık | 680,00 | ||
| 6 | K-105 | Webcam | 940,00 | ||
| 7 | K-106 | Yazıcı | 2.750,00 | ||
| 8 | K-107 | Hoparlör | 520,00 |
Ürün FiyatExcelDepo v1.0.0
3. Departman bazında kişi sayısı
A sütununda personel adları, B sütununda departmanlar var. Kodu standart modüle yapıştırın. Makro her departman için sayaç tutar, ardından Keys ve Items dizilerini D ve E sütunlarına tek hamlede aktarır.
VBA
29 satır
Option Explicit
Sub DepartmanSay()
Dim d As Object
Dim ws As Worksheet
Dim son As Long, i As Long
Dim dep As String
Set ws = ActiveSheet
Set d = CreateObject("Scripting.Dictionary")
son = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
' Her departman için sayacı bir artır
For i = 2 To son
dep = ws.Cells(i, 2).Value
If d.Exists(dep) Then
d(dep) = d(dep) + 1
Else
d.Add dep, 1
End If
Next i
' Anahtar ve değer dizilerini sütun olarak yaz
ws.Range("D2").Resize(d.Count, 1).Value = Application.Transpose(d.Keys)
ws.Range("E2").Resize(d.Count, 1).Value = Application.Transpose(d.Items)
' Belleği boşalt
d.RemoveAll
End Sub
Scripting Dictionary
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Personel | Departman | Departman Özeti | Kişi Sayısı | |
| 2 | Ayşe Yılmaz | Muhasebe | |||
| 3 | Mehmet Kaya | Satış | |||
| 4 | Fatma Demir | İnsan Kaynakları | |||
| 5 | Ali Çelik | Satış | |||
| 6 | Zeynep Arslan | Muhasebe | |||
| 7 | Hasan Şahin | Üretim | |||
| 8 | Elif Aydın | Satış | |||
| 9 | Mustafa Öztürk | Üretim | |||
| 10 | Selin Koç | Satış | |||
| 11 | Burak Yıldız | Üretim |
Personel SayımExcelDepo v1.0.0
Kullanırken dikkat edin
- Var olmayan anahtarı okumak anahtar ekler: Sözlükte olmayan bir anahtarı d("Anahtar") biçiminde okuduğunuzda hata almazsınız; bunun yerine anahtar boş değerle sözlüğe eklenir ve Count artar. Varlığı denetlemek için her zaman Exists yöntemini kullanın.
- Aynı anahtarı Add ile eklemeyin: Var olan bir anahtar için Add çağırmak 457 numaralı hataya yol açar. Değeri güncellemek istiyorsanız d(Key) = Value atamasını kullanın ya da önce Exists ile denetleyin.
- Harf duyarlılığı: Varsayılan karşılaştırma büyük/küçük harfe duyarlıdır; yani "Ankara" ile "ankara" iki ayrı anahtardır. CompareMode özelliğini vbTextCompare yapın, ancak bunu sözlük boşken, ilk Add işleminden önce yapmalısınız. Ayrıca metin olarak yazılmış sayı ile gerçek sayı da farklı anahtar sayılır.
- Keys ve Items dizileri sıfırdan başlar: Keys ve Items 0 tabanlı Variant dizisi döndürür; döngü kurarken LBound ve UBound kullanın. Sözlük boşken bu dizilerle çalışırken dikkatli olun; önce Count değerini denetleyin.
- Mac ve başvuru sorunları: Scripting.Dictionary yalnızca Windows'ta bulunur; Mac için Excel'de CreateObject çağrısı hata verir. Erken bağlamada başvuru eksikse kod başka bilgisayarda derleme hatası verir; dağıtacağınız dosyalarda geç bağlamayı tercih edin.
- Sıralama yapılmaz: Sözlük anahtarları eklenme sırasına göre döndürür ve sıralama özelliği yoktur. Sıralı çıktı gerekiyorsa anahtarları bir diziye alıp kendiniz sıralayın ya da sonuçları sayfaya yazdıktan sonra Veri > Sırala ve Filtre Uygula > Sırala (Data > Sort & Filter > Sort) komutunu kullanın.
- İlgili konular:
- Collection: VBA'nın yerleşik koleksiyon nesnesi; anahtarla erişir ancak Exists yöntemi ve anahtar listesi yoktur.
- CreateObject: Geç bağlamayla nesne oluşturma işlevi.
- For Each...Next: Keys ve Items dizileri üzerinde dolaşmak için döngü deyimi.
- Application.Transpose: Dizileri satırdan sütuna çeviren yöntem.
- Range.RemoveDuplicates: Yinelenen kayıtları sayfa üzerinde silen yöntem.
- WorksheetFunction.VLookup: Sayfa işlevi DÜŞEYARA'nın VBA karşılığı.
- ÇOKEĞERTOPLA ve EĞERSAY: Gruplama ve sayma için sayfa işlevleri.