try...except 中若處理例外錯誤,會中斷外層迴圈?? |
尚未結案
|
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
小弟我目前作一個程式
目的是用迴圈將某一目錄下的 *.sql (SQL Script 檔)
一個一個讀到 TQury 中,然後執行 execsql 方法
並使用 try..except 以便抓到 sql 處理失敗的檔案顯示在 Memo1 中 但每次有錯誤時,整個迴圈就停了
但若不處理例外(也就是 catch 中不放任何程式碼)
迴圈就會繼續(無聲的例外,但就不知執行中有沒有錯誤)
我不知各位長官是否有方法讓 except 處理後,迴圈能繼續
因為就算執行到其中某一 SQL Script 就算有錯 ,
也不代表下一個 SQL Script 也有錯
for i:= 0 to FileListBox1.Count-1 do begin fn := FileListBox1.Directory '\' FileListBox1.Items.Strings[i]; curr_fn:=FileListBox1.Items.Strings[i]; Memo1.Lines.Add('處理 ' curr_fn); Query1.close; Query1.sql.clear; Query1.sql.LoadFromFile(fn); try Query1.execsql; except //由於捕捉訊息會中斷迴圈,故不處理任何被捕捉到的訊息 // Memo1.Lines.Add(FileListBox1.Items.Strings[i] ' 處理失敗'); end; ProgressBar1.Position:=Trunc(((i 1)*100)/(FileListBox1.Count)); Application.ProcessMessages(); end; |
terrychen
尊榮會員 發表:90 回覆:794 積分:501 註冊:2003-05-01 發送簡訊給我 |
您好:
不知道有無誤解您的意思
tools=>debugger options=>language exceptions=>stop on delphi exceptions 將和取方塊取消
就不會因錯誤中斷回圈
小弟認為版主應有注意到此點
只是小弟做了如下的測試,可順利將錯誤ADD至MEMO中
procedure TForm1.Button1Click(Sender: TObject); Var i:integer; begin ADOQuery1.Open; for i := 0 to ADOQuery1.RecordCount- 1 do begin try ADOQuery2.ExecSQL;//故意出錯 except Memo1.Lines.Add('err'); end; end; end;~~應無所住而生其心~~ 發表人 - Terrychen 於 2004/02/02 16:10:46 |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
錯誤保護 try 的例外產生時,會一直影響程式往外延伸擴大直到再度遇到 try
所以我想你可以用兩層 try 試試看
for i:= 0 to FileListBox1.Count-1 do begin fn := FileListBox1.Directory '\' FileListBox1.Items.Strings[i]; curr_fn:=FileListBox1.Items.Strings[i]; Memo1.Lines.Add('處理 ' curr_fn); Query1.close; Query1.sql.clear; Query1.sql.LoadFromFile(fn); try try Query1.execsql; except 這樣應該可以不用關閉 Delphi 內定的例外機制,並加以處理例外狀況 //由於捕捉訊息會中斷迴圈,故不處理任何被捕捉到的訊息 // Memo1.Lines.Add(FileListBox1.Items.Strings[i] ' 處理失敗'); end; finally end; ProgressBar1.Position:=Trunc(((i 1)*100)/(FileListBox1.Count)); Application.ProcessMessages(); end; |
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
|
ko
資深會員 發表:28 回覆:785 積分:444 註冊:2002-08-14 發送簡訊給我 |
|
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
感謝各位長官
我再嚴僅的測試一遍
發覺研究方法有誤
try..except 真的不會中斷迴圈 其實是我放了一個ApplicationEvents 元件在 Form 上
在 try except 中我放了一個 raise
抓到錯誤時將 錯誤 raise 出去給ApplicationEvents 元件
(因為我不知道如何將 Exception 變成文字紀錄起來
我只會使用ApplicationEvents 元件中丟出來的 E.Message 這個東西) 但利用 ApplicationEvents 元件抓取錯誤時
真的會中斷迴圈的執行
procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception); begin if curr_fn<>'' then Memo1.Lines.Add(curr_fn ' 處理失敗'); Memo1.Lines.Add(E.Message); Memo1.Lines.Add(''); end;我後來找到直接在 try..except 中紀錄錯誤的方法(不透過ApplicationEvents 元件就不會中斷迴圈)如下 try Query1.execsql; except on E: EDBEngineError do //處理資料庫引擎錯誤 begin end; on E: EExternalError do //處理視窗類錯誤 begin end; on E: Exception do //處理所有 VCL 錯誤 begin Memo1.Lines.Add(E.Message); end; end;BCB 版如下 try { Query1->ExecSQL(); } catch(EDBEngineError &E) //處理資料庫引擎錯誤 { } catch(EExternalError &E) //處理視窗類錯誤 { } catch(Exception &E) //處理所有 VCL 錯誤 { Memo1->Lines->Add(E.Message); } |
hahalin
版主 發表:295 回覆:1698 積分:823 註冊:2002-04-14 發送簡訊給我 |
班門弄斧一下,紀錄錯誤訊息
try ADOQuery.ExecSQL; except on E:Exception do begin showmessage('執行階段錯誤: ' E.ClassName); SaveErr(E); end; end; procedure SaveErr(E:Exception); var s1 : string; st : TStringList; begin s1 := ExtractFilePath(Application.EXEName) 'err.txt'; st := TStringList.Create; try if FileExists(s1) then begin st.LoadFromFile(sFileName); end; st.Add(FormatDateTime('yyyy/mm/dd hh:nn am/pm', Now); st.Add(ClassName '-' E.Message); st.SaveToFile(sFileName); finally st.Free; end; end; |
shaofu
高階會員 發表:5 回覆:136 積分:103 註冊:2003-01-07 發送簡訊給我 |
引言: 其實是我放了一個ApplicationEvents 元件在 Form 上 在 try except 中我放了一個 raise 抓到錯誤時將 錯誤 raise 出去給ApplicationEvents 元件 (因為我不知道如何將 Exception 變成文字紀錄起來 我只會使用ApplicationEvents 元件中丟出來的 E.Message 這個東西) 但利用 ApplicationEvents 元件抓取錯誤時 真的會中斷迴圈的執行不是 ApplicationEvents 的原因, 是因為你 raise 的關係 |
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
引言: 不是 ApplicationEvents 的原因, 是因為你 raise 的關係 >>< face="Verdana, Arial, Helvetica"> 可是我試過 若再回圈中不用 try ... except 直接執行 Query1.execsql; 如下for i:= 0 to FileListBox1.Count-1 do begin fn := FileListBox1.Directory '\' FileListBox1.Items.Strings[i]; curr_fn:=FileListBox1.Items.Strings[i]; Memo1.Lines.Add('處理 ' curr_fn); Query1.close; Query1.sql.clear; Query1.sql.LoadFromFile(fn); Query1.execsql; ProgressBar1.Position:=Trunc(((i 1)*100)/(FileListBox1.Count)); Application.ProcessMessages(); end;當有錯誤發生, ApplicationEvents 元件仍抓得到例外錯誤,但迴圈一樣被中斷... 先前的作法其實有點"脫褲子放X",藉由 try...except 欄例外錯誤,再轉手將欄到的例外錯誤 raise 給 ApplicationEvents 元件, 反正 ApplicationEvents 元件只要有處理例外,迴圈就終止了 若 try..except 未 raise , 發生錯誤時, try..except 就"自行吸收",ApplicationEvents 元件就抓不到例外, 我只知道 raise 是把抓到的錯誤,"再"丟出去 ... |
shaofu
高階會員 發表:5 回覆:136 積分:103 註冊:2003-01-07 發送簡訊給我 |
|
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |