I have a datagridview control on a form (Records form). On the first form (Start form) I have a button (View Records button) that when clicked includes all the code (which I will list below) to the backgroundworker (named bw) I have on the Start form. When the user clicks the 'View Records' button a progress bar appears next to the button and shows the progress of the datagridview being loaded. I am loading the datagridview via a loop that grabs all the values from an excel file. I have that working fine, but now I'm looking to be able to reload the datagridview using the same loop, but grabbing the data from a different sheet in the excel workbook when the user presses the 'Previous Year' button on the Records form. Below I've included images of the Start form and Records Form, as well as their respective code
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
This is the code for the Previous Year button on the Records Form
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
UPDATED CODE
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
There are a lot of different ways to query excel and store the data in a variable. One method I have used in the past is OleDb
This is a function you can use to query excel and return the contents in a DataTable
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
So now you can use
Dim t2013 = QueryExcel("2013")
And assign it to the DataGridView
like this
DataGridView.DataSource = t2013
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.