2013-07-24 42 views
2

我一直在尋找我的問題的答案,我一直沒能找到太多,所以我在這裏發佈,希望更有經驗的開發人員能夠啓發我。在子結構中構造異常處理的正確方法是什麼?我是否應該包裝我的Try,Catch,End嘗試圍繞我的整個代碼塊,或者可以包裝Try,Catch,End嘗試圍繞我的子塊中的一個塊,然後嘗試,捕獲,結束嘗試圍繞另一塊代碼在同一個子?下面是我要問一個例子:在VB.NET中適當的異常處理

這是更好的?:(OPTION 1)

Try 
     'check if user has selected a file 
     If ListBoxPrePublish.SelectedItems.Count = 0 Then 
      MessageBox.Show("Please select a file to delete.") 
      Exit Sub 
     End If 

     'check if user has selected a Memo to publish, if so, move file to Publish folder; if user hasn't selected a Memo, move to next If statement 
     If ListBoxPrePublish.SelectedItem.Contains("-M.xls") Then 
      Dim resultMemo = MessageBox.Show("Are you sure you want to delete this Memo?", "", MessageBoxButtons.YesNo) 
      If resultMemo = DialogResult.Yes Then 
       Dim filePath As String = "W:\TOM\ERIC\Award_Letters\Excel pre_publish\" 
       Dim movePath As String = "W:\TOM\ERIC\Award_Letters\Publish\" 
       Dim filenm As String = ListBoxPrePublish.SelectedItem 
       Dim FileToMove = filePath & filenm 
       Dim MoveToLocation = movePath & filenm 
       'move the file 
       System.IO.File.Move(FileToMove, MoveToLocation) 
       ListBoxPublished.Items.Add(ListBoxPrePublish.SelectedItem) 
       ListBoxPrePublish.Items.Remove(ListBoxPrePublish.SelectedItem) 
       Exit Sub 
      Else 
       Exit Sub 
      End If 
     End If 



     'ask user if they're sure they want to publish selected file and corresponding files...remember, only if the selected item is not a Memo 
     Dim result = MessageBox.Show("This action will publish all corresponding files for the selected student except for Memos. Memos must be deleted individually. Do you want to continue?", "", MessageBoxButtons.YesNo) 
     If result = DialogResult.No Then 
      Exit Sub 
     Else 

      If result = DialogResult.Yes Then 
       'find ID for student in unapprovd accounting file, move the record to the Deleted Today file, delete record from unapproved accounting file 
       Dim UnapprovedAcctFile As String = "W:\TOM\ERIC\Award_Letters\Accounting Files\Unapproved\" & StatVar.xlApp.Sheets("New Calculator Input").Range("D30").Value & ".xlsx" 
       Dim ApprovedAcctFile As String = "W:\TOM\ERIC\Award_Letters\Accounting Files\Approved\" & StatVar.xlApp.Sheets("New Calculator Input").Range("D30").Value & " Import" & ".xlsx" 
       Dim searchString As String = StatVar.xlApp.Sheets("Cross Checking").Range("J6").Text 'this is the ID that will be searched for in the accounting file 
       Dim rng 

       'make sure accounting file for school exists 
       If Not IO.File.Exists(UnapprovedAcctFile) Then 
        MessageBox.Show("Could not locate the accounting file for this school. Please contact an administrator for assistance.") 
        Exit Sub 
       End If 

       'open accounting file and check if it's read only, if so, another user is editing it so close it and tell the user to try again in a few seconds, if it's not read only, see next comment 
       StatVar.xlWBUnapprovedAcctFile = StatVar.xlApp.Workbooks.Open(UnapprovedAcctFile) 
       If StatVar.xlApp.ActiveWorkbook.ReadOnly = True Then 'check if file is read only, if so close it and exit sub 
        StatVar.xlApp.ActiveWorkbook.Close(False) 
        MessageBox.Show("The system is busy. Please try again in a few seconds.") 
        Exit Sub 
       End If 

       'search unapproved accounting file for ID (SSN-award year example: 555555555-13) - use searchString variable above 
       rng = StatVar.xlApp.ActiveWorkbook.Sheets("Sheet1").Range("BD2:BD30002").Find(searchString, , Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlWhole, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, False) 
       'if searchString is found 
       If rng IsNot Nothing Then 
        rng.EntireRow.Select() 'select the row searchString was found in 
        'check if approved accounting file for this school exists, if not, create it 
        If Not IO.File.Exists(ApprovedAcctFile) Then 
         StatVar.xlApp.Workbooks.Add() 
         StatVar.xlApp.ActiveWorkbook.SaveAs(ApprovedAcctFile) 
         StatVar.xlApp.ActiveWorkbook.Close(True) 
        End If 
        StatVar.xlWBApprovedAcctFile = StatVar.xlApp.Workbooks.Open(ApprovedAcctFile) 'open the Approved file 
        If StatVar.xlApp.ActiveWorkbook.ReadOnly = True Then 'check if the Approved file is read only, if so, close it and exit sub because it needs to be writable 
         StatVar.xlApp.ActiveWorkbook.Close(False) 'close the Approved file, don't save changes 
         StatVar.xlApp.ActiveWorkbook.Close(False) 'close unapproved accounting file, don't save changes 
         MessageBox.Show("The system is busy. Please try again in a few seconds.") 
         Exit Sub 
        End If 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.Columns("AV").NumberFormat = "@" 'format column AV of the Approved file as text so "13/14" remains formatted correctly 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.Rows("1:1").Insert(Excel.XlInsertShiftDirection.xlShiftDown) 'insert a row at the top of the Approved file 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.Rows("1:1").Value = rng.EntireRow.Value 'set the 1st row of the Approved file equal to the row selected earlier in the unapproved accounting file 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.UsedRange.RemoveDuplicates(Columns:=(56)) 'search column 56 in Approved file for duplicates and remove entire row if a duplicate ID is found 
        rng.EntireRow.Delete() 'delete row the searchString was found in from the unapproved accounting file 
        StatVar.xlApp.ActiveWorkbook.Close(True) 'close the Approved file, save changes 
        StatVar.xlApp.ActiveWorkbook.Close(True) 'close unapproved accounting file, save changes 
        'MessageBox.Show("Eureka!") 
       Else 
        'if searchString is not found, close unapproved accounting file, inform user and exit sub 
        StatVar.xlApp.ActiveWorkbook.Close(False) 
        MessageBox.Show("Could not locate this record on the accounting file. Your files were not deleted.") 
        Exit Sub 
       End If 

       'move selected file and corresponding non-Memo files to Publish folder 
       Dim filePath As String = "W:\TOM\ERIC\Award_Letters\Excel pre_publish\" 
       Dim movePath As String = "W:\TOM\ERIC\Award_Letters\Publish\" 
       Dim filenm As String 

       'check if each item in listbox contains the string extracted from the selected item via Excel formula; listbox select event sends the filename to Excel and a formula extracts the string to find in each listbox item...look for this string 
       For Each c In ListBoxPrePublish.Items 
        If c.ToString.Contains(StatVar.xlApp.Sheets("Cross Checking").Range("H6").Text) Then 
         'make sure the current listbox item in this loop is not a Memo, if it's not, move it 
         If Not c.ToString.Contains("-M.xls") Then 
          filenm = c 
          Dim FileToMove = filePath & filenm 
          Dim MoveToLocation = movePath & filenm 
          System.IO.File.Move(FileToMove, MoveToLocation) 
          ListBoxPublished.Items.Add(c) 'add files files that are being published to the published files listbox 
         End If 
        End If 
       Next 

       'refresh prepublish list, if user has a school selected, REMOVE all list items that don't contain the school code being generated via VLOOKUP in Excel using the school name from comboboxschool; look for this string in the loop surrounded with "-" 
       Call ListFiles() 
       If ComboBoxSchool.Text <> "" Then 
        For i As Integer = ListBoxPrePublish.Items.Count - 1 To 0 Step -1 
         'if current loop item does not contain the school code for the selected school, remove the item from the listbox 
         If Not ListBoxPrePublish.Items(i).Contains("-" & StatVar.xlApp.Sheets("Cross Checking").Range("E3").Text & "-") Then 
          ListBoxPrePublish.Items.RemoveAt(i) 
         End If 
        Next 
       End If 
       'refresh deleted files listbox 
       Call ListDeletedTodayFiles() 

      End If 
     End If 
    Catch exc As Exception 
     MessageBox.Show("Unable to publish the selected file. Please verify this file or any of its corresponding files are not open by you or another user. If the problem persists, contact an administrator for assistance." & vbNewLine & vbNewLine & "Error: " & exc.Message) 
    End Try 

,或者這更好的?:(OPTION 2)

Try 
     'check if user has selected a file 
     If ListBoxPrePublish.SelectedItems.Count = 0 Then 
      MessageBox.Show("Please select a file to delete.") 
      Exit Sub 
     End If 

     'check if user has selected a Memo to publish, if so, move file to Publish folder; if user hasn't selected a Memo, move to next If statement 
     If ListBoxPrePublish.SelectedItem.Contains("-M.xls") Then 
      Dim resultMemo = MessageBox.Show("Are you sure you want to delete this Memo?", "", MessageBoxButtons.YesNo) 
      If resultMemo = DialogResult.Yes Then 
       Dim filePath As String = "W:\TOM\ERIC\Award_Letters\Excel pre_publish\" 
       Dim movePath As String = "W:\TOM\ERIC\Award_Letters\Publish\" 
       Dim filenm As String = ListBoxPrePublish.SelectedItem 
       Dim FileToMove = filePath & filenm 
       Dim MoveToLocation = movePath & filenm 
       'move the file 
       System.IO.File.Move(FileToMove, MoveToLocation) 
       ListBoxPublished.Items.Add(ListBoxPrePublish.SelectedItem) 
       ListBoxPrePublish.Items.Remove(ListBoxPrePublish.SelectedItem) 
       Exit Sub 
      Else 
       Exit Sub 
      End If 
     End If 
    Catch exc As Exception 
     MessageBox.Show("An error occured and the selected file was not published. Please contact an administrator if the problem continues." & vbNewLine & vbNewLine & "Error: " & exc.Message) 
    End Try 

    Try 
     'ask user if they're sure they want to publish selected file and corresponding files...remember, only if the selected item is not a Memo 
     Dim result = MessageBox.Show("This action will publish all corresponding files for the selected student except for Memos. Memos must be deleted individually. Do you want to continue?", "", MessageBoxButtons.YesNo) 
     If result = DialogResult.No Then 
      Exit Sub 
     Else 

      If result = DialogResult.Yes Then 
       'find ID for student in unapprovd accounting file, move the record to the Deleted Today file, delete record from unapproved accounting file 
       Dim UnapprovedAcctFile As String = "W:\TOM\ERIC\Award_Letters\Accounting Files\Unapproved\" & StatVar.xlApp.Sheets("New Calculator Input").Range("D30").Value & ".xlsx" 
       Dim ApprovedAcctFile As String = "W:\TOM\ERIC\Award_Letters\Accounting Files\Approved\" & StatVar.xlApp.Sheets("New Calculator Input").Range("D30").Value & " Import" & ".xlsx" 
       Dim searchString As String = StatVar.xlApp.Sheets("Cross Checking").Range("J6").Text 'this is the ID that will be searched for in the accounting file 
       Dim rng 

       'make sure accounting file for school exists 
       If Not IO.File.Exists(UnapprovedAcctFile) Then 
        MessageBox.Show("Could not locate the accounting file for this school. Please contact an administrator for assistance.") 
        Exit Sub 
       End If 

       'open accounting file and check if it's read only, if so, another user is editing it so close it and tell the user to try again in a few seconds, if it's not read only, see next comment 
       StatVar.xlWBUnapprovedAcctFile = StatVar.xlApp.Workbooks.Open(UnapprovedAcctFile) 
       If StatVar.xlApp.ActiveWorkbook.ReadOnly = True Then 'check if file is read only, if so close it and exit sub 
        StatVar.xlApp.ActiveWorkbook.Close(False) 
        MessageBox.Show("The system is busy. Please try again in a few seconds.") 
        Exit Sub 
       End If 

       'search unapproved accounting file for ID (SSN-award year example: 555555555-13) - use searchString variable above 
       rng = StatVar.xlApp.ActiveWorkbook.Sheets("Sheet1").Range("BD2:BD30002").Find(searchString, , Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlWhole, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, False) 
       'if searchString is found 
       If rng IsNot Nothing Then 
        rng.EntireRow.Select() 'select the row searchString was found in 
        'check if approved accounting file for this school exists, if not, create it 
        If Not IO.File.Exists(ApprovedAcctFile) Then 
         StatVar.xlApp.Workbooks.Add() 
         StatVar.xlApp.ActiveWorkbook.SaveAs(ApprovedAcctFile) 
         StatVar.xlApp.ActiveWorkbook.Close(True) 
        End If 
        StatVar.xlWBApprovedAcctFile = StatVar.xlApp.Workbooks.Open(ApprovedAcctFile) 'open the Approved file 
        If StatVar.xlApp.ActiveWorkbook.ReadOnly = True Then 'check if the Approved file is read only, if so, close it and exit sub because it needs to be writable 
         StatVar.xlApp.ActiveWorkbook.Close(False) 'close the Approved file, don't save changes 
         StatVar.xlApp.ActiveWorkbook.Close(False) 'close unapproved accounting file, don't save changes 
         MessageBox.Show("The system is busy. Please try again in a few seconds.") 
         Exit Sub 
        End If 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.Columns("AV").NumberFormat = "@" 'format column AV of the Approved file as text so "13/14" remains formatted correctly 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.Rows("1:1").Insert(Excel.XlInsertShiftDirection.xlShiftDown) 'insert a row at the top of the Approved file 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.Rows("1:1").Value = rng.EntireRow.Value 'set the 1st row of the Approved file equal to the row selected earlier in the unapproved accounting file 
        StatVar.xlApp.ActiveWorkbook.ActiveSheet.UsedRange.RemoveDuplicates(Columns:=(56)) 'search column 56 in Approved file for duplicates and remove entire row if a duplicate ID is found 
        rng.EntireRow.Delete() 'delete row the searchString was found in from the unapproved accounting file 
        StatVar.xlApp.ActiveWorkbook.Close(True) 'close the Approved file, save changes 
        StatVar.xlApp.ActiveWorkbook.Close(True) 'close unapproved accounting file, save changes 
        'MessageBox.Show("Eureka!") 
       Else 
        'if searchString is not found, close unapproved accounting file, inform user and exit sub 
        StatVar.xlApp.ActiveWorkbook.Close(False) 
        MessageBox.Show("Could not locate this record on the accounting file. Your files were not deleted.") 
        Exit Sub 
       End If 

       'move selected file and corresponding non-Memo files to Publish folder 
       Dim filePath As String = "W:\TOM\ERIC\Award_Letters\Excel pre_publish\" 
       Dim movePath As String = "W:\TOM\ERIC\Award_Letters\Publish\" 
       Dim filenm As String 

       'check if each item in listbox contains the string extracted from the selected item via Excel formula; listbox select event sends the filename to Excel and a formula extracts the string to find in each listbox item...look for this string 
       For Each c In ListBoxPrePublish.Items 
        If c.ToString.Contains(StatVar.xlApp.Sheets("Cross Checking").Range("H6").Text) Then 
         'make sure the current listbox item in this loop is not a Memo, if it's not, move it 
         If Not c.ToString.Contains("-M.xls") Then 
          filenm = c 
          Dim FileToMove = filePath & filenm 
          Dim MoveToLocation = movePath & filenm 
          System.IO.File.Move(FileToMove, MoveToLocation) 
          ListBoxPublished.Items.Add(c) 'add files files that are being published to the published files listbox 
         End If 
        End If 
       Next 

       'refresh prepublish list, if user has a school selected, REMOVE all list items that don't contain the school code being generated via VLOOKUP in Excel using the school name from comboboxschool; look for this string in the loop surrounded with "-" 
       Call ListFiles() 
       If ComboBoxSchool.Text <> "" Then 
        For i As Integer = ListBoxPrePublish.Items.Count - 1 To 0 Step -1 
         'if current loop item does not contain the school code for the selected school, remove the item from the listbox 
         If Not ListBoxPrePublish.Items(i).Contains("-" & StatVar.xlApp.Sheets("Cross Checking").Range("E3").Text & "-") Then 
          ListBoxPrePublish.Items.RemoveAt(i) 
         End If 
        Next 
       End If 
       'refresh deleted files listbox 
       Call ListDeletedTodayFiles() 

      End If 
     End If 
    Catch exc As Exception 
     MessageBox.Show("Unable to publish the selected file. Please verify this file or any of its corresponding files are not open by you or another user. If the problem persists, contact an administrator for assistance." & vbNewLine & vbNewLine & "Error: " & exc.Message) 
    End Try 

要麼是1這些方法比其他方法更好嗎?還是取決於我對我的程序做了什麼?很想聽到關於此的不同意見。

+1

圍繞巨大的代碼塊嘗試/捕捉被廣泛認爲是一個非常糟糕的做法。 –

+1

Try/catch塊很貴。儘量縮小範圍。這也使您能夠提供更精確的錯誤記錄,從而簡化調試過程。 –

+0

你介意闡述爲什麼?我不是在質疑你,只是想了解「爲什麼」。如果你能指點我一個很好的鏈接,我會閱讀它,但我一直沒有找到關於這個主題的很多有用的文獻 –

回答

4

將您的Try-Catch-Finally塊封裝在代碼的較小部分中,因爲那樣您將更有可能更快速地找到錯誤並且還可能從異常中恢復並繼續使用部分邏輯。在你的一個異常處理程序場景中,如果發生任何錯誤,那麼其餘的邏輯不會被執行,這也使得找到發生錯誤的地方更加困難。這提出了最後的建議,讓你的方法做得更少;你需要滾動多個頁面的方法做得太多了,很難理解和維護,幾乎可以肯定不可能在其他任何地方重用。

您也不應該僅僅使用基地Exception,因爲這是一個全面的異常類型,並且不提供有關實際發生的更具體的異常類型的信息。

+0

」在你的一個異常處理程序場景中,如果發生任何錯誤,那麼其餘的邏輯不會執行「...很酷,這正是我想要在這裏發生的事情。謝謝 –

1

你應該嘗試處理異常在全球的方式就像應用程序事件級別。如果你想讓其他代碼繼續下去,你應該儘可能縮小塊。捕捉異常會影響性能。

1

看起來更糟糕的問題比它,因爲你可以用分手這種方法成幾個小的

看它這樣

,如果你有A,B和C做,你想找出a/b和a/c,然後你把所有的東西都放在一個試圖捕捉div的零例外情況下,你需要更多的工作來確定b或c是否是壞人,兩個嘗試catch塊知道。

是的我知道這不是什麼時候使用異常的最好例子,而是您的問題的答案,取決於您想如何處理來自代碼段的已知異常。

在上面如果您確定您的句柄是「b或c爲零」,那麼一個塊就是解決方案。