Genel Bakış
Do - Loop (Do...Loop), bir koşul doğruyken ya da doğru olana kadar bir grup deyimi yineleyen VBA döngü deyimidir. Yineleme sayısının önceden bilinmediği durumlarda, örneğin verinin bittiği ilk boş satıra kadar ilerlemek için kullanılır. Koşul döngünün başında ya da sonunda sınanabilir.
Koşul döngünün sonunda sınanırsa:
Exit Do genellikle bir If deyiminin içinde, aranan değer bulunduğunda ya da güvenlik sınırı aşıldığında kullanılır. İç içe Do - Loop döngülerinde Exit Do yalnız içinde bulunduğu en iç döngüden çıkar.
Kodu yazmak için Geliştirici > Kod > Visual Basic (Developer > Code > Visual Basic) ile düzenleyiciyi açın, Ekle > Modül (Insert > Module) ile standart modül ekleyin ve kodu oraya yapıştırın.
Döngü, A8 hücresindeki ilk boş satıra gelince koşul False oldu ve sona erdi. Kalem satırının tutarı 300,00, Toner satırının tutarı 5.000,00 olarak hesaplandı; genel toplam E2 hücresinde 7.497,75 değerindedir. Yeni ürün eklenirse kodu değiştirmeniz gerekmez, döngü verinin bittiği yere kadar kendiliğinden ilerler.
Döngü gövdesi her turda bir ay yazar; Loop Until kalan <= 0 koşulu tur sonunda sınandığı için borç sıfırlanınca döngü biter. Plan 5. ayda tamamlandı. O ayki ödeme 500,00, kalan borç ise 0,00 olarak yazıldı; yani son taksit normal taksitten küçüktür. If ay >= 36 Then Exit Do satırı, hatalı veri girilmesi durumunda döngüyü sınırlayan güvenlik önlemidir.
Makro satırları sırayla kontrol etti ve stoğu kritik seviyenin altında olan ilk ürünü D2 hücresine (Dosya), bulunduğu satır numarasını E2 hücresine (4) yazdı. Ardından Exit Do ile döngüden çıkıldı. Toner satırı da kritik seviyenin altındadır, ancak döngü daha önce bittiği için taranmaz. Tüm kritik ürünleri listelemek isterseniz Exit Do satırını kaldırıp sonuçları ayrı satırlara yazabilirsiniz.
Söz dizimi
Do - Loop iki biçimde yazılır. Koşul döngünün başında sınanırsa:
VBA
5 satır
Do [While | Until koşul]
[deyimler]
[Exit Do]
[deyimler]
Loop
VBA
5 satır
Do
[deyimler]
[Exit Do]
[deyimler]
Loop [While | Until koşul]
- While koşul: koşul True olduğu sürece döngü yinelenir; isteğe bağlıdır.
- Until koşul: koşul True olana kadar döngü yinelenir, yani koşul True olunca döngü biter; isteğe bağlıdır.
- koşul: True ya da False sonucu veren ifade; sayısal bir ifade de olabilir (0 False, diğerleri True sayılır). While ya da Until kullanılırsa gereklidir.
- deyimler: her turda çalışacak bir ya da daha çok deyim; isteğe bağlıdır.
- Exit Do: döngüyü hemen terk edip Loop satırından sonraki deyime geçer; isteğe bağlıdır.
Koşulun yeri: başta mı, sonda mı
Koşul Do satırındaysa döngüye girmeden önce sınanır. Koşul ilk anda uygun değilse döngü gövdesi hiç çalışmaz. Koşul Loop satırındaysa gövde önce çalışır, koşul tur sonunda sınanır. Bu nedenle gövde en az bir kez çalışır.- Do While ... Loop: koşul True iken girer; verinin boş olma ihtimali varsa en güvenli seçimdir.
- Do Until ... Loop: koşul True olana kadar girer; "boş hücreye kadar" gibi bitiş koşullarını doğal biçimde anlatır.
- Do ... Loop While: gövde bir kez çalışır, koşul True kaldıkça yinelenir.
- Do ... Loop Until: gövde bir kez çalışır, koşul True olunca biter; hesaplamanın en az bir kez yapılması gereken durumlarda uygundur.
Döngüden çıkma ve sonsuz döngüden kaçınma
Döngü gövdesinde koşulu etkileyen bir değişkeni (sayaç, satır numarası, bakiye gibi) her turda değiştirmezseniz döngü hiç bitmez ve Excel yanıt vermez gibi görünür. Böyle bir durumda Esc ya da Ctrl + Break tuşlarıyla makroyu durdurabilir, açılan pencerede Sonlandır (End) düğmesini kullanabilirsiniz.Exit Do genellikle bir If deyiminin içinde, aranan değer bulunduğunda ya da güvenlik sınırı aşıldığında kullanılır. İç içe Do - Loop döngülerinde Exit Do yalnız içinde bulunduğu en iç döngüden çıkar.
Kodu yazmak için Geliştirici > Kod > Visual Basic (Developer > Code > Visual Basic) ile düzenleyiciyi açın, Ekle > Modül (Insert > Module) ile standart modül ekleyin ve kodu oraya yapıştırın.
Do - Loop ile For - Next arasındaki fark
Kaç tur döneceğinizi önceden biliyorsanız (For i = 1 To 10) For - Next daha kısa ve güvenlidir. Tur sayısı veriye ya da bir hesaba bağlıysa, örneğin ilk boş hücreye kadar gitmek, bakiye sıfırlanana kadar ödeme yapmak ya da bir değer bulunana kadar aramak gibi durumlarda Do - Loop kullanılır. Eski While ... Wend deyimi de benzer işi görür, ancak Exit ile çıkış sunmadığı için Do - Loop tercih edilmelidir.1. Boş satıra kadar tutar hesaplama (Do While)
Satış listesinde ürün sayısı değişebildiği için kaç satır olduğunu bilmiyoruz. Do While döngüsü A sütunu dolu olduğu sürece her satırın tutarını (adet x birim fiyat) D sütununa yazar ve genel toplamı E2 hücresinde verir. Kodu standart modüle yapıştırın ve TutarlariHesapla makrosunu çalıştırın.
VBA
21 satır
Option Explicit
Sub TutarlariHesapla()
Dim ws As Worksheet
Dim satir As Long
Dim toplam As Double
Set ws = Worksheets("Satışlar")
satir = 2 ' veri 2. satırdan başlar
' A sütunu boş olmadığı sürece döngü sürer
Do While ws.Cells(satir, 1).Value <> ""
ws.Cells(satir, 4).Value = ws.Cells(satir, 2).Value * ws.Cells(satir, 3).Value
toplam = toplam + ws.Cells(satir, 4).Value
satir = satir + 1 ' sayacı artırmayı unutmayın
Loop
ws.Range("D2:D" & (satir - 1)).NumberFormat = "#,##0.00"
ws.Range("E2").Value = toplam
ws.Range("E2").NumberFormat = "#,##0.00"
End Sub
Do - Loop
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ürün | Adet | Birim Fiyat | Tutar | Genel Toplam |
| 2 | Kalem | 120 | 2,50 | 300,00 | 7.497,75 |
| 3 | Defter | 45 | 18,75 | 843,75 | |
| 4 | Dosya | 60 | 7,90 | 474,00 | |
| 5 | Zımba | 15 | 42,00 | 630,00 | |
| 6 | Toner | 4 | 1.250,00 | 5.000,00 | |
| 7 | Silgi | 200 | 1,25 | 250,00 |
SatışlarExcelDepo v1.0.0
2. Borç bitene kadar taksit planı (Loop Until)
Toplam borç D2, aylık taksit E2 hücresindedir. Borcun kaç ayda biteceği bilinmiyor; ancak plan en az bir ay içerdiği için koşulu döngünün sonunda sınayan Loop Until biçimi uygundur. Son ayda kalan borç taksitten azsa yalnız kalan tutar ödenir. Kodu standart modüle yapıştırın ve BorcPlaniOlustur makrosunu çalıştırın.
VBA
33 satır
Option Explicit
Sub BorcPlaniOlustur()
Dim ws As Worksheet
Dim kalan As Double
Dim taksit As Double
Dim odeme As Double
Dim ay As Long
Set ws = Worksheets("Borç Planı")
kalan = ws.Range("D2").Value
taksit = ws.Range("E2").Value
Do
ay = ay + 1
' son ayda kalan borç taksitten azsa yalnız kalanı öde
If kalan < taksit Then
odeme = kalan
Else
odeme = taksit
End If
kalan = kalan - odeme
ws.Cells(ay + 1, 1).Value = ay
ws.Cells(ay + 1, 2).Value = odeme
ws.Cells(ay + 1, 3).Value = kalan
' güvenlik: taksit 0 girilirse döngü sonsuza gitmesin
If ay >= 36 Then Exit Do
Loop Until kalan <= 0
ws.Range("B2:C" & (ay + 1)).NumberFormat = "#,##0.00"
End Sub
Do - Loop
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ay | Ödeme | Kalan Borç | Toplam Borç | Aylık Taksit |
| 2 | 1 | 1.000,00 | 3.500,00 | 4.500,00 | 1.000,00 |
| 3 | 2 | 1.000,00 | 2.500,00 | ||
| 4 | 3 | 1.000,00 | 1.500,00 | ||
| 5 | 4 | 1.000,00 | 500,00 | ||
| 6 | 5 | 500,00 | 0,00 |
Borç PlanıExcelDepo v1.0.0
3. İlk kritik stoku bulma (Do Until ve Exit Do)
Stok listesinde stoğu kritik seviyenin altına düşen ilk ürünü bulmak istiyoruz. Do Until döngüsü ilk boş ürün hücresine kadar satırları tarar; aranan ürün bulunur bulunmaz Exit Do ile döngüden çıkılır. Ürün adı D2, satır numarası E2 hücresine yazılır. Kodu standart modüle yapıştırın ve IlkKritikUrunuBul makrosunu çalıştırın.
VBA
24 satır
Option Explicit
Sub IlkKritikUrunuBul()
Dim ws As Worksheet
Dim satir As Long
Set ws = Worksheets("Stok Takibi")
satir = 2
' ürün sütunu boşalana kadar tara
Do Until IsEmpty(ws.Cells(satir, 1).Value)
If ws.Cells(satir, 2).Value < ws.Cells(satir, 3).Value Then
ws.Range("D2").Value = ws.Cells(satir, 1).Value
ws.Range("E2").Value = satir
Exit Do ' ilk kritik ürün bulundu, taramayı bırak
End If
satir = satir + 1
Loop
' hiç kritik ürün bulunmadıysa bilgi ver
If IsEmpty(ws.Range("D2").Value) Then
ws.Range("D2").Value = "Yok"
End If
End Sub
Do - Loop
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ürün | Stok | Kritik Seviye | İlk Kritik Ürün | Satır No |
| 2 | Kalem | 120 | 50 | Dosya | 4 |
| 3 | Defter | 80 | 60 | ||
| 4 | Dosya | 30 | 40 | ||
| 5 | Zımba | 25 | 10 | ||
| 6 | Toner | 3 | 5 | ||
| 7 | Silgi | 200 | 100 |
Stok TakibiExcelDepo v1.0.0
Kullanırken dikkat edin
- Sayacı artırmayı unutmayın: Koşulu etkileyen değişkeni (satır numarası, bakiye gibi) gövdede değiştirmezseniz döngü sonsuza gider. Böyle bir durumda Esc ya da Ctrl + Break tuşlarıyla makroyu durdurun. Önemli çalışmalarda makroyu çalıştırmadan önce dosyayı kaydedin.
- Boş görünen hücrelere dikkat edin: Do Until Cells(satir, 1).Value = "" koşulu, içinde yalnız boşluk karakteri olan hücreyi boş saymaz. Verinizde böyle hücreler olabilirse Trim işlevini kullanın. Verinin arasında boş satır varsa döngü orada erken biter; bu durumda son dolu satırı Cells(Rows.Count, 1).End(xlUp).Row ile bulup For - Next kullanmak daha güvenilir olur.
- Koşulun yerini bilinçli seçin: Koşul Do satırındaysa gövde hiç çalışmayabilir, Loop satırındaysa en az bir kez çalışır. Veri boş olabiliyorsa başta sınayan biçimi, "önce işlemi yap, sonra kontrol et" mantığı için sonda sınayan biçimi seçin. Koşulu hem Do hem Loop satırına yazamazsınız.
- Exit Do yalnız en iç döngüden çıkar: İç içe döngülerde Exit Do dıştaki döngüyü sonlandırmaz. Her iki döngüden birden çıkmak için bir bayrak değişkeni (ör. bulundu = True) kullanıp dış döngünün koşuluna ekleyin.
- Büyük veride hız: Her turda hücreye tek tek yazmak büyük listelerde yavaştır. Makronun başında Application.ScreenUpdating = False yazıp sonunda True yapmak, mümkünse verileri bir dizide toplayıp tek seferde yazmak süreyi belirgin biçimde kısaltır.
- Koşulda Double karşılaştırması: Ondalıklı sayılarla çalışan döngülerde Loop Until x = 0 gibi tam eşitlik koşulları yuvarlama farkları yüzünden hiç gerçekleşmeyebilir. Mümkünse <= ya da >= kullanın ve her zaman bir güvenlik sınırı (Exit Do) koyun.
- İlgili konular:
- For ... Next: tur sayısı bilindiğinde kullanılan sayaçlı döngü.
- For Each ... Next: aralık ya da koleksiyondaki her öğe için döngü.
- While ... Wend: eski tip koşullu döngü; yerine Do - Loop önerilir.
- Exit Do ve Exit For: döngüyü erken terk etme deyimleri.
- If ... Then ... Else: döngü içinde koşullu işlem yapma; çalışma sayfasındaki EĞER işlevinin VBA karşılığı.
- IsEmpty işlevi: hücrenin boş olup olmadığını sınama.
- End(xlUp) özelliği: son dolu satırı bulma.
- Application.ScreenUpdating: döngü sırasında ekran güncellemesini kapatma.