If'li Koşul Yapıları

Programlamanın temel taşlarından biri koşullu yapılarsa, koşullu yapıların temeli de IF bloklarıdır. Birçok programlama dilinde de zaten bu yapı kullanılır, sadece syntaxı farklı olabilmektedir.
Genel yapı şu şekildedir: If....Then .... Tabi bu yapı farklı görünümler kazanabilmektedir. Hepsine tek tek bakalım, sonra da örnekleri verelim.

Kullanım şekli
Kullanım şekli Syntax
Tek satırda yazım(kısa bir işlem yaptıracaksak) If isim="Volkan" Then Goto devam
Tekli if bloğu. Birden fazla işlem yaptıracaksak If-End If bloğu arasında yazılır. If isim="Volkan" Then
   MsgBox "merhaba volkan"
   Goto devam
End If
Çoklu if bloğu: Eğer şöyleyse şunu yap yok değilse bunu yap, diğer durumlarda ise şunu yap. If isim="Volkan" Then
   MsgBox "Merhaba volkan"
ElseIf isim="Serkan" Then
   MsgBox "Merhaba serkan"
Else
   MsgBox "Merhaba değerli insan"
End If
İç içe If: Eğer şöyleyse, ve yine eğer böyleyse şunları yap If isim="Volkan" Then
  If şehir="İstanbul Then
   MsgBox "merhaba istanbullu volkan"
  Else
   MsgBox "merhaba anadolulu volkan"
   End If
Else
   MsgBox "merhaba değerli insan"
End If 
IIF(tek satırda pratik değer atama) YasDurum=IIF(yas<18;"Çocuk";Yetişkin")

Şimdi hemen küçük bir örnek yapalım:

							
								Sub basitif()
									Dim segment As integer
									Dim segmentAd as String

									segment=Application.Inputbox("Segment kodunu girin",Type:=1)

									If segment= 1 Then
										segmentAd = "Bireysel"
									Else
										segmentAd = "Tüzel"
									End If

									MsgBox "Müşteri " & segmentAd & " segmenttedir"
								End Sub

							
						
Operatörler

Temel operatörler şunlardır: eşitlik(=), eşit olmama(<>), büyük ve büyükeşit(>,>=) ile küçük ve küçükeşit(<,<=)
Bunlardan başka ne tür operatörler olduğunu aşağıda göreceğiz.

Boolean değişkenler ve If blokları

"If X=4" mü diye bir sorgulama yaparken aslında X=4 sonucu True mu False mu(doğru mu yanlış mı) şeklinde bir sorgulama yapmış oluyoruz. Aksi belirtilmedikçe tüm sorgulamalarda sonucun True mu olduğunu sorgulamış oluruz, ve True ise Then ifadesinden sonraki kısım işletilir.
If bloklarında False sorgulaması da yapılabilir, bunun için açıkça If x= False diye sormak gerekir, tabi x'in boolean tipinde olması kaydıyla. Böylece ifadenin False olması durumunda da Then'den sonraki kısmın işletilmesi sağlanabilir. Unutulmamalıdır ki yaratılmış ancak henüz değer atanmamış Boolean değişkenlerin değeri False'tur. Bazen bu bilgi çok kullanışlı olmaktadır. Bi örnek yapalım: Kullanıcıdan ismini girmesini isteriz ve bu ismi, arasında ";" olacak şekilde 10 kere yazdırmak istiyoruz diyelim. Şimdi ilk başta hatalı bir kod yazalım. Bu kodda en başta da istenmeyen bir ";" olacak.

							
								Sub booleanif1()

								isim = InputBox("İsminizi girin")

								For i = 1 To 10
								   kelime = kelime + ";" + isim
								Next i

								MsgBox kelime
								End Sub

							
						

Gördüğümüz gibi en baştaki ; fazladan oldu.

post-thumb

Ancak kodumuzda aşağıdaki gibi False sorgulamasını yaparsak istediğimizi elde ederiz.

						
								Sub booleanif1()
								Dim ilkDegerAtandımı As Boolean

								isim = InputBox("İsminizi girin")

								For i = 1 To 10
									If ilkDegerAtandımı = False Then 'İlk etapta Falsetur, ve false ise bu kısım işletilir
									   kelime = isim
									Else
									   kelime = kelime + ";" + isim
									End If

									ilkDegerAtandımı = True 'False'tan True'ya ilk geçişi burada yapıyoruz, sonrasında zaten 9 kez zaten True olan değere True atamış olacak
								Next i

								MsgBox kelime
								End Sub

							
						
post-thumb

Başka bir örnek daha yapalım, bunu Interaktivite bölümünde de görmüştük, kullanıcı InputBoxa giriş yapmadan çıkarsa bunu yakalayalım. Detay için buraya bakınız.

						
								Sub booleanif2()

								a = Application.InputBox("Yaşınızı girin", Type:=1)
								If a = False Then 'Variant her değeri alabileceği için False ifadesi aynen yazılır
								  MsgBox "Bir giriş yapılmadan çıkmayı tercih ettiniz"
								  'Diğer kodlar buraya
								Else
								  MsgBox "Giriş yapıldı"
								End If

								End Sub

							
						

NOT:Boolean ifadelerde True sorgulaması yaparken "=True" yazmaya gerek yoktur, o yüzden içinde = operatörü olmayan bir sorgulama şekli gördüğünüzde şaşırmayın. Aşağıda bir örnek var.

						
								Sub yaskontrol()
								Dim yas As Integer
								Dim resitmi As Boolean

								yas = Application.InputBox("yaşınızı girin", Type:=1)

								If yas >= 18 Then resitmi = True 'else durumunda False atamaya gerek yok hiçbir atama olmaz, atanmamaış boolenalar da default değeri yani false değeirini alır

								If resitmi Then '=True yazmadık, yazabilirdik de.
								   MsgBox "reşitsin"
								Else
								   MsgBox "reşit değilsin"
								End If

								End Sub

							
						

Bu yöntemi sadece değişkenlerle değil Booelan tipli dönüşü olan fonksiyon veya propertylerle de kullanabiliriz.

						
								If Application.DisplayAlerts Then '=True yazmamama gerek yok çünkü DisplayAlerts propertysi Booelan döndürür
								'kodlar
								End If

							
						
Mantıksal kontroller

If ile birlikte kullanılan bazı built-in kontrol yapıları vardır. Yani =, <,> ve is operatörlerinden başka bir de bu ifadelerle kontrol sağlanır, ki bunlar da aslında Boolean sorgulama şekilleridir.

  • IsEmpty:(Variant tipli) değişken boşmu, yani henüz bir değer atanmadı mı? Veya bir hücrenin içi boş mu?
  • IsDate:Değişken, tarihsel bir değişken mi? Pratikte, Inputboxa girilen bir tarihin doğru formatta girilip girilmediğini kontrol etmek için kullanılır.
  • IsNumeric:Değişken sayısal mı? Inputboxa sayısal girilmesi gereken bir verinin doğru girilip girilmediğini kontrol amaçlı kullanılabildiği gibi, bir hücredeki verinin sayısal veri içerip içermediğini kontrol etmek için de kullanılır. Gerçi Inputboxı Application.Inputbox şeklinde kullanıp bir de veritipi olarak 1 seçersek zaten kullanıcıyı otomatikman sayısal girmeye zorlamış oluruz ama normal Inputboxla sorulduğunda bunu kontrol amaçlı kullanabilirsiniz.
  • IsNull:Değişken, bir veri içeriyor mu?

Bütün bunları Not operatör ile ters mantıkta sorgulayabilirsiniz. Bu konuyu bir alt bölümde göreceğiz.
Çeşitli örnekler:

						
								1.Örnek
								'bulunduğunuz yerden ilk dolu hücreye kadar olan tüm boş hücreleri silmek için
								'tabi bu örneği bir döngü içinde yapmak daha şık olurdu ancak burda örnek vermek
								'adına If ve GoTo ile yapılmıştır
								bas:
								If IsEmpty(ActiveCell) Then
								   ActiveCell.EntireRow.Delete
								   ActiveCell.Offset(1,0).Select
								   GoTo bas
								End If

							
						
						
								2.Örnek
								'Be'Belli bir anda aktif hücrenin değerinin sayısal olmaması durumunda programı durduruyoruz
								If IsNumeric(ActiveCell.Value) Then Exit Subre>

							
						
If Not

Bazen bir kodu günlük konuşma dilinde olduğu gibi önce negatifini sorgulayarak yazmak isteyebiliriz. X=y değilse şu kod çalışsın. Biraz kötü bir örnek olacak ama mesela aşağıdaki kodda, sadece 18 yaşından küçükler için çalışacak bir kod yazmış oluyoruz.

						
								'Öncül kodlar
								If Not Yaş>18 Then
								'işletilecek kod
								End If

								'diğer kodlar

							
						

Kötü bir örnek dedik çünkü burda if Yaş<=18 diye yazsaydık daha az kodla yazılmış olurdu. Evet olurdu, ancak bazen öyle durumlar olacak ki günlük konuşma diline göre kod yazmak size daha rahat gelecek ve negatifi sorgulamak da daha mantıklı olacaktır.
Şimdi mybooelan adına bir Boolean tipli değişkeniniz olsun. Bu durumda If Not myboolean yazmak ile If mybooolean=False yazmak arasında bir fark yok gibi görünebilir ancak hem konuşma diline yakınlığı dolayısıyla anlaşılırlığı hem de performans açısından Not'lı versiyon biraz daha öndedir. Çünkü önce mybooleanını ne olduğunu hesaplıyor, bu 1; sonra bunun False mu olduğuna bakıyor, bu da 2. Halbuki Not diyince sadece 1 değerlendirme işlemi yapmış oluyorsunuz. Ancak bu performans farkı o kadar da büyük bir fark değil. Bu konu, daha çok okunaklılık ve kişisel tercihle alakalıdır.
Not yöntemi pratikte en çok Boolean karşılaştırmalarda kullanılır ve özellikle de Booelan değer dönüren bir fonksiyonu sonucu ile. Mesela DosyaMevcutmu diye bir fonksiyonunuz olsun, eğer mevcutsa True, değilse False döndürüyor olsun. Hergün saat 12de bir dosyanın oluşup oluşmadığına bakan scheduled bir kodunuz olsun. Eğer dosya henüz oluşmamışsa kullanıcılara mail atmadan çıksın, oluştuysa mail atsın.

						
								If Not DosyaMevcutmu(dosyadı) Then
								   Exit Sub
								Else
								   'uzunca bir mail atma kodu
								End If

							
						

Şimdi yine bir itiraz gelebilir, bu örnekte de aslında Not kullanmasak olabilir, ilk başa DosyaMevcutmu diye yazar mail işlemini Else öncesine koyabilir, Exit Sub'ı da Else sonrasına. Ancak gördüğünüz gibi mail işemi oldukça uzun olabilir, mesela 50 satır. Böyle bir durumda ilk bloğa daha kısa olan kodu koymak daha mantıklı ve okunaklıdır. Böylece dosya oluşmadıysa ne yapılacağını çok net görebilyorum, ancak başa dosya oluşma durumunu koyup Else'den sonra oluşmama durumuu koysaydık Else'den sonra ne olduğunu görmek için scrollbarı aşağı indirmek gerekecekti. Küçük bir detay ama bu tür pratiklikler size hep zaman kazandırır. Zaten makroların amacı da bu değil mi, bize her anlamda zaman kazandırmak. O yüzden kodlarımızı düzenlerken en okunaklı, bi zaman sonra tekrar içine baktığınıza anlaması en kısa sürecek şekilde düzenlemekte fayda var. Bu arada bu kod da pek tabiki Not DosyaMevcutmu yerine DosyaMevcutmu =False şeklinde yapılabilirdi ama yine okunurluk açısından Not'lı halini gündelik dile daha çok benzetiyorum. Tercih sizin.

Mantıksal fonksiyonlarla Not kullanımı

Yine mantıksal fonksiyonların ters sorgulaması yapıldığında False ile sorgulamak yerine gündelik dile daha yakın olması açsıından Not ile sorgularız. Ör:Kullanıcının boş mu dolu mu bir hücre seçtiğini kontrol edecek bir kod yazalım.

						
								tekrar:
								Set alan=Application.InputBox("Hücre seçin", Type:=8)

								If Not IsEmpty(alan) Then 'boş değilse. If IsEmpty(alan)=False de olur ama biraz garip görünür
									'işletilecek kodlar
								Else
									MsgBox "Boş bir hücre seçtiniz, lütfen dolu bir hücre seçin"
									GoTo tekrar
								End If

							
						
Nothing ve Not

Bir de Not'ın tamamen zorunlu olduğu bir durum var ki, o da Nothing ile birlikte kullanım şeklidir. Genel Syntax şöyledir: If Not nesne Is Nothing. Burada nesne Object tipindeki herşey olabilir. Range, Worksheet, Outlook application v.s. Kelime kelime tercümesi "nesne hiçlik değilse" şeklinde yapılabilecek olan bu cümlecik aslında "nesne birşeyse, yani birşey atanmışsa veya henüz boşaltılmadıysa" anlamında daha Türkçe olarak yorumlanabilir. Ancak VBA'da "Birşey" yani Something diye bir ifade olmadığı için bunun zıddı olan "Not Nothing" şeklinde yazılır.
Mesela Worksheet olayları bölümünde sıkça kullanacağımız bir Intersect metodu var. Worksheet değiştiğinde eğer değişen hücreler belli bir aralıkta mı diye kontrol ederiz, işte burda Not ve Nothing kombinasyonu kullaırlır.
Ör: If Not Intersect(Target, Range("C3:C4")) Is Nothing Then aslında şu demektir: If Intersect(Target, Range("C3:C4")) Is Something Then, yani değişen hücre(Target) C3:C4 alanı ile kesişim kümesindeyse, yani kesişim kümesi boşküme değilse, yani "birşeyse". Worksheet olaylarında daha detaylı örnekler için buraya tıklayınız.
Aşağıda da 3 değişkenden 2sine değer atanma durumu sözkonusu, idğer açıklamalar commentlerde bulunuyor.

						
								Sub ifnotnothing()

								Dim hucre As Range
								Dim ws As Worksheet
								Dim wb As Workbook

								Set hucre = ActiveCell
								Set ws = ActiveSheet

								If hucre Is Nothing Then 'if not nothing, hücrenin boş olup olmadığını sorgulamak değildir.
								'hucre değişkenine bir değer atanıp atanmadığnı sorgulamaktır. boş olup olmadığı IsEmpty ile sorgulanır
									Debug.Print "hucre değişkenine atama yapılmamış"
								Else
									Debug.Print "hucre değişkenine atama yapılmış"
								End If

								If Not ws Is Nothing Then 'if ws is something yani birşey ise
									Debug.Print "ws değişkenine atama yapılmış"
								Else
									Debug.Print "ws değişkenine atama yapılmamış"
								End If

								'sadece sometinh olma durumunda çalışacak kod bloğu
								If Not wb Is Nothing Then 'if wb is something yani birşey ise
									Debug.Print "buraya girmeyecek"
								End If
								End Sub

							
						
Koşulu terse çevirme

Bu arada boolean tipli özellikleri tersine çevirmek için o özelliğin mevcut durumunu öğrenmek amacıyla If yapısını kullanmaya gerek yoktur; Not operatörü ile doğrudan tersine çevirilebilir. Mesela sayfadaki gridler açıkken kapatan, kapalıyken açan(bu işlemlere toggle işlemleri denir) bir buton yapıp quickaccessbara ekleyebilrisiniz.
If'li kod şöyle olacaktır.

						
								Sub grid_toggle()
								If ActiveWindow.DisplayGridlines Then 'Dikkat ettiyeniz =True yazmadım, yazsam da bişey farketmeyecekti
								   ActiveWindow.DisplayGridlines=False
								Else
								   ActiveWindow.DisplayGridlines=True
								End If
								End Sub

							
						

Onun yerine basitçe şöyle de yazabilirsiniz:

						
								Sub grid_toggle()
								  ActiveWindow.DisplayGridlines = Not ActiveWindow.DisplayGridlines
								End Sub

							
						

Tabiki, bunu yapabilmeniz için ilgli propertynin(özelliğin) hem okunabilir hem yazılabilir(Returns and Sets) karakterde olması lazım.

İçiçe If ve Bağlaçlar(Birden fazla koşul sorgulama)

Birden fazla koşulu sorgulamak için içiçe birkaç IF bloğu yazılabilir. Ör: Açılış Tarihi bu yıldan önce olan şubelerden sadece Bireysel Şube sayısını öğreneceğimiz bir kod yazalım.

						
								If Subeaçılıştarihi< Year(Now) Then
								   If tip="Bireysel" Then
									  'işletilecek kodlar
								   End If
								End If

							
						

Bunu yapmanını bir diğer yolu da And bağlacını kullanmak olacaktır.

						
								If Subeaçılıştarihi< Year(Now) And tip="Bireysel" Then
									  'işletilecek kodlar
								End If

							
						

And kullanmak sanki daha mantıklı gibi ama ikinci koşuldan önce ara bir işlem yapmak isterseniz içiçe IF kullanmanız gerekir.

						
								If Subeaçılıştarihi
						

Koşul yapısı Veya şeklinde olacaksa da Or kullanılır. Ör: Şube tipi bireysel veya Karma ise şunları yap gibi.

						
								If tip="Bireysel" or tip="Karma" Then
									'işletilecek kodlar
								End If

							
						
Çoklu If bloğu vs Ayrı If blokları

Bazen öyle anlar gelir ki, konuşma dilinde söylediğimiz şey sanki çoklu if kullanmamız gerektiğini ima eder, ancak yapılması gereken işlem ayrı if blokları kullanmak olabilir. Hemen bir örnek yapalım.
Diyelim ki, bir schedule prosedürünüz var ve Excel açılır açılmaz devreye giriyor.(Scheduling işlemleri için buraya bakınız). O an saat 08:01den büyükse A makrosu, 08:11'den büyükse B makrosu v.s çalışsın istiyorsunuz. Söylerken kulağa çoklu if kullanılacakmış gibi geliyor ancak öyle yaptığımız durumda ilk koşul gerçekleşince kalanı işletilmez. Aslında burda düşüncemizi dile getirme şeklimiz de hatalı olabilir. O yüzden düşündüğümüz şeyi kelimelere daha doğru dökelim: A makrosu, o an saat 08:01'den büyükse çalışsın, B makrosu saat 08:11'den büyükse çalışsın v.s. Küçük bir nüans var, farkedebilidiniz mi? Evet, önce makronun adını sonra zamanı dile getirdik.
İlk versiyona göre kodumuzu şöyle hazırlardık ve hatalı bir işlem yapmış olurduk:

						
								If TimeValue(Now) > TimeValue("08:01:00") Then
									Application.OnTime Now + TimeValue("00:02:00"), Procedure:="pyskontrol"
								ElseIf TimeValue(Now) > TimeValue("08:11:00") Then
									Application.OnTime Now + TimeValue("00:02:30"), Procedure:="nrkontrol"
								ElseIf TimeValue(Now) > TimeValue("08:21:00") Then
									Application.OnTime Now + TimeValue("00:03:00"), Procedure:="pdmkontrol"
								ElseIf TimeValue(Now) > TimeValue("08:31:00") Then
									Application.OnTime Now + TimeValue("00:04:00"), Procedure:="pargkontrol"
								End If

							
						

Doğru kod aşağıdaki gibi olacaktır.

							
								If TimeValue(Now) > TimeValue("08:01:00") Then
									Application.OnTime Now + TimeValue("00:02:00"), Procedure:="pyskontrol"
								End If

								If TimeValue(Now) > TimeValue("08:11:00") Then
									Application.OnTime Now + TimeValue("00:02:30"), Procedure:="nrkontrol"
								End If

								If TimeValue(Now) > TimeValue("08:21:00") Then
									Application.OnTime Now + TimeValue("00:03:00"), Procedure:="pdmkontrol"
								End If

								If TimeValue(Now) > TimeValue("08:31:00") Then
									Application.OnTime Now + TimeValue("00:04:00"), Procedure:="pargkontrol"
								End If 

							
						
IIf

Bir değişkene, bir koşul sonucuna bakarak bir değer atamak istiyorsanız IIf yapısı çok kulanışlıdır ve kullanımı oldukça basittir.
Aşağıdaki kodda, segment kodu 1 ise Bireysel değilse Tüzel şeklinde bir atama yapılmaktadır.

						
								Segment=IIf(segmentkodu=1,"Bireysel","Tüzel")