1. Giriş

Sınıf ve nesne mantığı programlamaya yeni başlayanlar için biraz karmaşık gelebilir. Önce isterseniz Sınıf ve Nesne nedir onları anlatmakla başlayayım. Sınıf belli bir veri yapısını tanımlamak için kullanılan şablonlar olarak adlandırılabilir. Bu şablondan oluşturduğunuz ve programda kullanılan her yapı ise nesnedir. Bu açıdan bakıldığında kullanıcı tanımlı türe benzerdir.

Peki sınıfların kullanıcı tanımlı türden farkları nelerdir? Aşağıda bir listeye bir bakalım:

1.Sınıf kendi değişkenlerini barındırır: “Public” ve “Private” anahtar kelimeleri ile tanımlanabilir. “Public” olarak tanımlanmış bir değişkene SınıfAdı.DegiskenAdı şeklinde bir yazılım ile program içinden erişebilirsiniz. “Private” olarak tanımlanmış değişkenler sadece sınıf içinde kullanılabilir, program içinde erişime kapalıdır.

2. Sınıfın kendine ait yordamları olabilir: Sınıflar kendi içlerinde bazı atamaları, kontrolleri otomatik olarak yapmanızı sağlayacak kendi alt yordamlarını barındırabilir. Bu yordamlar “Public” olarak tanımlanırsa sınıf dışından da çağırılabilir. Örnek olarak bir sınıf içinde bir toplam yordamı var ise buna program içinde SınıfAdı.Toplam gibi bir satır ile erişebilirsiniz. “Private” olarak tanımlanırsa sadece sınıf içinden erişilebilir. Program içinden erişime kapalıdır

3. Sınıfın mülkü olarak adlandırabileceğimiz özel yordamları vardır: İngilizce “Property” olarak adlandırılır. Bu yapılar değişken gibi davranan yapılardır. Sınıf içindeki değişkenlere değer atamak için veya bu değişkenlerin değerlerini okumak için de kullanılır. Üç tane property vardır Let, Get ve Set. Bunların kullanımını ilerleyen aşamalarda anlatacağım.

4. Sınıf oluşturulduğu anda bazı işlemleri otomatik yapabilir: Oluşturucu (Constructer) adı verilen özel olaylar ile bir sınıftan yeni bir nesne türettiğinizde otomatik olarak çalışan bir alt yordamdır.

5. Sınıf hafızadan silindiğinde bazı işlemleri otomatik olarak çalıştırabilir: Yok Edici (Terminator) adı verilen olay ile o sınıftan türetilmiş olan nesne hafızadan kaldırılmadan önce otomatik olarak çalışacak yordamdır.

6. Sınıf içinde kedi özel olaylarınızı (event) oluşturabilirsiniz: Sınıf içinde bazı değişkenler değiştiğinde veya değişkenlere değer atandığında çalışmasını sağlayabilirsiniz. Bu konu ileri seviye bir uygulama olduğundan bu yazıda değinmeyeceğim.

Peki nesne yönelimli programlarını faydaları nelerdir? Çok sayıda benzer yapılar kullanıyorsanız bunları ayrı ayrı tanımlamak ve bu yapılar için kodları teker teker yazmak hem programınızı daha karmaşık hale getirir hem de daha sonra eklemeler yapmak istediğinizde tüm kodu gözden geçirmenize sebep olur. Nesne kullanarak bu tarz yapıları ayrı özel bir hale büründürürsünüz. Bu yapı ile ilgili tüm işlemler bu yapının içinde gerçekleşir. Ve siz sadece ihtiyacınız olan çıktıyı alırsınız. Birden fazla benzer veri yapıları ile uğraştığınızda bu size büyük bir fayda sağlar.

Örnek olarak siz kullanıcıdan bir doğum tarihi girmesini istediniz diyelim. Kullanıcının yaşını da hesaplamak istiyorsunuz. Bu durumda siz bu kullanıcının yaşını bulmak istediğinizde bir alt yordamı çağırarak bugünün tarihinden kullanıcının doğum tarihini çıkararak bu işlemi yapabilirsiniz. Ancak yüzlerce kullanıcı için bu işlemi yapmak ek bir kod demek. Bunun yerine nesne içinde bir Yas adlı özellik (property) tanımlayarak Kullanıcı.Yas gibi bir kod satırı ile bu değeri otomatik olarak çekebilirsiniz. Bu çok daha anlaşılabilirdir.

Kullanıcı yaşını hesapladık ama bir gün biri geldi dedi ki biz kullanıcılarımızın burçlarını da görmke istiyoruz. Bu durumda siz kodunuza burç hesaplayan bir yordam eklemek ve sonrasında tüm kullanıcılar için bu yordamı çağırmak zorunda kalacaksınız demektir. Ama nesne kullandı iseniz bu hesaplamayı nesen içine taşıyarak Kullanıcı.Burc gibi bir özellik ile anlık çağırabilirsiniz.

Nesne yönelimli programlamanın bazı zorlukları da var. İlk aşama nesne yapısını çok iyi planlamanız gerekmektedir. Hangi yordamlar nesne içinde olacak hangileri ana programa dahil olacak ayrımı çok iyi yapmanız gerek.

Nesne yönelimli programlamanın ilk aşamaları oldukça uzun sürecektir. Bunun nedeni gerekli nesneleri oluşturmadan ve ilgili yordamları bu nesnelerin içine gömmeden programın çalışmasını tam olarak sağlayamamanız. Planlama ile birlikte bu aşama programlamanın en önemli aşamaları zaten.

Nesne ve sınıf mantığı programlamaya yeni başlayanlar için biraz karmaşık bir konudur. Ancak programlama yaptıkça nesneye olan ihtiyaçlarınız doğacak ve kullanma durumunda kalacaksınız.

Siz nesne oluşturmasanız da VBA içinde nesneleri kullanıyorsunuz. Excel’deki çalışma kitabı, çalışma sayfası ve bu sayfanın içindeki hücre, çizim vs. hepsi aslında bir nesne. Siz bu nesneleri, neslerin içinde tanımlı değişkenleri, özellikleri, yordamları ve olayları kullanıyorsunuz.

2. Sınıf Tanımlama ve Nesne Oluşturma

Sınıf oluşturmak için proje yöneticisine sağ tıklayarak gelen menüden “Insert” (Ekle) “Class Module” seçeneğini seçmeliyiz. VBA düzenleyici çalışma kitabına yeni bir sınıf ekleyecektir. Bu sınıfın ismine çift tıkladığımızda o sınıf için kod yazmaya başlayabiliriz. Oluşturduğunuz sınııfın adını da Özellikler (Properties) penceresindeki İsim (name) alanına çift tıklayarak değiştirebilirsiniz. Ben bu sınıfa snfOgrenci adını vereceğim. Sonrasında bu sınıf içinde Ad ve Soyad adlı iki tane genel metin değişkeni tanımlayacağım. Aşağıdaki resimlerde sınıf ekleme ve sınıf ismini değiştirmeyi nasıl yaptığınızı gösterdim.

Not: Dikkat ederseniz yazılımda doğrudan Ogrenci yerine snfOgrenci kullandım. Bu uymak zorunda olmadığınız ancak uyarsanız fayda göreceğiniz bir isimlendirme çünkü bu sayede sınıflar ile o sınıflardan türetilmiş nesneleri hızlıca ayırabilirsiniz.

Not: vb.net kullanırken sınıfları ayrı bir modül içinde tanımlayabileceğiniz gibi çalışmakta oduğunuz modül içinde de tanımlayabilirsiniz. Bunun için

Public Class SınıfAdı

…..

….

End Class

Şeklinde bir yazılım kullanabilirsiniz.

Şimdi bu sınıf nesnesine çift tıklayarak programlama sayfasını açacağım ve Ad-Soyad adında iki tane metin değişkeni tanımlayacağım

Public Ad as String
Public SoyAd as String

Şimdi sınıfımızı tanımladığımıza göre bu sınıftan bir nesne türetelim. Yeni bir modül oluşturun ve modülün içine aşağıdaki kodu yazın:

Sub AnaProgram()

Dim Ogrenci as New snfOgrenci
Ogrenci.Ad=”Ahmet”
Ogrenci.SoyAd=”Taşkıran”

End Sub

Bu satırda dikkat ettiyseniz “New” (yeni) adlı bir anahtar kelime kullandık. Nesneleri ilk defa oluştururken derleyicinin bilgisayar hafızasıda gerekli alanı ayarlayabilmesi için bu anahtar kelime kullanılır. Bu anahtar kelime ile sil baştan, tamamen boş yeni bir nesne oluşturulur. Eğer siz New anahtar kelimesi kullanmazsanız bu nesneye değer atalamalarını yapamazsınız.

Burada kısa bir bilgi de vereyim, derleyici “New” anahtar kelimesini gördüğü anda eğer sınıf içinde bir Oluşturucu (constructor) yordamı var ise onu da çalıştırır.

Ogrenci nesnesinin içindeki alt değişkenlere erişim için ise NesneAdı.DeğişkenAdı şeklinde bir yazım kullandım. Tabii sınıf içindeki değişkenler “Public” olarak tanımlandığından doğrudan bu değişkenlere erişebildim. Eğer değişkenleri “Private” ile tanımlasaydık düzenleyici bu değişkenlere erişimimize izin vermeyecekti.

Eğer zaten mevcut olan bir nesneye erişim sağlamak istiyorsanız “New” anahtar kelimesine ihtiyacınız yok. Mesela kitap içinde zaten var olan bir çalışma sayfasına erişim için aşağıdaki gibi bir kod kullanabilirsiniz:

Dim IslemSayfasi as WorkSheet
Set IslemSayfasi=ThisWorkbook.Worksheets(1)

Ve eğer kitaba yani bir çalışma sayfası ekleyecekseniz bu çalışma sayfası daha önce mevcut olmadığından aşağıdaki gibi bir kod yazmanız gerek:

Dim YeniSayfa as New WorkSheet
Set YeniSayfa=ActiveWorkbook.WorkSheets.Add()

Not: Vb.net 2019 sürümünde bu tanımlama şu şekilde daha kısa biçimde yazılabilir:

Dim Ogrenci as New snfOgrenci with { .Ad = ”Ahmet”, .SoyAd = ”Taşkıran” }

Şimdi bu değişkenleri yazdıralım:

Sub AnaProgram

Dim Ogrenci as New snfOgrenci
Ogrenci.Ad = ”Ahmet”
Ogrenci.SoyAd = ”Taşkıran”
Debug.Print “Ad/Soyad= “ &Ogrenci.Ad &” “ &Ogrenci.SoyAd

End Sub

Programı çalıştırdığınızda “Immediate” penceresinde “Ad/Soyad= Ahmet Taşkıran” metni belirecektir.

3. Sınıf Yordamları

Artık bu değişken özel yapıya büründüğünden sınıf dışındaki başka bir modülden bu değişkene erişemezsiniz. Bu değişkene erişebilmek için mülk özelliğini kullanacağım. Sınıf program sayfasında iken tarih değişkeninin altına aşağıdaki kodu yazın:

Public Property Let DogumTarihi(trhDeger As Date)

If Year(Now()) – Year(trhDeger) > 14 Then MsgBox “Girilen Tarihe göre öğrenci yaşı 14’ten büyük, Lütfen tarihi kontrol edin”, vbCritical: Exit Property

trhDogumtarihi = trhDeger

End Property

Public Property Get DogumTarihi() As Date

DogumTarihi = trhDogumtarihi

End Property

Burada iki tane mülk yordamı söz konusu. Let yordamı bir değer atama yordamıdır. Get yordamı ise bu değeri okumaya yarar. Kullanılması da aynı değişken kullanımı gibidir. Değer atamak için = işareti kullandığınızda “Let” yordamı devreye girer. Atadığınız değeri okumak istediğinizde ise “Get” yordamı. Burada dikkat edeceğiniz en önemli konu Let yordamında dışarıdan aldığınız değer (trhDeger) değişken tipi ile Get yordamının döndürdüğü değişken türü aynı olmalıdır. Burada her iki değişken türü de tarih (date) türünde. Aksi takdirde derleyici iki değişken türünün aynı olmadığı ile iligi bir hata gösterecektir.

Burada kısa bir bilgi vereyim VB ilk sürümlerinde değer atama işlemi Let ile yapılıyordu. Yani Let A=19 gibi bir ifade kullanmak gerekiyordu. Sonradan bu gereklilik kaldırıldı.

Dikkat ederseniz mülk adı ile daha önce kullandığım değişken adı aynı. Bu yüzden programda bir değişiklik yapmama gerek yok. Şimdi “F8” tuşuna basarak yazdığınız kodu adım adım çalıştırın, bu tuşa her bastığınızda bir satır ilerlersiniz. Şimdi program DogumTarihi = satırına geldiğinde aşağıdaki ileti gösterilecektir. Tabii şu aşamada programın devamını engelleyen bir kodumuz yok.

Şimdi Öğrenci yaşının da hesaplanması istenirse bunu bugünkü tarihten doğum tarihi çıkarıp bir değişkene atayarak sağlayabilirsiniz. Ya da bir aşağıdaki gibi bir yöntem kullanabilirsiniz:

Yaş=Year(Now())-Year(Ogrenci.DogumTarihi)

Bu şekilde kullanımda mesela ilerleyen zamanlarda doğum tarihini sadece yıl olarak tutmak isterseniz  sınıfın DogumTarihi mülkü türü değişecek demektir. Bu durumda sizin yazdığınız kodu tamamen tarayarak bu hesaplamanın olduğu yerlerde kodu güncellemeniz gerekecek demektir.

Nesne içinde bir Yaş değişkeni tanımlayarak hesapladığınız değeri bu değişkende de tutabilirsiniz, ancak bu durumda her sene öğrencinin yaşını yeninden hesaplayarak bu değişkene atama yapmanız gerekir. Bu hem zaman hem de çok basit bir hesaplama ile elde edilebilecek değer için değişken kullanıldığından hafızanın verimsiz kullanımı olacaktır.

Mülk yordamları ile siz bu tarz hemen hesaplanabilecek değerleri, anlık olarak bir değişkene bağlı olmadan, hesaplanarak çağırılmasını sağlayabilirsiniz.

Bunun için sınıf program sayfasına giriyoruz ve aşağıdaki kodu ekliyruz:

Public Property Get Yas() As Integer

Yas = Year(Now()) – Year(trhDogumtarihi)

End Property

OgrenciYaz yordamını da aşağıdaki gibi güncelleyelim:

Public Sub OgrenciYaz()

Debug.Print “Ad/Soyad = “; Ad & ” ” & SoyAd & Chr(13) & “Dogum Tarihi = ” & trhDogumtarihi & ” Yaş =” & Yas

End Sub

Şimdi de modüle geri dönüp dogum tarihine 10/20/2009 değerini atayalım. Programı çalıştırdığınızda aşağıdaki çıktı alacaksınız:

Ad/Soyad = Ahmet Taşkıran

Dogum Tarihi = 20.10.2009 Yaş =10

Gördüğünüz gibi bir yaş değişkeni olmamasına rağmen mülk yordamı ile yaş anlık olarak hesaplandı ve gösterildi. İleride doğum tarihini tutma şeklini değiştirirseniz (mesela sadece yıl olarak) sadece sınıf içindeki yodamı değiştirmeniz yeterli olacaktır. Program kodunuza ek bir müdahaleye gerek kalmayacağından hem hataları engellemiş olursunuz hem de tüm yazdığınız kodu tarayarak eski kodu değiştirme işleminden de tasarruf edersiniz.

Burada gördüğünüz gibi mülklere “salt okunur” mülk deniyor. Çünkü değer ataması yaptığınız Let yordamınız yok ki zaten bunun için arka planda bir de değşiken olması gerek o da eksik. Bu yordam ile sadece değeri okuyorsunuz ki o da zaten çağırdığınız anda hesaplanıyor.

Bu iki yordam haricinde bir de Set yordamı var. Bu yordam ise bir nesne içindeki alt nesnelere değer atamak için kullanılır. Bu konu sınıflara aşina olmayı gerektirdiğinden bu aşamada anlatmayacağım. İlerleyen zamanlarda başka bir kaç nesne hakkında yazı yazdıktan sonra değinmenin daha doğru olacağını düşünüyorum.

4. Sınıf Olayları

Sınıfların 2 tane olay yordamı vardır. Bunlar nesne tabanlı dillerde Oluşturucu (Constructor) ve Yok Edici (Terminator) olarak adlandırılır. Amaçları nesne oluşturulduğu anda devreye girer. Amacı nesneniz için belirlediğiniz bazı varsayılan değerleri ayarlamak ve nesne içinde bir alt nesne kullanıyorsanız bunların oluşturulmasını sağlamak. Yok edici olayı ise siz nesnenizi sildiğinizde çalışır ve nesnenin hafızada tuttuğu değişkenleri temizlemenizi sağlar.

Olay eklemek için izleyebileceğiniz bir yöntemi aşağıdaki videoda görebilirsiniz. Bu yöntemi formlarda yer alan tüm form nesneleri hatta formun kendisi için tanımlanmış olayları programlamak için kullanabilirsiniz.

a. Oluşturucu Olayı

Bir nesne içinde değişken boyutlu bir dizin kullandığımızı varsayalım. Örnek olarak öğrencinin aldığı dersleri bir dizinde sakladığımızı varsayalım ve ek dersler ile bu dizinin değişken boyutta olduğunu düşünelim. Dizinleri anlattığım yazıda daha ayrıntılı bilgi bulabilirsiniz. Şimdi Sınıf program nesnesine girelim ve aşağıdaki satırı ekleyelim:

Public Dersler() as String

Bu dizini kullanmaya başlamadan önce ReDim komutu ile bu değişkene bir eleman eklememiz gerek. Bunu Let yordamı ile yapmak istersek işler karışacak ve her seferinde dizinin boyutunu kontrol edecek bir satır eklememiz gerekecek. Bu da verimsiz bir yöntem.

Biz bu dizin boyutunu sıfır olarak ayarlama işlemini nesne ilk oluşturulduğunda yapmamız gerekir ki ilerleyen aşamalarda sıkıntı yaşamayalım. Şimdi nesne içine aşağıdaki kodu ekleyelim:

Private Sub Class_Initialize()

ReDim Dersler(0)

End Sub

Ya da nesnenizi her oluşturduğunuzda Excel çalışma kitabında yeni bir sayfa açmanız gerektiğiniz düşünelim. Bu durumda hem bir WorkSheet değişkenine, hem de bu değişkene atanmış yeni bir çalışma sayfasına ihtiyacınız olacaktır.

Public OgrenciSayfasi as New Worksheet

Private Sub Class_Initialize()

Set OgrenciSayfasi = ThisWorkbook.WorkSheets.Add()

End Sub

Oluşturucu olayına dışarıdan bir değer yollayamayacağınızı da belirteyim. Eğer dışarıdan bir değer yollamak isyiyorsanız ya sınıfın genel değişkenlerini kullanmalısınız ya da mülk yordamlarını. Ya da bir genel yordam tanımlayıp nesneyi oluşturduktan sonra bu yordamı çağırmanız gerekiyor. Örnek olarak sınıf programlama sayfasında:

Public Sub SinifOlustur(DogumTarihi as Date)

trhDogumTarihi=DogumTarihi

End Sub

Kodunu yazdıktan sonra program içine aşağıdaki kodu eklemeniz gerek:

Dim Ogrenci as new snfOgrenci
Ogrenci.SinifOIustur

b Yok Edici Olayı

Oncelikle VBA’da nesneler oluşturuldukları bölgenin dışına çıkıldığında hafızadan otomatik olarak silinir. Misal bir alt yordam içinde Nesnenizi oluşturdunuz, o alt program sona erdiğinde oluşturduğunuz nesne de hafızadan silinecektir.  Ancak siz de bir nesneye “Nothing” ataması yaparsanız o nesne hafızadan silinir.

Şimdi aşağıdaki kodu sınıf nesnesinin program sayfasına yazın.

Public Sub Class_Terminate()

MsgBox(“Nesne Sonlandırıldı”)

End Sub

Sonra program içinde aşağıdkai kodu ekleyin

Set Ogrenci=Nothing

Kodu çalıştırdığınızda Ekranda “Nesne Sonlandırıldı” yazan bir ileti kutusu gösterilecektir.

Neden bir sonlandırıcı kullanmak gereği hissedersiniz? Hafızayı daha temiz tutarak daha verimli kullanmak için. VBA sizin yerinize nesne silme işlemlerini yapacaktır ancak nesne içindeki değişkenleri ve nesneleri sizin silmeniz daha etkili bir yöntem olacaktır.

Özellikle C++ gibi dillerde hafıza yönetimi tamamen programcıların ellerine teslim edilmiştir. Yani derleyici sizin adınıza hafızada yer ayırmayacağı gibi kullanılan değişkenlerin ve nesnelerin hafızadan silme işlemini de otomatik olarak yapmaz. Bu tarz programlarda hafızayı temizlemek için yok edicileri kullanmak zorundadır.

İlginizi Çekebilecek Diğer Yazılar
Etiketler: , , , ,

Leave a Reply