Değişkenler ve Veri Tipleri
Değişkenler, adı üstünde, tüm kod çalışırken zamanla içeriği değişebilecek alanlardır.(Tabiki tüm kod boyunca sabit de kalabilirler, adları değişken diye illa değişmek zorunda değillerdir.)
Neden ve Nasıl?
Değişken tanımlamamızın iki temel nedeni var:
- Bilgisayarın belleğini daha verimli kullanmak için. Her değişken için uygun veri tipini tanımlarsanız bellekte o kadar az yer tutulmuş olur. Aksi halde değişkenler Variant tipte olurlar ve en yüksek hacim olan 16 Byte'lık bir hafıza işgal ederler.
 - Hatalı işlem yapılmasını engellemiş olursunuz.
 
                        Birçoğunuzun bu aşamada ileri seviye programlamalar yapmayacağını varsayarak burada daha fazla bu konunun detaylarına şimdilik girmeyeceğim. Public/Private ayrımına da bu sayfada girmeyeceğim ancak isterseniz konularda biraz ilerleyince  buradan detaylı bilgiye ulaşabilrsiniz.
                        
Değişkenleri tanımlamak için nerdeyse her zaman Dim ifadesini ve değişkenden hemen sonra As ifadesini ve hemen arkasından veri tipini yazarız.
                        
Ör:
                    
                           
                                Dim İsim As String
                                Dim Yas As Integer
                                Dim Agirlik As Double
                                Dim Gerçekleştimi As Boolean   
                            
                        
                    
                        Bunların hiçbirini tanımlamasanız da çok büyük ihtimalle programınız çalışacaktır. Bunları tanımlayarak hem daha derli toplu hem de daha hızlı çalışan bir makroya sahip olmuş olursunuz.
                        
Değişken kullanmak efektiftir de, mesela i=Range("A1").Value demezseniz ve Range("A1")'deki değeri birkaç yerde kullanıyorsanız ve sonradan Range("A1") yerine Range("A2")'ye referans vermek isterseniz kod içinde Range("A1") geçen her yerde değişiklik yapmak zorunda kalırsınız, ama i=Range("A1").Value demişseniz sadece bunu değiştirmeniz ve diğer yerleri "i" olarak bırakmanız yeterlidir.
                        
Değişikenin tanımlı olması ve olmaması durumunda bellek kullanımı nasıl oluyor bir ona bakalım. Bunun için basit bir örnek üzerinden gidelim.
                    
                            
                                Sub NoVariable()
                                    Range("A1").Value = Range("B2").Value
                                    Range("A2").Value = Range("B2").Value * 2
                                    Range("A3").Value = Range("B2").Value * 4
                                    Range("B2").Value = Range("B2").Value * 5
                                End Sub   
                            
                        
                    
                        Yukardaki kodda, VBA B2 hücresine 5 kez başvurmaktadır. Yani işlemciyi 5 kez yormuş oluyoruz. Halbuki en baştan B2'nin değerini bir değişkene atamış olsak, işlemcimiz sadece bir kez yorulmuş olacaktır. Ayrıca Eğer B2 hücresindeki değeri silip B4'e taşımamız gerekseydi, kodumuzun 5 yerinde değişiklik yapmamız gerekecekti. Bir diğer detay da bu kodda kullanılan karakter sayısı fazla ve uzun gözüküyor.
                        
Şimdi bi de değişken kullanarak yapalım:
                    
                        
                                Sub WithVariable()
                                  Dim i as Integer
                                  i = Range("B2").Value
                                  Range("A1").Value = i
                                  Range("A2").Value = i * 2
                                  Range("A3").Value = i * 4
                                  Range("B2").Value = i * 5
                                End Sub  
                            
                        
                    
                        Şimdi ne olur? İşlemcimiz, B2 hücresine 5 kez değil 1 kez başvuracak, bu da daha az bellek kullanımı demektir. Ayrıca B2 yerine B4 kullanmak istersek sadece i değişkenini tanımladığımız satırda yani bir kez değiştirmemiz yeterli ve okunuşu daha kolay bir kod.
                       
 Bunun gibi 5-6 satırlık bir kodda çok büyük bir fark göremezsiniz, ama yüzlerce satırdan oluşan bir kodunuz olursa farkı o zaman hissedebilirsiniz.
                        
 Peki değişkenleri tanımlamadığımızda ne oluyor, program nasıl çalışıyor? VBA, bu tür değişkenleri Variant tipinde depolar ve her defasında bu değişkenin ne tür bir değişken olması gerektiğine karar vermeye çalışır, bu da zaman kaybıdır, yani ağır çalışan bir kod demektir. Bu nedenle sitenin anasayfasında dediğim gibi işimizi doğru yapmakla kalmayalım, zerafet içinde doğru yapalım, hızlı yapalım, o yüzden değişkenlerimizi mutlaka tanımlayalım.
                        
Aşağıda tipi belirtilerek değişken tanımladığımızda ve tanımlamadığımızda neler olduğunun süreyle ölçülmüş halini gösteren bir örneğimiz daha var. Fark oldukça açık ve net.
                        
 Bu kod, k değişkeni tanımlanmadan çalıştırıldığında 5,88 saniye sürmekteyken k'nın önündeki ' işareti kaldırılıp tanımlama yapıldığında ise 2,13 saniye sürmekte. İşte bellek yönetimi budur!
                    
                        
                                Sub timerkontrol()
                                Dim başlangıç As Single
                                Dim bitiş As Single
                                Dim i As Long
                                'Dim k As Long
                                başlangıç = Timer 'bu fonksiyon, kodunuzun ne kadar sürede çalıştığını tespit etmek için kullanılır
                                For i = 1 To 100000000 'Bu yapı For-Next döngüsüdür. Şimdilik bu döngünün nasıl kullanıldığını bilmiyor olabilirsiniz, buna takılmayın. Sonraki bölümlerde detaylıca incelenecek.
                                  k = k + 1
                                Next i
                                bitiş = Timer
                                MsgBox ("İşlem süresi:" & vbNewLine & Round(bitiş - başlangıç, 2) & " saniyedir.")
                                End Sub  
                            
                        
                    Bu arada bazı zamanlar olacaktır ki değişkenin içeriği sürekli değişebiliyordur, bazen sayısal bazen karekter bir içeriğe sahip olabiliyordur, hatta sadece sayısaldır ama bazen integer, bazen long integer veya bazen double olabiliyordur veya bir sebepten dolayı tipi bilinmiyordur, bu durumda değişkeni Variant olarak tanımlamaktan başka bir çare yoktur, sadece tipini Variant olarak belirtiyoruz, tip belirtmezsek de Excel onu Variant olarak algılar. Yani şu ikisi de aynı şekilde algılanır
                            
                                Dim deger As Variant
                                Dim deger
                            
                        
                    Değişken tanımlama kuralları
                        Değişkenleri tanımlamanın bi faydası da şudur: Değişkenlerinizde mutlaka bir tane Büyük harf bulunursa ve bundan sonra değişkenleriniz hep küçük harfle yazıp space'e veya Enter'a bastığınızda, Excel ilgili harfi otomatikman büyük harfe çevirir, eğer büyük harf olmuyorsa anlarsınız ki değişkeninizi yanlış yazmışsınız. Bu nedenle, burda bu uyarıyı yapmakta da fayda görüyorum.
                       
 UYARI!:Değişken isimlerinizde iki kelime veya daha çok varsa mutlaka bir harf, mümkünse ortadan bir harf, büyük olsun. Kod içinde diğer heryerde küçük harfle yazıp, VBA'in büyütmesini bekleyin. Buna programcılık dilinde camelCase notasyonu denmektedir. Genel olarak tüm programlama dillerinde en çok önerilen değişken tanımlama geleneği camelCase olarak bilinen yöntemdir. Ör:
                    
                        
                                Dim okulNo
                                Dim ayAdı   
                                enAltSatırNo 
                            
                        
                    
                        Böylece siz programınızın başka bir yerinde okulno yazdığınızda otomatikman okulNo olacaktır, aynı şekilde ayadı da otomatikman ayAdı olacaktır.
                        
Değişken tanımlamada dikkat edilecek diğer hususlar şöyledir:
                    
- İlk karakter bir harf olmalı
 - boşluk, nokta(.), ünlem(!), ve şu karakterler kullanılmaz (@, &, $, # )
 - Çok geçeğini sanmam ama karakter uzunluğu 255i geçmemeli
 - Çok geçeğini sanmam ama karakter uzunluğu 255i geçmemeli
 - Türkçe karakter serbest ancak başka birçok dilde geçersiz olduğu için kullanmamaya çalışın
 
Program boyunca sabit kalacak bir değişkeniniz varsa bunu Const ifadesi ile tanımlayabilirsiniz. Örneğin, mağaza sayısı 15 olan bir firma için bunu sabit olarak tanımlayabilir ve döngülerde bu sabiti kullanabilirsiniz.
                        
                                Const magaza As Integer = 15 'aynı satırda tanımlanmak zorunda
                                For i = 1 to magaza
                                'Kodlar
                                Next i
                            
                        
                    DIKKAT:Sık yapılan hatalardan biri de şudur. Şimdi iki String değişken tanımlamak istediğimizi düşünelim. Eğer kelimeden tasarruf edeyim deyip şu şekilde tanımlarsak hata yaparız:
                        
                                CDim metin1, metin2 as String
                            
                        
                    Çünkü bu şekilde aslında ilk değişkenin tipi belirtilmemiş oldu ve bu yüzden Variant oldu, String değil. Bu nedenle şu şekilde tanımlama yapmalıyız.
                        
                                Dim metin1 as String, metin2 as String
                                'veya daha güvenli olsun isterseniz
                                Dim metin1 as String
                                Dim metin2 as String
                            
                        
                    Option Explicit
Eğer buraya kadar okuduklarınızdan değişkenleri tanımlamanın gerçekten iyi bir fikir olduğunu düşünüyorsanız, bütün modüllerinizin başında Option Explicit ifadesi bulunsun, bu sizi değişkenleri tanımlamaya zorlayacaktır.
                        
                                Option Explicit
                                Sub zorunlu()
                                  mesaj="Merhaba"
                                  MsgBox mesaj
                                End sub 
                            
                        
                    
                        Yukardaki kodu çalıştırdığınızda hata verecektir, çünkü "mesaj" değişkeni tanımlanmamıştır.
                        
Her modülün başına tek tek bu ifadeyi yazmak istemiyorsanız, şu ayarlamayı yapın. VBE içinde Tools>Options düğmesine basın ve aşağıdaki seçeneği işaretleyin.
                    

Değer atama ve Default(Varsayılan) değerler
Değişkenleri tanımladıktan sonra onlara bir de değer atamak gerekir.Değişkenler, değer atanana kadar varsayılan değerlere sahip olurlar. Buna göre;
- Sayısal tipte bir değişken için varsayılan değer 0'dır.
 - Karekter/String tipinde bir değişken için varsayılan değer "" yani sıfır uzunluklu stringtir.
 - Nesne tipinde bir değişken için varsayılan değer ise Nothing'dir.
 
                        Bu konuda daha detaylı ve karşılaştırmalı bilgiye buradan ulaşabilirsiniz.
                        
Şimdiye kadarki örneklerde gördüğünüz üzere sayısal veya karakter tipte bir değişkene değer ataması için = işaretini kullanırız. Ör:
                    
                        
                                i=0
                                ay="Ocak"
                            
                        
                    Bir nesneye(Range, sheet, collection v.s) değer atamak içinse Set ifadesini kullanırız. Ör:
                        
                                Dim hucre As Range
                                Dim ws As Worksheet
                                Set hucre=Range("A1")
                                Set ws=Activesheet
                            
                        
                    Nesne tanımlamalarında, kod bitiminde bu nesneleri tekrar Nothing olarak atamak bellek yönetimi açısından faydalıdır, böylece Excel bu nesneler için bellekte gereksiz yer ayırmayacaktır.
                        
                                Sub Ornek()
                                    Dim hucre as Range
                                    Set hucre = Range("A1")
                                    'Diğer Kodlar
                                    Set hucre = Nothing
                                End Sub
                            
                        
                    Static deyimi ile değişken tanımı
                        Static kavramı biraz daha ileri seviye konularındandır, ancak tek başına ileri seviye konularının arasında sırıtacağı ve anlam bütünlüğü açısından da buraya daha uyduğu için buraya almak durumunda kaldım. Ayrıca ileri seviye terminolojik konuların ele alındığı şu sayfada Global değişkenlerle kıyaslaması da bulunamaktadır.
                        
Bu deyimle tanımlanmış değişkenlere ben zombi değişken diyorum, zira tanımlandıkları prosedür çalışmayı tamamlasa bile yaşamaya devam ederler, ta ki içinde bulundukları workbook kapanana kadar. Bu yüzden bunlara hafızalı değişkenler de denmektedir.
                    
Neden tanımlanır?
                        Dim ifadesi ile tanımladığımız tüm değişkenler ilgili prosedür çalıştırıldıktan sonra bellekten silinir. Ancak bazı durumlarda, tanımladığımız değişkenin prosedür çalıştıktan sonra bile bir önceki değerini tutmasını bekleriz.
                        
Aşağıdaki örnek kodu 3 kez çalıştırdığımızda sırayla şunu görürüz: i:1, j:1, sonra i:1, j:2 ve en son i:1,j:3.
                    
                        
                                Sub statictest()
                                    Dim i As Integer
                                    Static j As Integer
                                    i = i + 1
                                    Debug.Print "i:" & i
                                    j = j + 1
                                    Debug.Print "j:" & j
                                End Sub
                            
                        
                    
                        Aşağıda ise günlük hayat içinden bir örnek var.
                        
UYARI:Bundan sonrasına devam etmeden önce Application.OnTime metodunun öğrenilmesinde veya genel bir fikir edinilmesinde fayda var.
                        
Mesela her 5 dakikada çalışacak şekilde bir ayarlanmış bir prosedür düşünün. Sabah işe geldiğinizde 9:00 gibi çalışmaya başlatıyorsunuz, akşam 18:00'e kadar da 5 dk aralıklarla kendisi Refresh olup çalışıyor. Saat 17:00 olduğunda belli alıcılara bir mail atsın istiyoruz diyelim. Sabah çalıştırma saatimiz her zaman tam net 9:00 olmayacağı için "saat=17:00 mı" diye kontrol edemeyiz. Bunun yerine saat 16'dan büyük mü diye kontrol etmeliyiz. Diyelim ki bir önceki çalıştırma işlemi 16:58:23'te oldu, bir sonraki 17:03:23te olacak, tam bu anda yakalarz, ama bi sonraki de 17:08:23te olacak, yine kontrole takılır ve bu şekilde 12 kez mail gitmiş olur, ki böyle birşey istemeyiz.
                        
İşte böyle bir durumda statik bir değişken tanımlayabiliriz. Aşağıdaki örneğe bakalım. Saat 16'dan büyükse i'yi her defasında 1 artırıyoruz ancak sadece i=1 ise yani ilk kez gidecekse mail gönderimi yapıyoruz.
                    
                        
                                Sub statikornek()
                                Static i As Integer
                                If Hour(Now) > 16 Then 'Bu yapı koşullu karşılaştırma yapmamazı sağlayan IF yapısıdır. Şimdilik bu yapının nasıl kullanıldığını bilmiyor olabilirsiniz, buna takılmayın. Sonraki bölümlerde detaylıca incelenecek.
                                    i = i + 1
                                    If i = 1 Then Call mailproseduru
                                End If
                                Application.OnTime Now + TimeValue("00:05:00"), "statikornek" ' 5 dk sonra kendisini tekrar çalıştırıyor
                                End Sub
                                Sub mailproseduru()
                                  MsgBox "mail gönderimi"
                                  'diğer kodlar
                                End Sub
                            
                        
                    
                        Bu işlemi pek tabiki saatin 17:05:00'ten küçük olup olmadığına bakarak da yapabilirdik ama Static konusunu anlamak adına uygun bir örnek olacağını düşündüm.
                       
 Bu arada bir diğer alternatif de i'nin değerini sayfada boş ve görünmeyen bir hücreye yazıp bunun değerini kontrol etmek olabilirdi ama static değişken kullanmak daha şık bir yöntemdir.
                    
Exceldeki temel veri tiplerini iki gruba ayırabiliriz, sayısal ve sayısal olmayan. Toplamda 14 çeşit temel veri tipi bulunur. Neden bu kadar veri grubu var dersek, birinci sebep kullandıkları hafıza miktarı, ikincisi ise belli işlemlerin sadece belli veri tipleriyle yapılmasını sağlayarak hatalı işlemlerin olmasını engellemek diyebiliriz. Şimdi bunlara yakından bakalım.
Sayısal veri tipleri
| Tip | Alabileceği değerler | Hafıza Kullanımı (Byte) | 
|---|---|---|
| Byte | 0 ile 255 | 1 | 
| Integer | -32.768 ile 32.767 | 2 | 
| Long | -2.147.483.648 ile 2.147.483.648 | 4 | 
| Single | -3.4*10^38 ile 3.4*10^38 (Küsuratlar ihmal edilmiştir) | 4 | 
| Double | -1.7*10^308 ile 1.7*10^308 (Küsuratlar ihmal edilmiştir) | 8 | 
                        Currency diye bir tip daha var ama kariyer hayatım boyunca hiç kullanmadım, o yüzden buraya koymuyorum.
                        
Bunlardan en çok küsurata sahip olanı Double'dır. İhtiyacınıza göre birini kullanırsınız. Aşağıda küsuratları gösteren bir örnek var.
                    
                            
                                Sub tipler()
                                Dim d As Double, s As Single, c As Currency, l As Long, i As Integer, t As Byte
                                a = 9
                                b = 7
                                d = b / a
                                s = b / a
                                c = b / a
                                l = b / a
                                i = b / a
                                t = b / a
                                Debug.Print d, s, c, l, i, t 'sırasıyla 0,777777777777778 0,7777778 0,7778 1 1 1
                                End Sub
                            
                        
                    Bir de Decimal diye bir tip var, bu en yüksek küsurat duyarlığına sahip veri tipidir. Ancak bunun kullanımı biraz daha alengirli, o yüzden burada detaya girmiycem, zaten bunu da Currency tipi gibi kariyer hayatım boyunca kullanma ihtiyacım hiç olmadı.
Sayısal olmayan tipler
| Tip | Alabileceği değerler | Hafıza Kullanımı (Byte) | 
|---|---|---|
| String(sabit boyutlu) | Max 65400 karakter | sabit boyut | 
| String(değişken boyutlu) | Max 2 milyar karakter | 10+karakter sayısı | 
| Date | Makul bir tarih girin yeter | 8 | 
| Boolean | True ve False | 2 | 
| Object | Çok çeşitli(Ör:Range, Workbook, Collection) | 4 | 
| Variant(Varsayılan veri tipi) | Herşey olabilir | 16 | 
Burada String biraz enteresan görünüyor. Bununla ilgili bir örnek yapalım:
                            
                                Dim isim As String 'Boyut belirtmediğimiz için değişken boyutludur
                                isim="Volkan" 'şuan 6 karakter içerir+10=16 Byte
                                isim="Mustafa Kemal" 'şuan 13 kara
                            
                        
                    
                        Şimdi diyebilirsiniz ki, Variant tipi 16 Byte tutuyor, değişken boyutlu String'i neden kullanalım ki, yukardaki örnekte 23 Byte oldu. Variant'ın 16 Byte tutma olayı, ilk tanımlama anındadır. Sonrasında, içersindeki değişkenin tipine göre boyutu artabilir.
                        
Devam edelim, şimdi de sabit boyutlu String nasıl tanımlanır ona bakalım.
                    
                            
                                Dim isim as String*15
                                isim="Volkan" 'Hafızada şöyle tutulur "Volkan         " '15i tamamlayacak kadar boşluk eklenir
                            
                        
                    Temel olmayan veri tipleri
Bu yukarıdaki temel veri tipleri dışında Range, Collection, Worksheet gibi çeşitli class(sınıf)lardan üretilen nesneler var, o yüzden bunlar da veri tipi olarak düşünülebilir. Dim hucre As Range ifadesinde olduğu gibi. Bunun dışında ileri VBA sayfalarında göreceğimiz gibi kendi tanımladığımız sınıfları da veri tipi olarak düşünebiliriz. Mesela Student diye bir class tanımladıysanız Dim st As Student şeklinde bir değişken tanımlayabilirsiniz.
Enumeration/Constant
                        Bazı sabitler vardır ki bunlar Excel açılır açılmaz yüklenirler ve kullanıma hazırdırlar. Bunların kimisinin kullanımı faydalı iken kimisi zorunludur. Mesela vbNullString boş string amaçlı olarak "" yerine kullanılabilir. Böylece boşuna bellekte yer ayrılmamış olur, zira bu vbNullString zaten o anda bellektedir, yani ilave bellek tüketmez. Ancak mesaj kutularına verilen cevabın evet mi olduğunu anlamak için vbYes sabitini kullanmak zorunludur.
                        
Biz bu sabitlerden 3 çeşitini kullanıyor olacağız.
                    
- vb ile başlayanlar: VBA (kütüphanesinin)library'sinin sabitleri
 - xl ile başlyanlar: Excel library'sinin saibtleri
 - mso ile başlayanlar: Office library'sinin sabitleri
 
                        Bunların bir de numerik karşılıkları vardır, bunlara Enumeration değerleri denir. Örneğin vbYes'in değeri 6'dır. bunların ikisi de kullanılabilir.(NOT:İlerde kodlarınızı VSTO ortamına geçirmek istediğinzde numerik karşılıklarını kullanmanız gerekecektir)
                        
Mesela aşağıdaki kodu yazıp çalışıtığrıdığınızda size bu sabitin sayısal karşılığı olan 65280'i verir.
                    

Ayrıca kendi Enumeration tiplerinizi de oluşturabilirsiniz.
                            
                                Private Enum Bolgeler
                                  Akdeniz '0
                                  Karadeniz '1
                                  Marmara '2
                                  Ege '3
                                  Anadolu '4
                                End Enum
                            
                         
                    