簡體   English   中英

單擊按鈕時無法在datagridview中顯示不同的工作表數據

[英]Trouble displaying different worksheet data in datagridview on button click

我在窗體(記錄窗體)上有一個datagridview控件。 在第一個表單(“開始”表單)上,我有一個按鈕(“查看記錄”按鈕),當單擊該按鈕時,它將包括我在“開始”表單上擁有的后台工作人員(名為bw)的所有代碼(在下面列出)。 當用戶單擊“查看記錄”按鈕時,該按鈕旁邊會出現一個進度條,並顯示要加載的datagridview的進度。 我正在通過從Excel文件獲取所有值的循環加載datagridview。 我的工作正常,但現在我希望能夠使用相同的循環重新加載datagridview,但是當用戶按下“記錄”表單上的“上一年”按鈕時,從excel工作簿中的另一張表中獲取數據。 下面,我提供了“開始”表單和“記錄”表單的圖像,以及它們各自的代碼

開始表格

Imports Office = Microsoft.Office.Core
Imports Excel = Microsoft.Office.Interop.Excel

Public Class Start
Dim Records As New Records
Public excel_app As Excel.Application
Public workbook As Excel.Workbook
Public sheet_name As String
Public sheet As Excel.Worksheet

Public ColumnCount, RowCount, TotalCellCount As Long

Public yearstamp As String = _
    DateTime.Now.ToString("yyyy")

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Setup()
    bw.RunWorkerAsync()
End Sub
Private Sub Setup()

    Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
    Dim xlPath = IO.Path.Combine(exeDir.DirectoryName, "Records.xlsx")

    ' Get the Excel application object.
    excel_app = New Excel.Application

    ' Make Excel visible (optional).
    excel_app.Visible = False

    ' Open the workbook.
    workbook = excel_app.Workbooks.Open(xlPath)

    sheet_name = yearstamp
    Records.YearDisplay.Text = yearstamp & " Records"

    sheet = excel_app.Worksheets(sheet_name)

    ColumnCount = sheet.Range("A1").CurrentRegion.Columns.Count
    RowCount = sheet.Range("A1").CurrentRegion.Rows.Count

    Records.DataGridView1.ColumnCount = ColumnCount - 1
    Records.DataGridView1.RowCount = RowCount - 1
    Records.DataGridView1.ColumnHeadersVisible = True
    Records.DataGridView1.RowHeadersVisible = True
    TotalCellCount = Records.DataGridView1.ColumnCount * Records.DataGridView1.RowCount

    pb.Visible = True
    pb.Minimum = 0
    pb.Value = 1
    pb.Maximum = TotalCellCount

    Records.DataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing
    Records.DataGridView1.AllowUserToResizeColumns = False
    Records.DataGridView1.AllowUserToResizeRows = False
    Records.DataGridView1.ReadOnly = True


    Records.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

End Sub
Private Sub bw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork

    'Loop through each column
    Dim cIndex As Integer = 0
    Dim rIndex As Integer = 0
    While cIndex < Records.DataGridView1.ColumnCount

        'Loop through and populate each row in column
        rIndex = 0
        While rIndex < Records.DataGridView1.RowCount

            If cIndex = 0 Then
                'Set row header titles
                Records.DataGridView1.Rows.Item(rIndex).HeaderCell.Value = sheet.Range("A1").Offset(rIndex + 1, cIndex).Value()

                Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = sheet.Range("A1").Offset(rIndex + 1, cIndex + 1).Value()
            End If
            If cIndex > 0 Then
                Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = sheet.Range("A1").Offset(rIndex + 1, cIndex + 1).Value()
            End If

            'Set column header title
            Records.DataGridView1.Columns(cIndex).HeaderText = sheet.Range("A1").Offset(0, cIndex + 1).Value

            'Change last cell (Result) color Red or Green to represent positive gain or negative loss
            If rIndex = RowCount - 2 Then
                If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value < 0 Then
                    Records.DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Red
                    Records.DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value > 0 Then
                    Records.DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Green
                    Records.DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = 0 Then
                    Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = "Broke Even"
                End If

            End If

            'Update the progress bar after each cell is populated
            bw.ReportProgress(rIndex * cIndex)

            rIndex = rIndex + 1

        End While

        'Make column unsortable
        Records.DataGridView1.Columns(cIndex).SortMode = DataGridViewColumnSortMode.NotSortable

        'Update the progress bar after each cell is populated
        bw.ReportProgress(rIndex * cIndex)

        cIndex = cIndex + 1

    End While

    Records.DataGridView1.AutoResizeColumns()

    'Update the progress bar for last time
    bw.ReportProgress(rIndex * cIndex)


End Sub

Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
    pb.Value = e.ProgressPercentage
    pb.Increment(1)
    pb.Refresh()
End Sub

Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
    If e.Error IsNot Nothing Then
        MessageBox.Show(e.Error.Message, "Background Worker Exception", MessageBoxButtons.OK, MessageBoxIcon.Error)
    Else
        If e.Cancelled Then
            'worker was cancelled
        Else
            'worker completed, open form2 here
            'pb.Value = TotalCellCount
            Records.ShowDialog()
            If (Records.DialogResult) Then
                pb.Visible = False
                ' Close the workbook.
                workbook.Close()

                ' Close the Excel server.
                excel_app.Quit()
            End If

        End If
    End If
End Sub

記錄表

這是“記錄”表單上“上一年”按鈕的代碼

   Private Sub PreviousYear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    'The code in this Sub is not working
    Start.sheet_name = yearstamp - 1
    Me.Close()
    Start.bw.RunWorkerAsync()
    ''
End Sub

更新的代碼

    Public Class Records

Dim excel_app As Excel.Application
Dim workbook As Excel.Workbook
Dim sheet_name As String
Dim sheet As Excel.Worksheet
Dim ColumnCount, RowCount, TotalCellCount As Long
Dim yearstamp As String = _
    DateTime.Now.ToString("yyyy")
Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
Dim xlPath = IO.Path.Combine(exeDir.DirectoryName, "Records.xlsx")

Public Function QueryExcel(ByVal sheet As String) As DataTable
    'use this connection string for .xlsx files
    Dim cs2007 As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=xlPath;Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"

    Dim sql As String = String.Format("SELECT * FROM [{0}$]", sheet)

    'get contents of xls file
    Using cnn As New OleDb.OleDbConnection(cs2007.Replace("@FILENAME", "YOUR EXCEL FILE"))
        Using cmd As New OleDb.OleDbCommand(sql, cnn)
            Dim t As New System.Data.DataTable
            Try
                cnn.Open()
                t.Load(cmd.ExecuteReader)
            Catch ex As Exception
                'handle exception. in this case i'm just returning an empty table
            End Try
            Return t
        End Using
    End Using
End Function
Private Sub Records_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim t2013 = QueryExcel("2013")
    DataGridView1.DataSource = t2013

End Sub

查詢excel並將數據存儲在變量中有很多不同的方法。 我過去使用的一種方法是OleDb

此函數可用於查詢excel並返回數據表中的內容

  Public Function QueryExcel(sheet As String) As DataTable
    'use this connection string for .xlsx files
    Dim cs2007 As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=@FILENAME;Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"

    'use this connection string for .xls files
    Dim cs2003 As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=@FILENAME;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"

    Dim sql As String = String.Format("SELECT * FROM [{0}$]", sheet)
    dim cs = cs2007.Replace("@FILENAME", IO.Path.Combine(exeDir.DirectoryName, "Records.xlsx"))
    'get contents of xls file
    Using cnn As New OleDb.OleDbConnection(cs)
      Using cmd As New OleDb.OleDbCommand(sql, cnn)
        Dim t As New DataTable
        Try
          cnn.Open()
          t.Load(cmd.ExecuteReader)
        Catch ex As Exception
          'handle exception. in this case i'm just returning an empty table
        End Try
        Return t
      End Using
    End Using
  End Function

所以現在您可以使用

Dim t2013 = QueryExcel("2013")

並像這樣將其分配給DataGridView

DataGridView.DataSource = t2013

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM