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 - 1
M. Temel Korkmaz - 01.10.2001
Son iki aydır TXT dosyaları ve Dosyalama Fonksiyonları ile ilgili detaylı bilgiler verdik. Bu ay biraz daha değişik ve farklı konulara değinmek ihtiyacını hissettik.

Hemen hemen bütün programların bel kemiği niteliğinde olan bazı konular vardır. Bunlar programların olmazsa olmazlarıdır. Bunlardan bir kaçını zikredecek olursak, For-Next Döngüleri, For-Each-Next Döngüleri, Do While-Loop Döngüleri, If-Else Şartları, Select-Case Şartlarını sayabiliriz. En az bir programlama dili bilen bazı okuyucularımızın “Yapmayın Hocam, siz demi? Siz de mi her yerde sürekli karşılaştığımız bu konuları anlatacaksınız? İnanın sıkıldık artık” dediğini duyar gibi oluyoruz. Hani bu arkadaşlarımıza hak vermemek elde değil. Kim bir programcılık hakkında basit bir yazı yazsa (sözümüz meclisten dışarı, sakın herkes üzerine alınmasın yada bazı yazarlarımız) dolgu malzemesi olarak bu konular anlatılır. Fakat ne yazık ki, bir çok okuyucu, bu anlatılanların %70 kadarını anlamamaktadır. Doğrusunu isterseniz ilk programcılığı öğrenmeye çalıştığımızda (üniversite birinci sınıfta Basic ve Pascal dersleri almıştık işte o zamanlardan bahsediyorum) ya bizim dikkatsizliğimizden yada anlatan şahısların seviyeyi düşürüp bir türlü dinleyenlerin düzeyinde anlatamamasından veyahut da hakikaten bu konuların gerçekten bazılarının anlaşılmasının kolay olmadığından olsa gerek, bir türlü anlayamadığımız konular oluyordu. Bunların başını sürekli karşılaşılan For-Next döngüsü sonra onun ardından gelen Do While-Loop döngüleriydi. İnanın ben uzun zamanlar bunları görmemek ve karşılaşmamak için dua ediyordum. Ne olurdu önüme bir problem gelse de, bu problemde de Do While-Loop olmasa. Ama mutlaka For-Next olacaktır, ondan kurtuluş yoktu zaten.

Ama tabi, belki de söylediğim gibi bu anlamama olayı tamamen benden kaynaklanıyordu. Çünkü bazı arkadaşlarımız CİN gibiydi ve benim anlamadığım o karışık konuları hemen anlıyorlardı. O halde konuda veya anlatan kişide bir problem yoktu. Problem sadece bendeydi.

Çok da fazla uzatmaya gerek yok, sonunda ben de bu anlayamadığım konuları bir gün oturdum ve çalıştım. Konular hakkında basit basit bir çok örnekler çözdüm ve sonunda o zor zannettiğim konuları öğrenmiştim.

Neden mi bunları anlattım?
Eh bir çoğunuzu anlamıştır sanırım. Şunu kastediyorum. Ben bile bu tür konuları anlamış ve burada anlatıyorsam, siz her halükarda anlayacaksınızdır. Yapmanız gereken tek şey, burada anlatılanlar haricinde basit basit örneklerle konuları pekiştirmek. Şimdi konumuza giriş yapalım. Unutmayın konuyu bol ve basit örneklerle anlatmaya gayret edeceğim. Mutlaka siz de bilgisayarınıza uygulayın. Önce döngüler.

DÖNGÜLER

Adından da anlaşıldığı gibi, Döngüler, kod içerisinde belli şartlar sağlanıncaya kadar sürekli tekrarlanan işlemleri kısaca halledebilmek için yazılan kısa kod satırlarıdır. Olayı şöyle düşünün. Hani makrolara ilk başladığımız zaman şuna yakın bir ifade kullanmıştık. “Makrolar, sürekli tekrarlanan işlemleri, otomatik hale getiren kodlardır.” Mesela Bir ay 30 gün olsun. Hazırlayacağınız bir tablo ayın her günü için geçerli olacak. O halde yapmanız gereken şey şuydu. İlk hazırladığınız tabloyu makro olarak kaydediyordunuz ve diğer sayfalarda da bu makroyu çalıştırarak tablolarınız hazırlanıyordu. 30 kere çalıştırdığınızda 30 adet tablonuz oluyordu. Yani bir çok defa da yapacağınız işleri makro ile bir defada hallediyordunuz. Şimdi döngülerde buna benzer. Bir çok satırda tekrarlamanız gereken işlemleri küçük bir kod bloğunda yazarak halledebilirsiniz.

Şimdi en fanatik döngü olan FOR-NEXT döngüsü ile öğrenmeye başlayalım.

FOR-NEXT DÖNGÜSÜ

Bu döngüde, For-Next bloğu arasına yazılmış olan kodlar (komutlar) belirtildiği kadar tekrarlanırlar. Aşağıda For-Next’in kullanılış şekline dikkat edin.

For sayaç = başlangıç_değeri To bitiş_değeri
            …………
            ………… [Komutlar]
            …………
Next sayaç

Yukarıdaki ifademizde “belirtildiği kadar” ile kastettiğimiz şey şu: bitiş_değeri’nden başlangıç_değeri’ni çıkartıp elde edilen ifadeye 1 eklediğimizde aldığımız sonuç kadardır.

Mesela,
For i = 1 To 1500 dediğimizde, [Komutlar] bölümündeki kodlar tam 1500-1+1=1500 defa çalıştırılacaktır. Burada 1 den başladığı için ifade belki size saçma gelebilir. Eğer misalimiz For i=7 To 16 olsa idi bu defa daha anlaşılır olacaktı. Yani kodlar 16-7+1=10 defa çalıştırılacaktı.

Şimdi For-Next döngüsünün ne kadar gerekli olduğuna dair basit bir örnek verelim. Amacımız A1 hücresinden başlayarak A1500 hücresine kadar sayılar girelim. Görüntümüz Şekil-1’dekine benzer olsun.


Şekil-1: A1 hücresinden A1500 hücresine kadar verilerin yazıldığı varsayın.

Elbette Excel’de bu girişi yapmak çok kolay. Fakat burada amacımız bu verileri kodlar ile  girmek.

Eğer bu verileri kod sayfasına kodlama ile girecek olsaydık, en basit olarak aşağıdaki gibi bir kod bloğu yazacaktık.

Sub ForNext_01()
    Range("A1").Value = 1
    Range("A2").Value = 2
    Range("A3").Value = 3
    Range("A4").Value = 4
    Range("A5").Value = 5
    Range("A6").Value = 6
    '...............
    '...............
End Sub

Ya da biraz daha farkla aşağıdaki gibi yazacaktık.

Sub ForNext_02()
    Cells(1, 1).Value = 1
    Cells(2, 1).Value = 2
    Cells(3, 1).Value = 3
    Cells(4, 1).Value = 4
    Cells(5, 1).Value = 5
    Cells(6, 1).Value = 6
    '...............
    '...............
End Sub

Kodun yazımı çok kolay oldu. Fakat, bunun 1500 kere tekrarlandığını düşündüğünüzde o zaman iş çığırından çıkacak ve size büyük bir bıkkınlık verecektir. İşte çaresizliğe düştüğünüz tam bu sırada For-Next döngüsü imdadınıza yetişecektir.

Yukarıda yazdığımız kodlara dikkat edelim. Çünkü size basit bir sır vereceğim. Bu sır sadece sizinle benim aramda kalmalı. Evet diyorsanız sırrımızı açıklayacağım.

SIR
For-Next döngüsünü kullanmak istediğinizde,  kodların artışında mutlak bir ritim olmalıdır. Diğer bir ifadeyle, bir sayaç kullanacağınız  için değişikliğe uğratacağınız veya sürekli artmasını/azalmasını istediğiniz değerin artışında bir ritim olmalıdır.

Bizim yukarıda verdiğimiz örnekte Cells(ritmik ifade,1).Value=ritmik ifade şeklinde olduğunu görmektesiniz. Yani sayılar belirli bir kural içinde artmaktadır. Eğer kuralsız bir artış olursa For-Next döngüsü sizin için bir kabusa dönüşür. Bu küçük sırrımızı asla unutmayın.

Artık yukarıdaki ifadeyi döngü içerisine sokalım. Aşağıdaki kodu yazıp çalıştırdığınızda sonucun şaşırtıcı ama bir o kadarda basit bir kodla elde edildiğini göreceksiniz.

Sub ForNext_03()
    For sayac = 1 To 1500
        Cells(sayac, 1).Value = sayac
    Next sayac
End Sub


Neler Oldu ?

Bilgisayar ilk olarak birinci satırı okuyacak.

For sayac = 1 To 1500

“sayac adlı ifadeyi 1 den başlayarak 1500’ e kadar tek tek arttır” ifadesini görecek ve ilk olarak sayac ifadesine 1 değerini verecek. Yani sayac=1 olacak. Daha sonra ikinci satıra geçilecek ve Cells(sayac, 1).Value = sayac satırı ile karşılaşılacak. Burada sayac ifadesi yerine 1 yazacağız. O zaman satır şu şekilde değişecek. Cells(1, 1).Value = 1.

Siz bu ifadenin ne olduğunu biliyorsunuz. Yani A1 hücresine 1 değeri yazılacak. Bu satırda da işimiz bitti. 3 satıra geldiğimizde Next sayac  ile karşılaşılacak.

Buraya dikkat edelim. Ne demek Next sayac ? Yani sayac ifadesinin değerine bakılacak. Eğer sayac ifadesi en son değer olan 1500 değerine eşit değilse, tekrar For satırına geri dönülecek. Ne zaman 1500 değerine eşit olursa, o zaman bir sonraki satıra geçilecek. Şimdi  bakalım, sayac ifadesi kaç’a eşit. Tabi ki, daha ilk döngüde olduğumuz için 1’e eşit. O halde doğruca For satırına geri dönelim ve sayac değerini 1 arttıralım.

sayac=2 oldu. Bir sonraki satırda sayac yerine 2 yazalım. Cells(2, 1).Value = 2 oldu. Siz bu kodunda ne manaya geldiğini biliyorsunuz. Yani A2 hücresine 2 değeri yazılacak. Tekrar üçüncü satıra gelinecek ve sayac değerinin 1500 olup olmadığına bakılacak. Daha sayac değeri 2 olduğuna göre tekrar for satırına gidilecek. İşlemler bu şekilde sürüp gidecek.

Biz birkaç adım atlayalım ve aradaki değerleri tek tek anlattığımızı varsayalım. Yoksa dergi sayfa sayılarını arttırmak zorunda kalacağız yada bir daha bana bu dergide bize yazma hakkı vermeyecekler. O yüzden şimdi var sayalım ki bilgisayarınız aradaki işlemleri yaptı. Biz son adımı anlatalım.

sayac=1500 oldu. İkinci satırı düzenleyelim. Cells(1500, 1).Value = 1500 oldu. Yani A1500 hücresine 1500 değeri yazıldı. Üçüncü satıra gelindi ve sayac değerinin 1500 olup olmadığı kontrol edildi. Evet sayac değerimiz 1500 olmuş. O halde döngüde işimiz bitti. Bir sonraki satır olan End Sub satırına geçilerek işlemi  bitiriyoruz.

İkinci bir örneğe geçmeden evvel Şekil-2 ve Şekil-3’ deki tabloları inceleyin ve Range(“A1”) ifadesinin yazılma tarzını oluşturan Hücre adresi ile Cells(1,1) ifadesini oluşturan hücre adreslerinin neler olduğuna dikkat ediniz.


Şekil-2: Range(“A1”) formunda yazılan hücre adresi


Şekil-3: Cells(1,1) formunda yazılan hücre adresi

Yukarıdaki örnekte gördüğünüz gibi, eğer bir For-Next döngüsü yapmamız gerekiyorsa, bunu Excel’in temel yapı taşlarından olan ve hücrelerden oluşan satır ve sütün değerlerini değiştirerek yada direk olarak hücre değerini değiştirerek yapıyoruz. Meselenin daha iyi kavranabilmesi için örneklerimize basitten başlayarak devam edelim.

Öncelikle istiyoruz ki, belirlediğimiz miktardaki hücrelere “x” işareti koyulsun. Bunu 10 adet hücre için yapalım. Eğer kodu aşağıdaki gibi yazarsanız, “i” sayacına ait artışın satırlara denk gelen hücrelerde olduğunu göreceksiniz. Bunun ne manaya geldiğini Şekil-3’ü inceleyerek anlamaya çalışın.

Sub ForNext_04()
    Dim i As Integer
    For i = 1 To 10
        Cells(i, 1).Value = "x"
    Next i
End Sub


Şekil-4: Cells(1,1) formundaki bir hücre adresinin satır değerleri için döngüde kullanılması.

ForNext_04 adlı kodda küçük bir değişiklik yapalım ve “i” sayaç değerini bu fa sütunlar için kullanalım.

Sub ForNext_05()
    Dim i As Integer
    For i = 1 To 10
        Cells(1, i).Value = "x"
    Next i
End Sub


Şekil-5: Cells(1,1) formundaki bir hücre adresinin sütun değerleri için döngüde kullanılması.

Bu iki örneğe dikkat ettiğimizde, birbirinin aynı olan iki kodun küçük bir oynama yapıldığında ne şekle dönüştüğünü gördük. Bu basit değişiklik bize hücre adresini Cells(1,1) formatında yazdığımız için kolay geldi. Şimdi aynı işlemi Range(“A1”) formatında nasıl yapacağız diye düşünen arkadaşlarımız, aşağıdaki kodu yazıp çalıştırsınlar.

Sub ForNext_06()
    Dim i As Integer
    For i = 1 To 10
        Range("A" & i).Value = "x"
    Next i
End Sub

Kodu çalıştırdığınız zaman Şekil-4’deki görüntünün aynısı ile karşılaşacaksınız.

Şimdi de uygulamalarımızı biraz daha geliştirerek Döngü içersine yeni argümanlar katalım. Aşağıdaki kodu yazı ve çalıştırın. Tabi daha sonrada yaptığımız açıklamayı okuyun. Şekil-6

Sub ForNext_07()
    Dim i As Integer
    Dim k As Integer
    k = 10
    For i = 1 To 10
        Cells(i, k).Value = "x"
        k = k - 1
    Next i
End Sub


Şekil-6: Döngüye dışarıdan bir argüman ekledik

Dikkat ettiğinizde bu defa Cells(1,1) ifadesinde hem satır değeri hem de sütun değeri, bir değişkene atandı. Bu iki değişkenden bir tanesi döngü dışında tanımlanmış olan “k” dır. “k” değişkenine ilk etapta 10 değerini atadık ve sonrada döngü içersinde bu değişkeni azalan tarzda kullandık.

Döngü ilk etapta, “i” sayacına 1 değerini   atıyor ve k=10 olarak duruyor. Şimdi bu değerleri Cells(i,k) da yerine koyduğumuzda Cells(1,10) sonucunu alacağız. Yani J1 hücresine “x” sonucunu yazdıracak. Daha sonra bir alt satıra gelinecek ve k=k-1 satırı içra edilecek 10 dan 1 çıkartılacak ve “k” bu defa 9 değerini alacak. Tekrar Cells(i,k) satırına gelindiğinde, i=2 ve k=9 dur. Yani Cells(2,9), diğer bir deyişle I2 hücresine “x” sonucu yazdırılacaktır.

İÇİÇE FOR-NEXT DÖNGÜSÜ

For Next döngülerini bir prosedürde bir çok defalar kullanabiliriz. İster bu döngüleri ayrı ayrı kullanırız. İstersek de, iç içe kullanabiliriz.

Sub ForNextAyri()
       For i= 1 to 10
                  ………………..
                  ………………..
                  ………………..
        Next i
       For j= 1 to 10
                  ………………..
                  ………………..
                  ………………..
       Next j
End Sub

Yukarıda ayrı ayrı kullanılmış bir örnek görüyorsunuz. Bu tip bir yazım için herhangi bir kural yoktur. Fakat aynı döngüyü iç içe kullanmak istediğinizde basit bir kurala dikkat etmek gerekir.

Sub ForNextAyri()
            For j= 1 to 10
                   ………………..
                   ………………..
                   For i= 1 to 10
                        ………………..
                        ………………..
                        ………………..
                  Next i
                  ………………..
                  ....……………..
            Next j
End Sub

Evet, sizin de hemen fark ettiğiniz gibi en önemli kural, önce açılan döngü sonra kapatılmıştır. Hemen anladınız biliyorum ama ben yinede rahat kavranması için bir iki örnek vereyim. Bunu büyük kutunun içine yerleştirebileceğiniz küçük kutu olarak düşünebilir, yada küçük balığı yutmuş büyük balık olarak düşünebilirsiniz.

Basit bir örnek olarak aşağıdaki kodu yazın ve çalıştırın. Şekil-7

Sub ForNext_07()
    Dim i As Integer
    Dim j As Integer
    For j = 1 To 10
        For i = 1 To 10
            Cells(i, j).Value = "x"
        Next i
    Next j
End Sub


Şekil-7: İç içe çalışan basit bir ForNext döngüsü

Şimdi, bazı okurlarımızın yavaş yavaş kızmaya başladıklarını fark ediyorum. “Nedir yani bu ForNext döngüsü, hücrelere sadece x işareti mi koymaya yarar?” dediklerini de duyar gibi oluyorum. Tabi ki değil. Kızmanıza gerek yok bunlar sadece bilmeyen arkadaşlarımızı alıştırmak için verilmiş bir dizi  örnek.

Şunu bilmeniz gerekir ki, kızarsanız bu işleri yapamazsınız, çünkü ForNext döngüleri programlamanın bel kemiğidir. Yani olmazsa olmaz. Birazdan vereceğim basit ve karmaşık örnekleri siz de deneyin, ne kadar önemli olduğunu görün.

Soru 1: Excelde bir dosyayı açtıktan sonra çıkan sayfaları isim sırasına göre otomatik sıralamak istersek bunu nasıl yapabiliriz ve bununla ilgili makro ne şekilde olmalıdır. Bu sorumuzu cevaplarsanız çok sevineceğiz. Saygılar. (İbrahim Öktem)

Cevap 1: Eğer dosyanızın açılır açılmaz bu işlemi gerçekleştirmesini istiyorsanız, makroyu Auto_Open makrosuna yazmalısınız.

Sub Auto_Open()
    Dim i As Integer
    Dim j As Integer
    If Worksheets.Count = 1 Then Exit Sub
    For i = 1 To Worksheets.Count - 1
        For j = i + 1 To Worksheets.Count
            If Worksheets(j).Name < Worksheets(i).Name Then
                Worksheets(j).Move before:=Worksheets(i)
            End If
        Next j
    Next i
End Sub

Soru 2: Sistemde bulunan renkleri ve renk kodlarını hücrelere yazdırabilir miyim? Şablon olarak görmek istiyorum.

Cevap 2: Aşağıdaki kodu yazın ve çalıştırın. Şekil-8

Sub Renkler()
    Dim i As Integer
    On Error Resume Next
    For i = 1 To 56
        Cells(i, 1).Interior.ColorIndex = i
        Cells(i, 2).Value = Cells(i, 1).Interior.ColorIndex
        Cells(i, 3).Value = Cells(i, 1).Interior.Color
    Next i
End Sub


Şekil-8: Renkler Excel hücrelerine ForNext döngüsü ile yazdırıldı.

Bu defa bir fonksiyon örneği verelim.

Soru 3: Belirli aralıklarla bir sütunda toplama yaptırıyorum. Daha sonra bu yaptırdığım toplama işlemlerini başka bir hücrede toplatmak istiyorum.

Cevap 3: Sorunuzun aşağıdaki gibi olduğunu düşünelim.

A sütununda belli aralıklar yazılmış verileriniz var. Ve siz bu verileri belirli aralıklarla formülle toplatmışsınız. Şekil-9


Şekil-9: Belirli aralıklar toplam formülleri yazılmış.

VBE sayfasında bir modüle aşağıdaki kodu yazın.

Function aralitopla(hucreler As Range, artma As Integer)
    Dim i As Integer
    For i = artma To hucreler.Count Step artma
        aralitopla = aralitopla + hucreler.Rows(i)
    Next
End Function

Çalıştığınız kitabı herhangi bir isimle kaydedin.

Şimdi yazdığımız Fonksiyonu sayfa üzerinde kullanalım. C1 hücresine aşağıdaki gibi formülü girin.

=aralitopla(A1:A16;4)

Şekil-10 daki gibi A sütununda bulunan belirli aralıktaki “Toplam” ların toplandığını göreceksiniz.


Şekil-10: C1 hücresinde sonucu göreceksiniz

Önümüzdeki ay, döngülere devam edeceğiz. Siz şimdilik ForNext Döngüsünü pekiştirecek örnekler yapınız. Konu ile ilgili örnek bulmak için www.excel.gen.tr adresinde araştırma yapabilirsiniz.
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.