Excel VBA Döngüler , Do Until While Wend For Next

Makro, formül vb.. şekilde bazı örneklerin paylaşılabileceği alan
Kullanıcı avatarı
ExcelVBA
Site Admin
Mesajlar: 10
Kayıt: 20 Haz 2023, 18:12
Lokasyon: İstanbul
Web Sitesi: https://www.excelvba.net
Meslek: Yönetim Kurulu Başkanı (Özel Sektör)
Adınız:
Soyadınız:

Excel VBA Döngüler , Do Until While Wend For Next

Mesaj gönderen ExcelVBA »

If, ElseIf , Else Then
Do , Loop While, Wend , Until ,For , Next , Exit
And , Or , Goto , With



Do , While, Wend , Until , Loop

Bu döngü modelleri aradaki şartlandırmalara göre değer döndürür , şartlandırma sonuçlarına göre döngüden çıkılabilir. Dilenen yerde Exit Do ile döngü çıkışı sağlanabilir. Do döngüsünde Until ve While modellerini de kullanmak mümkün. Her ikisi de farklı anlamlarda şartlandırma yapar, biri doğruysa döndürür, diğeri doğru değilse döndürür, sorgular ve kodlamadaki içeriğe göre sonuçlandırır.

Şimdi test ederek anlamaya çalışalım.
A1 'den A7 'ye kadar sayılar yazalım, 1.2.3...7 ve kodu çalıştıralım.

Kod: Tümünü seç

Sub DoUntilTest()
Range("A1").Select
    Do Until Selection.Value = ""
        Selection.Value = Selection.Value + 1
        Selection.Offset(1, 0).Select
    Loop
End Sub

Bu şartlı döngümüzde A1 hücresinin seçiminin ardından şartın yerine gelmemesi durumunda değerler döndürülüyor.


Do Until ve Do While, If mantığına yakın bir sorgulama tarzıdır.

Kod: Tümünü seç

If Selection.Value = "" Then

Kod mantığı tek değer için sorgu yapar, diğer sorgumuz Do döngüsü bitene kadar devam eder.

Kod: Tümünü seç

Do Until Selection.Value = ""

Kod parçamız seçilmiş olan hücrenin boş olup olmadığını değerlendiriyor. Eğer boş ise döngüden çıkılıyor. Dolu ise bir sonraki kod satırı dikkate alınıyor.

Ters işlem ile de döngümüzü yorumlayabiliriz:

Kod: Tümünü seç

Sub LoopUntilTest()
Range("A1").Select
    Do
        Selection.Value = Selection.Value + 1
        Selection.Offset(1, 0).Select
    Loop Until Selection.Value = ""
End Sub

Bu kod parçamız da aynı mantıkta çalışacaktır.

Kod: Tümünü seç

Range("A1").Select
ile hücremiz seçilecek Do ile döngümüz başlayacak,

Kod: Tümünü seç

Selection.Value = Selection.Value + 1
ile seçili değere 1 ilave edilecek,

Kod: Tümünü seç

Selection.Offset(1, 0).Select
ile seçili hücrenin bir alt satırı seçili yapılacak,

Kod: Tümünü seç

Loop Until Selection.Value = ""
ile döngü şartı tamamlandıysa döngüden çıkılacak.
Döngü burada şunu diyor :
Loop Until Selection.Value = ""
Eğer seçili ( Selection ) hücre değeri boş değil ise ( Until ) o halde döngüye tekrar başla. Yani buradaki şartlandırmayı test edecek, şart yerine gelmedi ise tekrar döngü başına gidip aynı işlemleri seçili hücre için tekrarlayacak. Şart yerine geldi ise döngüden çıkış yapacak.

While ile Until işleminin tersi yapılıyor demiştik. Şimdi onu da test edelim.

Kod: Tümünü seç

Loop While Selection.Value <> ""

Until 'de eğer hücre değeri boş değilse idi , While 'de de eğer hücre değeri boş değilse olacak ki döngü devam etsin ancak biri eşitlik biri eşitsizlik arayacak, buna göre çalışacaktır.
[size]

Kod: Tümünü seç

Sub LoopWhileTest()
Range("A1").Select
    Do
        Selection.Value = Selection.Value + 1
        Selection.Offset(1, 0).Select
Loop While Selection.Value <> ""
End Sub
Kod parçamız ile diğer kodlardaki sonucun aynısı döndürülecektir.

Aynı şekilde While şartımızı Do ile de birleştirip aynı kodu çalıştırabilir, aynı sonucu üretebiliriz.

Kod: Tümünü seç

Sub DoWhileTest()
Range("A1").Select
    Do While Selection.Value <> ""
        Selection.Value = Selection.Value + 1
        Selection.Offset(1, 0).Select
    Loop
End Sub
Burada önemli olan hasas nokta neyin şarta bağlanacağıdır. Döngü içerisinde bir sorgulama çalışıyor, sorgulama döngüye devam edilmesini ya da çıkılmasını sağlıyor.

Bunları If Then ile de yapamaz mıydık ? Elbette yapardık. Ama yine bir şekilde döngü kurmamız gerekecek. Ya For .. Next, ya da bol bol If .. Then kullanmamız gerekecek. For .. Next 'ten farkı kaç defa döneceğini içindeki kodlara göre tespit etmesidir. For .. Next ise kaç defa döneceğini For kısmında tanımlanacak sayısal döngü değerine göre yapacak. Bundan da bahsedeceğiz.

Şimdi şu örneği bir inceleyelim:

Kod: Tümünü seç

Sub DoUntilTest_2()
     Range("b1").Select
     Do Until Selection.Offset(0, -1).Value = ""
         If Selection.Value = "" Then
             Selection.EntireRow.Delete
         Else
             Selection.Offset(1, 0).Select
         End If
      Loop
      Range("b1").Select
End Sub
Bu örneğimiz için öncelikle Sayfa1 A1:A5 aralığına 1,2,3,4,5 B1:B5 aralığına da A,B,C,D,E yazalım. Şimdi B4 hücresinde yazılı D harfini silelim ve kodumuzu çalıştıralım.

Örnek kodlama şunu diyor :

Kod: Tümünü seç

Range("b1").Select ': Hücre B1 'i seç,
Do Until Selection.Offset(0, -1).Value = "" ': Eğer seçili hücrenin solu boş değil ise döngüye devam et, sonraki satırları oku;
If Selection.Value = "" Then ': Eğer seçili hücre boş ise
Selection.EntireRow.Delete ': Seçili satırı sil
Loop ' : Döngünün başına Do kısmına git şartları yine kontrol et
Biraz önceki anlatımlarda dediğimiz şekilde , aşağıdaki kod parçasındaki gibi bunun ters işlemini de yapmak mümkün, ikisi de aynı anlama geldiğinden aynı işlemi yapacaktır.

Kod: Tümünü seç

Sub LoopUntilTest_2()
     Range("b1").Select
     Do
         If Selection.Value = "" Then
             Selection.EntireRow.Delete
         Else
             Selection.Offset(1, 0).Select
         End If
      Loop Until Selection.Offset(0, -1).Value = ""
      Range("b1").Select
End Sub
Aşağıdaki örneğimiz için A1:A5 aralığına 1,2,3,4,5 yazınız.
Döngü içerisindeki bazı şartların oluşması durumunda döngüyü durdurup çıkışı görelim:

Kod: Tümünü seç

Sub DoWhileTest_2()
Range("a1").Select
Do While Not Selection = ""
    If Selection.Offset(0, 0) = "" Then
        Exit Do
    Else
        Selection.Offset(0, 1) = "ExcelVBA.Net " & Selection.Offset(0, 1)
        Selection.Offset(1, 0).Select
    End If
Loop
End Sub
Bu kodlama seçili hücrenin boş olup olmamasına bakacak, boş ise döngüyü bitirecek, dolu ise ve sağındaki boş ise yanına ExcelVBA.Net yazacak, yanındakilerden biri dolu ise o hücre değerini de dikkate alarak, ExcelVBA.Net ve dolu hücredeki değeri birleştirip yazacak.
Döngü sonuna kadar işlemi aynı şekilde tekrarlayacak.

Şimdi kodlamamıza bir satır ilave edelim ve A1:A5 aralığındaki hücre değerlerinin şartlarını kontrol ettirelim:

Kod: Tümünü seç

Sub DoWhileTest_3()
Range("a1").Select
Do While Not Selection = ""
    If Selection.Offset(0, 0) = "" Then
        Exit Do
    ElseIf Selection.Offset(0, 0).Value > 3 Then
        Exit Do
    Else
        Selection.Offset(0, 1) = "ExcelVBA.Net " & Selection.Offset(0, 1)
        Selection.Offset(1, 0).Select
    End If
Loop
End Sub
Kod satırlarına ilave ettiğimiz:

Kod: Tümünü seç

ElseIf Selection.Offset(0, 0).Value > 3 Then
Exit Do
kodları seçili satırın 3 'ten büyük olması durumunda yine döngüden çıkmasını sağlayacak.
Alacağımız görüntü şu olmalıdır :
exitdo_1.JPG
If, Else , ElseIf ,Then , EndIf , And , Or , Goto

Şartlara bağlı sorgulama tipi kodlamadır. If ile sorgulamayı başladır, alt satırlarında yapılacak işlemleri belirlersiniz, End If ile sorgulamayı bitirirsiniz.

Kod: Tümünü seç

Sub IfThenEndIfTest()
Range("a1").Select
    If Selection.Value <= 10 Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
End Sub
A1:A5 arasında 7 , 8 , 9 , 10 , 11 yazın ve kodu çalıştırın. İlk yazdığınız 7 rakamına karşılık B1 hücresinde ExcelVBA.Net yazdığını göreceksiniz. Ama diğer alt satırlar da 10 sayısından küçük veya eşit. Neden Diğerlerine yazdıramadık ?

Çünkü şartlandırmayı tek seferlik kullandık. Bunu genişletecek olursak :

Kod: Tümünü seç

Sub IfElseIfThenEndIf_Test()
    Range("a3").Select
        If Selection.Value = 7 Then
            Selection.Offset(0, 1).Value = 10
                ElseIf Selection.Value = 8 Then
                    Selection.Offset(0, 1).Value = 20
                        ElseIf Selection.Value = 9 Then
                            Selection.Offset(0, 1).Value = "ExcelVBA.Net"
                                ElseIf Selection.Value = 10 Then
                                    Selection.Offset(0, 1).Value = 40
                                        ElseIf Selection.Value = 11 Then
                                            Selection.Offset(0, 1).Value = 50
        End If
End Sub
Şeklindeki bir yapı ile seçilen a3 hücresinin değerini test ettitip koşullara uyan var ise gerekli kodun çalışmasını sağlayabiliriz. Bu da yine bir tek sorgulamaya doğru cevap vereceğinden 9 karşısındaki değere ExcelVBA.Net yazacaktır.

Bunu döngüsüz model ile de halledebiliriz aslında ama bu kez de bir yönlendirmeye ihtiyaç olacak. Bu modelde bu kez Goto yölendirmesini kullanarak denememizi yapalım.

Kod: Tümünü seç

Sub IfElseIfThenEndIf_And_IsNumeric_Goto_Test()
    Range("a1").Select
10      If Selection.Value <> "" And IsNumeric(Selection.Value) And Selection.Value <= 10 Then
            With Selection
                .Offset(0, 1).Value = "ExcelVBA.Net"
                .Offset(1, 0).Select
            End With
                GoTo 10
        End If
End Sub
Şimdi kodlamada dedik ki :
A1 hücresini seç
Eğer seçilen değer boş değil ise ve seçilen değer sayısal bir değer ise ya da seçilen değer 10 sayısından küçük yahut eşit ise:

Kod: Tümünü seç

Selection.Offset(0, 1).Value = "ExcelVBA.Net" 'koduyla git o seçili hücrenin sağına ExcelVBA.Net yaz.
Selection.Offset(1, 0).Select 'koduyla da bir alt satıra geç
GoTo 10 'koduyla da 10 ile başlayan satıra yönlen.Kod buraya yönlendiğinde gerekli işlemleri yap ve şart bitene kadar yönlenmeye devam et.
Bunun için aslında en iyisi başlarda bahsedilen döngü modellerine başvurmaktır. Bir tanesini seçip kullanalım o halde.

Kod: Tümünü seç

Sub DoLoopIfThenEndIfTest()
Range("a1").Select
Do
    If Selection.Value <= 10 Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
       Selection.Offset(1, 0).Select
Loop
End Sub
Bu kodu çalıştırdıktan sonra CTRL + Pause ( Break ) tuşlarına basın ve makro çalışmasını durdurun. Şimdi sayfamıza bakalım neler olmuş. Evet 7 , 8 , 9 ve 10 yazdığımız hücrelerin yanına ExcelVBA.Net yazılmış 11 yazılı hücrenin yanı boş çünkü şartlandırmada eğer 10 sayısına eşit ya da daha küçük ise demiştim. Ama o da ne ? Alt satırlarda da halen ExcelVBA.Net yazıyor, hemde yüzlerce... Demek ki şartlandırmamızı tam yapamamışız. Peki bu durumda bir kaç satır daha ilave edelim bakalım olacak mı ?

Burada ekleyeceğimiz kod ilavesinde And , Or gibi operatörleri kullanabiliriz.

Kod: Tümünü seç

Sub DoLoopIfThenEndIf_And_Test()
Range("a1").Select
Do
    If Selection.Value <= 10 Or Selection.Value <> "" Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
       Selection.Offset(1, 0).Select
Loop
End Sub
Kodlamayı sayfamızda Alt + F8 tuşlarına basarak makromuzu seçip çalıştıralım. Durdurmak için yine CTRL + Pause ( Break ) tuşlarına basalım çünkü 65536 ' ya kadar gidecek bu işlem.
Yine nerde hata yaptık acaba ?
O zaman koşulları gözden geçirip çıkmamız gereken durumu belirleyelim.

Kod: Tümünü seç

Sub DoLoopIfThenEndIf_And__ExitSubTest()
Range("a1").Select
Do
    If Selection.Value = "" Then Exit Sub
    If Selection.Value <= 10 And Selection.Value <> "" Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
        Selection.Offset(1, 0).Select
Loop
End Sub
Evet seçilen hücre değeri boş ise çıkış yaptıralım. Şimdiki kodlamayı denediğimizde işlemin tek seferde tamamlandığını görebiliriz.

bunu şu şekilde de çalıştırmamız mümkün:

Kod: Tümünü seç

Sub DoLoopWhileIfThenEndIf_AndTest()
Range("a1").Select
Do
    If Selection.Value <= 10 And Selection.Value <> "" Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
        Selection.Offset(1, 0).Select
Loop While Selection.Value <> ""
End Sub
Şartlandırmalarımızdaki sorguyu And operatörü ile bir kaç kez de sorgulayabiliyoruz. Eğer şu değil de bu ise gibi...

Kod: Tümünü seç

Sub DoLoopWhileIfThenEndIf_And_2_Test()
Range("a1").Select
Do
    If Selection.Value <= 10 And Selection.Value > 7 Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
        Selection.Offset(1, 0).Select
Loop While Selection.Value <> ""
End Sub
bu defa bakacağı yer örnek verilerimize göre 10 sayısındaki küçük veya eşit ile 7 sayısından büyük olması şartıdır. Sonuç olarak 8 , 9 ve 10 yazdığımız hücrelerin yanına ExcelVBA.Net yazacaktır.

For Next Exit For With End With
Bu döngü türü de şartlandırmaları döngü başındaki değişkene atanacak değer kadar döndürecektir.
Bir önceki örneğimizi ele aldığımızda şu şekilde bir döngü ile sonuca ulaşabiliriz:

Kod: Tümünü seç

Sub ForNextIfThenEndIf_AndTest()
Range("a1").Select
For i = 1 To Range("a65536").End(xlUp).Row
    If Selection.Value <= 10 And Selection.Value <> "" Then
        Selection.Offset(0, 1).Value = "ExcelVBA.Net"
    End If
        Selection.Offset(1, 0).Select
Next i
End Sub
Kodlama seçili hücrelere göre çalışacak. Ama aslında bizim bunu değişken değerine göre düzenleyip çalıştırmamız gerekli idi. Yoksa Do..While..Wend...Until..Loop döngülerinden farkı olmayacak.

Kod: Tümünü seç

Sub ForNextIfThenEndIf_Test()
For i = 1 To Sheets("sayfa1").Range("a65536").End(xlUp).Row
    If Sheets("sayfa1").Cells(i, 1) <= 10 Then
        Sheets("sayfa1").Cells(i, 2).Value = "ExcelVBA.Net"
    End If
Next i
End Sub

Kod: Tümünü seç

For i = 1 To Range("a65536").End(xlUp).Row ': For ile döngü olduğunu tanımlayarak i değişkeninin de 1 ile en a sütununda alttan yukarı doğru geldiğimizde durduğumuz hücrenin adresteki sayısı kadar dönmesi gerektiğini belirtiyoruz. Son hücremiz örneğimize göre A5 hücresi olduğuna göre; i değişkeninin döndüğü müddetçe  en fazla alabileceği değer 5 olacaktır. Tabi şartlandırmalarda belirli bir sayıda Exit For uygulamadıysak.
Bunları en güzel test etme şekli F8 ile adım adım satır okutmayla olacaktır. F8 bastığınızda For i satırını okuttuktan sonra mouse ile i üzerine gidin. Değişkenin 1 değerinde olacağını göreceksiniz. F8, F8 devamında şartların uygunluğu durumunda Next i satırından sonra döngü yine başa saracaktır. Yine For i okuyacak, ve okuduğu bu satırdan sonra siz yine mouse imleci ile i değişkeninin üzerine gittiğinizde, değerin bu kez 2 olduğunu göreceksiniz. Değişken müsaade ettiğimiz en son değerini alana kadar Next döngümüzü döndürecektir.

Şimdi With ile kod tekrarlarının kısaltılmasını ekleyelim.

Kod: Tümünü seç

Sub ForNextIfThenEndIf_WithTest_1()
With Sheets("Sayfa1")
For i = 1 To .Range("a65536").End(xlUp).Row
    If .Cells(i, 1) <= 10 Then
        .Cells(i, 2).Value = "ExcelVBA.Net"
    End If
Next i
End With
End Sub
Biraz daha abartacak olursak ;

Kod: Tümünü seç

Sub ForNextIfThenEndIf_WithTest_2()
With Sheets("Sayfa1")
    For i = 1 To .Range("a65536").End(xlUp).Row
        If .Cells(i, 1) <= 10 Then
            With .Cells(i, 2)
                .Value = "ExcelVBA.Net"
                .Interior.ColorIndex = 6
                .Font.Bold = True
                .Font.ColorIndex = 3
                .Borders.Value = 12
                .ColumnWidth = 15
                .HorizontalAlignment = xlCenter
            End With
        End If
    Next i
End With
End Sub
İç içe With kullanımına bu tarzda örnek verebiliriz. Burada With aralığındaki kodların ne anlama geldiğini belirtmeye gerek yok, sadece örneklemeydi. Merak ederseniz satırları tek tek kullanarak ne işler yaptığını test edebilirsiniz. Bizim buradaki amacımız Döngü içerisinde ( ya da döngüsüz kodlamalarda ) With kullanımını göstermekti.