Genel Bakış
Workbook_SheetChange (Workbook.SheetChange event), çalışma kitabındaki herhangi bir sayfada hücre değeri kullanıcı, VBA kodu ya da dış bağlantı tarafından değiştirildiğinde kendiliğinden çalışan bir olaydır. Her sayfa için ayrı olay yazmak yerine tüm kitabı tek bir yerden izlemenizi sağlar; veri doğrulama, otomatik hesaplama, değişiklik kaydı ve girdi temizleme gibi işlerde kullanılır.
Bir çalışma kitabında bu olay yordamından yalnızca bir tane bulunabilir. Tek bir sayfayı izlemek istiyorsanız o sayfanın kod modülündeki Worksheet_Change olayını kullanın.
Alanı sınırlamak için genellikle Intersect işlevi kullanılır: Intersect(Target, Sh.Range("B2:B11")) sonucu Nothing ise değişiklik izlediğiniz alanın dışındadır.
Şu durumlarda çalışmaz:
EnableEvents özelliği açılmazsa Excel'i kapatıp açana kadar tüm olaylar devre dışı kalır; bu en sık yapılan hatalardandır.
Stok değerleri B2:B7 aralığına yazıldıkça olay her değişiklik için çalışır ve Durum sütununu doldurur. Örneğin Defter satırında Kritik, Zımba satırında Kritik, Dosya satırında ise Yeterli yazılır. Etiketler formül değil, olayın yazdığı düz metindir; stok değerini yeniden değiştirdiğinizde etiket de yeniden belirlenir.
Tek hücrelik değişiklikte C3 hücresine şu not yazılır: Maaş Listesi sayfasında B3 değişti (1 hücre). B5:B6 aralığı tek işlemle değiştirildiğinde olay yalnızca bir kez çalışır ve Target iki hücreyi birden gösterir; bu yüzden C5 hücresinde Maaş Listesi sayfasında B5:B6 değişti (2 hücre) ve C6 hücresinde Maaş Listesi sayfasında B5:B6 değişti (2 hücre) görülür. Değişmeyen satırların not hücreleri boş kalır.
A2, A3 ve A4 hücrelerine boşluklu metin girildiğinde olay her hücre için çalışır, boşlukları siler ve temizlenmiş adın uzunluğunu B sütununa yazar. Karakter sayıları sırasıyla 6, 5 ve 5 olur. Hiç değiştirilmeyen Adana satırında olay çalışmadığı için B5 boş kalır.
Olay yordamı nereye yazılır
Bu olay yordamı yalnızca ThisWorkbook modülüne yazılır. Standart modüle ya da sayfa modülüne yazarsanız olay tetiklenmez.- Adım 1: Alt+F11 tuşlarıyla Visual Basic Düzenleyicisi'ni (VBE) açın.
- Adım 2: Proje Gezgini'nde (Project Explorer) ThisWorkbook öğesine çift tıklayın.
- Adım 3: Kod penceresinin üstündeki sol açılır listeden Workbook, sağ listeden SheetChange seçin. Düzenleyici yordamın iskeletini sizin için yazar.
- Adım 4: Dosyayı makro içerebilen biçimde (.xlsm) kaydedin ve makroların çalışmasına izin verin.
Bir çalışma kitabında bu olay yordamından yalnızca bir tane bulunabilir. Tek bir sayfayı izlemek istiyorsanız o sayfanın kod modülündeki Worksheet_Change olayını kullanın.
Söz dizimi
Olayın söz dizimi şöyledir:
VBA
3 satır
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
' Değişiklik olduğunda çalışacak kod
End Sub
- Sh: Değişikliğin yapıldığı sayfayı temsil eder. Türü Object olduğu için Sh.Name ile sayfa adını alıp hangi sayfada çalışacağınızı belirleyebilirsiniz. Zorunludur, siz değer vermezsiniz; Excel gönderir.
- Target: Değişen hücre ya da hücre aralığıdır (Range nesnesi). Birden çok hücre aynı anda değişmişse (yapıştırma, Ctrl+Enter, aralığa değer yazma, silme) olay tek kez çalışır ve Target tüm aralığı gösterir. Zorunludur.
Alanı sınırlamak için genellikle Intersect işlevi kullanılır: Intersect(Target, Sh.Range("B2:B11")) sonucu Nothing ise değişiklik izlediğiniz alanın dışındadır.
Ne zaman tetiklenir, ne zaman tetiklenmez
Olay, hücreye değer ya da formül girildiğinde, hücre içeriği silindiğinde, yapıştırma ve doldurma işlemlerinde, VBA ile hücre değeri yazıldığında ve dış bağlantı hücre değerini değiştirdiğinde çalışır.Şu durumlarda çalışmaz:
- Yeniden hesaplama: Bir formülün sonucunun değişmesi bu olayı tetiklemez. Bunun için Workbook_SheetCalculate olayı kullanılır.
- Biçim değişiklikleri: Yalnızca renk, yazı tipi ya da sayı biçimi değiştirildiğinde olay oluşmaz.
- Grafik sayfaları: Olay yalnızca çalışma sayfalarındaki hücreler için geçerlidir.
- Olaylar kapalıyken: Application.EnableEvents özelliği False ise hiçbir olay çalışmaz.
Sonsuz döngüyü önleme
Olay içinde hücreye değer yazarsanız bu yazma işlemi olayı yeniden tetikler ve kontrolsüz bir özyineleme oluşabilir. Bunu önlemek için hücreleri değiştirmeden önce olayları kapatın, işiniz bitince mutlaka açın. Hata olursa olayların kapalı kalmaması için hata yakalayıcı kullanın:
VBA
5 satır
Application.EnableEvents = False
On Error GoTo Cikis
' hücreleri değiştiren kod
Cikis:
Application.EnableEvents = True
EnableEvents özelliği açılmazsa Excel'i kapatıp açana kadar tüm olaylar devre dışı kalır; bu en sık yapılan hatalardandır.
1. Stok düşünce durum etiketi yazma
Bir stok listesinde B sütununa stok miktarı girilir. Stok 10'un altına düşünce C sütununa "Kritik", aksi halde "Yeterli" yazılmasını istiyorsunuz. Aşağıdaki kodu ThisWorkbook modülüne yapıştırın. Kod yalnızca "Stok Kontrol" sayfasında ve B2:B7 aralığında çalışır; Intersect ile alanı sınırlar, olayları kapatıp açarak sonsuz döngüyü önler.
VBA
29 satır
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim alan As Range
Dim hucre As Range
' Yalnızca Stok Kontrol sayfasını izle
If Sh.Name <> "Stok Kontrol" Then Exit Sub
' Değişiklik B2:B7 dışındaysa çık
Set alan = Intersect(Target, Sh.Range("B2:B7"))
If alan Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Cikis
For Each hucre In alan.Cells
If IsNumeric(hucre.Value) And Not IsEmpty(hucre.Value) Then
If hucre.Value < 10 Then
hucre.Offset(0, 1).Value = "Kritik"
Else
hucre.Offset(0, 1).Value = "Yeterli"
End If
End If
Next hucre
Cikis:
Application.EnableEvents = True
End Sub
Workbook_SheetChange
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Ürün | Stok | Durum |
| 2 | Kalem | 45 | Yeterli |
| 3 | Defter | 8 | Kritik |
| 4 | Dosya | 120 | Yeterli |
| 5 | Zımba | 5 | Kritik |
| 6 | Makas | 60 | Yeterli |
| 7 | Klasör | 9 | Kritik |
Stok KontrolExcelDepo v1.0.0
2. Değişiklik notunu Target ile yazma
Maaş listesinde B sütunundaki bir hücre ya da hücre grubu değiştiğinde, C sütununa değişikliğin hangi sayfada, hangi adreste ve kaç hücreyi kapsadığını yazan bir not eklemek istiyorsunuz. Kodu ThisWorkbook modülüne yapıştırın. Target.Address ve Target.Cells.Count ile aralığın bilgisi alınır.
VBA
23 satır
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim alan As Range
Dim not_metni As String
If Sh.Name <> "Maaş Listesi" Then Exit Sub
' Yalnızca B2:B7 aralığındaki değişiklikleri ele al
Set alan = Intersect(Target, Sh.Range("B2:B7"))
If alan Is Nothing Then Exit Sub
not_metni = Sh.Name & " sayfasında " & alan.Address(False, False) & " değişti (" & alan.Cells.Count & " hücre)"
Application.EnableEvents = False
On Error GoTo Cikis
' Notu, değişen hücrelerin hemen sağındaki hücrelere yaz
alan.Offset(0, 1).Value = not_metni
Cikis:
Application.EnableEvents = True
End Sub
Workbook_SheetChange
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Personel | Maaş | Not |
| 2 | Ayşe Yılmaz | 18.500,00 | |
| 3 | Mehmet Demir | 23.000,00 | Maaş Listesi sayfasında B3 değişti (1 hücre) |
| 4 | Fatma Kaya | 19.500,00 | |
| 5 | Ali Çelik | 20.000,00 | Maaş Listesi sayfasında B5:B6 değişti (2 hücre) |
| 6 | Zeynep Arslan | 20.000,00 | Maaş Listesi sayfasında B5:B6 değişti (2 hücre) |
| 7 | Hasan Şahin | 16.500,00 |
Maaş ListesiExcelDepo v1.0.0
3. Girilen metni otomatik temizleme
Şehir adlarının girildiği A sütununda kullanıcılar bazen başa ya da sona fazladan boşluk bırakıyor. Hücreye değer girilir girilmez baştaki ve sondaki boşlukları silip B sütununa temizlenmiş adın karakter sayısını yazan kodu ThisWorkbook modülüne yapıştırın.
VBA
25 satır
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim alan As Range
Dim hucre As Range
If Sh.Name <> "Şehir Girişi" Then Exit Sub
Set alan = Intersect(Target, Sh.Range("A2:A11"))
If alan Is Nothing Then Exit Sub
' Kendi yazdığımız değişiklikler olayı yeniden tetiklemesin
Application.EnableEvents = False
On Error GoTo Cikis
For Each hucre In alan.Cells
' Baştaki ve sondaki boşlukları sil
hucre.Value = Trim(hucre.Value)
' Temizlenmiş metnin uzunluğunu yan hücreye yaz
hucre.Offset(0, 1).Value = Len(hucre.Value)
Next hucre
Cikis:
Application.EnableEvents = True
End Sub
Workbook_SheetChange
Formülünü incelemek için bir hücre seçin.| A | B | |
|---|---|---|
| 1 | Şehir | Karakter |
| 2 | Ankara | 6 |
| 3 | İzmir | 5 |
| 4 | Bursa | 5 |
| 5 | Adana |
Şehir GirişiExcelDepo v1.0.0
Kullanırken dikkat edin
- Olayları kapatmayı ve açmayı unutmayın: Olay içinde hücre değiştiriyorsanız Application.EnableEvents özelliğini önce False yapın, sonra mutlaka True yapın. Hata durumunda da açılması için On Error GoTo ile bir çıkış etiketi kullanın; aksi halde Excel kapatılıp açılana kadar hiçbir olay çalışmaz.
- Target birden çok hücre olabilir: Yapıştırma, silme, Ctrl+Enter ile doldurma ya da aralığa değer yazma durumunda Target tek hücre değil aralıktır. Target.Value gibi tek hücre varsayan kodlar bu durumda hata verir. Her zaman For Each ile hücreleri tek tek dolaşın ya da Target.Cells.Count değerini denetleyin.
- Alanı sınırlayın: Olay kitaptaki her sayfadaki her değişiklikte çalışır. Gereksiz çalışmayı önlemek için önce Sh.Name ile sayfayı, sonra Intersect ile alanı denetleyin ve ilgisiz değişikliklerde hemen Exit Sub ile çıkın. Büyük kitaplarda bu, yavaşlamayı önler.
- Geri alma (Undo) geçmişi silinir: Olay yordamı içinde VBA ile hücre değiştirmek Excel'in geri alma geçmişini temizler. Kullanıcılar kendi girdilerini Ctrl+Z ile geri alamayabilir; bunu kullanıcılara önceden belirtin.
- Formül sonuçları tetiklemez: Başka bir hücreye bağlı formülün sonucu değiştiğinde bu olay çalışmaz; yalnızca hücrenin kendisine yazılan değer ya da formül sayılır. Hesaplama sonrası işlem gerekiyorsa Workbook_SheetCalculate olayını kullanın.
- Olay çalışmıyorsa: Kodun ThisWorkbook modülünde olduğunu, yordam adının ve parametrelerin birebir doğru yazıldığını, dosyanın .xlsm olarak kaydedildiğini ve makroların etkin olduğunu kontrol edin. Önceki bir hata yüzünden EnableEvents kapalı kalmış olabilir; Hemen Pencere'de bu özelliği yeniden True yaparak deneyin.
- İlgili konular:
- Worksheet_Change: Tek bir sayfanın kod modülünde çalışan benzer olay.
- Workbook_SheetSelectionChange: Seçim değiştiğinde çalışan olay.
- Workbook_SheetCalculate: Sayfa yeniden hesaplandığında çalışan olay.
- Workbook_Open: Kitap açıldığında çalışan olay.
- Application.EnableEvents: Olayları açıp kapatan özellik.
- Intersect: İki aralığın kesişimini veren yöntem.
- Application.Undo: Son işlemi geri alan yöntem.
- Range.Address: Aralığın adresini metin olarak veren özellik.
- Veri > Veri Araçları > Veri Doğrulama (Data > Data Tools > Data Validation): Kod yazmadan girdi denetimi için alternatif.