Genel Bakış
Worksheet_Change (Worksheet.Change event), bir çalışma sayfasında hücre değeri kullanıcı ya da kod tarafından değiştirildiğinde otomatik çalışan olaydır. Veri girişini denetlemek, bağlı hücreleri güncellemek veya bir hücre değişince başka hücreye bilgi yazmak gibi işlerde kullanılır. Olay, değişen hücre ya da aralığı Target parametresiyle koda iletir.
Olay yordamı içinde aynı sayfada bir hücreye değer yazarsanız Excel olayı yeniden tetikler ve kod kendi kendini sonsuza dek çağırabilir. Bunu önlemek için hücre yazmadan önce Application.EnableEvents = False yazın, işiniz bitince mutlaka True yapın. Hata olsa bile True değerine dönülmesi için On Error GoTo ile bir temizleme etiketi kullanmak iyi bir alışkanlıktır.
Bu kalıp, kullanıcı birden çok hücre yapıştırsa bile yalnızca izlenen aralığa düşen hücreleri işlemenizi sağlar.
Tetikleyen makro Defter satırındaki miktarı 25, Dosya satırındaki miktarı 40 yaptı. Olay iki kez çalıştı ve bu iki satırın Tutar hücrelerine miktar ile birim fiyatın çarpımı yazıldı: 468,75 ve 396,00. Değişmeyen satırların Tutar hücreleri boş kaldı; çünkü olay yalnızca değişen hücreler için çalışır.
Stok sayımı satırının durumu Tamamlandı yapılınca Bitiş Tarihi hücresine makro çalıştığı günün tarihi yazıldı: 27.10.2026. Fatura kontrolü satırının durumu Devam Ediyor olarak değiştirildiği için o satırdaki eski tarih silindi ve D4 hücresi boşaldı. Değişmeyen satırlara dokunulmadı.
Burak Çelik satırına 135 girildiği için puan 100'e çekildi ve uyarı sütununa Üst sınır: 100 yazıldı. Oğuz Tekin satırına sayı olmayan bir metin girildiği için uyarı olarak Sayı girin yazıldı. Deniz Karaca satırına geçerli bir puan girildiği için uyarı hücresi boş kaldı. Bu örnek, olay yordamında girişi denetleyip hücre değerini düzeltmenin yolunu gösterir.
Olay yordamı nereye yazılır
Olay yordamı, ilgili sayfanın kendi kod modülüne yazılmalıdır. Visual Basic Düzenleyicisi'ni Alt+F11 ile açın, Proje Gezgini'nde sayfayı (ör. Sayfa1) çift tıklayın ya da sayfa sekmesine sağ tıklayıp Kod Görüntüle (View Code) seçin. Kod penceresinin üstündeki sol listeden Worksheet, sağ listeden Change öğesini seçerseniz Excel yordamın iskeletini kendisi oluşturur.- Standart modül: Olay yordamını standart modüle yazarsanız çalışmaz; yalnızca sıradan bir Sub olarak kalır.
- ThisWorkbook modülü: Tüm sayfaları birden izlemek istiyorsanız aynı işi yapan Workbook_SheetChange olayını kullanın.
- Kapsam: Yordam yalnızca yazıldığı sayfadaki değişiklikleri izler. Sayfa modülünde Me, o sayfanın kendisini temsil eder.
Söz dizimi
Olayın söz dizimi şöyledir:
VBA
3 satır
Private Sub Worksheet_Change(ByVal Target As Range)
' Değişikliğe tepki veren kodunuz
End Sub
- Target: Değişen hücre ya da hücre aralığı (Range nesnesi). Zorunludur ve Excel tarafından otomatik verilir. Birden çok hücreye yapıştırma, silme ya da doldurma yapıldığında tüm değişen aralığı kapsar.
- Target.Address: Değişen aralığın adresini metin olarak verir.
- Target.Row ve Target.Column: İlk hücrenin satır ve sütun numarasıdır.
- Target.Cells.Count: Değişen hücre sayısıdır; tek hücre mi çoklu aralık mı olduğunu anlamak için kullanılır.
- Target.Value: Yeni değerdir. Aralık çoklu ise dizi döner; bu yüzden çoklu aralıkta hücreleri For Each ile tek tek dolaşın.
Hangi işlemler olayı tetikler
Olay; hücreye değer yazılması, değerin silinmesi, kopyala-yapıştır, otomatik doldurma ve VBA kodunun hücreye değer yazması ile tetiklenir. Hücre biçimini değiştirmek, hücre seçmek ya da bir formülün sonucunun yeniden hesaplanarak değişmesi olayı tetiklemez. Seçim değişikliği için Worksheet_SelectionChange, hesaplama için Worksheet_Calculate olayını kullanın.Olay yordamı içinde aynı sayfada bir hücreye değer yazarsanız Excel olayı yeniden tetikler ve kod kendi kendini sonsuza dek çağırabilir. Bunu önlemek için hücre yazmadan önce Application.EnableEvents = False yazın, işiniz bitince mutlaka True yapın. Hata olsa bile True değerine dönülmesi için On Error GoTo ile bir temizleme etiketi kullanmak iyi bir alışkanlıktır.
Belirli bir aralığı izlemek
Olay sayfadaki her değişiklikte çalıştığı için çoğu zaman yalnızca ilgilendiğiniz aralığı süzmeniz gerekir. En güvenilir yöntem Intersect işlevidir: izlenecek aralık ile Target kesişmiyorsa sonuç Nothing döner ve yordamdan çıkılır.
VBA
3 satır
Dim alan As Range
Set alan = Intersect(Target, Me.Range("B2:B20"))
If alan Is Nothing Then Exit Sub
1. Miktar değişince tutarı hesaplama
Miktar sütunundaki (B2:B6) bir değer değişince aynı satırın Tutar hücresi (D sütunu) miktar ile birim fiyatın çarpımıyla güncellenir. Kodu bu sayfanın kod modülüne yapıştırın. Intersect ile yalnızca B2:B6 izlenir; EnableEvents ile olayın kendini tekrar çağırması engellenir.
VBA
22 satır
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim alan As Range
Dim hucre As Range
' Yalnızca B2:B6 aralığındaki değişiklikleri işle
Set alan = Intersect(Target, Me.Range("B2:B6"))
If alan Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Cikis
For Each hucre In alan.Cells
' Tutar = Miktar x Birim Fiyat
Me.Cells(hucre.Row, "D").Value = hucre.Value * Me.Cells(hucre.Row, "C").Value
Next hucre
Cikis:
' Hata olsa da olsa olaylar yeniden açılır
Application.EnableEvents = True
End Sub
Worksheet_Change
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Ürün | Miktar | Birim Fiyat | Tutar |
| 2 | Kalem | 120 | 4,50 | |
| 3 | Defter | 25 | 18,75 | 468,75 |
| 4 | Silgi | 200 | 2,25 | |
| 5 | Dosya | 40 | 9,90 | 396,00 |
| 6 | Zımba Teli | 150 | 6,50 |
Stok TakipExcelDepo v1.0.0
2. Durum değişince bitiş tarihi yazma
Durum sütunundaki (C) bir hücreye Tamamlandı yazılınca aynı satırın Bitiş Tarihi hücresine (D) bugünün tarihi yazılır; başka bir durum seçilirse tarih silinir. Kodu bu sayfanın kod modülüne yapıştırın. Yordam yalnızca tek hücrelik değişikliklerde ve C sütununda çalışır. D sütununa yazmak da olayı yeniden tetikler; ancak değişen hücre C sütununda olmadığı için yordam bu ikinci çağrıda hemen çıkar ve döngü oluşmaz.
VBA
18 satır
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' Çoklu hücre değişikliklerini ve başlık satırını atla
If Target.Cells.Count > 1 Then Exit Sub
If Target.Row = 1 Then Exit Sub
' Yalnızca C (Durum) sütunu izlenir
If Target.Column <> 3 Then Exit Sub
If Target.Value = "Tamamlandı" Then
' Bugünün tarihini Bitiş Tarihi sütununa yaz
Me.Cells(Target.Row, 4).Value = Date
Else
' Başka bir durumda tarihi temizle
Me.Cells(Target.Row, 4).ClearContents
End If
End Sub
Worksheet_Change
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Görev | Sorumlu | Durum | Bitiş Tarihi |
| 2 | Aylık rapor hazırlama | Ayşe Yılmaz | Devam Ediyor | |
| 3 | Stok sayımı | Mehmet Kaya | Tamamlandı | 27.10.2026 |
| 4 | Fatura kontrolü | Elif Demir | Devam Ediyor | |
| 5 | Müşteri araması | Can Öztürk | Beklemede |
Görev ListesiExcelDepo v1.0.0
3. Geçersiz puan girişini düzeltme
Puan sütununa (B2:B8) 0 ile 100 arasında sayı girilmesi beklenir. Sınırı aşan değer 100'e çekilir, sayı olmayan giriş ise uyarı notuyla işaretlenir. Uyarılar C sütununa yazılır; geçerli girişte uyarı silinir. Kodu bu sayfanın kod modülüne yapıştırın. Yordam hem hücre değerini düzelttiği hem de uyarı yazdığı için EnableEvents kapatılır ve hata durumunda bile yeniden açılır.
VBA
34 satır
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim alan As Range
Dim hucre As Range
' Yalnızca Puan sütunundaki değişiklikler işlenir
Set alan = Intersect(Target, Me.Range("B2:B8"))
If alan Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Cikis
For Each hucre In alan.Cells
If IsEmpty(hucre.Value) Then
' Hücre silindi: uyarıyı temizle
Me.Cells(hucre.Row, 3).ClearContents
ElseIf VarType(hucre.Value) <> vbDouble Then
' Sayı olmayan giriş
Me.Cells(hucre.Row, 3).Value = "Sayı girin"
ElseIf hucre.Value > 100 Then
hucre.Value = 100
Me.Cells(hucre.Row, 3).Value = "Üst sınır: 100"
ElseIf hucre.Value < 0 Then
hucre.Value = 0
Me.Cells(hucre.Row, 3).Value = "Alt sınır: 0"
Else
Me.Cells(hucre.Row, 3).ClearContents
End If
Next hucre
Cikis:
Application.EnableEvents = True
End Sub
Worksheet_Change
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Öğrenci | Puan | Uyarı |
| 2 | Zeynep Aksoy | 74 | |
| 3 | Burak Çelik | 100 | Üst sınır: 100 |
| 4 | Selin Arslan | 91 | |
| 5 | Oğuz Tekin | yok | Sayı girin |
| 6 | Deniz Karaca | 82 | |
| 7 | Merve Polat | 88 | |
| 8 | Kaan Şimşek | 79 |
Puan GirişiExcelDepo v1.0.0
Kullanırken dikkat edin
- EnableEvents değerini geri açmayı unutmayın: Application.EnableEvents özelliğini False yapıp True'ya döndürmezseniz Excel oturumu kapanana kadar hiçbir olay çalışmaz ve bunu fark etmek zor olur. Kodda hata ihtimali varsa On Error GoTo ile bir temizleme etiketi kullanın. Olaylar kapalı kalmışsa Doğrudan Çalıştır (Immediate) penceresinden Application.EnableEvents = True yazarak düzeltebilirsiniz.
- Çoklu hücre değişikliği: Kullanıcı bir aralığı yapıştırır, siler ya da doldurursa Target birden çok hücre içerir. Target.Value gibi tek hücre varsayan kodlar bu durumda hata verir. Ya Target.Cells.Count ile tek hücreyi sınayın ya da For Each ile alan içindeki hücreleri tek tek işleyin.
- Değeri girilmeden önceki duruma ulaşılamaz: Olay, değişiklik yapıldıktan sonra çalışır; eski değer Target içinde yoktur. Eski değere ihtiyacınız varsa SelectionChange olayında ya da bir değişkende saklamanız gerekir. Application.Undo, VBA ile yapılan değişiklikleri geri almaz; bu nedenle düzeltmeyi hücreye değer yazarak yapın.
- Formül sonucu değişince olay çalışmaz: Bir formülün hesaplanan sonucu değiştiğinde Worksheet_Change tetiklenmez. Yalnızca hücrenin kendisinin değişmesi, yani değer ya da formülün girilmesi olayı çalıştırır. Hesaplama sonrasında işlem yapmak istiyorsanız Worksheet_Calculate olayını kullanın.
- Performans ve büyük işlemler: Olay her değişiklikte çalıştığı için yordam kısa tutulmalıdır. Yordamın başında Intersect ile gereksiz çalışmaları hemen eleyin. Çok sayıda hücreye kodla yazı yazıyorsanız toplu yazma yapın ya da işlem boyunca EnableEvents özelliğini kapatın.
- Makro güvenliği: Olay yordamı içeren çalışma kitabı, makro içerebilen biçimde (.xlsm) kaydedilmelidir. Makrolar devre dışı bırakılmışsa olay da çalışmaz; kullanıcıya içeriği etkinleştirmesi gerektiği belirtilmelidir.
- İlgili konular:
- Workbook_SheetChange: Tüm sayfalardaki değişiklikleri ThisWorkbook modülünden izler.
- Worksheet_SelectionChange: Hücre seçimi değişince çalışır; eski değeri saklamak için kullanılabilir.
- Worksheet_Calculate: Sayfa yeniden hesaplandığında çalışır.
- Application.EnableEvents: Olayların çalışmasını açıp kapatan özelliktir.
- Intersect: İki aralığın kesişimini verir; izlenecek aralığı süzmek için kullanılır.
- Range.Address: Aralığın adresini metin olarak verir.
- Veri Doğrulama (Data Validation): Girişleri formül ya da makro olmadan kısıtlamak için kullanılır.
- EĞER: Makrosuz koşullu hesaplamalar için kullanılan işlevdir.