Özellik ikonu

Class

İndirme izni yok

Genel Bakış

Class (Sınıf), özellikleri, yöntemleri ve olayları olan bir nesne türünün şablonudur; VBA'da bu şablon bir sınıf modülünde yazılır. Sınıf modülü sayesinde veriyi ve o veriyle çalışan kodu tek bir pakette toplar, New ile istediğiniz sayıda bağımsız nesne (örnek) üretirsiniz. Böylece kodunuz daha düzenli, yeniden kullanılabilir ve bakımı kolay olur.

Sınıf ve sınıf modülü nedir​

Sınıf, bir nesnenin nasıl görüneceğini ve neler yapabileceğini tanımlayan şablondur. Nesne (örnek, instance) ise bu şablondan New ile üretilen somut kopyadır. Excel'in kendi nesneleri de birer sınıftır: Range, Worksheet, Workbook, Collection gibi. Aynı sınıftan üretilen iki nesne kendi verisini ayrı tutar.

Kendi sınıfınızı yazmak için Visual Basic Düzenleyicisi'nde Ekle > Sınıf Modülü (Insert > Class Module) komutunu kullanın. Modülün adı, sınıfın adı olur; adı Özellikler (Properties) penceresindeki Name kutusundan değiştirebilirsiniz (pencereyi F4 ile açarsınız). Ad vermede yaygın alışkanlık, clsUrun gibi cls önekini kullanmaktır.

Excel'deki ThisWorkbook modülü, sayfa modülleri ve UserForm modülleri de birer sınıf modülüdür; bu yüzden onlarda da Public değişken, yordam ve olay yazabilirsiniz. Sınıf modülleri yalnızca makro içerebilen dosya türlerinde (xlsm, xlsb, xlam) saklanır; xlsx dosyasına kaydederseniz kod silinir.

Sınıf modülünün yapısı​

Bir sınıf modülü şu öğelerden oluşabilir:
  • Private değişkenler: nesnenin iç verisini tutar; dışarıdan doğrudan erişilmez.
  • Property Get / Property Let / Property Set: özelliği okumak (Get), değer atamak (Let) ve nesne atamak (Set) için kullanılır. Özellik salt okunur olacaksa yalnız Property Get yazılır.
  • Public Sub ve Function: nesnenin yöntemleridir; Sub değer döndürmez, Function döndürür.
  • Class_Initialize: nesne New ile oluşturulurken otomatik çalışır; başlangıç değerlerini atamak için kullanılır. Parametre almaz.
  • Class_Terminate: nesne bellekten kaldırılırken çalışır; kaynakları temizlemek için kullanılır.
  • Instancing: sınıfın Özellikler penceresindeki ayarıdır. Varsayılan Private'tır; PublicNotCreatable seçeneği sınıfı başka projelerin görmesine izin verir ama onlar New ile örnek üretemez.
Aşağıda clsUrun adlı örnek bir sınıf modülü görülüyor. Bu kodu Ekle > Sınıf Modülü ile açtığınız modüle yapıştırın ve modülün adını clsUrun yapın:
VBA 35 satır
Option Explicit

Private pAd As String
Private pFiyat As Double

Private Sub Class_Initialize()
    pFiyat = 0
End Sub

Public Property Get Ad() As String
    Ad = pAd
End Property

Public Property Let Ad(ByVal Deger As String)
    pAd = Deger
End Property

Public Property Get Fiyat() As Double
    Fiyat = pFiyat
End Property

Public Property Let Fiyat(ByVal Deger As Double)
    If Deger < 0 Then
        Err.Raise vbObjectError + 1000, "clsUrun", "Fiyat negatif olamaz."
    End If
    pFiyat = Deger
End Property

Public Function KdvliFiyat(ByVal Oran As Double) As Double
    KdvliFiyat = pFiyat * (1 + Oran)
End Function

Private Sub Class_Terminate()
    ' Nesne bellekten kalkarken çalışır
End Sub
Bu yapıda dış dünya yalnızca Ad, Fiyat ve KdvliFiyat üyelerini görür; pAd ve pFiyat gizli kalır. Bu ilkeye kapsülleme denir ve geçersiz değerlerin (ör. negatif fiyat) nesneye girmesini engellemenizi sağlar.

Sınıfı kullanma​

Sınıfı kullanmak için önce nesne değişkenini tanımlar, sonra Set ve New ile örneği oluşturursunuz. İşiniz bitince Set ile Nothing atayarak başvuruyu bırakabilirsiniz. Nesne değişkenine atama her zaman Set ile yapılır; Set yazmazsanız Excel nesnenin varsayılan özelliğini atamaya çalışır ya da hata verir. Standart modülde şöyle kullanılır:
VBA 10 satır
Sub UrunDene()
    Dim u As clsUrun
    Set u = New clsUrun

    u.Ad = "Kalem"
    u.Fiyat = 12.5
    Debug.Print u.Ad, u.KdvliFiyat(0.2)

    Set u = Nothing
End Sub
Değişkeni As clsUrun diye tanımlamak erken bağlama (early binding) sağlar: yazarken üye listesi açılır, derleme sırasında yazım hataları yakalanır ve kod daha hızlı çalışır. As Object ile tanımlarsanız geç bağlama olur; bu durumda hatalar ancak çalışma anında ortaya çıkar.

Class_Initialize parametre alamadığı için başlangıç değerlerini bir fabrika işleviyle vermek yaygındır: aynı modülde Public Function UrunOlustur(ad, fiyat) As clsUrun yazar, içinde New ile nesneyi üretir, özelliklerini atar ve işlev adına Set ile geri döndürürsünüz.

İki değişken aynı nesneyi gösterebilir: Set b = a yeni bir nesne üretmez, yalnızca ikinci bir başvuru oluşturur. İki değişkenin aynı nesneye bağlı olup olmadığını Is işleciyle sınarsınız. Nesnenin türünü öğrenmek için TypeName işlevini, belirli bir sınıf olup olmadığını sınamak için TypeOf ... Is yapısını kullanın.

Olaylar, WithEvents ve Implements​

Sınıflar kendi olaylarını tanımlayabilir. Sınıf içinde Public Event ile olayı bildirir, uygun yerde RaiseEvent ile tetiklersiniz. Olayı dinleyen kod ise nesne değişkenini WithEvents ile tanımlar; WithEvents yalnızca sınıf modüllerinde, UserForm'larda ve belge modüllerinde modül düzeyinde kullanılabilir.

WithEvents ile Excel'in Application nesnesinin olaylarını da yakalayabilirsiniz. Sınıf modülü (örneğin clsUygulamaIzleyici):
VBA 5 satır
Public WithEvents App As Application

Private Sub App_NewWorkbook(ByVal Wb As Workbook)
    Debug.Print "Yeni kitap açıldı: " & Wb.Name
End Sub
Bu sınıfı etkinleştirmek için standart modülde modül düzeyinde bir değişken tanımlar ve bir yordamdan başlatırsınız:
VBA 6 satır
Dim izleyici As clsUygulamaIzleyici

Sub IzlemeyiBaslat()
    Set izleyici = New clsUygulamaIzleyici
    Set izleyici.App = Application
End Sub
Değişken modül düzeyinde olmalıdır; yordam içinde tanımlarsanız yordam bitince nesne yok olur ve olaylar artık yakalanmaz.

Implements deyimi ise bir sınıfın başka bir sınıfın (arayüzün) üyelerini uygulamasını sağlar. Arayüz sınıfında yalnızca üye başlıkları yazılır; uygulayan sınıfta her üye, arayüzAdı_üyeAdı biçiminde ve Private olarak yeniden yazılmak zorundadır. Böylece farklı sınıflara aynı değişkenle ortak biçimde ulaşırsınız.

1. Collection sınıfından bağımsız örnekler​

Aynı sınıftan üretilen nesneler birbirinden bağımsızdır. Bu örnekte Collection sınıfından New ile iki ayrı nesne oluşturulur; ürünler kategorisine göre ilgili koleksiyona eklenir. Kodu Ekle > Modül ile açtığınız standart modüle yapıştırın.
VBA 33 satır
Option Explicit

' Collection sınıfından iki ayrı nesne (örnek) oluşturur
Sub KoleksiyonlariDoldur()
    Dim ws As Worksheet
    Dim meyve As Collection
    Dim temizlik As Collection
    Dim i As Long

    Set ws = ActiveSheet
    Set meyve = New Collection
    Set temizlik = New Collection

    ' Her ürünü kategorisine uygun koleksiyona ekle
    For i = 2 To 7
        If ws.Cells(i, 2).Value = "Meyve" Then
            meyve.Add ws.Cells(i, 1).Value
            ws.Cells(i, 3).Value = meyve.Count
        Else
            temizlik.Add ws.Cells(i, 1).Value
            ws.Cells(i, 3).Value = temizlik.Count
        End If
    Next i

    ' Her satıra kendi koleksiyonunun toplam öğe sayısını yaz
    For i = 2 To 7
        If ws.Cells(i, 2).Value = "Meyve" Then
            ws.Cells(i, 4).Value = meyve.Count
        Else
            ws.Cells(i, 4).Value = temizlik.Count
        End If
    Next i
End Sub
Class
Formülünü incelemek için bir hücre seçin.
ABCD
1ÜrünKategoriKoleksiyondaki SıraKoleksiyon Toplamı
2ElmaMeyve13
3DeterjanTemizlik13
4PortakalMeyve23
5SabunTemizlik23
6MuzMeyve33
7Çamaşır SuyuTemizlik33
Ürün ListesiExcelDepo v1.0.0
Meyve koleksiyonuna eklenen ilk ürün Elma olduğu için C2 hücresine sıra numarası olarak 1 yazılır; Muz üçüncü meyve olduğundan C6 hücresinde 3 görünür. Temizlik koleksiyonu ayrı bir nesne olduğu için kendi sırasını tutar: Deterjan için 1, Çamaşır Suyu için 3. D sütunu her kategorinin toplam öğe sayısını gösterir: Meyve için 3, Temizlik için 3. İki koleksiyon aynı sınıftan üretilmiş olsa da birbirinin verisini etkilemez.

2. Nesnenin sınıfını öğrenme​

Her nesne bir sınıfa aittir. TypeName işlevi nesnenin sınıf adını döndürür, TypeOf ... Is yapısı ise nesnenin belirli bir sınıftan olup olmadığını sınar. Kodu standart modüle yapıştırın; sınıf adları B sütununa, Worksheet sınaması C sütununa yazılır.
VBA 29 satır
Option Explicit

' Farklı nesnelerin sınıf adlarını sayfaya yazar
Sub SinifAdlariniYaz()
    Dim ws As Worksheet
    Dim nesneler(1 To 6) As Object
    Dim i As Long

    Set ws = ActiveSheet

    Set nesneler(1) = ThisWorkbook
    Set nesneler(2) = ActiveSheet
    Set nesneler(3) = ws.Range("A1")
    Set nesneler(4) = Application
    Set nesneler(5) = New Collection
    Set nesneler(6) = ws.Range("A1").Font

    For i = 1 To 6
        ' Sınıf adı
        ws.Cells(i + 1, 2).Value = TypeName(nesneler(i))

        ' Nesne Worksheet sınıfından mı?
        If TypeOf nesneler(i) Is Worksheet Then
            ws.Cells(i + 1, 3).Value = "Evet"
        Else
            ws.Cells(i + 1, 3).Value = "Hayır"
        End If
    Next i
End Sub
Class
Formülünü incelemek için bir hücre seçin.
ABC
1Nesne İfadesiSınıf AdıWorksheet mi?
2ThisWorkbookWorkbookHayır
3ActiveSheetWorksheetEvet
4Hücre A1RangeHayır
5ApplicationApplicationHayır
6New CollectionCollectionHayır
7Hücre A1 yazı tipiFontHayır
Nesne TürleriExcelDepo v1.0.0
ThisWorkbook için sınıf adı Workbook, etkin sayfa için Worksheet, A1 hücresi için Range olarak bulunur. Application nesnesi Application, New ile üretilen nesne Collection, yazı tipi nesnesi ise Font sınıfındandır. C sütunu TypeOf ... Is sınamasının sonucunu gösterir: etkin sayfa için Evet, ThisWorkbook için Hayır. Böylece bir nesne değişkeninin gerçekte hangi sınıfı gösterdiğini çalışma anında öğrenebilirsiniz.

3. Nesne başvurusu ve Is işleci​

Nesne değişkenleri nesnenin kendisini değil, ona giden bir başvuruyu tutar. Bu örnekte Set b = a ile aynı nesneye ikinci bir başvuru oluşturulur; New ile ise ayrı bir nesne üretilir. Kodu standart modüle yapıştırın.
VBA 43 satır
Option Explicit

' Başvuru atama ile yeni örnek oluşturma arasındaki farkı gösterir
Sub BasvuruTesti()
    Dim ws As Worksheet
    Dim a As Collection
    Dim b As Collection
    Dim c As Collection

    Set ws = ActiveSheet

    ' a nesnesine iki öğe ekle
    Set a = New Collection
    a.Add "Ocak"
    a.Add "Şubat"
    ws.Cells(2, 2).Value = a.Count

    ' b aynı nesneyi gösterir; b üzerinden öğe ekle
    Set b = a
    b.Add "Mart"
    ws.Cells(3, 2).Value = a.Count

    ' c yeni ve boş bir nesnedir
    Set c = New Collection
    ws.Cells(4, 2).Value = c.Count

    ' Is işleci ile nesne eşitliği sınaması
    If a Is b Then
        ws.Cells(5, 2).Value = "Evet"
    Else
        ws.Cells(5, 2).Value = "Hayır"
    End If

    If a Is c Then
        ws.Cells(6, 2).Value = "Evet"
    Else
        ws.Cells(6, 2).Value = "Hayır"
    End If

    ' a başvurusunu bırak; nesne b sayesinde yaşamaya devam eder
    Set a = Nothing
    ws.Cells(7, 2).Value = b.Count
End Sub
Class
Formülünü incelemek için bir hücre seçin.
AB
1DenemeSonuç
2a: iki öğe eklendi, a.Count2
3b = a atandı, b ile öğe eklendi, a.Count3
4c = New Collection, c.Count0
5a Is bEvet
6a Is cHayır
7a = Nothing sonrası b.Count3
Başvuru TestiExcelDepo v1.0.0
İlk satırda a nesnesinde 2 öğe vardır. b değişkeni aynı nesneye bağlandığı için b üzerinden eklenen öğe a'da da görünür; ikinci satırdaki sayı 3 olur. c ise New ile üretilmiş ayrı bir nesnedir ve öğe sayısı 0 değerindedir. Is sınamasında a ile b için Evet, a ile c için Hayır sonucu çıkar. a'ya Nothing atandıktan sonra bile nesne b tarafından tutulmaya devam eder; b.Count değeri 3 olarak kalır. Nesne, kendisine bağlı hiçbir değişken kalmayınca bellekten kalkar.

Kullanırken dikkat edin​

  • Set unutmayın: Nesne değişkenine atama Set ile yapılır. Set kullanmadan atama yapmak ya da New ile örneği hiç oluşturmadan üyeye erişmek, 'Nesne değişkeni ya da With bloğu değişkeni ayarlanmamış' (Object variable or With block variable not set, hata 91) iletisine yol açar.
  • Dim ... As New kullanımından kaçının: Tanımlama satırında As New yazarsanız nesne ilk kullanıldığı anda oluşur. Nothing atadıktan sonra değişkene tekrar dokunmanız nesneyi sessizce yeniden yaratır. Tanım ile örnek oluşturmayı ayrı yapmak (Dim, sonra Set ... New) davranışı daha öngörülebilir kılar.
  • Class_Initialize parametre almaz: Sınıf oluşturulurken değer geçirmek istiyorsanız Class_Initialize kullanamazsınız. Bunun yerine nesneyi üretip özelliklerini atayan bir fabrika işlevi yazın ya da Init gibi bir yöntem tanımlayın.
  • Sınıf modülü doğrudan çalıştırılmaz: Sınıf modülündeki bir Sub'ı F5 ile ya da Makrolar penceresinden çalıştıramazsınız; önce standart modülden sınıfın bir örneğini oluşturmanız gerekir. Sınıfı başka bir projeye taşımak için modülü sağ tıklayıp dosyaya aktarabilir (Export) ve diğer projeye içe aktarabilirsiniz.
  • Döngüsel başvurular bellek sızdırır: İki nesne birbirini özellik olarak tutuyorsa, dışarıdaki tüm değişkenlere Nothing atasanız bile nesneler bellekten kalkmayabilir ve Class_Terminate çalışmaz. Karşılıklı başvuru gerekiyorsa işiniz bitince başvurulardan birini elle Nothing yapın.
  • WithEvents değişkeni uygun yerde olmalı: Olay dinleyen nesne değişkeni modül düzeyinde tanımlanmalıdır. Yordam içinde tanımlanan değişken yordam bitince yok olur ve olaylar yakalanmaz. Ayrıca WithEvents standart modüllerde kullanılamaz.
  • Sınıf içinde alan adlarını özellik adından ayırın: Private değişkene pAd, özelliğe Ad gibi farklı adlar verin. Aynı adı kullanamazsınız; ön ek alışkanlığı kodun okunmasını da kolaylaştırır.
  • İlgili konular:
    • Set, New ve Nothing: nesne oluşturma ve başvuru bırakma
    • Property Get, Property Let, Property Set: sınıf özellikleri
    • Implements: arayüz uygulama
    • WithEvents, Event, RaiseEvent: sınıfta olay tanımlama ve dinleme
    • TypeName ve TypeOf ... Is: nesne türünü sınama
    • Is işleci: iki nesne başvurusunu karşılaştırma
    • Collection nesnesi: hazır bir sınıf örneği
    • CallByName: özelliğe ya da yönteme adıyla erişme
    • UserForm modülü ve ThisWorkbook: sınıf modülü olarak çalışan belge modülleri
    • Ekle > Modül (Insert > Module): standart modül oluşturma
Örneklerdeki makroların tamamı indirilebilir Excel dosyasındadır (.xlsm). Dosyayı açtıktan sonra makroları etkinleştirin, ardından Alt + F11 ile Visual Basic Düzenleyicisi'nde kodları inceleyebilir ve Alt + F8 ile çalıştırabilirsiniz.
Yazar
ExcelDepo
İndirme sayısı
0
Gösterim
9
İlk yayın
Güncel

Puanlar

0.00 Oylama 0 İnceleme
Geri
Üst