Genel Bakış
Sleep (Windows API), Windows'un kernel32 kitaplığında bulunan ve çalışan iş parçacığını verilen milisaniye kadar durduran bir API yordamıdır. VBA'da kendi başına bulunmaz; Declare deyimiyle modülün başında bildirildikten sonra çağrılır. Makroya kısa beklemeler eklemek, art arda yapılan istekleri aralıklandırmak ve dış programın işini bitirmesini beklemek için kullanılır.
Bekleme süresi Windows sistem zamanlayıcısının çözünürlüğüne bağlıdır; istenen süreden birkaç ile yaklaşık 15 milisaniye arası sapma olabilir. Hassas süre ölçümü gerekiyorsa Timer işleviyle gerçek geçen süreyi ölçün.
Alternatifler:
Declare içeren makrolar bu sayfada çalıştırılmaz. Makroyu kendi dosyanızda çalıştırdığınızda B2 hücresi önce "İşleniyor", yaklaşık 2 saniye sonra "Tamamlandı" olur. Sleep sırasında Excel donuk kalacağı için ara durum ekranda görünmeyebilir; durum çubuğu iletisi de aynı nedenle geç yenilenebilir.
Bu örnek Declare içerdiği için burada çalıştırılmaz. Kendi dosyanızda çalıştırdığınızda döngü 5 kez döner. Her satırın durumu "Sorgulandı" olur ve C sütununa 0,3 saniyeye yakın bir süre yazılır. Toplam bekleme yaklaşık 1,5 saniyedir. Döngü sonludur; Sleep yalnızca her turda kısa bir ara verir.
Makro çalıştıktan sonra "Veri çekme" adımı için C2 hücresinde 2000, "Kullanıcı girişi" için C3 hücresinde 500 değeri görünür; Sleep çağrısında bu sayılar doğrudan kullanılabilir. "Uzun bekleme" satırı Long sınırını aştığı için C6 hücresine Sınır aşıldı yazılır. Gerçek bir makroda Sleep'i çağırmadan önce bu tür bir denetim taşma hatasını önler.
Söz dizimi
Sleep, VBA'da hazır gelmediği için önce bildirilmelidir. Modern Excel sürümleri (VBA7) için bildirim ve çağrı şöyledir:
VBA
9 satır
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub Ornek()
Sleep 1500 ' 1,5 saniye bekler
End Sub
- dwMilliseconds: Beklenecek süre, milisaniye cinsinden (1000 milisaniye = 1 saniye). Zorunludur, varsayılanı yoktur. ByVal ile değer olarak geçirilir.
- Dönüş değeri: Yoktur. Sleep bir Sub olarak bildirilir; sonucu bir değişkene atanmaz ve çağrıda parantez kullanılmaz.
- 0 değeri: İş parçacığı kalan zaman dilimini başka işlere bırakır, fiilen bekleme olmaz.
- Üst sınır: VBA'daki Long türü en fazla 2.147.483.647 değerini taşır (yaklaşık 24 gün). Bundan büyük değer taşma hatası verir.
Declare bildirimi nasıl yazılır
Bildirimi Visual Basic Düzenleyicisi'nde (Geliştirici > Visual Basic (Developer > Visual Basic) ya da Alt+F11) Ekle > Modül (Insert > Module) ile açtığınız modülün en üstüne, Sub ve Function tanımlarından önce yazın.- PtrSafe: 64 bit Excel'de zorunludur; yoksa derleme hatası alırsınız. Eski 32 bit sürümlerde bu sözcük tanınmaz.
- #If VBA7 Then ... #Else ... #End If: Aynı dosyanın hem eski hem yeni sürümlerde derlenmesini sağlayan koşullu derleme bloğudur. Yukarıdaki iki satırlı biçimi her zaman kullanmak güvenlidir.
- Private ve Public: Standart modülde Public Declare yazarak Sleep'i tüm projeden çağırabilirsiniz. Sayfa, ThisWorkbook, UserForm ve sınıf modüllerinde Declare yalnızca Private olabilir.
- Lib "kernel32": İşlevin bulunduğu Windows kitaplığıdır. Bu bildirim yalnızca Windows'ta çalışır; Mac için Excel'de kernel32 yoktur.
Sleep nasıl çalışır ve sınırları
Sleep, Excel'in çalıştığı iş parçacığını tamamen durdurur. Bu süre boyunca Excel yanıt vermez, ekran yenilenmeyebilir, hücrelere tıklanamaz ve başlık çubuğunda "Yanıt Vermiyor" görülebilir. Esc ya da Ctrl+Break ile de bekleme kesilemez; süre dolana kadar beklemeniz gerekir. Bu nedenle uzun süreler yerine kısa ve sayılı beklemeler tercih edilir.Bekleme süresi Windows sistem zamanlayıcısının çözünürlüğüne bağlıdır; istenen süreden birkaç ile yaklaşık 15 milisaniye arası sapma olabilir. Hassas süre ölçümü gerekiyorsa Timer işleviyle gerçek geçen süreyi ölçün.
Alternatifler:
- Application.Wait: Saniye hassasiyetindedir ve belirli bir saate kadar bekler; API bildirimi gerektirmez.
- Application.OnTime: Makroyu Excel'i dondurmadan, belirli bir zamanda çalıştırır.
- Timer işlevi: Gün başından beri geçen saniyeyi verir; süre ölçmek için kullanılır.
1. Uzun işlem öncesi kısa bekleme
Bir raporun hazırlandığını taklit eden basit bir makro yazın. Bildirim ve makro aynı standart modüle (Ekle > Modül) yapıştırılır. Makro, durumu "İşleniyor" yapar, durum çubuğuna ileti yazar, 2 saniye bekler ve durumu "Tamamlandı" yapar.
VBA
19 satır
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub RaporuHazirla()
' Durumu güncelle ve kullanıcıya bilgi ver
Range("B2").Value = "İşleniyor"
Application.StatusBar = "Sunucu yanıtı bekleniyor..."
' 2000 milisaniye = 2 saniye bekle
Sleep 2000
Range("B2").Value = "Tamamlandı"
Application.StatusBar = False
End Sub
Sleep
Formülünü incelemek için bir hücre seçin.| A | B | |
|---|---|---|
| 1 | Rapor | Durum |
| 2 | Aylık Satış | Bekliyor |
Rapor DurumuExcelDepo v1.0.0
2. Döngüde istekleri aralıklandırma
Beş şehir için art arda sorgu yapıldığını varsayın ve sunucuyu yormamak için her sorgudan sonra 300 milisaniye bekleyin. Kodu standart modüle yapıştırın. Timer ile her adımın süresi C sütununa yazılır.
VBA
25 satır
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub SehirleriSorgula()
Dim i As Long
Dim t As Single
For i = 2 To 6
t = Timer
' Burada gerçek sorgu işlemi yapılır
Cells(i, 2).Value = "Sorgulandı"
' Sonraki isteğe geçmeden önce 300 ms bekle
Sleep 300
' Geçen süreyi saniye olarak yaz
Cells(i, 3).Value = Round(Timer - t, 2)
Next i
End Sub
Sleep
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Şehir | Durum | Süre (sn) |
| 2 | İstanbul | Bekliyor | |
| 3 | Ankara | Bekliyor | |
| 4 | İzmir | Bekliyor | |
| 5 | Bursa | Bekliyor | |
| 6 | Antalya | Bekliyor |
Şehir SorgularıExcelDepo v1.0.0
3. Saniyeyi milisaniyeye çevirme ve sınır denetimi
Sleep milisaniye ister; çoğu zaman süreyi saniye olarak düşünürüz. Bu örnek Declare içermez ve gerçekten çalışır: B sütunundaki saniye değerlerini milisaniyeye çevirip C sütununa yazar, Long sınırını aşan değeri işaretler. Hesaplanan değerler Sleep'e verilecek sayılardır. Kodu standart modüle yapıştırın.
VBA
21 satır
Option Explicit
Sub MilisaniyeHesapla()
Dim ws As Worksheet
Dim i As Long
Dim ms As Double
Set ws = ActiveSheet
For i = 2 To 6
' Saniyeyi milisaniyeye çevir
ms = ws.Cells(i, 2).Value * 1000
' Sleep için Long sınırı: 2.147.483.647
If ms > 2147483647# Then
ws.Cells(i, 3).Value = "Sınır aşıldı"
Else
ws.Cells(i, 3).Value = CLng(ms)
End If
Next i
End Sub
Sleep
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Adım | Bekleme (sn) | Milisaniye |
| 2 | Veri çekme | 2 | 2000 |
| 3 | Kullanıcı girişi | 0,5 | 500 |
| 4 | Rapor yenileme | 1,5 | 1500 |
| 5 | Kuyruk bekleme | 0,25 | 250 |
| 6 | Uzun bekleme | 3000000 | Sınır aşıldı |
Bekleme PlanıExcelDepo v1.0.0
Kullanırken dikkat edin
- Declare bildirimi en üstte olmalı: Declare deyimi modülün bildirim bölümünde, yani ilk Sub ya da Function'dan önce yer almalıdır. Yordamın içine yazarsanız derleme hatası alırsınız. Aynı adla ikinci bir Sleep bildirimi de "Belirsiz ad" hatasına yol açar.
- 64 bit uyumluluğu: PtrSafe içermeyen eski bildirimler 64 bit Excel'de derlenmez. Dosyayı farklı sürümlerdeki kullanıcılarla paylaşacaksanız #If VBA7 Then bloğunu mutlaka kullanın.
- Excel donar: Sleep sırasında Excel hiçbir işleme yanıt vermez ve Esc ile durdurulamaz. Kullanıcıya uzun süreli donma yaşatmamak için bekleme sürelerini kısa tutun. Sleep'ten önce bir ekran güncellemesi gerekiyorsa tek bir DoEvents çağrısı ekranı tazeleyebilir; bunu bekleme döngüsü olarak kullanmayın.
- Sleep bir Sub'dır: Sleep değer döndürmez. Sleep(1000) biçiminde sonuç bekleyen bir çağrı yazmayın; doğru kullanım Sleep 1000 şeklindedir. Sayıyı değişkenle verecekseniz değişkenin Long olmasına dikkat edin.
- Platform sınırı: kernel32 yalnızca Windows'ta bulunur. Mac için Excel'de ve Excel'in web sürümünde bu bildirim çalışmaz. Platformlar arası dosyalarda Application.Wait gibi API gerektirmeyen yöntemi tercih edin.
- Makro güvenliği: API çağrısı içeren dosyalar .xlsm ya da .xlsb olarak kaydedilmelidir; .xlsx biçimi makro saklamaz. Kullanıcıların makroları etkinleştirmesi gerekir.
- İlgili konular:
- Declare deyimi: Dış kitaplıktaki yordamları VBA'ya tanıtır.
- PtrSafe: 64 bit uyumlu API bildirimi anahtar sözcüğüdür.
- #If...Then...#Else: Koşullu derleme yönergesidir.
- Application.Wait: Belirli bir zamana kadar bekleten Excel yöntemidir.
- Application.OnTime: Makroyu zamanlanmış çalıştırır.
- Timer işlevi: Geçen süreyi saniye olarak ölçer.
- DoEvents: Excel'in bekleyen olayları işlemesine izin verir.
- Application.StatusBar: Durum çubuğuna ileti yazar.
- Application.ScreenUpdating: Ekran güncellemesini açar ya da kapatır.