Genel Bakış
On Error (On Error statement), VBA'da çalışma zamanı hatası oluştuğunda makronun nasıl davranacağını belirleyen deyimdir. Hatayı bir etikete yönlendirebilir, hatayı yok sayıp sonraki satırdan devam edebilir ya da hata yakalamayı kapatabilirsiniz. Böylece makro beklenmedik bir hata iletisiyle durmak yerine kontrollü biçimde çalışmayı sürdürür ya da sonlanır.
Biçimlerin hepsi zorunludur, yani deyim bu dört kalıptan biriyle yazılır. Deyimdeki öğeler şunlardır:
Bir yordam hata yakalayıcı tanımlamamışsa hata, onu çağıran yordama yükselir ve Excel çağrı zincirinde yukarı doğru etkin bir yakalayıcı arar. Hiçbiri bulunmazsa standart hata iletisi görünür. Bu sayede ortak bir yakalayıcıyı yalnızca ana yordama yazabilirsiniz.
Derleme hataları (söz dizimi hataları) On Error ile yakalanamaz; yalnızca kod çalışırken oluşan hatalar yakalanır.
Kalem Seti için birim fiyat 50,00, Dosya için 24,00, Zımba için 60,00 olarak hesaplanır. Defter satırında adet sıfır olduğundan Durum sütununa Hata 6: Overflow yazılır; Klasör satırında adet metin olduğundan Hata 13: Type mismatch yazılır. Hatalı satırlarda Birim Fiyat hücresi boş kalır ve döngü sonraki satırla devam eder. Resume Devam deyimi hem akışı döngüye geri döndürür hem de hata durumunu temizler.
Geçerli girişlerde zamlı maaş yazılır: Ayşe Yılmaz için 20.350,00, Fatma Kaya için 24.200,00, Zeynep Arslan için 21.725,00. Sayıya çevrilemeyen girişlerde (Mehmet Demir ve Ali Çelik) Zamlı Maaş hücresi boş kalır ve Durum sütununda Geçersiz giriş ifadesi görünür. Hata yakalamanın kapsamı dar tutulmuştur: On Error GoTo 0 döngü turunun sonunda yok sayma davranışını kapatır, böylece kodun geri kalanındaki gerçek hatalar gizlenmez.
Stoğu yeterli ürünlerde Kalan sütunu doldurulur ve Durum sütununda Uygun yazar; Klavye için kalan miktar 15 olur. Fare ve Kulaklık satırlarında satış stoktan büyük olduğundan Err.Raise hata üretir; Kalan hücresi boş kalır ve Durum sütununa Stok yetersiz yazılır. Hata, KalanBul işlevinde yakalayıcı olmadığı için çağıran StokKontrol yordamındaki Hata etiketine ulaşır. Monitör satırında satış ile stok eşit olduğundan hata oluşmaz ve kalan 0 olarak yazılır.
Söz dizimi
On Error deyiminin dört biçimi vardır:
VBA
4 satır
On Error GoTo satırEtiketi
On Error GoTo 0
On Error GoTo -1
On Error Resume Next
- GoTo satırEtiketi: Hata oluşunca çalışmayı aynı yordam içindeki etiketli satıra aktarır. Etiket satırın başına yazılır ve iki nokta ile biter (örneğin Hata
. Etiket aynı Sub, Function ya da Property içinde olmalıdır. - GoTo 0: Geçerli yordamda etkin olan hata yakalamayı kapatır. Bundan sonraki hatalar Excel'in standart hata iletisiyle makroyu durdurur. Err nesnesi de temizlenir.
- GoTo -1: Etkin hata durumunu sıfırlar, yani yakalayıcı içindeyken oluşmuş hatayı temizler. Çoğu durumda Resume deyimi yeterlidir, bu biçim nadiren gerekir.
- Resume Next: Hatayı yok sayar ve hataya neden olan satırdan hemen sonraki satırdan devam eder. Hatanın olup olmadığını Err.Number değerine bakarak kendiniz denetlersiniz.
Hata yakalayıcı nasıl çalışır
On Error GoTo ile etiket belirttiğinizde, o satırdan sonra oluşan her çalışma zamanı hatası etikete atlar. Etiketten sonraki bölüm hata yakalayıcı (error handler) olarak çalışır. Yordamın normal akışı ile yakalayıcı arasına mutlaka Exit Sub (işlevde Exit Function) koyun. Aksi halde hata olmasa bile kod yakalayıcıya düşer. Tipik yapı şöyledir:
VBA
7 satır
Sub Ornek()
On Error GoTo Hata
' normal kodlar
Exit Sub
Hata:
' hata işleme kodları
End Sub
Derleme hataları (söz dizimi hataları) On Error ile yakalanamaz; yalnızca kod çalışırken oluşan hatalar yakalanır.
Err nesnesi ve Resume seçenekleri
Hata oluştuğunda bilgi Err nesnesinde tutulur. Sık kullanılan üyeler şunlardır:- Err.Number: Hata numarası. Hata yoksa 0 değerindedir. Örneğin 11 sıfıra bölme, 13 tür uyuşmazlığı, 9 dizi dizini sınırların dışında hatasıdır.
- Err.Description: Hatanın açıklama metni. Excel'in diline göre görünür.
- Err.Source: Hatayı üreten nesnenin ya da uygulamanın adı.
- Err.Clear: Err nesnesindeki bilgiyi temizler. Resume Next kullanırken bir hatayı işledikten sonra çağırın.
- Err.Raise: Kendi hatanızı üretir. Özel hata numaraları için vbObjectError sabitine ekleme yapılır.
- Resume: Hataya neden olan satırı yeniden dener. Neden ortadan kalkmadıysa sonsuz döngüye girer, dikkatli kullanın.
- Resume Next: Hatalı satırdan sonraki satırdan devam eder.
- Resume etiket: Belirtilen etikete atlar ve hata durumunu temizler.
Hata yakalama ayarı
Visual Basic Düzenleyicisi'nde Araçlar > Seçenekler > Genel > Hata Yakalama (Tools > Options > General > Error Trapping) bölümünde üç seçenek bulunur: Tüm Hatalarda Durdur (Break on All Errors), Sınıf Modülünde Durdur (Break in Class Module) ve İşlenmeyen Hatalarda Durdur (Break on Unhandled Errors). Kodunuzdaki hata yakalayıcıyı denerken makronun hatada durmasını istiyorsanız Tüm Hatalarda Durdur seçeneğini kullanın. Seçili ayar, yakalayıcılarınızın geliştirme sırasında devreye girip girmeyeceğini etkiler.1. Hatayı etikete yönlendirme
Toplam tutarı adede bölerek birim fiyat bulan bir makro yazıyoruz. Adet sıfır ya da metin olduğunda makro durmaz, hata bilgisi Durum sütununa yazılır. Kodu standart bir modüle yapıştırın.
VBA
22 satır
Option Explicit
Sub BirimFiyatHesapla()
Dim ws As Worksheet
Dim i As Long
Set ws = ActiveSheet
' Hata olursa Hata etiketine git
On Error GoTo Hata
For i = 2 To 6
ws.Cells(i, 4).Value = ws.Cells(i, 2).Value / ws.Cells(i, 3).Value
ws.Cells(i, 5).Value = "Hesaplandı"
Devam:
Next i
Exit Sub
Hata:
' Hatayı ilgili satıra yaz, döngüye geri dön
ws.Cells(i, 5).Value = "Hata " & Err.Number & ": " & Err.Description
Resume Devam
End Sub
On Error
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ürün | Toplam Tutar | Adet | Birim Fiyat | Durum |
| 2 | Kalem Seti | 1.250,00 | 25 | 50,00 | Hesaplandı |
| 3 | Defter | 840,00 | 0 | Hata 6: Overflow | |
| 4 | Dosya | 960,00 | 40 | 24,00 | Hesaplandı |
| 5 | Klasör | 530,00 | Yok | Hata 13: Type mismatch | |
| 6 | Zımba | 720,00 | 12 | 60,00 | Hesaplandı |
Bölme KontrolüExcelDepo v1.0.0
2. Resume Next ile hatayı denetleme
Kullanıcıların elle girdiği maaş değerlerine yüzde 10 zam uygulanacak. Sayıya çevrilemeyen girişler On Error Resume Next ile yakalanır ve Durum sütununda işaretlenir. Kodu standart bir modüle yapıştırın.
VBA
29 satır
Option Explicit
Sub ZamHesapla()
Dim ws As Worksheet
Dim i As Long
Dim sayi As Double
Set ws = ActiveSheet
For i = 2 To 6
sayi = 0
' Yalnızca dönüştürme satırı için hatayı yok say
On Error Resume Next
sayi = CDbl(ws.Cells(i, 2).Value)
If Err.Number <> 0 Then
' Dönüştürme başarısız oldu
ws.Cells(i, 4).Value = "Geçersiz giriş"
Err.Clear
Else
ws.Cells(i, 3).Value = Round(sayi * 1.1, 2)
ws.Cells(i, 4).Value = "Geçerli"
End If
' Hata yakalamayı hemen kapat
On Error GoTo 0
Next i
End Sub
On Error
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Personel | Girilen Maaş | Zamlı Maaş | Durum |
| 2 | Ayşe Yılmaz | 18.500,00 | 20.350,00 | Geçerli |
| 3 | Mehmet Demir | yirmi bin | Geçersiz giriş | |
| 4 | Fatma Kaya | 22.000,00 | 24.200,00 | Geçerli |
| 5 | Ali Çelik | n/a | Geçersiz giriş | |
| 6 | Zeynep Arslan | 19.750,00 | 21.725,00 | Geçerli |
Maaş GirişleriExcelDepo v1.0.0
3. Err.Raise ve hatanın çağıran yordama yükselmesi
Satış miktarı stoktan büyükse özel bir hata üreten bir işlev yazıyoruz. İşlevde hata yakalayıcı yoktur; hata çağıran Sub yordamındaki yakalayıcıya yükselir. Kodu standart bir modüle yapıştırın.
VBA
29 satır
Option Explicit
Sub StokKontrol()
Dim ws As Worksheet
Dim i As Long
Set ws = ActiveSheet
On Error GoTo Hata
For i = 2 To 7
ws.Cells(i, 4).Value = KalanBul(ws.Cells(i, 2).Value, ws.Cells(i, 3).Value)
ws.Cells(i, 5).Value = "Uygun"
Devam:
Next i
Exit Sub
Hata:
' Hata mesajını Durum sütununa yaz ve sonraki satıra geç
ws.Cells(i, 5).Value = Err.Description
Resume Devam
End Sub
Function KalanBul(ByVal stok As Long, ByVal satis As Long) As Long
' Bu işlevde hata yakalayıcı yok: hata Sub yordamına yükselir
If satis > stok Then
Err.Raise vbObjectError + 1001, "KalanBul", "Stok yetersiz"
End If
KalanBul = stok - satis
End Function
On Error
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ürün | Stok | Satış | Kalan | Durum |
| 2 | Klavye | 40 | 25 | 15 | Uygun |
| 3 | Fare | 60 | 75 | Stok yetersiz | |
| 4 | Monitör | 15 | 15 | 0 | Uygun |
| 5 | Kulaklık | 30 | 42 | Stok yetersiz | |
| 6 | Yazıcı | 8 | 3 | 5 | Uygun |
| 7 | Tablet | 22 | 10 | 12 | Uygun |
Stok DurumuExcelDepo v1.0.0
Kullanırken dikkat edin
- Exit Sub'ı unutmayın: Yakalayıcı etiketinden hemen önce Exit Sub ya da Exit Function yazmazsanız, hata olmasa bile yordam akışı yakalayıcı koduna düşer ve yanlış hata işlemleri çalışır.
- Resume Next yaygın bir hata gizleme kaynağıdır: On Error Resume Next bütün hataları sessizce yok sayar. Yalnızca hatanın beklendiği tek bir satır için kullanın, hemen ardından Err.Number değerini denetleyin ve işiniz bitince On Error GoTo 0 ile kapatın. Tüm yordamın başına koymak, gerçek hataları fark etmenizi engeller.
- Err nesnesini temizlemeyi unutmayın: Resume Next kullanırken hatayı işledikten sonra Err.Clear çağırmazsanız, bir sonraki denetimde eski hata hala geçerli görünür. On Error deyimleri ve Resume deyimleri de Err nesnesini sıfırlar.
- Yakalayıcı içinde yeni hata: Yakalayıcı çalışırken ikinci bir hata oluşursa, aynı yordamda yeniden yakalanmaz; hata çağıran yordama yükselir ya da hata iletisi görünür. Yakalayıcı kodunu mümkün olduğunca basit tutun.
- Döngü içinde Resume kullanımı: Resume hatalı satırı tekrar çalıştırır. Hatanın nedeni giderilmezse makro sonsuz döngüye girer. Çoğu durumda Resume Next ya da Resume etiket daha güvenlidir.
- Yakalayıcıyı denerken: Hata yakalayıcınızı denerken VBE'de Araçlar > Seçenekler > Genel altındaki Hata Yakalama ayarını kontrol edin. Tüm Hatalarda Durdur seçiliyse makro yakalayıcıya girmeden hatada durur.
- İlgili konular: Err nesnesi (Number, Description, Source, Clear, Raise), Resume deyimi, GoTo deyimi, Exit Sub ve Exit Function deyimleri, Error işlevi, vbObjectError sabiti, Debug.Print, Araçlar > Seçenekler > Genel > Hata Yakalama ayarı ve çalışma sayfası tarafında EĞERHATA, EHATALIYSA ve EHATA işlevleri.