2013-07-29 103 views
0

我正在試圖使用後臺工作人員處理1k +記錄並將其更新到excel sheet的數據。所以我想到了使用後臺工作人員,並且background worker被擊中,但沒有執行任何動作就觸發background work completed事件。使用後臺工作人員並更新狀態

下面是我的代碼:

Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click 
      ProgressBar1.Maximum = 100 
      ProgressBar1.Step = 1 
      ProgressBar1.Value = 0 
      BackgroundWorker1.WorkerReportsProgress = True 
      BackgroundWorker1.RunWorkerAsync()  
     End Sub 

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
        If cmbAccounts.SelectedIndex = 0 Then 
         Dim Input1 As String = Directory.GetCurrentDirectory & "\Samples\abc.xlsx" 
         Dim tdate As String = Me.PresentDate.Value.ToString("yyyy-MM-dd") 

         Using myConnection As New SqlConnection("Data Source=mydatasource;Initial Catalog=db0XXX;Persist Security Info=True;User ID=sa;Password=abcd"), myCommand As New SqlCommand("GetChargeEntryControlLog", myConnection), adapter As New SqlDataAdapter(myCommand) 
          myConnection.Open() 
          myCommand.CommandType = CommandType.StoredProcedure 
          myCommand.Parameters.AddWithValue("@AccountID", 1924) 


    myCommand.Parameters.AddWithValue("@Date", tdate) 
         ' Create the DataAdapter 
         Dim myDataAdapter As New SqlDataAdapter(myCommand) 

         ' Create the DataSet 
         Dim myDataSet As New DataSet 

         ' Fill the DataSet 
         myDataAdapter.Fill(myDataSet) 
         Me.DataGridView1.DataSource = myDataSet.Tables(0) 
         Me.DataGridView2.DataSource = myDataSet.Tables(1) 
         Me.DataGridView3.DataSource = myDataSet.Tables(2) 

         ' Close the connection 
         myConnection.Close() 


         Dim xlApp As New Excel.Application 
         Dim xlWorkBook As Excel.Workbook 
         xlWorkBook = xlApp.Workbooks.Add 

         xlWorkBook = xlApp.Workbooks.Open(Input1) 
         xlWorkBook.Sheets(1).activate() 
         xlApp.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter 
         xlApp.DisplayAlerts = False 
         xlApp.Columns.ColumnWidth = 25 


         For i = 1 To myDataSet.Tables(0).Rows.Count 
          For j = 0 To myDataSet.Tables(0).Columns.Count - 1 
           xlApp.Cells(i + 1, j + 1) = _ 
            myDataSet.Tables(0).Rows(i - 1)(j).ToString() 
          Next 
         Next 
         EndOfFirstTable = myDataSet.Tables(0).Rows.Count + 1 

         Dim SecondTableFirstRow As Integer = EndOfFirstTable + 1 
         For i = 1 To myDataSet.Tables(1).Rows.Count 
          For j = 0 To myDataSet.Tables(1).Columns.Count - 1 
           xlApp.Cells(i + SecondTableFirstRow, j + 1) = _ 
            myDataSet.Tables(1).Rows(i - 1)(j).ToString() 
          Next 
         Next 
         EndOfSecondTable = myDataSet.Tables(1).Rows.Count + 1 

         Dim ThirdTableFirstRow As Integer = EndOfSecondTable + 1 
         For i = 1 To myDataSet.Tables(2).Rows.Count 
          For j = 0 To myDataSet.Tables(2).Columns.Count - 1 
           xlApp.Cells(i + ThirdTableFirstRow, j + 1) = _ 
            myDataSet.Tables(2).Rows(i - 1)(j).ToString() 
          Next 
         Next 
         EndOfThirdTable = myDataSet.Tables(2).Rows.Count + 1 


         If DataGridView1.Rows.Count - 1 + DataGridView2.Rows.Count - 1 + DataGridView3.Rows.Count - 1 = 0 Then 
          For i = 1 To 2 
           For j = 0 To myDataSet.Tables(0).Columns.Count - 1 
            xlApp.Cells(2, j + 1) = "NULL" 
           Next 
          Next 
         End If 

         xlApp.Columns.AutoFit() 

         Dim rSearchRange As Range 
         rSearchRange = xlWorkBook.Sheets(1).UsedRange.Columns(1) 

         'for example 
         If xlApp.WorksheetFunction.CountBlank(rSearchRange) Then 
          rSearchRange.SpecialCells(XlCellType.xlCellTypeBlanks).EntireRow.Delete() 
         End If 

         lblChargeEntry.Text = DataGridView1.RowCount - 1 + DataGridView2.RowCount - 1 + DataGridView3.RowCount - 1 
         value1 = lblChargeEntry.Text 

         Dim _ 
          Destinationpath As String = Directory.GetCurrentDirectory & "\Output\abc_" & tdate & ".xlsx" 
         xlApp.ActiveWorkbook.SaveAs(Destinationpath) 
         '~~> Close the File 
         xlWorkBook.Close() 
         '~~> Quit the Excel Application 
         xlApp.Quit() 
        End Using 


        Using myConnection As New SqlConnection("Data Source=mydatasource;Initial Catalog=db0XXX;Persist Security Info=True;User ID=sa;Password=abcd"), myCommand As New SqlCommand("GetEOBControlLog", myConnection), adapter As New SqlDataAdapter(myCommand) 
         Dim Input2 As String = Directory.GetCurrentDirectory & "\Samples\bbc.xls" 
         myConnection.Open() 
         myCommand.CommandType = CommandType.StoredProcedure 
         myCommand.Parameters.AddWithValue("@AccountID", 1924) 
         myCommand.Parameters.AddWithValue("@Date", tdate) 
         ' Create the DataAdapter 
         Dim myDataAdapter As New SqlDataAdapter(myCommand) 

         ' Create the DataSet 
         Dim myDataSet As New DataSet 

         ' Fill the DataSet 
         myDataAdapter.Fill(myDataSet) 
         Me.DataGridView4.DataSource = myDataSet.Tables(0) 

         ' Close the connection 
         myConnection.Close() 


         Dim xlApp As New Excel.Application 
         Dim xlWorkBook As Excel.Workbook 
         xlWorkBook = xlApp.Workbooks.Add 

         xlWorkBook = xlApp.Workbooks.Open(Input2) 
         xlWorkBook.Sheets(1).activate() 
         xlApp.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter 
         xlApp.DisplayAlerts = False 
         xlApp.Columns.ColumnWidth = 25 


         Try 
          Dim EndOfFirstTable As Integer 
          For i = 1 To myDataSet.Tables(0).Rows.Count 
           For j = 0 To myDataSet.Tables(0).Columns.Count - 1 
            xlApp.Cells(i + 1, j + 1) = _ 
             myDataSet.Tables(0).Rows(i - 1)(j).ToString() 
           Next 
          Next 
          EndOfFirstTable = myDataSet.Tables(0).Rows.Count + 1 


          If DataGridView4.Rows.Count - 1 = 0 Then 
           For i = 1 To 2 
            For j = 0 To myDataSet.Tables(0).Columns.Count - 1 
             xlApp.Cells(2, j + 1) = "NULL" 
            Next 
           Next 
          End If 

          xlApp.Columns.AutoFit() 
         Catch 
         End Try 

         Dim rSearchRange As Range 
         rSearchRange = xlWorkBook.Sheets(1).UsedRange.Columns(1) 
         'for example 
         If xlApp.WorksheetFunction.CountBlank(rSearchRange) Then 
          rSearchRange.SpecialCells(XlCellType.xlCellTypeBlanks).EntireRow.Delete() 
         End If 

         lblPaymentPosting.Text = DataGridView4.RowCount - 1 
         value2 = lblPaymentPosting.Text 

         Dim _ 
          Destinationpath As String = Directory.GetCurrentDirectory & _ 
                 "\Output\bbc_" & tdate & ".xls" 
         xlApp.ActiveWorkbook.SaveAs(Destinationpath) 
         '~~> Close the File 
         xlWorkBook.Close() 
         '~~> Quit the Excel Application 
         xlApp.Quit() 
         cmbAccounts.SelectedIndex = 1 
        End Using 
       End If 

       If cmbAccounts.SelectedIndex = 1 Then 
        Dim Input3 As String = Directory.GetCurrentDirectory & "\Samples\123.xlsx" 
        Dim tdate As String = Me.PresentDate.Value.ToString("yyyy-MM-dd") 

        Using myConnection As New SqlConnection("Data Source=mydatasource;Initial Catalog=db0XXX;Persist Security Info=True;User ID=sa;Password=abcd"), myCommand As New SqlCommand("GetChargeEntryControlLog", myConnection), adapter As New SqlDataAdapter(myCommand) 
         myConnection.Open() 
         myCommand.CommandType = CommandType.StoredProcedure 
         myCommand.Parameters.AddWithValue("@AccountID", 2647) 
         myCommand.Parameters.AddWithValue("@Date", tdate) 
         ' Create the DataAdapter 
         Dim myDataAdapter As New SqlDataAdapter(myCommand) 

         ' Create the DataSet 
         Dim myDataSet As New DataSet 

         ' Fill the DataSet 
         myDataAdapter.Fill(myDataSet) 
         Me.DataGridView1.DataSource = myDataSet.Tables(0) 
         Me.DataGridView2.DataSource = myDataSet.Tables(1) 
         Me.DataGridView3.DataSource = myDataSet.Tables(2) 

         ' Close the connection 
         myConnection.Close() 



         Dim xlApp As New Excel.Application 
         Dim xlWorkBook As Excel.Workbook 
         xlWorkBook = xlApp.Workbooks.Add 

         xlWorkBook = xlApp.Workbooks.Open(Input3) 
         xlWorkBook.Sheets(1).activate() 
         xlApp.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter 
         xlApp.DisplayAlerts = False 
         xlApp.Columns.ColumnWidth = 25 



         For i = 1 To myDataSet.Tables(0).Rows.Count 
          For j = 0 To myDataSet.Tables(0).Columns.Count - 1 
           xlApp.Cells(i + 1, j + 1) = _ 
            myDataSet.Tables(0).Rows(i - 1)(j).ToString() 
          Next 
         Next 
         EndOfFirstTable = myDataSet.Tables(0).Rows.Count + 1 

         Dim SecondTableFirstRow As Integer = EndOfFirstTable + 1 

         For i = 1 To myDataSet.Tables(1).Rows.Count 
          For j = 0 To myDataSet.Tables(1).Columns.Count - 1 
           xlApp.Cells(i + SecondTableFirstRow, j + 1) = _ 
            myDataSet.Tables(1).Rows(i - 1)(j).ToString() 
          Next 
         Next 
         EndOfSecondTable = myDataSet.Tables(1).Rows.Count + 1 

         Dim ThirdTableFirstRow As Integer = EndOfSecondTable + 1 
         For i = 1 To myDataSet.Tables(2).Rows.Count 
          For j = 0 To myDataSet.Tables(2).Columns.Count - 1 
           xlApp.Cells(i + ThirdTableFirstRow, j + 1) = _ 
            myDataSet.Tables(2).Rows(i - 1)(j).ToString() 
          Next 
         Next 

         If DataGridView1.Rows.Count - 1 + DataGridView2.Rows.Count - 1 + DataGridView3.Rows.Count - 1 = 0 Then 
          For i = 1 To 2 
           For j = 0 To myDataSet.Tables(0).Columns.Count - 1 
            xlApp.Cells(2, j + 1) = "NULL" 
           Next 
          Next 
         End If 

         xlApp.Columns.AutoFit() 


         Dim rSearchRange As Range 
         rSearchRange = xlWorkBook.Sheets(1).UsedRange.Columns(1) 'for example 
         If xlApp.WorksheetFunction.CountBlank(rSearchRange) Then 
          rSearchRange.SpecialCells(XlCellType.xlCellTypeBlanks).EntireRow.Delete() 
         End If 

         lblChargeEntry.Text = DataGridView1.RowCount - 1 + DataGridView2.RowCount - 1 + DataGridView3.RowCount - 1 
         value3 = lblChargeEntry.Text 
         Dim Destinationpath As String = Directory.GetCurrentDirectory & "\Output\2647_Charge Entry Control Log_" & tdate & ".xlsx" 
         xlApp.ActiveWorkbook.SaveAs(Destinationpath) 
         '~~> Close the File 
         xlWorkBook.Close() 
         '~~> Quit the Excel Application 
         xlApp.Quit() 
        End Using 

    For j As Integer = 0 To 99999 
     Caluculate(j) 
     backgroundWorker.ReportProgress((j * 100) \ 100000) 
    Next 
End If 
End Sub 

    Private Sub Caluculate(i As Integer) 
     Dim pow As Double = Math.Pow(i, i) 
    End Sub 

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) 
     progressBar1.Value = e.ProgressPercentage 
    End Sub 

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) 
      MsgBox("Reports created succesfully!") 
    End Sub 
+0

您是否嘗試過調試它(使用簡單的斷點)? – sloth

+0

是的,但它並沒有顯示我任何錯誤,只是出來的If語句和觸發完成的工作......如果我刪除我的代碼,然後它可以正常工作進度條狀態 – coder

回答

1

嘗試把一個try/catch周圍的if語句。這不會解決問題,但應該讓你看到例外。從線程內訪問ComboBox時,您遇到了跨線程UI訪問問題。

在這裏看到:https://stackoverflow.com/a/5074467/264607

如果你真的想訪問的UI元素在這裏看到:

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.checkaccess.aspx

+0

@ BlackICE-我已經嘗試過,也沒有不起作用,它可以拋出任何例外。 – coder

+0

你在後臺工作中有很多UI訪問,你將不得不改變它,你不能直接從UI線程以外的線程訪問UI元素。 – BlackICE

+0

您可以在reportprogress(2:nd參數)中將datagridview作爲對象傳遞。執行progresschanged事件或已完成事件中的所有更改。 –