How to quit excel application from VB.NET - vb.net

My program is able to retrieve data from an excel macro 2010 workbook and change contents and save changes made, all using the datagridview within VB.NET. However I'm facing a problem where the program saves but will not close. When I look at the processes in the task manager its still showing Excel 2010 as running. If anyone can help me find a way to quit this application I would greatly appreciate it!
Imports System.Data.OleDb
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports System.IO
Public Class Form1
Dim SheetList As New ArrayList
Private excelObj As ExcelObject
Private dt As DataTable = Nothing
Dim DS As DataSet
Dim DS2 As DataSet
Dim ds3 As DataSet
Dim ds4 As DataSet
Dim ds5 As DataSet
Dim ds6 As DataSet
Dim ds7 As DataSet
Dim ds8 As DataSet
Dim ds9 As DataSet
Dim ds10 As DataSet
Dim ds11 As DataSet
Dim ds12 As DataSet
Dim ds13 As DataSet
Dim ds14 As DataSet
Dim ds15 As DataSet
Dim ds16 As DataSet
Dim ds17 As DataSet
Dim ds18 As DataSet
Dim MyCommand As OleDb.OleDbDataAdapter
Dim MyCommand2 As OleDb.OleDbDataAdapter
Dim MyCommand3 As OleDb.OleDbDataAdapter
Dim MyCommand4 As OleDb.OleDbDataAdapter
Dim MyCommand5 As OleDb.OleDbDataAdapter
Dim MyCommand6 As OleDb.OleDbDataAdapter
Dim MyCommand7 As OleDb.OleDbDataAdapter
Dim MyCommand8 As OleDb.OleDbDataAdapter
Dim MyCommand9 As OleDb.OleDbDataAdapter
Dim MyCommand10 As OleDb.OleDbDataAdapter
Dim MyCommand11 As OleDb.OleDbDataAdapter
Dim MyCommand12 As OleDb.OleDbDataAdapter
Dim MyCommand13 As OleDb.OleDbDataAdapter
Dim MyCommand14 As OleDb.OleDbDataAdapter
Dim MyCommand15 As OleDb.OleDbDataAdapter
Dim MyCommand16 As OleDb.OleDbDataAdapter
Dim MyCommand17 As OleDb.OleDbDataAdapter
Dim MyCommand18 As OleDb.OleDbDataAdapter
Dim objExcel As New Excel.Application()
Dim objWorkBook As Excel.Workbook = objExcel.Workbooks.Add
Dim objWorkSheet1 As Excel.Worksheet = objExcel.ActiveSheet
Dim objWorkSheet2 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet3 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet10 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet11 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet12 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet13 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet23 As Excel.Worksheet = objExcel.ActiveSheet
Dim objworksheet24 As Excel.Worksheet = objExcel.ActiveSheet
'<TBD make 15 more of these>
Dim MyConnection As OleDb.OleDbConnection
Dim MYDBConnection As DAO.Connection
Public MyWorkspace As DAO.Workspace
Public sizetable As DAO.Recordset
Public MyDatabase As DAO.Database
Public ReadOnly Property Excel() As ExcelObject
Get
If excelObj Is Nothing Then
excelObj = New ExcelObject(txtFilePath.Text)
End If
Return excelObj
End Get
End Property
Sub openExcelfile()
Dim dlg As New OpenFileDialog()
dlg.Filter = "Excel Macro Enabled Files|*.xlsm*|Excel Files|*.xls|Excel 2007 Files|*.xlsx|All Files|*.*"
If dlg.ShowDialog() = DialogResult.OK Then
excelObj = New ExcelObject(dlg.FileName)
txtFilePath.Text = dlg.FileName
btnRetrieve.Enabled = txtFilePath.Text.Length > 0
End If
Dim ExcelSheetName As String = ""
'open the excel workbook and create an object for it
objExcel = CreateObject("Excel.Application")
'do some exception handling on a blank txtfilepath.text
objWorkBook = objExcel.Workbooks.Open(txtFilePath.Text)
Dim i As Integer
i = 1
For Each objWorkSheets In objWorkBook.Worksheets
SheetList.Add(objWorkSheets.Name)
Select Case i
Case 4
objWorkSheet1 = objExcel.Worksheets(objWorkSheets.Name)
Case 5
objWorkSheet2 = objExcel.Worksheets(objWorkSheets.Name)
'ListBox1.Items.Add(objWorkSheets.Name)
'etc
End Select
i = i + 1
Next
End Sub
Sub Write2Excel()
Dim rowindex As Integer
Dim columnindex As Integer
For rowindex = 1 To DataGridView1.RowCount
For columnindex = 1 To DataGridView1.ColumnCount
objWorkSheet1.Cells(rowindex + 4, columnindex + 0) = DataGridView1(columnindex - 1, rowindex - 1).Value
Next
Next
'etc
End Sub
Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
openExcelfile()
End Sub
Sub oldretrieve()
' Dim dt As DataTable = Me.Excel.GetSchema()
' cmbTableName.DataSource = (From dr In dt.AsEnumerable() Where Not dr("TABLE_NAME").ToString().EndsWith("$") Select dr("TABLE_NAME")).ToList()
' cmbTableName.Enabled = cmbTableName.Items.Count > 0
' btnGo.Enabled = cmbTableName.Items.Count > 0
' btnDrop.Enabled = cmbTableName.Items.Count > 0
End Sub
Sub RetrieveExcel()
'Create a connection to either 2007 and 2010 xls file
Dim fi As New FileInfo(txtFilePath.Text)
If fi.Extension.Equals(".xls") Then
MyConnection = New OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.8.0; " & "data source=" & txtFilePath.Text & "; " & "Extended Properties=Excel 8.0;")
ElseIf fi.Extension.Equals(".xlsx") Then
MyConnection = New OleDb.OleDbConnection( _
"provider=Microsoft.Ace.OLEDB.12.0; " & _
"data source=" & txtFilePath.Text & "; " & "Extended Properties=Excel 12.0;")
ElseIf fi.Extension.Equals(".xlsm") Then
MyConnection = New OleDb.OleDbConnection( _
"provider=Microsoft.Ace.OLEDB.12.0; " & _
"data source=" & txtFilePath.Text & "; " & "Extended Properties=Excel 12.0;")
End If
'First worksheet'
MyCommand = New OleDbDataAdapter("select * from [1- COTS Worksheet$A4:I150]", MyConnection)
'1- COTS Worksheet.Column(1).Locked = True
DS = New System.Data.DataSet()
MyCommand.Fill(DS)
'---This will prevent the user from editing the size of the rows and columns of the datagrid---'
DataGridView1.AllowUserToResizeColumns = False
DataGridView1.AllowUserToResizeRows = False
DataGridView1.AllowUserToOrderColumns = False
DataGridView1.AllowUserToAddRows = False
DataGridView1.AllowUserToDeleteRows = False
DataGridView1.DataSource = DS.Tables(0).DefaultView
'---The following line makes the column read only---'
DataGridView1.Columns(5).ReadOnly = True
DataGridView1.Columns(6).ReadOnly = True
'''''''if the column is editible then the foreground = blue ''''''''
DataGridView1.Columns(0).DefaultCellStyle.ForeColor = Color.Blue
DataGridView1.Columns(1).DefaultCellStyle.ForeColor = Color.Blue
DataGridView1.Columns(2).DefaultCellStyle.ForeColor = Color.Blue
DataGridView1.Columns(3).DefaultCellStyle.ForeColor = Color.Blue
DataGridView1.Columns(4).DefaultCellStyle.ForeColor = Color.Blue
DataGridView1.Columns(7).DefaultCellStyle.ForeColor = Color.Blue
DataGridView1.Columns(8).DefaultCellStyle.ForeColor = Color.Blue
' ''''''This will get rid of the selection blue color for the cells''''''''''''''''''''
DataGridView1.DefaultCellStyle.SelectionBackColor = DataGridView1.DefaultCellStyle.BackColor
DataGridView1.DefaultCellStyle.SelectionForeColor = DataGridView1.DefaultCellStyle.ForeColor
'TABLE TO WRITE TO -
'FIELD TO WRITE TO -
End Sub
Private Sub btnRetrieve_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRetrieve.Click
Try
Cursor.Current = Cursors.WaitCursor
RetrieveExcel()
Finally
Cursor.Current = Cursors.Default
End Try
End Sub
Private Sub Form1_Activated(sender As Object, e As EventArgs) Handles Me.Activated
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' btnRetrieve.Enabled = True
MyWorkspace = DAODBEngine_definst.Workspaces(0)
End Sub
Private Sub txtFilePath_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFilePath.TextChanged
btnRetrieve.Enabled = System.IO.File.Exists(txtFilePath.Text)
End Sub
Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
If Me.excelObj IsNot Nothing Then
Me.excelObj.Dispose()
End If
closexlsfile()
End Sub
Private Sub DBFilePath_TextChanged(sender As Object, e As EventArgs) Handles DBFilePath.TextChanged
End Sub
Private Sub BtnBrowseDB_Click(sender As Object, e As EventArgs) Handles BtnBrowseDB.Click
opendbfile()
End Sub
Function opendbfile() As Boolean
Dim dlg As New OpenFileDialog()
dlg.Filter = "DB files|*.mdb|Access DB files|*.accdb|All Files|*.*"
If dlg.ShowDialog() = DialogResult.OK Then
DBFilePath.Text = dlg.FileName
'temporarily myfile will be set to c:/Exceltest/template.mdb
' myfile = "c:/Exceltest/template.mdb"
Try
If DBFilePath.Text <> "" Then
'On Error GoTo errorhandler
MYDBConnection = MyWorkspace.OpenConnection("provider=Microsoft.Ace.OLEDB.12.0; " & "data source=" & txtFilePath.Text)
MyDatabase = MyWorkspace.OpenDatabase(DBFilePath.Text)
sizetable = MyDatabase.OpenRecordset("size", DAO.RecordsetTypeEnum.dbOpenTable)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End Function
Private Sub btnWrite_Click(sender As Object, e As EventArgs) Handles btnWrite.Click
'---This Try Finally block with set current cursor to waiting cursor while the program write to excel---'
Try
Cursor.Current = Cursors.WaitCursor
Write2Excel()
Finally
Cursor.Current = Cursors.Default
End Try
End Sub
Sub closexlsfile()
Try
''Do we need to save the file first?
objWorkBook.Save()
objWorkBook.Close()
objExcel.Quit()
'something weird happening on this line
MyConnection.Close()
MyConnection.Dispose()
objWorkBook = Nothing
objExcel = Nothing
Catch
End Try
'TBD the other objworksheets get closed here
End Sub
Private Sub closexls_Click(sender As Object, e As EventArgs) Handles closexls.Click
closexlsfile()
NAR(objWorkSheet1)
NAR(objWorkSheet2)
NAR(objworksheet3)
NAR(objworksheet10)
NAR(objworksheet11)
NAR(objworksheet12)
NAR(objworksheet13)
NAR(objworksheet23)
NAR(objworksheet24)
objWorkBook.Close(False)
NAR(objWorkBook)
NAR(MyConnection)
objExcel.Quit()
NAR(objExcel)
Debug.WriteLine("Sleeping...")
System.Threading.Thread.Sleep(5000)
Debug.WriteLine("End Excel")
End Sub
'---This is a method that I found of MSDN to quit an office application but it doesn't seem to work---'
Private Sub NAR(ByVal obj As Object)
Try
While (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0)
End While
Catch
Finally
obj = Nothing
End Try
End Sub
End Class

You obviously have a lot of code and I can't go through all of that. However I dealt with this problem in the past. It is usually due to an unreleased object of some kind. For example lots of code samples from the intertubes suggests that you do things like
objWorkBook = objExcel.Workbooks.Open(txtFilePath.Text)
This is potentially dangerous, you should never have more than ONE . in a single right hand value. Instead go for something like
Workbooks wrkbks = objExcel.Workbooks
objWorkBook = wrkbks.Open(txtFilePath.Text)
Otherwise there will be memory allocated for the WorkBooks that isn't explicitly released. This is really a pain to go through all your code base once you've discovered this, but it solved the problem for me.

Your NAR sub should have it handled, but I far prefer Marshal.FinalReleaseComObject method - no loop required. You need to make sure all instances have been addressed - like in the closexlsfile() method you do not call NAR for these Com objects. I suggest some code cleanup.

Related

Datagridview Horizontal to vertical button

The following code isn't working when exporting the datagridview data when trying to make it vertical with headers along the left side along with text beside each one. Once this is flipped the user would click on button1 to export to excel.
Imports System.Data.DataTable
Imports System.IO
Imports Microsoft.Office.Interop
Public Class Form1
Dim table As New DataTable(0)
Public checkBoxList As List(Of CheckBox)
Private ds As DataSet = Nothing
Private dt As DataTable = Nothing
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ds = New DataSet()
dt = New DataTable()
ds.Tables.Add("Table")
Dim my_DataView As DataView = ds.Tables(0).DefaultView
DataGridView1.DataSource = my_DataView
table.Columns.Add("Forename", Type.GetType("System.String"))
table.Columns.Add("Surname", Type.GetType("System.String"))
table.Columns.Add("Food", Type.GetType("System.String"))
checkBoxList = New List(Of CheckBox) From {CheckBox1, CheckBox2, CheckBox3, CheckBox4}
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim currentDataSet As DataSet = FlipDataSet(ds) ' Flip the DataSet
Dim values As String = "" &
String.Join(" & ", checkBoxList _
.Where(Function(cb) cb.Checked).Select(Function(cb) cb.Text))
' use values for placing into your DataGridView
CheckBox1.Text = values
CheckBox2.Text = values
CheckBox3.Text = values
CheckBox4.Text = values
table.Rows.Add(TextBox1.Text, TextBox2.Text, values.ToString)
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
DataGridView1.RowTemplate.Height = 100
DataGridView1.AllowUserToAddRows = False
DataGridView1.DataSource = table
'Save to excel with headers
Dim ExcelApp As Object, ExcelBook As Object
Dim ExcelSheet As Object
Dim i As Integer
Dim j As Integer
'create object of excel
ExcelApp = CreateObject("Excel.Application")
ExcelBook = ExcelApp.WorkBooks.Add
ExcelSheet = ExcelBook.WorkSheets(1)
With ExcelSheet
For Each column As DataGridViewColumn In DataGridView1.Columns
.cells(1, column.Index + 1) = column.HeaderText
Next
For i = 1 To Me.DataGridView1.RowCount
.cells(i + 1, 1) = Me.DataGridView1.Rows(i - 1).Cells("Forename").Value
For j = 1 To DataGridView1.Columns.Count - 1
.cells(i + 1, j + 1) = DataGridView1.Rows(i - 1).Cells(j).Value
Next
Next
End With
ExcelApp.Visible = True
'
ExcelSheet = Nothing
ExcelBook = Nothing
ExcelApp = Nothing
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
Public Function FlipDataSet(ByVal my_DataSet As DataSet) As DataSet
Dim ds As New DataSet()
For Each dt As DataTable In my_DataSet.Tables
Dim table As New DataTable()
For i As Integer = 0 To dt.Rows.Count
table.Columns.Add(Convert.ToString(i))
Next
Dim r As DataRow
For k As Integer = 0 To dt.Columns.Count - 1
r = table.NewRow()
r(0) = dt.Columns(k).ToString()
For j As Integer = 1 To dt.Rows.Count
r(j) = dt.Rows(j - 1)(k)
Next
table.Rows.Add(r)
Next
ds.Tables.Add(table)
Next
Return ds
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim currentDataSet As DataSet = FlipDataSet(ds) ' Flip the DataSet
Dim currentDataView As DataView = currentDataSet.Tables(0).DefaultView
DataGridView1.DataSource = currentDataView
Button2.Enabled = False
End Sub
End Class
When clicking button2 it should flip the data with the following;
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles
Button2.Click
Dim currentDataSet As DataSet = FlipDataSet(ds) ' Flip the DataSet
Dim currentDataView As DataView = currentDataSet.Tables(0).DefaultView
DataGridView1.DataSource = currentDataView
Button2.Enabled = False
End Sub
End Class
I've tried debugging but it i can't seem to find anything wrong? It will allow me to insert data in the textbox's whilst selecting checkbox's and when clicking button 1 to export it works fine, but it doesn't flip the data.
Please can anyone suggest how to fix this as i have a presentation on the 8th June and this data needs to automatically be flipped
Sourcecode: Download Myproject
Image of target
Answered:
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Public Class Form1
Private ds As DataSet = Nothing
Private dt As DataTable = Nothing
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.AllowUserToAddRows = False
dt = New DataTable("MyTable")
dt.Columns.Add("Forename", Type.GetType("System.String"))
dt.Columns.Add("Surname", Type.GetType("System.String"))
dt.Columns.Add("Food", Type.GetType("System.String"))
ds = New DataSet
ds.Tables.Add(dt)
Dim my_DataView As DataView = ds.Tables("MyTable").DefaultView
DataGridView1.DataSource = my_DataView
End Sub
Private Sub Button_AddRowData_Click(sender As Object, e As EventArgs) Handles Button_AddRowData.Click
Dim foods As String = String.Join(" & ", CheckedListBox1.CheckedItems.Cast(Of String))
dt.Rows.Add(New Object() {TextBox_Forename.Text, TextBox_Surname.Text, foods})
End Sub
Private Sub Button_FlipAndSave_Click(sender As Object, e As EventArgs) Handles Button_FlipAndSave.Click
FlipAndSave(ds.Tables("MyTable"))
End Sub
Private Sub FlipAndSave(table As DataTable)
Dim ExcelApp As New Excel.Application
Dim WrkBk As Excel.Workbook = ExcelApp.Workbooks.Add()
Dim WrkSht As Excel.Worksheet = CType(WrkBk.Worksheets(1), Excel.Worksheet)
With WrkSht
For ci As Integer = 0 To table.Columns.Count - 1
.Cells(ci + 1, 1) = table.Columns(ci).ColumnName
Next
For ri As Integer = 0 To table.Rows.Count - 1
For ci As Integer = 0 To table.Columns.Count - 1
.Cells(ci + 1, ri + 2) = table.Rows(ri).Item(ci).ToString
Next
Next
End With
ExcelApp.Visible = True
'use this lines if you want to automatically save the WorkBook
'WrkBk.SaveAs("C:\Some Folder\My Workbook.xlsx") '(.xls) if you have an old version of Excel
'ExcelApp.Quit() 'use this line if you want to close the Excel Application
ReleaseObject(ExcelApp)
ReleaseObject(WrkBk)
ReleaseObject(WrkSht)
End Sub
Private Sub ReleaseObject(obj As Object)
Marshal.ReleaseComObject(obj)
obj = Nothing
End Sub
End Class

Display Excel values in DataGridView

I am having an issue with filling a DataGridView from an Excel file that is online. On button click, the app should create a new tab, add a DataGridView and populate with values from the Excel file. How can I do it?
Here is what I did so far:
Public Class Form1
Dim tempTabExist = False
Private Sub SiteList_Click(sender As Object, e As EventArgs) Handles SiteList.Click
Dim xlApp As Excel.Application
Dim wkbTemplRaspored As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
If tempTabExist = False Then
Call CreateNewTabPage()
End If
xlApp = New Excel.Application
xlApp.Visible = True
wkbTemplRaspored = xlApp.Workbooks.Open("http://CRNO/RAN/Raspored%20R%20A%20N_v1.xlsx")
xlWorkSheet = wkbTemplRaspored.Worksheets("Sheet1")
End Sub
Private Sub CreateNewTabPage()
Dim tp As New TabPage
tempTabExist = True
tp.Name = "SiteList"
tp.Text = "SiteList"
Call CreateNewGrid(tp)
Me.TabControl.TabPages.Add(tp)
End Sub
Private Sub CreateNewGrid(ByRef TP As TabPage)
Dim dg As New DataGridView
dg.Dock = DockStyle.Fill
dg.Name = "Raspored"
dg.Columns.Add(dg.Name, "Site Name")
dg.Columns.Add(dg.Name, "Technology")
dg.Columns.Add(dg.Name, "Week")
dg.Columns.Add(dg.Name, "Engineer")
TP.Controls.Add(dg)
End Sub
End Class
Most of your code seems to be working. I would change a few things however apart from listing the data in your DataGridView the code does appear to work.
To retrieve data from Excel and view in a DataGridView I would look at the following code:
Using con As New Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Test.xlsx'; Extended Properties='Excel 12.0;';"),
com As Data.OleDb.OleDbCommand = con.CreateCommand()
con.Open()
Dim dtSheetName As DataTable
dtSheetName = con.GetSchema("Tables")
If dtSheetName.Rows.Count > 0 Then
com.CommandText = "select * from [" & dtSheetName.Rows(0)("TABLE_NAME").ToString() & "]"
com.CommandType = CommandType.Text
dtRows.Load(com.ExecuteReader())
End If
End Using
There are bits of code here you may need to change as I haven't tested with your Data Source. Instead I used my own.
I would look at changing your method CreateNewTabPage slightly to return a TabPage:
Private Function CreateNewTabPage() As TabPage
Dim tp As New TabPage
tp.Name = "SiteList"
tp.Text = "SiteList"
Return tp
End Function
Instead of calling CreateNewGrid from CreateNewTabPage I would do this on your button click. I would however pass through the DataTable as well as the TabPage.
Additionally since we are assigning a DataTable as the DataSource we don't need to add columns manually. Here is what I would do:
Private Sub CreateNewGrid(ByRef TP As TabPage,
ByVal dt As DataTable)
Dim dg As New DataGridView
dg.Dock = DockStyle.Fill
dg.Name = "Raspored"
dg.DataSource = dt
TP.Controls.Add(dg)
End Sub
This is how I would call both methods:
If dtRows.Rows.Count > 0 Then
Dim tabPage As TabPage = CreateNewTabPage()
If tabPage IsNot Nothing Then
If TabControl1.TabPages.ContainsKey(tabPage.Name) Then
TabControl1.TabPages.RemoveByKey(tabPage.Name)
End If
CreateNewGrid(tabPage, dtRows)
TabControl1.TabPages.Add(tabPage)
End If
End If
Notice that I check for the tab and should it exist, I remove it. You may want to do something similar.
All together your code would look something like this:
Private Sub SiteList_Click(sender As Object, e As EventArgs) Handles SiteList.Click
Dim dtRows As New DataTable
Using con As New Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='http://CRNO/RAN/Raspored%20R%20A%20N_v1.xlsx'; Extended Properties='Excel 12.0;';"),
com As Data.OleDb.OleDbCommand = con.CreateCommand()
con.Open()
Dim dtSheetName As DataTable
dtSheetName = con.GetSchema("Tables")
If dtSheetName.Rows.Count > 0 Then
com.CommandText = "select * from [" & dtSheetName.Rows(0)("TABLE_NAME").ToString() & "]"
com.CommandType = CommandType.Text
dtRows.Load(com.ExecuteReader())
End If
End Using
If dtRows.Rows.Count > 0 Then
Dim tabPage As TabPage = CreateNewTabPage()
If tabPage IsNot Nothing Then
If TabControl1.TabPages.ContainsKey(tabPage.Name) Then
TabControl1.TabPages.RemoveByKey(tabPage.Name)
End If
CreateNewGrid(tabPage, dtRows)
TabControl1.TabPages.Add(tabPage)
End If
End If
End Sub
Private Function CreateNewTabPage() As TabPage
Dim tp As New TabPage
tp.Name = "SiteList"
tp.Text = "SiteList"
Return tp
End Function
Private Sub CreateNewGrid(ByRef TP As TabPage,
ByVal dt As DataTable)
Dim dg As New DataGridView
dg.Dock = DockStyle.Fill
dg.Name = "Raspored"
dg.DataSource = dt
TP.Controls.Add(dg)
End Sub
If you haven't already you may need to download Microsoft Access Database Engine 2010 Redistributable.
There are several ways to do this. Here are two ideas for you to muse over.
Imports System.Data.SqlClient
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='C:\Users\Excel\Desktop\Book1.xls';Extended Properties=Excel 8.0;")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
MyCommand.TableMappings.Add("Table", "Net-informations.com")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
DataGridView1.DataSource = DtSet.Tables(0)
MyConnection.Close()
End Sub
End Class
Also, try this.
Imports Excel = Microsoft.Office.Interop.Excel
Imports System.Data.OleDb
'~~> Define your Excel Objects
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim xlApp As New Excel.Application
'Dim xlWorkBook As Excel.Workbook
'Dim xlWorkSheet As Excel.Worksheet
Dim strConn As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dao_dbE As dao.DBEngine
Dim dao_DB As DAO.Database
Dim strFirstSheetName As String
dao_dbE = New dao.DBEngine
dao_DB = dao_dbE.OpenDatabase("C:\Users\Excel\Desktop\Coding\DOT.NET\Samples VB\Import into DataGrid from Excel & Export from DataGrid to Excel #2\Book3.xls", False, True, "Excel 8.0;")
strFirstSheetName = dao_DB.TableDefs(0).Name
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Users\Excel\Desktop\Coding\DOT.NET\Samples VB\Import into DataGrid from Excel & Export from DataGrid to Excel #2\Book3.xls;Extended Properties=""Excel 8.0;"""
da = New OleDbDataAdapter("SELECT * FROM [" & _
strFirstSheetName & "]", strConn)
da.TableMappings.Add("Table", "Excel")
da.Fill(ds)
DataGridView1.DataSource = ds.Tables(0).DefaultView
da.Dispose()
dao_DB.Close()
End Sub
End Class

Auto-fill textbox on a dialog form, from a Datagridview on the original form, vb.net 2013

I am currently working in windows form applications using vb.net 2013. I have two forms, we can call them form1 and form 2 for now. Form1 has a datagridview with a checkbox column that the end user will click to open form2 as a dialog form. Once form2 opens I want it to automatically load and fill two text boxes that have information from corresponding columns from the original DGV. In short, the DGV on form1 has 3 columns; JobNumber, LineNumber, and the checkbox. The end user will click the checkbox to bring up form2 and I want the Jobnumber and Linenumber to automaticaly fill into two textboxes on form2. Here is my code from form1.
'assembly dialog result form
dr = f.ShowDialog
If dr = Windows.Forms.DialogResult.OK Then
'dim y as job string
Dim Y As String = DataGridOrdered.Rows(e.RowIndex).Cells(3).Value
'open connection
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As SqlCommand = New SqlCommand("UPDATE Production.dbo.tblFCOrdered SET Complete = 1, RackIn = 1 WHERE JobNumber = '" & Y & "'", conn1)
comm1.ExecuteNonQuery()
conn1.Close()
End Using
End Using
Call DGVOrderedRefresh()
ElseIf dr = Windows.Forms.DialogResult.Yes Then
'dim M as job string
Dim M As String = DataGridOrdered.Rows(e.RowIndex).Cells(3).Value
'open connection
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As SqlCommand = New SqlCommand("UPDATE Production.dbo.tblFCOrdered SET Complete = 1, RackIn = 1 WHERE JobNumber = '" & M & "'", conn1)
comm1.ExecuteNonQuery()
conn1.Close()
End Using
End Using
Call DGVOrderedRefresh()
ElseIf dr = Windows.Forms.DialogResult.Cancel Then
'refresh datagridview ordered
Call DGVOrderedRefresh()
End If
ElseIf e.ColumnIndex = 0 Then
'fail safe to make sure the header is not clicked
If e.RowIndex = -1 Then
Exit Sub
End If
The code for my dialog is as follows
Imports System.Data
Imports System.Data.SqlClient
Public Class BuildName
' Dim connstring As String = "DATA SOURCE = BNSigma\CORE; integrated security = true"
Dim connstring As String = "DATA SOURCE = BNSigma\TEST; integrated security = true"
Private Sub Label3_Click(sender As Object, e As EventArgs) Handles Label3.Click
End Sub
Private Sub BuildName_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ds As New DataTable
Try
'load name combo box
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As SqlCommand = New SqlCommand("SELECT Name FROM Production.dbo.FCNames", conn1)
Dim adapater As New SqlDataAdapter
adapater.SelectCommand = comm1
adapater.Fill(ds)
adapater.Dispose()
conn1.Close()
CBName.DataSource = ds
CBName.DisplayMember = "Name"
CBName.ValueMember = "Name"
End Using
End Using
Catch ex As Exception
MsgBox("Error loading name List, please contact a mfg. Engr.!")
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Update built by name
Dim v As Object = TBFloor.Text
Dim G As Object = TBLine.Text
Dim O As Object = TBJobNumber.Text
Try
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As SqlCommand = New SqlCommand("UPDATE Production.dbo.tblFCOrdered SET BuiltBy = #Name Where JobNumber = '" & O & "'", conn1)
comm1.Parameters.AddWithValue("#Name", CBName.Text)
comm1.ExecuteNonQuery()
conn1.Close()
End Using
End Using
Catch ex As Exception
MsgBox("Error updating Ordered table, please contact a MFG. ENGR.!")
MsgBox(ex.ToString)
End Try
End Sub
End Class
UPDATED CODE FOR VALTER
Form1 code
Public row_Index As Integer = 0
Private Sub DataGridOrdered_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles DataGridOrdered.CurrentCellDirtyStateChanged
If DataGridOrdered.IsCurrentCellDirty Then
DataGridOrdered.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
Private Sub DataGridOrdered_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridOrdered.CellValueChanged
If DataGridOrdered.Columns(e.ColumnIndex).Name = 9 Then
Dim checkCell As DataGridViewCheckBoxCell = CType(DataGridOrdered.Rows(e.RowIndex).Cells(9), DataGridViewCheckBoxCell)
If CType(checkCell.Value, [Boolean]) = True Then
row_Index = e.RowIndex
BuildName.ShowDialog(Me)
End If
End If
End Sub
Form 2 code
Private Sub BuildName_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim value1 As Object = FormOrdered.DataGridOrdered.Rows(FormOrdered.row_Index).Cells(3).Value
Dim value2 As Object = FormOrdered.DataGridOrdered.Rows(FormOrdered.row_Index).Cells(4).Value
TBJobNumber.Text = CType(value1, String)
TBFloor.Text = CType(value2, String)
In your form1 add:
Public Row_Index As Integer = 0 //use a simple variable
Sub datagridOrdered_CurrentCellDirtyStateChanged( _
ByVal sender As Object, ByVal e As EventArgs) _
Handles datagridOrdered.CurrentCellDirtyStateChanged
If datagridOrdered.IsCurrentCellDirty Then
datagridOrdered.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
Private Sub datagridOrdered_CellValueChanged(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles datagridOrdered.CellValueChanged
If datagridOrdered.Columns(e.ColumnIndex).Name = "Assemble" Then //<- here
Dim checkCell As DataGridViewCheckBoxCell = _
CType(datagridOrdered.Rows(e.RowIndex).Cells(2), _ //<- here
DataGridViewCheckBoxCell)
If CType(checkCell.Value, [Boolean]) = True Then
//RowIndex = e.RowIndex you dont need this
Row_Index = e.RowIndex
BuildName.ShowDialog(Me)
End If
End If
End Sub
//Nor this
//Private _count As Integer
//Public Property RowIndex() As Integer
//Get
//Return _count
//End Get
//Set(value As Integer)
//_count = value
//End Set
//End Property
And in dialog load event use Form1.Row_Index instead:
Private Sub BuildName_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim value1 As Object = FormOrdered.datagridOrdered.Rows(Form1.Row_Index).Cells(0).Value //<- here
Dim value2 As Object = FormOrdered.datagridOrdered.Rows(Form1.Row_Index).Cells(1).Value //<- here
TBJobNumber.Text = CType(value1, String)
TBFloor.Text = CType(value2, String)
...
...
End Sub
or add a module and add the Row_Index there. You can use it then as is
Private Sub BuildName_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim value1 As Object = FormOrdered.DataGridView1.Rows(Row_Index).Cells(0).Value
Dim value2 As Object = FormOrdered.DataGridView1.Rows(Row_Index).Cells(1).Value
TBJobNumber.Text = CType(value1, String)
TBFloor.Text = CType(value2, String)
...
...
End Sub

Reading row of data from excel

I need to read rows from my excel and insert it to SQl server. While inserting i ll check whether those rows are existing or not, according to that a flag ll b return to the front end.
So far, i have did a column wise reading. please any one help me to read data row wise from excel, and insert to SQL server in VB.Net
Need to use Data table and data set.
In VB.NET
Public Class Form1
'#Region "Decleration"
'Dim exApp As Microsoft.Office.Interop.Excel.Application
'Dim exSheet As Microsoft.Office.Interop.Excel.Worksheet
'Dim exCell As Microsoft.Office.Interop.Excel.Range
'Dim dataset1 As New DataSet
'Dim rCount As Integer = 0
'Dim cCount As Integer = 0
'Dim objValues As Object
'Dim totalRecords As Integer = 0
'#End Region
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim objExcel As Excel.Application
Dim objWorkBook As Excel.Workbook
Dim objWorkSheets As Excel.Worksheet
Dim ExcelSheetName As String = ""
' objExcel = CreateObject("Excel.Application")
' objWorkBook = objExcel.Workbooks.Open("C:\Users\Jidh\Desktop\tttttttttttttttttt.xlsx")
End Sub
Private Sub OpenFileDialog_FileOk(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles FileUpload1.FileOk
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs)
End Sub
Private Sub btnChoseDoc_Click(sender As System.Object, e As System.EventArgs) Handles btnChoseDoc.Click
If FileUpload1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
Dim DS As DataSet
Dim MyCommand As OleDb.OleDbDataAdapter
Dim MyConnection As OleDb.OleDbConnection
Dim dtExcelSchema As DataTable
MyConnection = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Jidh\Desktop\tttttttttttttttttt.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"";")
MyConnection.Open()
dtExcelSchema = MyConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
Dim SheetName As String = dtExcelSchema.Rows(0)("TABLE_NAME").ToString()
MyConnection.Close()
MyConnection.Open()
' Select the data from Sheet1 of the workbook.
MyCommand = New OleDb.OleDbDataAdapter("Select * from [" & SheetName & "]", MyConnection)
DS = New System.Data.DataSet()
MyCommand.Fill(DS)
grvRecords.DataSource = DS.Tables(0).DefaultView
MyConnection.Close()
Catch ex As Exception
MsgBox(ex.ToString)
Finally
End Try
End If
End Sub
'Private Sub ReleaseComObject(ByVal obj As Object)
' Try
' System.Runtime.InteropServices.Marshal.ReleaseComObject(objValues)
' obj = Nothing
' Catch ex As Exception
' obj = Nothing
' Finally
' GC.Collect()
' End Try
'End Sub
End Class
So I've compiled your code and it seemed to extract all the data from Excel pretty well. Of course, if you don't want the first row of data to be your column headers then you just change the HDR to NO and that will solve that problem. Next, you've asked for it to be put into a dataset, which your code already does. This is then easily transferred to a datatable, and you have that.
Now, the part you asked to have it put into SQL. There are a few different ways. You can either put all the data into an XML document and then have an SQL stored procedure read that and insert it. Next, you can loop through each of the rows in the datatable and add it that way. I've gone with the method I think would be best, basing from MSDN (MSDN - Bulk Copy Data into SQL).
Let me know how you go.
Public YourDatatableWithExcelData As New System.Data.DataTable
Private Sub btnChoseDoc_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If FileUpload1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
Dim DS As DataSet
Dim MyCommand As OleDb.OleDbDataAdapter
Dim MyConnection As OleDb.OleDbConnection
Dim dtExcelSchema As System.Data.DataTable
MyConnection = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\dawid\Desktop\Book1.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"";")
MyConnection.Open()
dtExcelSchema = MyConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
Dim SheetName As String = dtExcelSchema.Rows(0)("TABLE_NAME").ToString()
MyConnection.Close()
MyConnection.Open()
' Select the data from Sheet1 of the workbook.
MyCommand = New OleDb.OleDbDataAdapter("Select * from [" & SheetName & "]", MyConnection)
DS = New System.Data.DataSet()
MyCommand.Fill(DS)
grvRecords.DataSource = DS.Tables(0).DefaultView
YourDatatableWithExcelData = DS.Tables(0)
MyConnection.Close()
Catch ex As Exception
MsgBox(ex.ToString)
Finally
End Try
End If
End Sub
Private Sub InsertIntoSQL(sender As Object, e As EventArgs) Handles Button2.Click
Using destinationConnection As SqlConnection = New SqlConnection("Data Source=servername;" & "Initial Catalog=databasename;" & "User ID=username;" & "Password=userpassword;")
destinationConnection.Open()
Using bulkCopy As SqlBulkCopy = New SqlBulkCopy(destinationConnection)
bulkCopy.DestinationTableName = "dbo.YourTableNameToCopyDataTo"
Try
bulkCopy.WriteToServer(YourDatatableWithExcelData)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
End Using
End Sub
We've made a globally declared datatable called YourDatatableWithExcelData which is assigned the value of the dataset, and then we call the datatable in the InsertIntoSQL function with the Button2.Click.
Hope this helps.

Code behind for print?

I have a report that I need to print after a sale has completed.
I am having issues with the length and printing when using PrintForm and PrintDocument components however if I right click and select Print from the list the report prints perfectly.
Is there any way that I could write code in my form load event that would imitate the right click print?
Ive been struggling with this part of my project for ages now and the whole thing is now way behind schedule.
My Code for the whole Receipt form page is:
Imports System.Data.OleDb
Imports System.IO
Imports System.Drawing.Printing
Public Class Receipt
Public PicLocation As String
Dim Ctrl1, Ctrl2 As Control
Dim CN As New OleDb.OleDbConnection
Dim CMD As New OleDb.OleDbCommand
Dim DataR As OleDb.OleDbDataReader
'To display into datagrid purpose
Dim dataS As New DataSet
Dim dataAd As New OleDb.OleDbDataAdapter
Public SqlStr, SqlStr1, DBPath, DBStatus, SearchBox As String
Dim X, Y, SqlH, Onh As Integer
Dim SqlUser As String
Dim DataP As Decimal
Dim Balance As Integer
Private Sub Receipt_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'ProductListDataSet' table.
DBPath = (Application.StartupPath & "\ProductList.accdb")
If CN.State = ConnectionState.Open Then
CN.Close()
DBStatus = ("Not Connected")
End If
SqlStr = ("Provider = Microsoft.ACE.OLEDB.12.0;Data Source =" & DBPath)
CN.ConnectionString = SqlStr
CN.Open()
Onh = Nothing
lblTime.Text = DateAndTime.Now
lblUser.Text = Login.userTB.Text
Dim sql As String
sql = "SELECT * Receipt"
Me.ReceiptTableAdapter.ClearBeforeFill = True
Me.ReceiptTableAdapter.Connection = CN
Me.ReceiptTableAdapter.Connection.CreateCommand.CommandText = sql
Me.ReceiptTableAdapter.Fill(Me.ProductListDataSet.Receipt)
Me.ReportViewer1.RefreshReport()
Me.Refresh()
End Sub
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
With Me.PrintForm1
.PrintAction = Printing.PrintAction.PrintToPrinter
Dim MyMargins As New Margins
With MyMargins
.Left = 0
.Right = 0
.Top = 0
.Bottom = 0
End With
.PrinterSettings.DefaultPageSettings.Margins = MyMargins
.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.CompatibleModeClientAreaOnly)
End With
End Sub
End Class