Anasayfa | Akademik Forum | Sizden Gelenler | Sipariş
Menü Açıklamaları
Sorular - Cevaplar
Makaleler
Makrolar
Yerleşik İşlevler
Animasyonlar
Yumurtalar
Fonksiyonlar
MTK Programlar
ExcelCE
Dosya İndir
Neler Yaptık?
İletişim
Makaleler
Programlamanın Bel Kemiği: DÖNGÜLER - 3
M. Temel Korkmaz - 01.12.2001

Geçen iki ay For-Next ve For-Each-Next döngüleri üzerinde detaylı olarak durduk. İnanıyorum ki, yeterli örnekler yaptınız, uyguladınız ve bu iki önemli konuyu hazmettiniz. Bu ay sıra geri kalan diğer döngülere geldi. Her nedense bu diğer döngüler bir türlü sevilmiyor. Bu ayki yazımızı da dikkatle takip ettiğinizde, bu döngülerle de aranızda samimi bir bağ oluşacağından şüphem yok. Öncelikle geri kalan bu döngülerin adlarını açıklayarak konumuza başlayalım.

Do While ……. Loop
Do Loop  …….While
Do Until  ……. Loop
Do Loop  …….Until
GoTo

Birinci döngüden başlayalım anlatmaya.

DO WHILE --- LOOP

Kullanım Şekli:

Do While Koşul
            ………….
            …………. {Komutlar}
            …………
Loop

Do: Yapmak, yap
While: (süre, zaman) oluncaya kadar
Loop: Döngü, çevrim

Bu tür döngülerde asıl anlatım şudur. “Koşul sağlanıncaya kadar aradaki komutları icra et” Bir diğer deyişle, bilgisayar önce Koşul ifadesine bakar, eğer koşul doğru ise arada bulunan komutlar çalıştırılır. Loop satırına gelindiğinde, tekrar Do While satırına dönülür ve koşulun sağlanıp sağlanmadığına bakılır. Eğer koşul yine doğruysa aradaki komutlar çalıştırılır, yok eğer koşul doğrulanmıyorsa Loop satırından sonraki satıra geçilerek döngü sonlandırılır. İşte bu kadar basit. Basit örneklerle olayı tekrar gözden geçirelim.

Örnek 1:
For-Next döngülerinde verdiğimiz bir örneğe benzer bir örnek verelim. Amacımız A1 hücresinden A10 hücresine kadar hücre içeriklerine “ExcelTim” yazdıralım. Bunun için aşağıdaki kodu yazın ve çalıştırın.

Sub DoWhileLoop_01()
    Dim i As Integer
    i = 1
    Do While i <= 10
        Cells(i, 1).Value = "ExcelTim"
        i = i + 1
    Loop
End Sub

Kodu çalıştırdığınızda Şekil-1’deki gibi bir görüntü elde edeceksiniz. Nelerin olduğunu kısaca açıklamadan evvel sık yapılan bir iki hatadan bahsedelim. Olayı tam olarak anlamamış yada kodlamaya yeni başlamış arkadaşlarımızın aklına ilk takılan sorular şöyle oluyor.


Şekil-1:  İlk Do While Loop döngümüzü çalıştırdık

Soru 1: Neden i=1 yazıyoruz da i=0’dan başlamıyoruz?

Güzel bir soruya benzemekle birlikte, meseleyi tam olarak anlamadığınızda bu tür soruların sorulması doğaldır. Unutmayın ki kodlama bloğunu bir bütün olarak düşünmeliyiz. Aksi takdirde sürekli hatalara neden oluruz. Eğer bahsettiğiniz gibi “i” değişkeninin yerine “0” yazmış olsaydınız ve kodu da bu şekilde iken çalıştırsaydınız Şekil-2’deki gibi hata mesajı  ile karşılaşacaktınız.


Şekil-2:  Bu hata mesajını sıfır satırı olmadığı için aldınız.

“i” sayaç değerinin yerine “0” koyalım. Normalde bir problem yok fakat bu tür bir kodlamada Nesne aralıklarına dikkat etmeliyiz. Cells(i, 1).Value = "ExcelTim" ifadesinde i=0 olursa Cells(0, 1).Value = "ExcelTim" olur ki, Çalışma Sayfasında satırlar 1 den başlar, sıfırla başlayan bir satır bulunmadığı için bu tür bir hata ile karşılaşmanız doğal olacaktır.

Soru 2: For-Next döngülerinde, döngü bloğu içersinde sayacı arttırma ihtiyacı duymamıştık burada neden “i=i+1” yazma ihtiyacı duyduk?

Bu da güzel bir soru. Fakat unutmayalım ki, döngü kuralları birbirinde farklıdır. For-Next döngüsünün yapısında sayacın kendisi otomatik olarak arttırılmaktadır. Yani döngü yapısı, kuralı koyanlar tarafından bu şekilde oluşturulmuştur. Ama gerekirse bazen o tip döngülerde de, blok içersinde sayaç değeri arttırılabilir. Bu tür döngülerde sayaç arttırılmaz ise neler olabiliri öğrenmek istiyorsanız bahis konusu olan “i=i+1” satırı silin ve kodu tekrar çalıştırın.

Kodu çalıştırdığınızda neler oldu? Tabi ki, istenmeyen bir durum oluştu. İlk başta i=1 olduğu için ve bu asla değişmediği için A1 hücresine sonsuza kadar “ExcelTim” yazdırmaya başladı. Ta ki, siz kodu durdurana yada bilgisayarınız “Bellek Yetersiz” hatasını verene kadar bu durum devam edecektir.

Örnek 2:
Bu örneğimizde Örnek 1 gibi ancak bu defa sonuçları 1 arttırarak hücreye rakam yazacağız.

Sub DoWhileLoop_02()
    Dim i As Integer
    i = 1
    Do While i <= 10
        Cells(i, 1).Value = i
        i = i + 1
    Loop
End Sub

Kodu çalıştırdığınızda Şekil-3’deki görüntüyü elde edeceksiniz. Başlangıçta 1 değerini alan “i” sayacı 10. döngüde i=10 olacaktır. Loop satırına gelindiğinde tekrar koşula bakılacak. "i” sayacının 10 değerine eşit olduğu görülünce döngü sonlandırılacak aradaki komutlar icra edilmeyecektir.


Şekil-3:  Her hücrede sayı 1 arttırıldı.

Örnek 3:
Do While Loop döngüsü ile ilgili son bir örnek vereceğim. Bu örneği iyi analiz etmenizi istiyorum. Çünkü Excel’i bir veri tabanı olarak kullanmanın en basit yöntemlerinden bir tanesini size anlatacağım. Öncelikle Şekil-4’deki gibi bir tablo hazırlayın.


Şekil-4:  Veritabanı Tablosu

Aşağıdaki kodu yazdıktan sonra Sayfada bulunan düğmeye bu kodu atayın. Daha sonra F1 hücresine İsim Soyisim ve F2 hücresine de ismini yazdığınız kişinin ikametini yazın. Düğmeye tıkladığınızda Sıra numarasının otomatik olarak yazdırıldığını ve diğer hücrelere de gerekli bilgilerin atandığını göreceksiniz.

Sub DoWhileLoop_03()
    Range("A1").Select
    Do While Not IsEmpty(ActiveCell)
        ActiveCell.Offset(1, 0).Select
    Loop
    If IsNumeric(ActiveCell.Offset(-1, 0).Value) = True Then
        ActiveCell.Value = ActiveCell.Offset(-1, 0).Value + 1
    Else
        ActiveCell.Value = 1
    End If
    ActiveCell.Offset(0, 1).Value = Range("F1").Value
    ActiveCell.Offset(0, 2).Value = Range("F2").Value
    Range("F1").Value = ""
    Range("F2").Value = ""
    Range("F1").Select
End Sub


Şekil-5:  VeriTabanı Tablosuna otomatik kayıt girişleri yaptık

Sanıyorum yukarıdaki kodun ne manaya geldiğini bir çok okuyucularımız çözmeye çalışacaklardır. Ben çözemeyecek olan okurlarımız için bu kodların ne manaya geldiğini izah edeyim.

Range("A1").Select

Mutlaka bu hücre başlangıçta seçilmelidir. Çünkü hemen aşağıda gelecek olan Do While Loop döngüsü bu hücrenin bulunduğu sütunu kontrol edecektir.

Do While Not IsEmpty(ActiveCell)

Burada Aktif hücrenin boş olup olmadığı araştırılıyor. Eğer aktif olan hücre boş değil ise aradaki komut icra edilecek. Yok eğer aktif hücre boş ise döngü sonlandırılacak. Burada IsEmpty(ActiveCell) ifadesi ile boş olan hücre kontol ediliyor ama başına gelen “Not” (değil) ifadesi ile bunun tersi alınıyor. Şimdi örneğimize dönelim. İlk satırda A1 hücresi seçildiğine göre Aktif hücre budur. Ve bakıyoruz Aktif hücre dolu yani boş değil. Koşul sağlandığına göre aradaki komut icra edilecek.

ActiveCell.Offset(1, 0).Select

A1 hücresi dolu olduğu için bir alt hücre seçildi. Yani A2 hücresi seçildi. A2 hücresi boş olduğu için ikinci döngüde işlem sonlandırıldı yani döngüden çıkılacak ve Loop’dan sonraki satıra gelinecek.

   
If IsNumeric(ActiveCell.Offset(-1, 0).Value) = True Then
        ActiveCell.Value = ActiveCell.Offset(-1, 0).Value + 1
    Else
        ActiveCell.Value = 1
    End If

Burada bir hata denetimi yapıyoruz. Eğer Aktif olan boş hücrenin bir üzerindeki hücredeki değer nümerik bir değer ise o zaman aktif hücrenin değerini, üzerindeki hücrenin değerinden bir fazla yap. Yok eğer üstteki hücre nümerik değilse o halde ilk veri girişi yapılacağı için Sıra No ya 1 değerini atamak için aktif hücreye 1 değerini yaz.

ActiveCell.Offset(0, 1).Value = Range("F1").Value

Sıra no yazdırdığımız hücrenin bir sağındaki hücreye yani aktif hücrenin 1 sütun sağındaki hücreye F1 hücresindeki isim değerini yazdır.

ActiveCell.Offset(0, 2).Value = Range("F2").Value

Sıra no yazdırılan hücrenin yani aktif hücrenin iki solundaki hücreye F2 hücresinin değerini yazdır.

Range("F1").Value = ""
Range("F2").Value = ""
Range("F1").Select

Kayıt işlemleri bitti. O halde F2 ve F2 hücresinin içeriğini temizle ve F1 hücresini seçili duruma getir ki, yeni veri girişine müsait olsun.

Umarım bu kodu bu kadar uzun anlattığım için bana kızmamışsınızdır. Çünkü ileride bu o kadar çok işinize yarayacak ki.


DO --- LOOP WHILE

Kullanılış Şekli:

Do
      .........
      .........{Komutlar}
      .........
Loop While Koşul

Bu ifadeyi de şu şekilde tercüme edebiliriz. “Aradaki komutları yap. Ta ki Koşul sağlanıncaya kadar.”

Bu döngü türünde de, koşul ifadesi Doğru (True) olduğu sürece devam eder. Koşul ifadesi Yanlış (False) olduğu zaman döngü sona erer. Diğerinden tek farkı, bu döngüde Koşul döngü sonunda kontrol edilir. Dolayısı ile bu da aralarında bariz olan şu farkı oluşturur.

Do Wihile.......Loop döngüsünde şart koşul sağlanmadığında döngü hiçbir defa çalıştırılmadan sona erer. Oysa bu türde döngü koşulu sonda olduğundan bir defalıkta olsa mutlaka çalıştırılır.

Sub DoLoopWhile()
    Dim i As Integer
    i = 1
    Do
        Cells(i, 1).Value = i
        i = i + 1
   Loop While i <= 10
End Sub

Kodu çalıştırdığınızda Şekil-1’deki görüntünün aynısını elde edeceksiniz.

Aşağıdaki örnekte ise faktöriyel hesabı yapılmaktadır.

Sub DoLoopWhile()
    Fakt = 1
    i = 1
    Do
        Fakt = Fakt * i
        Cells(i, 1).Value = Fakt
        i = i + 1
    Loop While i <= 10
End Sub

Yukarıdaki kodu çalıştırdığınızda Şekil-6’daki görüntüyü elde edeceksiniz.


Şekil-6:  Bir Faktöriyel hesabı


DO UNTIL........LOOP


Kullanılış Şekli:

Do Until Koşul
          .........
          .........[Komutlar]
          .........
Loop

Bu tip döngüde de, önce Koşula bakılır. Eğer koşul Yanlış (False) ise aradaki Komut satırları çalıştırılır. Loop satırına gelindiğinde tekrar başa dönülür ve Koşul kontrol edilir. Bu işlem koşulun Doğru (True) olmasına kadar devam eder. Bu komut için Do While........Loop döngüsünün tersidir diyebiliriz.

Sub DoUntilLoop()
    Dim i As Integer
    i = 1
    Do Until i > 10
        Cells(i, 1).Value = i
        i = i + 1
    Loop
End Sub

Bu örnek yukarıda anlattığımız Do While......Loop örneğinin benzeridir. Burada sadece koşul satırı olan

           
Do Until i > 10          

satırında “i” nin 10’dan büyük olması koşulu değiştirilmiştir. Diğerinden 10’dan küçük veya eşit idi. Şimdi kodu çalıştırdığınızda Şekil-1’deki görüntü ile karşılaşacaksınız.


DO........LOOP UNTIL

Kullanılış Şekli:

            Do
                        .........
                        .........[Komutlar]
                        .........
            Loop Until Koşul

Bu döngü bir önceki döngünün benzeridir. Tek fark koşulun sonda bulunmasıdır. Bu da, her ne olursa olsun komut bir defaya mahsus mutlaka çalışacaktır.

Sub DoLoopUntil()
    Dim i As Integer
    i = 1
     Do
        Cells(i, 1).Value = i
        i = i + 1
    Loop Until i > 10
End Sub

Kodu çalıştırdığınızda Do Until......Loop komutunun çalıştırıldığı zaman elde edilen sonucun aynısı elde edilecektir. Şekil-1’deki görüntüyü elde edeceksiniz.

GOTO

Bu tip bir döngüye koşulsuz, döngü adını verebiliriz. Şartlar ve koşullar ne olursa olsun, çalışan komut satırı bu döngünün bulunduğu satıra geldiğinde GoTo deyimin gidilmesini istediği satıra gidilir.

Sub DonguGoTo()
    Dim i As Integer
    i = InputBox("1-100 arasında bir sayı giriniz")
    GoTo topla
topla:
     i = i + 20
    MsgBox "Girdiğiniz sayının 20 fazlası:" & i
End Sub

Hazırladığımız bu makroyu çalıştırdığınızda  sırasıyla aşağıdaki görüntüleri alacaksınız. (Şekil-7 ve Şekil-8)


Şekil-7


Bu bir InputBox penceresidir. Yani bilgi girişi yapılacak penceredir. İlgili bölümde yeterince bilgi edinebilirsiniz. Klavyeden istediğiniz bir sayı girin ve Ok düğmesine tıklayın. Biz 50 değerini girdik.


Şekil-8


Bu tip basit bir örnek vermemizin sebebi GoTo deyiminin anlaşılabilmesi içindir.

InputBox’a değeri girip Ok tuşuna tıkladığınızda “GoTo topla” satırı çalışacaktır. Bu arada “topla:” satırı neredeyse bilgisayar o satıra gidecek ve komutları çalıştırmaya oradan devam edecektir. Eğer GoTo deyiminin bulunduğu satır ile sizi gönderdiği satır arasında başka komut satırları varsa ve bu satırlara sizi ulaştıracak başka bir komut verilmemişse, aradaki komutlar hiç dikkate alınmayacaktır.

Aşağıdaki kodu inceleyelim.

Sub DonguGoTo()
    Dim i As Integer
    i = InputBox("Bir sayı giriniz")
    GoTo topla
    Range("A1").Value = "Muhammed"
topla:
     i = i + 20
    MsgBox "Girdiğiniz sayının 20 fazlası:" & i
End Sub

İlk verdiğimiz koddan farklı olarak, GoTo deyimi ile bu deyimin gönderdiği “topla” işlem başlangıcı arasında

Range("A1").Value = "Muhammed"

komut satırı bulunmaktadır. Kodu çalıştırdığınızda, bilgisayar, direk olarak GoTo satırından “topla” satırına geçtiği için A1 hücresine “Muhammed” yazdırmıyor.

Bu arada dikkat edilmesi gereken önemli bir nokta var. GoTo satırının sizi gönderdiği işlem başlangıcı olan satırda, işlem başlangıcı adının sonunda “:” iki nokta üst üste olmasıdır. Eğer bunu yazmazsanız. Bilgisayar size Şekil-9’daki uyarıyı verecektir.


Şekil-9


Compile error                       : Derleme Hatası
Sub or Function not defined   : Sub veya Fonksiyon tanımlı değil.

Bunun nedeni basit, bu örnek için konuşacak olursak; burada “topla” ifadesine herhangi bir belirteç koyulmazsa bilgisayar bu satıra geldiğinde; “Bu da nedir? Ben bunu tanımıyorum” der.

Bu ayki konu anlatımımızda burada sona erdi. Şimdi birkaç örnek verelim. Yine örneklerimiz değişik sitelerden derlenmiş olabilir. Eğer İngilizce tanımlar varsa değişik sitelerden sizler için derlediğim örnekler var demektir. Türkçe ise sizin için benim hazırladığım örnekler bulunuyor demektir.

Örnek Kodlar:

Örnek 1:
InputBox’a girdiğiniz karakteri kontrol eden bir kod. İnceleyiniz.

Sub MyTestArray()
    Dim myCrit(1 To 4) As String
   
Dim Response As String
    Dim i As Integer
    Dim myFlag As Boolean

   
myFlag = False
    myCrit(1) = "A"
    myCrit(2) = "B"
    myCrit(3) = "C"
    myCrit(4) = "D"   

   
Do Until myFlag = True
    Response = InputBox("Please enter your choice: (i.e. A,B,C or D)")
       
For i = 1 To 4 
            If UCase(Response) = UCase(myCrit(i)) Then
                myFlag = True: Exit For
            End If
        Next i
    Loop
End Sub

Örnek 2:

Eğer hücre dolu ise hücre değerini mesaj kutusunda verecek ve sonra bir alttaki hücreye geçerek o hücrenin değerini de mesaj kutusunda verecek. Ta ki, bu işlem boş hücreye gelene dek devam edecek.

Sub DoluHucreTesti()
    If IsEmpty(ActiveCell) Then Exit Sub
    Do Until IsEmpty(ActiveCell)
        MsgBox ActiveCell.Value
        ActiveCell.Offset(1, 0).Select
    Loop
End Sub

Örnek 3:

Bu örnek ile Örnek 2 aynı işlemi yapar. Bu defa GoTo kullanılmıştır.

Sub DuluHucreTesti()
    If IsEmpty(ActiveCell) Then Exit Sub
top:
    MsgBox ActiveCell.Value
    ActiveCell.Offset(1, 0).Select
    If Not IsEmpty(ActiveCell) Then GoTo top
End Sub

Örnek 4:

Belirlediğiniz Klasördeki XLS dosyalarını sıralar.

Sub sirala()
    Dim i As Integer
    Dim Dosya As String
    Dosya = Dir("C:\Belgelerim\*.XLS")
    i = 1
    Do Until Dosya = ""
        Cells(i, 1) = Dosya
        Dosya = Dir
        i = i + 1
    Loop
End Sub

Örnek 5:

Bu örnekte ise inputbox’a peş peşe kaç adet değer girdiniz ve bu değerlerin toplamı nedir? i mesajbox’da veren bir kod.

Sub GirileniToplar()
   deger = Val(InputBox("Sıfırdan farklı değer giriniz"))
   sayac = 0
   Topla = 0
   While deger > 0
     Topla = Topla + deger
     sayac = sayac + 1
     deger = Val(InputBox("sonraki deger"))
   Wend
   MsgBox ("Toplanan Adet: " & sayac & " Toplam Değer: " & Topla)
End Sub

Burada anlatmadığımız Wend örnek olarak verilmiştir. Önümüzdeki ay yerimiz kalırsa kısaca bu döngüye de yer vereceğiz.

Örnek 6:
Bu örnekte iki aşama kaydedeceğiz. Öncelikle aşağıdaki kodu yazın.

Sub HucreyeYazdir()
   Do
     Range("A1") = Range("A1") + 1
   Loop
End Sub

Siz kodu durdurana kadar A1 hücresi 1 artarak sonsuza kadar devam edecektir. Oysa kodu aşağıdaki gibi değiştirdiğimizde istediğimiz sayıya kadar arttırıldığını göreceksiniz.

Sub HucreyeYazdir()
   Do
     Range("A1") = Range("A1") + 1
     If Range("A1") = 50 Then Exit Do
   Loop
End Sub

Burada da biraz daha farklı bir döngü örneği görmekteyiz. Siz de fark ettiniz ki, aslında bütün döngüler mantık olarak aynı temele oturmuşlardır.

Destek
M.ÖZTÜRK - Y.KARAMAN
Bu siteyi, "Hayatını çocuklarının Ahlâklı ve Dürüst yetişmesi için harcamış olan Cefakar ve Fedakar, Canım ANNEM'e adadım."
Copyright © 1998-2011 M. Temel Korkmaz - Tüm hakları saklıdır.