DİZİLER (VISUAL BASIC)
DİZİLER
Diziler birbirleriyle ilgili nesne grubunu içeren değişkenlerdir. Aynı tür bilgileri bellekte tutmak için kullanabileceğimiz listelere dizi adı verilir. Dizi kullanmanın avantajı aynı tür bilgiler bir listede tutularak daha hızlı işlem yapılabilmesi sağlanmış olacaktır. Bir dizi tanımlamak için normal veri tanımlama komutu olan Dim, Public, Private komutlarını kullanılır.
Örneğin
Dim sayıDizisi(7) As Integer 8 elemanlı (0-7 arası) bir sayı dizisi
Dim byteDizisi(4 To 32) As Byte 29 elemanlı bir sayı dizisi
Public metinDizisi(1 To 10) As String 11 elemanlı metin dizisi
Diziler sabit boyutlu(dinamik) veya değişken boyutlu(static) olabilirler.
Sabit boyutlu dizilerde dizinin eleman sayısı değişmez, oysa değişken boyutlu dizilerde dizinin eleman sayısı ihtiyaca göre değişebilir.
Peki değişkenin veya dizinin statik ya da dinamik olduğunu nereden bileceğiz?
Değişkenler
Diziler (Array)
Statik
1. Declarations kısmında tanımlanan değişkenler.
2. Static ifadesiyle tanımlanan değişkenler.
1. Declarations kısmında boyutuyla tanımlanan diziler.
Örneğin:
Dim Dizi(1 To 45)
2. Static ifadesiyle tanımlanan yerel diziler.
Dinamik
Yerel (local) değişkenler.
1. Declarations kısmında boyutsuz olarak tanımlanan diziler.
Örneğin:
Dim MyArray()
2. Dim veya Redim ifadeleri kullanılarak tanımlanan yerel diziler.
Diziler alt yordamlarda argüman olarak kullanılabilir.
Dim Sira_No( ) As Integer ‘ Dinamik dizi
Dim Sira_No(255) As Integer ‘ Static dizi 256 Integer içerir
Statik Diziler
Dizinin kaç elemandan oluştuğu, değişken isminden sonra parantez içine yazılır.
Dim değişken_adı(İndis) As Veri_Tipi = atanacak_bilgi
Dim x(5) As Integer ‘ 6 elemanlı bir dizidir. Yani a(0), a(1),a(2),...,a(5) şeklinde elemanları vardır.
Herhangi bir fonksiyon veya alt programda dizi tanımı “Dim” deyimi ile yapılamaz, sadece General-Declaratıons kısmında veya modül içinde tanımlanabilir.
Eğer bir fonksiyon veya alt program içinde dizi tanımlanacaksa “ReDim” veya “Static” deyimleriyle tanımlanmalıdır.
VBA'da dizi şu şekildedir .
Örnek:
Dim ad(2) As String
Dim no(2) As Integer
ad(0) = "Seçkin"
ad(1) = "Ali"
ad(2) = "Ahmet"
no(0) = 13
no(1) = 35
no(2) = 25
Bu örnek'te ad ve no olmak üzere iki adet dizi tanımlanmaktadır. ad dizisi string türünde bilgileri tutacak ve no dizisi ise integer türündeki bilgileri saklayacaktır. Görmüş olduğunuz gibi dizilere bilgi atama şekli dizi_adı(indis_sırası)=atanacak_bilgi şeklindedir.
Burada dizi indisleri sıfırdan başlayarak tanımlama yaparken bizim belirttiğimiz değere kadardır.
Yani bizim bu dizilere atayabileceğim veri sayısı diziyi tanımlarken belirttiğimiz indis değerinden bir fazla olacaktır.
Eğer değer atama yaparken belirttiğimiz sınırların dışına çıkarsak hata oluşur.
Başka bir örnek: Dizi elemanlarına değer atamak için
Dim isim(1 To 10) As String
Private Sub CommandButton1_Click()
isim(1) = "Murat"
isim(2) = "Ali"
isim(3) = "Salih"
End Sub
veya
Dim isim(1 To 10) As String
Private Sub CommandButton1_Click()
isim(1) = Text1.Text
isim(2) = Text2.Text
isim(3) = Text3.Text
End Sub
Bu örnekte ise isim dizisinin elemanlarına döngü içinde değer atanıyor ve listeye diziliyor.
Dim isim(1 To 10) As String
Private Sub CommandButton1_Click()
For i = 1 To 10
isim(i) = "İsim numarası " & i
ListBox1.AddItem isim(i)
Next i
End Sub
Dizilere değer atarken dizi sınırlarını kontrol etmekle olası bir hatayı önlemiş oluruz.
Bir dizinin sınırlarını belirlemek için;
Dim a(3 to7) ‘ile ilk elemanı a(3) ve son elemanı a(7) olan bir eleman tanımlanabilir.
Dim Sira(4) As String ‘aslında bu şekildeki bir dizi de sınırlıdır. Nasıl mı 0 ile 4 arasında
Bazen de dizilere değer atarken hangi elemandan başlayacağını belirtebiliriz.
Bunun için ise; Option Base deyimini kullanırız. Option Base dizilerin başlangıç sayısını belirtmekte kullanılır. Option Base 0 ve 1 değerini alabilir.
Option Base 0: Böyle bir dizi 0 dan başlayan ve 3 te biten elemanlara sahiptir ilk elemanının numarası 0 dır ve toplam 4 elemanı vardır.
Yani Option Base 0 yazmak ile hiç option base kullanmamak arasında bir fark yoktur.
Option Base 1: Eğer diziyi sıfırdan değil de bir den itibaren başlatmak istersek diziyi tanımlamadan önce Option Base 1 satırını eklemeliyiz..
Örnek:
Option Base 1
Dim sayi(5) As Integer
Private Sub UserForm_Activate()
sayi(1) = 100
sayi(2) = 200
End Sub
Private Sub CommandButton1_Click()
TextBox1.Text = sayi(1) + sayi(2)
End Sub
Bu örnekte görüldüğü gibi projenin "General Declarations" kısmında sayi() dizisi tanımlanıyor. Bu dizi tanımlanmadan önce dizi indislerinin 1 den itibaren başlayacağını belirten Option Base 1 satırı koda dahil edilmiştir. UserForm1 yüklendiğinde bu dizinin ilk elemanına 100 sayısı ikinci elemanına 200 sayısı atanıyor. Eğer kullanıcı CommandButton1 isimli butona tıklarsa dizinin ilk ve ikinci elemanları toplanarak Form üzerinde TextBox1 adlı nesnenin Text özelliğine atanıyor. Yani TextBox1'in bu sayıların toplamını göstermesi sağlanıyor.
Dinamik Diziler
Değişken boyutlu (dinamik) dizilerde dizinin eleman sayısı ihtiyaca göre değişebilir. Dinamik diziyi tanımlarken parantez içi boş bırakılır. Bu tip dizilerde kullanılacak yer sayısında bir sınırlama yoktur. Bu tip diziler ilk başta aşağıdaki şekilde görüldüğü gibi bir tanımlamaya ihtiyaç duyarlar.
Dim dizi_adı( ) As Veri_Tipi
Örnek kullanım:
Dim dnmogrenci() As String
Diziler önce tanımlanıp, sonradan da genişletilebilir. Dim, Public veya Private komutlarıyla tanımlanmış bir dizi ReDim komutuyla genişletilebilir veya daraltılabilir. Böyle dizilere Dinamik Diziler denir. Dizi elemanlarının değerleri korunmak istenirse ReDim Preserve komutu kullanılır.
Hiçbir prosedür bölgesinde kalmayan yani global olan yere şöyle bir kod yazılabilir.
Dim Sayılar() As Long
Sonradan bir boyut verilebilir.
Sub BoyutVer(Boyut As Integer)
ReDim Sayılar(0 To Boyut) As Long
End Sub
Dinamik dizilerin eleman sayısını istediğiniz herhangi bir anda “ReDim” deyimi ile dizinin eleman sayısını değiştirebilirsiniz.
ReDim dizi_adı(boyut ) As Veri_Tipi
Örnek kullanım:
Redim dnmogrenci(20)
“ReDim” deyiminin her kullanılışında dizinin içeriği silinir. Bunu önlemek için “Preserve” komutu kullanılır;
ReDim Preserve s(boyut) As Veri_tipi
Örnek kullanım:
ReDim Preserve dnmogrenci(20)
Bu şekilde dizinin daha önceki elemanları korunur. Artık bu veri dizisini projemiz içinde kullanabiliriz. Verileri korumak istiyorsanız Preserve komutu önemlidir.
Örneğin,
Dim a() As String ‘Decleration kısmına yazacaksınız.
Private Sub CommandButton1_Click()
ReDim a(0 To 3) As String
a(0) = "Ahmet"
a(1) = "Mahmut"
a(2) = "Muhammed"
a(3) = "Mustafa"
End Sub
Yukarıda 4 elemanlı yapılan a dizisinin elemanlarına değerler verildi.
Private Sub CommandButton2_Click()
ReDim a(0 To 5) As String
a(4) = "Ali"
a(5) = "Veli"
End Sub
ReDim a(0 To 5) As String
Kodu
a(0), a(1), a(2), a(3) elemanlarının değerlerini sıfırladı. Bunu engellemek için (sıfırlanmamasını sağlamak için) CommandButton2 ye tıklandığında şöyle bir kod olması gerekir.
Private Sub CommandButton2_Click()
ReDim Preserve a(0 To 5) As String
a(4) = "Ali"
a(5) = "Veli"
End Sub
Yani a(0), a(1), a(2), a(3) dizisinin değerleri saklı kalmış oldu.
Başka bir örnek:
Kodlar Kodların Açıklaması
Option Base 1 ‘Dizi 1 den başlasın
Dim s() As String ‘s değişkeni dinamik dizi olarak Decleration kısmında tanımlanıyor.
Private Sub CommandButton1_Click()
ReDim s(3) As String s dizisi CommandButton1 in klik olayında s değişkeninin dizi boyutu silinir ve yeniden boyutlandırılır. (istendiği anda)
s(1) = "Merhaba" s dizisinin 1. elemanına “Merhaba” sözcüğü atanıyor.
s(2) = "Mahmut" s dizisinin 1. elemanına “Mahmut” sözcüğü atanıyor.
s(3) = "Nasılsın" s dizisinin 1. elemanına “Nasılsın” sözcüğü atanıyor.
TextBox1.Text = s(1) + s(2) + s(3) TextBox ta dizi elemanları birleştirilerek gösteriliyor.
End Sub
Private Sub CommandButton2_Click()
ReDim Preserve s(5) As String s dizisi ise önceki prosedürde s(3) şeklinde boyutlandırılmıştı. Burada s(3) saklı kalmak şartı ile tekrar boyutlandırılıyor.
s(4) = "Ahmet"
s(5) = "İyi misin"
TextBox1.Text = s(4) + s(5)
End Sub
Not: Sadece Redim ifadesini kullanmak da dizileri boyutlandırır. Preserve parametresinin kullanım sebebi, ise diziye atılmış eski verileri korumaktır.
Redim arrSh(y) demiş olsaydık, döngünün ilk adımlarında yüklenen sayfa adları, döngünü diğer adımlarında silinecekti. Preserve ile, arrSh'yi tekrar boyutlandırırken, eski veriler aynen kalmaktadır.
Yani Redim Preserve arrSh(2) dediğimizde, örneğin;
Arrsh(0) ->Sayfa1
ArrSh(1) ->Sayfa2
ArrSh(2) ->Sayfa3 değerlerini saklamakla beraber,
Redim arrSh(2) dediğimizde;
ArrSh(0) ->""
ArrSh(1) ->""
ArrSh(2) ->Sayfa3 dizi atamaları gerçekleşir
Bu tip dizilerde ise dizinin eleman sayısını program akışı içerisinde kontrol edebiliyoruz bunu ise diziyi Dim Sayilar() as Integer şeklinde dizinin eleman sayısı hakkında herhangi bir değer vermeden belirttikten sonra ReDim Sayilar(10) as Integer şeklinde dizinin eleman sayısını program akışı esnasında tanımlıyoruz. Ancak diziyi yeniden boyutlandırırken unutulmaması gereken nokta dizinin içindeki verilerin silineceğidir. Eğer verilerin silinmemesini istiyorsak diziyi yeninden boyutlandırırken ReDim Preserve Sayilar(10) As Integer şeklinde belirtmemiz gerekir. Şimdi buraya kadar öğrendiklerimizi bir örnekle pekiştirelim.
Örnek 1: Girilen 10 tane sayının toplamını ve ortalamasını veren örnek program
Yukarda ki örnekte bilmediğimiz hiç bir komut olmadığı için programın satır satır açıklamasını yapmayacağım onun yerine sadece ekran görüntülerini vereceğim.
Yukarda ki resimlerden de anlaşılacağı üzere 10 adet sayıyı teker teker girdiğimizde programımız bize bu sayıların toplamını ve ortalamasını verecektir.
Örnek 2 : Şimdi de yukarda ki örneğimizi aktif bir dizi ile daha etkileşimli hale çevirelim .
Bu örneğin uygulamasını da sizlere bırakıyorum.
Çok Boyutlu Dizi Değişkenlerin Tanımlanması
Dim Tablo(4,3) As Integer
Dim DersSonuçları(3,3,1) As Integer
Yukarda ki tanımlama ile çok boyutlu diziler yaratmış olduk Dikkat ettiyseniz her boyuta ait index numarası birbirinden virgülle ayrılarak diziler boyutlandırılabiliyor. Bu konuyu her zaman yaptığımız gibi bir örnekle açıklayalım
Etiketlerin (Label) ve Düğmelerin başlıklarını VB 'nin sol tarafındaki "Properties" Penceresinde ki "Caption" değerine yeni başlığı yazarak değiştirebiliriz.
Bileşenleri formumuza yukarda ki gibi yerleştirdikten sonra Matematik dersi için koyduğumuz 3 tane "Text Box" 'ın adını VBA 'nın sol tarafındaki "Properties" Penceresinde ki "(Name)" değerini değiştirerek sırası ile "Matematik1", "Matematik2" ve "Matematik3" yapalım bu işlemi diğer dersler içinde tekrarlayalım daha sonra "Ortalaması" başlıklı Labellerimizin hepsinede "Ortalama" adını verelim bu sırada VBA bize "You have already a control named 'Ortalama'. Do you want to create a control array?" diyerek bir kontrol dizisi oluşmak isteyip istemediğimizi soracak bu soruyu "Evet" diye cevaplandırarak bir kontrol dizisi oluşturalım(*) "Ortalama" başlıklı düğmemize çift tıklayarak aşağıda ki kodları yazalım.
Yukarda ki örneğimizde derslere ait notlar dizimize aktarılıyor daha sonra ise dizimizde ki notları "
For ...Next" döngüsü ile kod tekrarı yapmadan ortalamasını alıp bunu Ortalama isimli kontrol dizimizde ki etiketlerimiz de (Label) görüntülüyoruz.
Dizi İçin Sınırlar :
VBA 'da dizi için alt ve üst sınırlar belirleyebiliriz bu sınır 0 ve pozitif sayılar olabileceği gibi negatif sayılarda olabilir.
Örneğin
Dim Dizi1(1 To 20) As Integer
Dim Dizi2(0 To 5) As String
Dim Dizi2(-10 To 10) As Byte
Dizi elemanları şu şekildedir.
Dim Boyut(1 To 2, 1 To 3)= Dizi elemanları Boyut(1,1) Boyut(1,2) Boyut(1,3) Boyut(2,1) Boyut(2,2) Boyut(2,3)
Dizilerde LBound ve UBound Fonksiyonları :
İstenilen bir dizinin belirtilen boyutunun alt ve üst sınırlarının ne olduğunu öğrenmemize yarar örneğin;
Private Sub CommandButton1_Click()
Dim Dizi(-5 To 15, -10 To 20) As Integer
MsgBox "1. Boyutunun Alt Sınırı : " & LBound(Dizi, 1)
MsgBox "1. Boyutunun Üst Sınırı : " & UBound(Dizi, 1)
MsgBox "2. Boyutunun Alt Sınırı : " & LBound(Dizi, 2)
MsgBox "2. Boyutunun Üst Sınırı : " & UBound(Dizi, 2)
End Sub
Dizilerde Tür Tanımlamaları
Bir modüle (Decleration kısmına) tip tanımlayalım.
Type Ogrenci
Ad As String
Soyad As String
No As Integer
Sinif As String
GectigiDersler() As String 'Bu bir, tür içindeki dinamik dizidir.
End Type
Bu tür içindeki dinamik diziyi herhangi bir prosedür içinde genişletebilirsiniz.
Private Sub CommandButton1_Click()
Dim Mahmut As Ogrenci
ReDim Mahmut.GectigiDersler(0 To 4) As String
End Sub
gibi.
veya kendi tanımladığınız türü de dizi olarak kullanabilirsiniz.
Sub TürüDiziYap()
Dim Mahmut(0 To 8) As Ogrenci
End Sub
türünüzü dinamik olarak da tanımlayabilirsiniz.
Dim Mahmut() As Ogrenci
Private Sub cmdGenislet_Click()
ReDim Mahmut(6) As Ogrenci
ReDim Mahmut(1).GectigiDersler(1 To 5) As String
ReDim Mahmut(3).GectigiDersler(0 To 12) As String
End Sub