Genel Bakış
UserForm_QueryClose (QueryClose olayı), bir UserForm kapanmadan hemen önce tetiklenen olaydır. Formun neden kapandığını CloseMode parametresinden öğrenmenizi, kapanışı da Cancel parametresiyle iptal etmenizi sağlar. Kaydedilmemiş verileri denetlemek, eksik alan varken formun kapanmasını önlemek ya da çarpı düğmesini devre dışı bırakmak için kullanılır.
Bu koşul önemlidir: Cancel değerini her durumda True yaparsanız kendi düğmenizdeki Unload Me de iptal edilir ve form hiçbir yolla kapanmaz.
Bu sayfadaki örnekler, form göstermeden çalışabilmesi için olayın mantığını standart modülde çalışan yordamlarla sınar. Karar veren işlevi aynen UserForm modülünüzdeki olay yordamından çağırabilirsiniz.
Makro çalışınca kullanıcı çarpı düğmesine tıkladığında CloseMode değeri 0, kodda Unload çalıştığında 1 olur. Windows kapanışı için 2, Görev Yöneticisi için 3 değeri gelir. MDI sabiti 4 değerini taşır ancak Excel UserForm'larında kullanılmaz.
Kayıt yapılmamışken çarpı düğmesiyle kapatma denemesinin sonucu Engellendi olur. Aynı düğme kayıt yapıldıktan sonra kullanılırsa sonuç Kapanır olur. Kendi düğmenizdeki Unload Me (CloseMode 1) kayıt yokken bile Kapanır sonucunu verir; böylece form kodla kapatılabilir. Windows ve Görev Yöneticisi senaryolarında da sonuç Kapanır ve Kapanır olur.
Makro her alanı kontrol eder; Şehir alanı boş olduğundan Durum sütununda Boş yazılır, diğer alanlar için örneğin Dolu görünür. Eksik alan sayısı 1 olarak bulunur ve karar hücresine Kapatma engellenir (Cancel = True) yazılır. Gerçek formda bu sonuç, olay yordamında Cancel parametresine True atanması anlamına gelir; kullanıcıya MsgBox ile hangi alanın eksik olduğunu da bildirebilirsiniz.
Olay yordamı nereye yazılır
Olay yordamı, ilgili UserForm'un kendi kod modülüne yazılır; standart modüle ya da ThisWorkbook modülüne yazılan yordam olay olarak çalışmaz. Visual Basic Düzenleyicisi'nde (VBE) Proje Gezgini'nde formu seçip F7 tuşuna basın ya da forma sağ tıklayıp Kodu Görüntüle (View Code) deyin. Kod penceresinin sol üstündeki listeden UserForm, sağ üstündeki listeden QueryClose seçildiğinde yordamın iskeleti doğru parametrelerle kendiliğinden oluşur. Bu iskeleti elle yazmak yerine bu yolla oluşturmak, parametre türlerinde hata yapmanızı önler.Söz dizimi
Olay yordamının genel biçimi şöyledir:
VBA
3 satır
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' kapanıştan önce yapılacak denetimler
End Sub
- Cancel: Integer türünde, değiştirilebilen (başvuruyla geçen) parametre. Yordam başlarken değeri 0 (False) olur. Sıfırdan farklı bir değer, örneğin True, atarsanız form kapanmaz ve olay sonrasında Unload ile Terminate işlemleri yapılmaz. Değeri değiştirmezseniz form kapanır.
- CloseMode: Integer türünde, yalnızca okunan parametre. Kapanışı neyin başlattığını söyler; değerleri bir sonraki bölümde listelenmiştir.
CloseMode sabitleri ve Cancel kullanımı
CloseMode parametresi şu VBA sabitlerinden birini taşır:- vbFormControlMenu (0): Kullanıcı formun sağ üstündeki Kapat (X) düğmesine tıkladı ya da Alt+F4 tuşlarına bastı.
- vbFormCode (1): Kodda Unload deyimi çalıştı (örneğin Kapat düğmesinin Click olayında Unload Me).
- vbAppWindows (2): Windows oturumu sonlanıyor.
- vbAppTaskManager (3): Uygulama Görev Yöneticisi tarafından kapatılıyor.
- vbFormMDIForm (4): MDI alt formu, MDI ana formu kapandığı için kapanıyor. Excel UserForm'larında MDI yapısı olmadığından bu değerle karşılaşmazsınız.
VBA
6 satır
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
MsgBox "Lütfen Kapat düğmesini kullanın."
End If
End Sub
Ne zaman tetiklenir, sıralama nasıl işler
Olay, form Unload edilmeden hemen önce çalışır. Kapanış iptal edilmezse sırasıyla form kaldırılır ve UserForm_Terminate olayı çalışır. Formu yalnızca gizleyen Hide yöntemi QueryClose olayını tetiklemez, çünkü form bellekte kalır. Aynı şekilde End deyimi ve VBE'deki Sıfırla (Reset) düğmesi de formu bu olay tetiklenmeden sonlandırır. Bu nedenle verileri kaydetme ya da temizleme işini yalnızca bu olaya bırakmayın.Bu sayfadaki örnekler, form göstermeden çalışabilmesi için olayın mantığını standart modülde çalışan yordamlarla sınar. Karar veren işlevi aynen UserForm modülünüzdeki olay yordamından çağırabilirsiniz.
1. CloseMode sabitlerinin sayısal değerleri
Bu örnekte QueryClose olayının CloseMode sabitlerinin sayısal karşılıkları C sütununa yazılır. Kodu standart bir modüle (Ekle > Modül, Insert > Module) yapıştırın ve makroyu çalıştırın. Yorum satırlarındaki olay yordamı ise gerçek formunuzun kod modülüne yazılacak biçimi gösterir.
VBA
18 satır
Option Explicit
' Gerçek UserForm kod modülünde olay yordamı şöyle yazılır:
' Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' If CloseMode = vbFormControlMenu Then Cancel = True
' End Sub
Sub CloseModeDegerleriniYaz()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Kapatma Modları")
' Her sabitin sayısal değerini C sütununa yaz
ws.Range("C2").Value = vbFormControlMenu
ws.Range("C3").Value = vbFormCode
ws.Range("C4").Value = vbAppWindows
ws.Range("C5").Value = vbAppTaskManager
ws.Range("C6").Value = vbFormMDIForm
End Sub
UserForm_QueryClose
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Kapatma Yolu | Sabit Adı | CloseMode Değeri |
| 2 | Kullanıcı Kapat (X) düğmesine tıkladı | vbFormControlMenu | 0 |
| 3 | Kodda Unload deyimi çalıştı | vbFormCode | 1 |
| 4 | Windows oturumu kapanıyor | vbAppWindows | 2 |
| 5 | Görev Yöneticisi uygulamayı kapatıyor | vbAppTaskManager | 3 |
| 6 | MDI ana formu kapanıyor | vbFormMDIForm | 4 |
Kapatma ModlarıExcelDepo v1.0.0
2. Kapatma kararını CloseMode ile verme
Bu örnekte, kayıt yapılmamışsa yalnızca çarpı düğmesiyle kapanışın engellendiği mantık sınanır. KapatmaEngellenir işlevi, olay yordamındaki Cancel değerinin karşılığını döndürür. Kodu standart bir modüle yapıştırıp KararlariYaz makrosunu çalıştırın. Gerçek formunuzda olay yordamı bu işlevi çağırır; formdaki kayıt durumunu tutan değişkeni de siz tanımlarsınız.
VBA
25 satır
Option Explicit
' UserForm modülünde bu işlev şöyle çağrılır:
' Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' Cancel = KapatmaEngellenir(CloseMode, mKaydedildi)
' End Sub
Function KapatmaEngellenir(ByVal CloseMode As Integer, ByVal Kaydedildi As Boolean) As Boolean
' Yalnızca çarpı düğmesiyle ve kayıt yokken kapanışı engelle
KapatmaEngellenir = (CloseMode = vbFormControlMenu And Not Kaydedildi)
End Function
Sub KararlariYaz()
Dim ws As Worksheet
Dim r As Long
Set ws = ThisWorkbook.Worksheets("Kapatma Kararı")
For r = 2 To 6
If KapatmaEngellenir(CInt(ws.Cells(r, 2).Value), CBool(ws.Cells(r, 3).Value)) Then
ws.Cells(r, 4).Value = "Engellendi"
Else
ws.Cells(r, 4).Value = "Kapanır"
End If
Next r
End Sub
UserForm_QueryClose
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Senaryo | CloseMode | Kaydedildi | Sonuç |
| 2 | X düğmesi, kayıt yapılmamış | 0 | YANLIŞ | Engellendi |
| 3 | X düğmesi, kayıt yapılmış | 0 | DOĞRU | Kapanır |
| 4 | Kaydet ve Kapat düğmesi | 1 | YANLIŞ | Kapanır |
| 5 | Windows kapanıyor | 2 | YANLIŞ | Kapanır |
| 6 | Görev Yöneticisi | 3 | YANLIŞ | Kapanır |
Kapatma KararıExcelDepo v1.0.0
3. Eksik alan denetimi
Bu örnekte formdaki alanların doldurulup doldurulmadığı denetlenir; eksik alan varsa kapanışın iptal edileceği (Cancel değerinin True yapılacağı) sonucuna varılır. Gerçek formda alan değerlerini TextBox denetimlerinden okursunuz; burada sayfadaki değerler kullanılır. Kodu standart bir modüle yapıştırıp AlanlariDenetle makrosunu çalıştırın.
VBA
33 satır
Option Explicit
' Gerçek formda aynı mantık UserForm_QueryClose içinde şöyle kurulur:
' Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' If CloseMode = vbFormControlMenu Then
' If Len(Trim(Me.txtSehir.Value)) = 0 Then Cancel = True
' End If
' End Sub
Sub AlanlariDenetle()
Dim ws As Worksheet
Dim r As Long
Dim eksik As Long
Set ws = ThisWorkbook.Worksheets("Form Alanları")
' Her alanın dolu olup olmadığını denetle
For r = 2 To 5
If Len(Trim(CStr(ws.Cells(r, 2).Value))) = 0 Then
ws.Cells(r, 3).Value = "Boş"
eksik = eksik + 1
Else
ws.Cells(r, 3).Value = "Dolu"
End If
Next r
' Genel sonucu yaz
ws.Range("B6").Value = eksik
If eksik > 0 Then
ws.Range("C6").Value = "Kapatma engellenir (Cancel = True)"
Else
ws.Range("C6").Value = "Kapatma serbest"
End If
End Sub
UserForm_QueryClose
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Alan | Girilen Değer | Durum |
| 2 | Ad Soyad | Ayşe Demir | Dolu |
| 3 | Şehir | Boş | |
| 4 | Telefon | 0532 555 01 02 | Dolu |
| 5 | Ürün | Kulaklık | Dolu |
| 6 | Genel sonuç | 1 | Kapatma engellenir (Cancel = True) |
Form AlanlarıExcelDepo v1.0.0
Kullanırken dikkat edin
- Cancel değerini koşulsuz True yapmayın: Cancel değerini her çağrıda True yaparsanız kodunuzdaki Unload Me de iptal edilir ve form hiçbir yolla kapanmaz. İptali CloseMode değerine göre sınırlayın; genellikle yalnızca vbFormControlMenu durumunda iptal etmek yeterlidir.
- QueryClose içinde Unload çağırmayın: Olay yordamının içinde Unload Me yazmak formu yeniden kapatma sürecine sokar ve olayın tekrar tetiklenmesine yol açabilir. Formu kodla kapatmak istiyorsanız bunu Kapat düğmesinin Click olayında yapın; olayın içinde yalnızca denetim ve iptal kararı verin.
- Hide yöntemi olayı tetiklemez: Me.Hide formu yalnızca gizler; form bellekte kaldığı için QueryClose olayı çalışmaz. End deyimi ve VBE'deki Sıfırla düğmesi de formu bu olay çalışmadan sonlandırır. Mutlaka çalışması gereken temizlik işlerini yalnızca bu olaya bağlamayın.
- Sistem kapanışında iptale güvenmeyin: Windows kapanırken (vbAppWindows) ya da Görev Yöneticisi ile sonlandırmada (vbAppTaskManager) kapanışı iptal etmeye çalışmak çoğu zaman sonuç vermez. Bu durumlarda MsgBox göstermek yerine verileri sessizce korumaya ya da geçici olarak saklamaya bakın.
- Olay yordamını doğru modüle yazın: Yordam yalnızca ilgili UserForm'un kod modülünde olay olarak çalışır. Parametre türlerini (Integer) değiştirirseniz ya da yordam adını yanlış yazarsanız olay hiç tetiklenmez ve hata da vermez. İskeleti kod penceresindeki açılır listelerden oluşturmak en güvenli yoldur.
- İlgili konular:
- UserForm_Initialize: form belleğe yüklenirken çalışan olay.
- UserForm_Activate: form etkinleştirildiğinde çalışan olay.
- UserForm_Terminate: form kaldırıldıktan sonra çalışan olay.
- Unload deyimi: formu kodla kapatır ve QueryClose olayını tetikler.
- Hide yöntemi: formu bellekten kaldırmadan gizler.
- Show yöntemi: formu gösterir; modal ya da modsuz açılabilir.
- MsgBox işlevi: kapanış öncesinde kullanıcıya onay sorusu sormak için kullanılır.
- Workbook_BeforeClose: çalışma kitabı kapanmadan önce çalışan olay.