try...except try...finally

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
Guybrush
Üye
Mesajlar: 15
Kayıt: 24 Kas 2005 04:13
Konum: İzmir

try...except try...finally

Mesaj gönderen Guybrush »

Merhaba. Bu ara hata ayıklama, istisna işleme vb. konularıyla uğraşıyorum. Ve bu iki kavramı anlamaya çalışıyorum. Aslında try...except'in de try...finally'nin de teoride ne işe yaradıklarını anladım da (işte birinde hata gerçekleşen kısım yok sayılıyor diğerinde her halûkârda kod işleme konuluyor) özellikle try...finally'nin genelde hangi durumlar için ne şekilde kullanıldığını tam çözemedim. Küçük bir örnek kodla açıklarsanız sevinirim...
Kullanıcı avatarı
MGd.
Üye
Mesajlar: 41
Kayıt: 08 Nis 2006 06:47
Konum: Aydın

Mesaj gönderen MGd. »

Merhaba. Küçük bir örnek;

Kod: Tümünü seç

uses unit1
.....
.....
.....
var 
    sayi1,sayi2 int;
    sonuc float;
....
....
sayi1:=1;
sayi2:=0;

try
   sonuc:=sayi1/sayi2;
   //sıfıra bölme hatası verecektir.
except 
   application.messagebox('sıfıra bölünemez ','sıfıra bölme hatası');
end;
....
Burada byzero hatası yerine kendi yazmış olduğumuz mesajın gösterilmesi sağlandı.
Mgdizayn.
mkysoft
Kıdemli Üye
Mesajlar: 3110
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Mesaj gönderen mkysoft »

try ... finally bloğunda hatanın neden kaynaklandığıunı yakalayamazsın. Sadece hata oluşur ve finally ... end; arasında kalan kısım çalıştırılır. Hataları kontrol etmek için try ... except kullanılır. Kullanım olarak şöyle bişi yapabilirsin. Mesala bir sürü bilgi giriş alanın var ve hata olmaya ihtimali var. Hataları tek tek kontrol etmek istemiyorsun bu durumda try ... finally yapıp veri finally kısmında veri tabanına kaydedilenleri iptal edebilirsin.
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

Merhaba,

Kod: Tümünü seç

try
....
....
normal şartlar altında işletilecek kodlar
...
..
except
...
..
normal şartlar altında işletilecek kodlar yürütülürken bir istisna oluştuğunda işletilecek kodlar
..
.
end;
try-except hata oluşması muhtemel bloklarda istenmeyen sonuçları önlemek ya da kullanıcıyı bilgilendirmek amacıyla tercih edilir genelde.Bazı durumlarda derleyici değilde kendiniz istisna yaratmak isterseniz belli koşullara göre bu durumdada try-except e ihtiyacınız olacaktır.

Kod: Tümünü seç

try
....
....
normal şartlar altında işletilecek kodlar
...
..
finally
...
..
ne olursa olsun her zaman işletilecek komutlar
..
.
end;
try-finally de normal kod işletilirken istisna oluşşun yada oluşmasın mutlaka işletilmesini istediğimiz durumlarda imdadımıza yetişen bir yöntemdir.Bellek taşmalarını v.b durumları önlemek için bir anlamda korumalı kodlar oluşturmamıza olanak sağlar. Örneğin ,
bir TStringList e ihtiyacımız oldu yarattık kullandık ve işlem sonunda mutlaka yoketmeliyiz, bu şartı kesin sağlamak için try-finally e ihtiyaç duyulur.

Kod: Tümünü seç

procedure tryfinallyTest;
var
Liste:TStringList;
begin
try
  Liste:=TStringList.Create;
  Liste.Add('Deneme');
  Liste.SaveToFile('C:\DOSYA.TXT');
finally
  Liste.Free;
end;
end;
Görüldüğü üzre Liste yaratılıyor ve kullanıldıktan sonra mutlaka yok edilmesi için Free metodu finally bloğu altına yazılıyor.
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Örnek:

Mesaj gönderen sabanakman »

Basit bir örnekte benden :

Kod: Tümünü seç

try
  ADOConnection1.BeginTrans;
  ADOTable1.First;
  while not ADOTable1.Eof do begin
    .
    .
    .
    //kayıt yazma işlemleri.
    ADOTable1.Next;
  end;
  ADOConnection1.CommitTrans;{hata çıkmazsa kayıt işlemleri tamamlanır ve yazılır}
except
  ADOConnection1.RollbackTrans; //hata çıkınca kayıt işlemleri geri alınır
end;
çıkan hata mesajını ve nesnesini elde etmek istersen de

Kod: Tümünü seç

try
  ADOConnection1.BeginTrans;
  ADOTable1.First;
  while not ADOTable1.Eof do begin
    .
    if ADOTable1Toplam.AsFloat<0 then Abort;
    .
    //kayıt yazma işlemleri.
    ADOTable1.Next;
  end;
  ADOConnection1.CommitTrans;{hata çıkmazsa kayıt işlemleri except
  on E:Exception do begin
    ADOConnection1.RollbackTrans; //hata çıkınca kayıt işlemleri geri alınır
    if not E is EAbort ShowMessage(E.Message); {eğer kodlarımla abort çalıştırmamışsam göster}
  end;
end;
şeklinde elde edebilirsin. Kolay gelsin
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
Guybrush
Üye
Mesajlar: 15
Kayıt: 24 Kas 2005 04:13
Konum: İzmir

Teşekkür!

Mesaj gönderen Guybrush »

Yardımlarınız için teşekkürler!
egedenizi
Üye
Mesajlar: 38
Kayıt: 25 May 2005 02:01

Mesaj gönderen egedenizi »

Merhabalar.
Try except ile kitaptan birçok örnek yaptım.Fakat şu sorun çıktı.
örneğin 1/0 hatasıyla ilgili
programı çalıştırdığımda uyarı mesaajı geliyor ve programın akışı kesiliyor.Daha sonra except satırı çalışıyor.bu try except uyarıyı bertaraf etmesi gerekmezmi? yoksa benmi yanlış biliyorum.
Teşekkür ederim.....
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

Merhaba,
Muhtemelen delphi ortamında çalıştırıyorsunuz progrmanızı, varsayılan olarak derleyici mesajları görüntülenir, EXE yi dışarıdan çalıştırırsanız görüntülenmez, eğer derleyicidede görünmesini istemiyorsanız genelde tavsiye olunmaz, Tools / Debugger Options / Language Exceptions sekmesinde ki Stop on Delphi Exceptions seçeneğini deaktif etmelisiniz.
Not: Delphi 5 IDE sine göre anlatılmıştır.
İyi çalışmalar.
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
drony
Üye
Mesajlar: 48
Kayıt: 10 Tem 2004 04:41
Konum: Istanbul
İletişim:

Mesaj gönderen drony »

egedenizi yazdı:Merhabalar.
Try except ile kitaptan birçok örnek yaptım.Fakat şu sorun çıktı.
örneğin 1/0 hatasıyla ilgili
programı çalıştırdığımda uyarı mesaajı geliyor ve programın akışı kesiliyor.Daha sonra except satırı çalışıyor.bu try except uyarıyı bertaraf etmesi gerekmezmi? yoksa benmi yanlış biliyorum.
Teşekkür ederim.....
apiler arası giriş çıkışta bu hatalar gösterliyor. buna tepki veren remote api oluyor
bunu önelemek için çok bir disket sürücü kontrol kodu vardır. ondan global hatalara geri dönüşü içerin bir kdo parçası var onunla bertarafa edeibilirisn
..


ayrıca


tr

.. except ve finally komutunu hataya göre özeleştriblrisi

on {hataclassı} do begin
.....

end;
end;

şeklinde de kullabilirsiniz.
Kullanıcı avatarı
vipaydin
Üye
Mesajlar: 82
Kayıt: 23 Ara 2004 04:52

Mesaj gönderen vipaydin »

Merhaba arkadaşlar.

Peki except ifadesinde hatayı yakaladık. Fakat truncate işlemi yapan query nin hatalı satırı göstermesini ve hatalı olan satırı atlayıp işleme devam etmesini nasıl sağlarız.

Kod: Tümünü seç

try
AdoQuery2.Close;
AdoQuery2.SQL.Clear;
AdoQuery2.SQL.Add('TRUNCATE TABLE '+nextfirmtable+'');
AdoQuery2.ExecSQL;
except
  on E:Exception do
  begin
    raise Exception.Create('hata'+E.Message);
   AdoQuery1.Next;
   end;
Burada hatayı yakalayıp uyarı mesajını veriyoruz. Mesajdan sonra AdoQuery1.Next işlemi ile kaldığı yerden işine devam etmesini nasıl sağlarız?

Tşk.ederim.
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Mesaj gönderen aslangeri »

s.a.
kodun tamamını gönderirseniz... burdan bişey demek zor.
ancak eğer bir döngünü içinde ise next den sonra continue demeniz döngünün başına dönmesini sağlar.
kolay gelsin.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
vipaydin
Üye
Mesajlar: 82
Kayıt: 23 Ara 2004 04:52

Mesaj gönderen vipaydin »

AdoQuery1 de tablo isimlerinin tutulduğu bir döngü var. AdoQuery1 de listelenen tablo isimleri, diğer döngü ile tek tek truncate edililiyor. AdoQuery1 içerisinde bulunan bir tablo eğer yoksa truncate edilemiyor. Dolayısıyla program o noktada kırılıyor.

Öyle fazla özellikli bir şey değil. Sadece hata yakalandıktan sonra mesaj verilip, işleme kaldığı yerden devam edilecek.

continue diyemeyiz, çünkü döngünün başına gitmeyeceğiz. Sadece kaldığı yerden devam edecek.

O tablo ismini bulamadığı için sıradaki tabloya geçecek. Yani NEXT olayı.

Tşk.ederim cevabın için.
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Soru gerekli açıklamalar açısından çok yetersiz. Kullandığın veri tabanı MS SQL Server olarak düşünerek cevap yazıyorum.

-Truncate table primary key tanımlı olup ilişkilendirilmiş tablolarda hata çıkarır. Bunun kayıt satırı ile alakası yoktur. Hatta içinde kayıt olmasa bile hata mesajı doğal olarak gelecektir. Bunun yerine hata çıktığında delete from [tabloadi] kullanmanı tavsiye ederim. Bu arada basit SQL cümleleri için TADOConnection nesnesini kullanmanı öneririm.

Örn:

Kod: Tümünü seç

try
  ADOConnection1.Execute('TRUNCATE TABLE '+nextfirmtable);
except
  on E1:Exception do try
    ADOConnection1.Execute('DELETE FROM '+nextfirmtable);
    S:=E1.Message;
    except
      on E2:Exception do begin
        ShowMessage(Format('Bir hata oluştu'#13#10'%s'#13#10'%s',[S,E2.Message]));
        raise Exception.CreateFmt('%s'#13#10'%s',[S,E2.Message]);
      end;
    end;
  end;
end;
gibi bir kodla TRUNCATE TABLE ile sorun çıkaran tablolar DELETE FROM ile boşaltılmaya çalışılması sağlandığından çok sorun çıkarmaz gibi me geliyor.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
vipaydin
Üye
Mesajlar: 82
Kayıt: 23 Ara 2004 04:52

Mesaj gönderen vipaydin »

Pardon hocam. MSSQL ve B2006 kullanıyorum.

AdoQuery1 ile;
REF - TABLENAME
1 A-TABLO
2 B-TABLO
3 C-TABLO

AdoQuery2 ile yukarıdaki tablolar döngü ile tek tek truncate ediliyor.

Benim sorunum B-TABLO'sunun olmaması durumunda oluşuyor.
TRUNCATE TABLE B-TABLO veya DELETE FROM B-TABLO komutlarında da aynı hata alınacak.
Çünkü B-TABLO diye bir tablo yok.

Döngü ilk satıra geliyor. A-TABLO nun içini boşaltıyor. Bu işlem sırayla devam edecek ama B-TABLO ya geldiği zaman bakıyor ki B-TABLO'su yok. Dolayısıyla program kırılıyor.

Benim istediğim burada bir hata mesajı vermesi (BTABLO su bulunamadı gibi) ve işleme devam etmesi. Sırada C-TABLO'sunun temizlenmesi var. İşlemlerine kaldığı yerden devam edecek.

Tşk.ederim..
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Mesaj gönderen aslangeri »

s.a.
continue aslında senin istediğin işlemi yapıyor.
döngünün başına gidiyor. tablonun başına değil.
kodlara bakınca raise yerine messagedlg veya showmessage kullansan sorunun hallolur gibi duruyor.

Kod: Tümünü seç

......
  on E:Exception do
  begin
    raise Exception.Create('hata'+E.Message);//ama senin asıl sıkıntın burası 
   //raise dediğin zaman programı kırar onun yerine messagedlg yada showmessage kullan. ozaman continueyede gerek kalmaz.
  //hatta raise burdayken continue bile çalışmaz....
   AdoQuery1.Next;
   continue;//burada döngünün başına gider alttaki satırları çalıştırmaz.
   //döngü kaldığı yerden devam eder...
   end; 
........
kolay gelsin.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Cevapla