Genel Bakış
DoEvents, çalışan VBA kodunu çok kısa süreliğine duraklatıp denetimi işletim sistemine ve Excel'e bırakan bir deyim (işlev olarak da çağrılabilir). Bu sırada bekleyen ekran güncellemeleri, fare ve klavye girdileri ile diğer olaylar işlenir, ardından kod kaldığı yerden devam eder. Uzun süren döngülerde Excel'in donmuş gibi görünmesini önlemek ve kullanıcının işlemi yönetebilmesini sağlamak için kullanılır.
Makro çalıştıktan sonra Klavye satırının tutarı 5.400,00, USB Bellek satırının tutarı 4.800,00 olarak yazılır. Döngü sürerken durum çubuğunda ilerleme metni görünür; bu örnekte veri az olduğu için fark hissedilmez, ancak binlerce satırlık tablolarda ilerleme canlı izlenebilir.
B2 hücresine yazılan dönüş değeri 0 olur; Excel'de bu değer bilgi taşımaz. B3 hücresi ise döngüde yapılan çağrı sayısını gösterir: 50. Yani DoEvents kodun akışını değiştirmez, yalnızca her çağrıda denetimi kısa süreliğine Excel'e verir.
Döngü kesintisiz tamamlandığında Ocak ayının kümülatifi 15.000,00, Haziran ayının kümülatifi 114.950,00 olur. Döngü sürerken Durdur makrosu çalıştırılırsa kalan aylar boş kalır. Bayrak denetimi ile DoEvents birlikte kullanılmazsa Durdur makrosu, ana makro bitene kadar çalışamaz.
Söz dizimi
DoEvents iki biçimde yazılabilir: tek başına bir deyim olarak ya da bir değişkene değer döndüren işlev olarak.
VBA
4 satır
DoEvents
' İşlev olarak kullanım
sonuc = DoEvents()
- Parametre: DoEvents hiçbir parametre almaz.
- Deyim biçimi: Yalnızca DoEvents yazılır, bir değer döndürülmez. En sık kullanılan biçim budur.
- İşlev biçimi: DoEvents() bir Integer değer döndürür.
Nasıl çalışır ve dönüş değeri
Excel makroları varsayılan olarak tek bir iş parçacığında çalışır. Makro bitene kadar Excel, kullanıcının tıklamalarına ve ekranı yenileme isteklerine yanıt veremez; bu yüzden pencere "Yanıt vermiyor" durumuna düşebilir. DoEvents çağrıldığında Excel, kuyrukta bekleyen iletileri işler ve denetimi makroya geri verir.- Dönüş değeri: Excel'de işlev olarak çağrıldığında her zaman 0 döner. Bu değer Excel için bir bilgi taşımaz; yalnızca söz diziminin uyumluluğu için vardır.
- Ekran güncelleme: Hücre değişikliklerinin ve Application.StatusBar metninin döngü sırasında görünmesine yardımcı olur. Application.ScreenUpdating değeri False ise ekran yine de yenilenmez.
- Kullanıcı girdisi: Döngü sürerken kullanıcı başka bir makroyu çalıştırabilir, hücre seçebilir ya da bir düğmeye basabilir. Bu özellik, "Durdur" düğmesi gibi yapıların kurulmasını sağlar.
Ne zaman ve nasıl kullanılmalı
DoEvents her çağrıldığında küçük bir zaman maliyeti vardır. Binlerce yineleme olan döngülerde her turda çağırmak makroyu belirgin biçimde yavaşlatır. Bunun yerine belirli aralıklarla, örneğin her 100 turda bir çağırmak daha iyidir.- İlerleme göstermek: Döngü içinde durum çubuğuna ilerleme yazıp ardından DoEvents çağırın.
- İptal bayrağı: Modül düzeyinde bir Boolean değişken tutun, başka bir makro bu değişkeni True yapsın, döngü de her turda değişkeni denetleyip Exit For ile çıksın.
- Kullanmayın: Belirli bir süre beklemek için içinde DoEvents bulunan sonsuz ya da zamanlayıcıya dayalı döngüler kurmak işlemciyi gereksiz yorar.
1. Döngüde ilerleme gösterme
Altı üründe adet ile birim fiyatı çarparak Tutar sütununu dolduran bir makro yazıyoruz. Her satırdan sonra durum çubuğuna ilerleme yazılır ve DoEvents çağrılarak Excel'in ekranı yenilemesine izin verilir. Kodu standart bir modüle yapıştırın.
VBA
24 satır
Option Explicit
Sub TutarHesapla()
Dim ws As Worksheet
Dim i As Long, son As Long
Set ws = ActiveSheet
' A sütunundaki son dolu satırı bul
son = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 2 To son
' Tutar = Adet x Birim Fiyat
ws.Cells(i, 4).Value = ws.Cells(i, 2).Value * ws.Cells(i, 3).Value
' İlerlemeyi durum çubuğunda göster
Application.StatusBar = "İşleniyor: " & (i - 1) & " / " & (son - 1)
' Excel'e ekranı yenileme ve olayları işleme fırsatı ver
DoEvents
Next i
' Durum çubuğunu varsayılan hâline döndür
Application.StatusBar = False
End Sub
DoEvents
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Ürün | Adet | Birim Fiyat | Tutar |
| 2 | Klavye | 12 | 450,00 | 5.400,00 |
| 3 | Fare | 25 | 180,00 | 4.500,00 |
| 4 | Monitör | 5 | 4.200,00 | 21.000,00 |
| 5 | Kulaklık | 18 | 650,00 | 11.700,00 |
| 6 | Webcam | 9 | 900,00 | 8.100,00 |
| 7 | USB Bellek | 40 | 120,00 | 4.800,00 |
Satış HesabıExcelDepo v1.0.0
2. Dönüş değerini ve çağrı sayısını yazma
Bu örnekte DoEvents önce işlev olarak çağrılıp dönüş değeri B2 hücresine yazılır. Ardından elli kez deyim olarak çağrılır ve kaç kez çağrıldığı B3 hücresine yazılır. Kodu standart bir modüle yapıştırın.
VBA
19 satır
Option Explicit
Sub DonusDegeriniYaz()
Dim d As Long
Dim i As Long
Dim sayac As Long
' İşlev olarak çağrı: Excel'de her zaman 0 döner
d = DoEvents()
ActiveSheet.Range("B2").Value = d
' Deyim olarak 50 kez çağır ve çağrıları say
For i = 1 To 50
DoEvents
sayac = sayac + 1
Next i
ActiveSheet.Range("B3").Value = sayac
End Sub
DoEvents
Formülünü incelemek için bir hücre seçin.| A | B | |
|---|---|---|
| 1 | Ölçüt | Sonuç |
| 2 | DoEvents dönüş değeri | 0 |
| 3 | DoEvents çağrı sayısı | 50 |
Dönüş DeğeriExcelDepo v1.0.0
3. İptal bayrağıyla durdurulabilir döngü
Altı aylık satışlardan kümülatif toplamı hesaplayan makroda, modül düzeyinde bir Boolean değişken iptal bayrağı görevi görür. DoEvents sayesinde döngü sürerken Durdur makrosu (bir düğmeye ya da kısayol tuşuna atanarak) çalıştırılabilir ve bayrak True olunca döngü sonlanır. Kodu standart bir modüle yapıştırın ve KumulatifHesapla makrosunu çalıştırın.
VBA
29 satır
Option Explicit
' Döngüyü durdurmak için kullanılan bayrak
Private durdurBayragi As Boolean
Sub KumulatifHesapla()
Dim i As Long
Dim toplam As Double
Dim ws As Worksheet
Set ws = ActiveSheet
durdurBayragi = False
For i = 2 To 7
' Kullanıcı Durdur makrosunu çalıştırdıysa döngüden çık
If durdurBayragi Then Exit For
toplam = toplam + ws.Cells(i, 2).Value
ws.Cells(i, 3).Value = toplam
' Bekleyen olayların (örneğin Durdur makrosunun) işlenmesine izin ver
DoEvents
Next i
End Sub
Sub Durdur()
' Bu makroyu bir düğmeye ya da kısayol tuşuna atayın
durdurBayragi = True
End Sub
DoEvents
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Ay | Satış | Kümülatif |
| 2 | Ocak | 15.000,00 | 15.000,00 |
| 3 | Şubat | 18.500,00 | 33.500,00 |
| 4 | Mart | 21.000,00 | 54.500,00 |
| 5 | Nisan | 17.250,00 | 71.750,00 |
| 6 | Mayıs | 23.400,00 | 95.150,00 |
| 7 | Haziran | 19.800,00 | 114.950,00 |
Aylık ToplamExcelDepo v1.0.0
Kullanırken dikkat edin
- ScreenUpdating etkisi: Application.ScreenUpdating değeri False iken DoEvents çağırmak ekranın yenilenmesini sağlamaz. İlerlemeyi ekranda görmek istiyorsanız bu özelliği True bırakın ya da ilerlemeyi durum çubuğunda gösterin.
- Yeniden giriş (reentrancy) riski: DoEvents sürerken kullanıcı aynı makroyu yeniden başlatabilir, hücreleri değiştirebilir ya da sayfa değiştirebilir. Bu durum beklenmedik sonuçlara yol açabilir. Kodun başında bir "çalışıyor" bayrağı kullanmak ve gerekirse Application.Interactive özelliğini geçici olarak False yapmak daha güvenlidir; ancak makro hata verirse özelliği True yapmayı unutmayın.
- Performans maliyeti: Her çağrı küçük bir gecikme getirir. Çok sayıda yinelemesi olan döngülerde DoEvents çağrısını her turda değil, belirli aralıklarla yapın; örneğin turun 100'e bölümünden kalanın sıfır olduğu durumlarda (If i Mod 100 = 0 Then DoEvents).
- Tek uzun işlemi bölmez: DoEvents yalnızca çağrıldığı noktada etki eder. Tek satırda çalışan ve uzun süren bir işlem, örneğin büyük bir aralığı kopyalamak ya da bir sıralama yapmak, bitene kadar Excel'i meşgul eder. Bu tür işlemleri parçalara bölerek aralarında DoEvents çağırabilirsiniz.
- Bekleme aracı değildir: DoEvents kodu belirli bir süre bekletmez. Zamanlanmış çalıştırma için Application.OnTime kullanılmalıdır. İçinde DoEvents bulunan bitmeyen ya da zamana bağlı bekleme döngüleri işlemciyi gereksiz yere yorar.
- Esc ve iptal tuşu: Kullanıcının makroyu Esc ya da Ctrl+Break ile kesebilmesi Application.EnableCancelKey özelliğinin ayarına bağlıdır. Kendi iptal mekanizmanızı kurmak istiyorsanız Örnek 3'teki gibi bayrak yöntemi daha denetlenebilirdir.
- İlgili konular:
- Application.ScreenUpdating: Ekran yenilemeyi açıp kapatır.
- Application.StatusBar: Durum çubuğuna ilerleme metni yazar.
- Application.Interactive: Kullanıcı girdisini geçici olarak engeller.
- Application.EnableCancelKey: Esc ile makro kesmeyi denetler.
- Application.OnTime: Makroyu belirli bir zamanda çalıştırır.
- Application.Calculate: Hesaplamayı elle başlatır.
- Application.EnableEvents: Olay yordamlarını açıp kapatır.
- For...Next ve Exit For: Döngü kurma ve döngüden çıkma deyimleri.