PDA

View Full Version : مديريت خطا در حلقه ها و روتين هاي Call شده بيش از يک بار



kitcat_m18
پنج شنبه 07 مهر 1390, 19:28 عصر
من يه Sub دارم به اين صورت




On Error GoTo Khata

For File_Count = 0 To File1.ListCount - 1
Call Add_From_DOS_To_Win
Khata:

If Err Then
Call Log(File1.FileName, Format(Now, "HH:mm:ss"), Format(Now, "yyyy-mm-dd"), Err.Number & " " & Err.Description)
Err.Clear
End If

Next File_Count




وقتي تو قسمت Add_From_DOS_To_Win به خطايي مي خورم بار اول کنترل خطا انجام ميشه اما بار دوم ديگه کنترل خطا انجام نميشه
اگه دقت کنيد من حتي بعد از لاگ کردن خطا Err رو Clear کردم اما برام جالبه که با اين حال کنترل خطا براي بار دوم اجراي حلقه در Add_From_DOS_To_Win صورت نميگيره . برنامه ارور ميده

يه سوال ديگه:

وقتي از on error goto A تو يه حلقه استفاده مي کنم بعد از رفع خطا از حلقه هم خارج ميشه دليل اين مسئله چيه؟؟؟

مثلا:



Dim i As Long

On Error GoTo p

For i = 1 To Rs_Fox.RecordCount
Rs_DataBase.AddNew

Rs_DataBase.Fields!a= MohsenConvertor.Convert_To_Windows(Rs_Fox.Fields!a Revers_Result_NoRevers)
Rs_DataBase.Fields!b= MohsenConvertor.Convert_To_Windows(Rs_Fox.Fields!b Revers_Result_NoRevers)
p:
Rs_DataBase.Update
Rs_Fox.MoveNext

Next i



تو اين حلقه رفع خطا انجام ميشه اما Next i بعدي انجام نميشه و از حلقه خارج ميشه. :متعجب:

کسي مي تونه منو راهنمايي کنه؟؟؟:متفکر:

با تشکر

محسن واژدی
پنج شنبه 07 مهر 1390, 21:28 عصر
سلام
خب چرا دستگیره را در حلقه قرار داده اید؟!!
همانطور که اطلاع دارید، دستگیره خطا را بایستی در انتهای روال پس دستورات روال قرار دهیم به گونه ای که هیچ دستوری بجز دستورات مرتبط با خطا، پس از آن قرار نداشته باشد

موفق باشید

kitcat_m18
پنج شنبه 07 مهر 1390, 21:42 عصر
سلام،
با تشکر از راهنماييتون کد به اين صورت اصلاح شد:



On Error GoTo Khata

For File_Count = 0 To File1.ListCount - 1
Call Add_From_DOS_To_Win
Edame:
Next File_Count

Khata:

If Err Then
Call Log(File1.FileName, Format(Now, "HH:mm:ss"), Format(Now, "yyyy-mm-dd"), Err.Number & " " & Err.Description)
Err.Clear
resume Edame
End If

محسن واژدی
پنج شنبه 07 مهر 1390, 22:06 عصر
سلام
کد را بصورت زیر اصلاح کنید، بهتر نیست؟

Private Sub Command1_Click()
On Error GoTo Khata

For File_Count = 0 To File1.ListCount - 1

Call Add_From_DOS_To_Win

Edame:

Next File_Count


Exit Sub
Khata:

Call Log(File1.FileName, Format(Now, "HH:mm:ss"), Format(Now, "yyyy-mm-dd"), Err.Number & " " & Err.Description)

Resume Edame

End Sub


و چون در هر زمان که برنامه با خطا مواجه شود این قسمت اجرا میشود و با گذشتن از خطا؛ هندل خطا صفر میشود، پس شرط If Err Then و Err.Clear اضافی است
موفق باشید

kitcat_m18
پنج شنبه 07 مهر 1390, 22:56 عصر
منظور شما اينه با رسيدن به Resume ارور هم پاک ميشه؟(Err.Clear)

بايد تست کنم تا حالا امتخان نکردم من اينو نمي دونستم براي همين:

من ترجيح ميدم ارور رو پاک کنم و سپس براي مرحله بعد ادامه بدم (Err.Clear)

به نظر من جايگزين شدن ارور بعدي با ارور قبلي که در قطعه کد شما اين شکل برگزيده شده است کنترل دقيقي به ما نميده (البته نه در کد ساده بالا)
در کل من به اين سبک کار مي کنم تا بتونم در طول برنامه هر جا که خواستم چک کنم برنامه ارور ديگه اي داده يا نه:

کنترل ارور==>ثبت ارور==>پاک کردن ارور==>ادامه عمليات

و شما:
کنترل ارور==>ثبت ارور==>ادامه عمليات

البته به سبک کار شما هم ميشه با ثبت ارور نامبر قبلي اين کارو کرد اما يه کم بيشتر کار مي بره من ترجيح دادم اين کار بيشتر رو در مبداء خطا با يه شرط و پاک کردن ارور انجام بدم تا در طول برنامه و با ذخيره ارور در متغير و سپس چک کردن اون با ارور جديد، حالا اگه ارور قبلي و ارور جديد هم شماره باشند که باز هم کنترل ارور براي ثبت ارور هم نام نامناسب ميشه

محسن واژدی
پنج شنبه 07 مهر 1390, 23:07 عصر
بله، اما بصورت خودکار بلافاصله پس از انتقال برنامه به خط بعدی اطلاعات خطای قبلی کاملا" حذف و شماره خطا صفر میشود یعنی عمل Err.Clear
کد زیر را بررسی کنید:

Option Explicit

Private Sub Command1_Click()
On Error GoTo hErr
Dim i%
i% = 100000000
nxt:
Debug.Assert False
MsgBox "Err.Number: " & Err.Number & vbNewLine & "Err.Description: " & Err.Description, vbInformation, "Auto cleared"


Exit Sub
hErr:
MsgBox "Err.Number: " & Err.Number & vbNewLine & "Err.Description: " & Err.Description, vbCritical
Resume nxt
End Sub



موفق باشید

kitcat_m18
جمعه 08 مهر 1390, 00:08 صبح
متشکرم جا افتاد

ميشه درباره اين دو کد توضيح بدين؟؟؟


Debug.Assert
Debug.Print


وقتي برنامه رو کامپايل مي کنيم اگر از ديباگ استفاده کرده باشيم اين کد هم کامپايل مي شود و اجرا نمي شود يا اصلا کامپايل نمي شود؟؟؟