[英]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.