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