Özellik ikonu

UserForm_QueryClose

İndirme izni yok

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.

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.
Olayın yordam adı değişmez: form modülünde UserForm_QueryClose biçiminde olmalıdır. Parametre adlarını değiştirebilirsiniz ancak sıra ve Integer türü korunmalıdır.

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.
Çarpı düğmesini devre dışı bırakıp yalnızca kendi Kapat düğmenizle kapanmasını istiyorsanız, Cancel değerini yalnızca CloseMode sıfır olduğunda True yapın:
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
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.

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.
ABC
1Kapatma YoluSabit AdıCloseMode Değeri
2Kullanıcı Kapat (X) düğmesine tıkladıvbFormControlMenu0
3Kodda Unload deyimi çalıştıvbFormCode1
4Windows oturumu kapanıyorvbAppWindows2
5Görev Yöneticisi uygulamayı kapatıyorvbAppTaskManager3
6MDI ana formu kapanıyorvbFormMDIForm4
Kapatma ModlarıExcelDepo v1.0.0
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.

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.
ABCD
1SenaryoCloseModeKaydedildiSonuç
2X düğmesi, kayıt yapılmamış0YANLIŞEngellendi
3X düğmesi, kayıt yapılmış0DOĞRUKapanır
4Kaydet ve Kapat düğmesi1YANLIŞKapanır
5Windows kapanıyor2YANLIŞKapanır
6Görev Yöneticisi3YANLIŞKapanır
Kapatma KararıExcelDepo v1.0.0
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.

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.
ABC
1AlanGirilen DeğerDurum
2Ad SoyadAyşe DemirDolu
3ŞehirBoş
4Telefon0532 555 01 02Dolu
5ÜrünKulaklıkDolu
6Genel sonuç1Kapatma engellenir (Cancel = True)
Form AlanlarıExcelDepo v1.0.0
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.

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.
Örneklerdeki makroların tamamı indirilebilir Excel dosyasındadır (.xlsm). Dosyayı açtıktan sonra makroları etkinleştirin, ardından Alt + F11 ile Visual Basic Düzenleyicisi'nde kodları inceleyebilir ve Alt + F8 ile çalıştırabilirsiniz.
Yazar
ExcelDepo
İndirme sayısı
0
Gösterim
8
İlk yayın
Güncel

Puanlar

0.00 Oylama 0 İnceleme
Geri
Üst