vb.net traversing an xls / xlsx file? - vb.net

is there a simple way in vb.net to load an excel file and read it? perhaps there is a way to load the file but have it not be visible to the user?

Alex - here is some old code I dug up to query excel. Pretty basic scenario here. Don't pay attention to the poor error handling and lack of the 'Using' construct.
Dim connString As String = "Provider=Microsoft.Jet.OLEDB.4.0" & _
";Data Source=" & ExcelFile & _
";Extended Properties=Excel 8.0;"
Dim conn As OleDbConnection = Nothing
Dim dt As System.Data.DataTable = Nothing
Dim excelDataSet As New DataSet()
Try
conn = New OleDbConnection(connString)
conn.Open()
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
If dt Is Nothing Then
Return Nothing
End If
Dim excelSheets(dt.Rows.Count) As String
Dim i As Integer = 0
For Each row As DataRow In dt.Rows
excelSheets(i) = row("TABLE_NAME").ToString
System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)
If i = SheetNumber Then
Exit For
End If
Next
Using excelCommand As New OleDbCommand("Select * from [" & excelSheets(SheetNumber - 1) & "]", conn)
Using excelAdapter As New OleDbDataAdapter(excelCommand)
excelAdapter.Fill(excelDataSet)
End Using
End Using
Catch ex As OleDbException
Throw
Catch ex As Exception
Throw
Finally
conn.Close()
If conn IsNot Nothing Then
conn.Dispose()
End If
If dt IsNot Nothing Then
dt.Dispose()
End If
End Try
Return excelDataSet

Work with the Excel Object Model directly from .NET.

You can use ado.net to read from excel spreadsheets via the OLEDB JET 4 provider
This just opens the excel file as a file stream instead of opening the actual excel spreadsheet.
Alternatively you could use com-interop and simply set the application object visible property to false.
See http://www.connectionstrings.com/excel
One gotcha to watch out for when using .net and com interop with any office application is that if you try opening the application as a user who is more of a windows service than an actual human user then you will need to login to windows as that user and open the relevant application as that user so that all the registry entries are correctly updated for certain features of the office application.

If you have a more simple (ie small) excel spreadsheet that does not need to be dynamic, I think you could export it as a comma delimited file and then use a loop and streamreader object to parse each comma seperated value into an array.
Kinda round about though...

Related

Mapping onedrive files to string for OLEDB to read specific files within drive Visual Basic .NET

I have a program that reads an excel file that is on my local disk. I need this file to be accessible to other individuals to edit the file and allow the program to execute based on its contents. The way were making this accessible is sharing it via OneDrive. The file is read by a OLEDB Script I wrote that takes the directory of the file to read it and load into temp table on the app. I have been searching online for a solution to this in visual basic but a lot of the solutions are written in c# and its hard for me to translate or understand the logic. Here is an example of the solution in pseudo code:
If (ONEDRIVE_FILE_DIRECTORY IsNot Nothing) Then
' STORE FILE FROM ONE DRIVE INTO LOCAL_FILE_DIRECTORY
End If
Dim strConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="LOCAL_FILE_DIRECTORY";Extended Properties=""Excel 8.0;HDR=YES"";"
Dim dt As New DataTable
dt.TableName = "Results"
dt.Columns.AddRange(New DataColumn() {New DataColumn("LOC_ID", GetType(String)),
New DataColumn("EMAIL", GetType(String)),
New DataColumn("INTERVAL", GetType(String)),
New DataColumn("PASSWORD", GetType(String))
})
Dim connection As OleDbConnection = New OleDbConnection(strConnectionString)
Dim strSQL As String = "SELECT [LOC_ID], [EMAIL], [INTERVAL], [PASSWORD] FROM [Report$] WHERE [LOC_ID] <> ''"
Try
connection.Open()
Using Adp As New OleDbDataAdapter(strSQL, connection)
Adp.Fill(dt)
End Using
Catch ex As Exception
LogMessage(ex.ToString, "Error message in """ & strApplicationName & """ job on " & strComputerName & " by: " & strUsername)
SendEmailErrorMessage(ex.ToString)
Finally
If connection.State = ConnectionState.Open Then
connection.Close()
End If
End Try

How do I export a Service-Based SQL table from a Windows Form App into Excel?

I'm building an application to simulate building a real application and not just small examples.
The application has a Main Form and 3 other Windows Forms for Orders, Sales and Products, I also have one Service-Based SQL Database which is local and application-only Database, this Service-Based DB has 3 tables, one for each Form. They are all good, it works fine and the application saves the data I place on it when I run the app from debug folder, but now I need to keep records of those tables separately in an excel sheet and I have no idea on how to do it.
I've learned everything I need to build this application from the video below and I'm enhancing it as I can, maybe if I wasn't clear enough this can help to give some context. https://www.youtube.com/watch?v=NLs44hxV514
And this is how my application is looking like https://imgur.com/a/ElS6V6v
Tried some examples I found online but none have worked, most of them were directed to real SQL servers, not those Service-Based ones.
I know this is not helpful at all but this is what I have so far on my Export Button.
Try
sfdProdutos.InitialDirectory = "c:\"
sfdProdutos.Title = "Save your file."
sfdProdutos.ShowDialog()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
And not one drop of an idea as to how to finish it, lol.
As for now I'm trying to just save it into an existing Excel file, because I know there will be something to complicate my life if I try everything at once, let that for another day.
So you can understand how I've been working with the database within the application so far, this is my 'save record' button for one of the forms
If ProductTextBox.Text = Nothing Then
ProductTextBox.Text = "unknown"
End If
If ProviderTextBox.Text = Nothing Then
ProviderTextBox.Text = "unknown"
End If
If PriceTextBox.Text = Nothing Then
PriceTextBox.Text = "unknown"
End If
If Bar_CodeTextBox.Text = Nothing Then
Bar_CodeTextBox.Text = "unknown"
End If
Try
Me.Validate()
Me.ProductsTableBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.ProdutosDataSet)
MessageBox.Show("The product has been edited.", "Information.", MessageBoxButtons.OK)
ProductTextBox.Select()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Any help is very much appreciated!
Thanks in advance just for reading all of this.
I would use a datatable and populate it from the sql table, then you can easily export that data to excel
Dim strSql As String = "SELECT EmpCode,EmpID,EmpName FROM dbo.Employee"
Dim dtb As New DataTable
Using cnn As New SqlConnection(connectionString)
cnn.Open()
Using dt As New SqlDataAdapter(strSql, cnn)
Dt.Fill(dtb)
End Using
cnn.Close()
End Using
Use this to export to excel
use this to Fill (Populate) DataTable using your SqlDataAdapter
Dim constring As String = "Data Source=.\SQL2005;Initial Catalog=Northwind;User id = sa;password=pass#123"
Using con As New SqlConnection(constring)
Using cmd As New SqlCommand("SELECT * FROM Customers", con)
cmd.CommandType = CommandType.Text
Using sda As New SqlDataAdapter(cmd)
Using dt As New DataTable()
sda.Fill(dt)
dataGridView1.DataSource = dt
End Using
End Using
End Using
End Using

How to make an Excel file a VB.NET resource for dataGridview form?

I’m learning VB.NET, so please forgive my ignorance...
I’m using a dataGridView form to display an Excel file (.xls) as a help file. I use Excel format because it formats very well, can be updated in Excel, and looks great in the dataGridView form...much easier and better than a standard text file.
But even though I can access the file from disk ("C:\DTC.XLS”), I want to place the file inside the VB app itself as a resource. I haven’t been able to do this successfully. I dragged the file into Solution Explorer > My Project > Resources. It shows up as “DTC” under files.
In my code, if I replace the file path (‘C:\DTC.XLS') with the resource handle (My.Resources.DTC), I get an exception: “ System.Data.OleDb.OleDbException: 'Cannot update. Database or object is read-only.’ ”
I’m ok with “read-only”...it’s just a help file. How can I get the dataGridView form to open this resource without exception?
My routine:
Private Sub DTCinfo(sender As Object, e As EventArgs) Handles DTCdataGridView_button.Click
If DTCdataGridView_button.Text = "CLOSE Info" Then
DataGridView1.Hide()
DTCdataGridView_button.Text = "DTC Info"
DTCdataGridView_button.BackColor = SystemColors.ControlDarkDark
Else
DTCdataGridView_button.Text = "CLOSE Info"
DTCdataGridView_button.BackColor = Color.Red
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
' ***** THE FOLLOWING LINE WORKS OK WITH THIS SUBROUTINE:
' MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\DTC.xls';Extended Properties=Excel 8.0;")
' ***** THE FOLLOWING LINE DOES NOT WORK WITH THIS SUBROUTINE (GENERATES AN EXCEPTION):
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source=My.Resources.DTC;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)
DataGridView1.ReadOnly = True
DataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.[True]
AutoSizeColumnsMode = True
AutoSizeRowsMode = True
DataGridView1.Columns(0).AutoSizeMode = False
DataGridView1.Columns(0).Width = 50
DataGridView1.Columns(2).Width = 200
DataGridView1.Columns(3).Width = 150
DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
With DataGridView1
.RowHeadersVisible = False
.Columns(0).HeaderText = "DTC"
.Columns(1).HeaderText = "Test Mode"
.Columns(2).HeaderText = "Description"
.Columns(3).HeaderText = "Action"
End With
MyConnection.Close()
DataGridView1.Show()
End If
End Sub
I found another example of how to do this online. It's simpler to read and easier to understand, but I still get the same exception: "Cannot update: the database or object is read only." How to fix?
' here's another test....
Sub testDataGridView()
Dim dt As New DataTable
' Note, you should use My.Settings rather than My.Resources for storing the data source
' Dim connectionString As String =
' $"provider=Microsoft.Jet.OLEDB.4.0;Data Source={My.Settings.gizmotest};Extended Properties=Excel 8.0;"
Dim connectionString As String =
$"provider=Microsoft.Jet.OLEDB.4.0;Data Source={My.Resources.DTC};Extended Properties=Excel 8.0;"
' Note, you should use import statements for these objects e.g.
' Place this as the first line in the code file
' Imports System.Data.OleDb
Using cn As New OleDbConnection With {.connectionString = connectionString}
Using cmd As New OleDbCommand With {.Connection = cn, .CommandText = "select * from [Sheet1$]"}
Try
cn.Open()
dt.Load(cmd.ExecuteReader)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Using
End Using
End Sub
OK, seems that the DataGridView form won't work with a read-only source...or at least it won't if it's using the Excel input format...true? And I guess a resource can only be read-only...I guess? I couldn't figure this all out definitively, but it's my best guess...
So I created a temporary file on disk when opening the form, copied the resource to the file, opened the file in the DataGridView form, then closed and deleted the file. Voila! Works. Seems a bit kludgy to me, but hey, it works, looks good, so now on to bigger things....

Searching Excel Document Columns with Visual Basic and Interop

I'm struggling with a problem that involves interop and excel.
Basically, I have excel files with columns that contain "headers" and the rows beneath the columns have the data. For example, the column Age will have 12,14,etc underneath it. I am new to Interop and I'm trying to allow the user to enter the name of the column header they wish to extract data from, so if they enter "Age", it'll find age is colum B for example and then extract all the data from the proceeding rows.
I've Googled extensively and haven't found anything solid, all rather context orientated and being new to Interop makes this a little tricky.
What I've got so far:
Public Sub getExcelData(ByVal directory As String)
Dim excelAppFirstFile As Excel.Application = Nothing
excelAppFirstFile = CreateObject("Excel.Application")
Try
excelAppFirstFile.Workbooks.Open(directory)
Dim excelSheet As Excel.Worksheet = excelAppFirstFile.Worksheets(1)
Catch ex As Exception
MsgBox("There was a problem: " + ex.Message)
End Try
End Sub
I know it isn't much but I've gone in circles with ranges,etc and can't figure out how to get where I need to.
EDIT:
I forgot to add that the Column name being searched for is a variable called field which is set at an earlier stage by the user.
If all you want to do is read data in the Excel file, I suggest you to use OleDb instead of interop (which is much faster):
Dim filePath As String = "C:\Book1.xls"
Dim connectionString As String = (Convert.ToString("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=") & filePath) + ";Extended Properties=""Excel 8.0"";"
Dim connection As New OleDbConnection(connectionString)
Dim cmdText As String = "SELECT * FROM [Sheet1$]"
Dim command As New OleDbCommand(cmdText, connection)
command.Connection.Open()
Dim reader As OleDbDataReader = command.ExecuteReader()
If reader.HasRows Then
While reader.Read()
Console.WriteLine("{0}" & vbTab & "{1}", reader(0).ToString(), reader(1).ToString())
End While
End If

How to create a ComboBox autofill using SQLite Data Reader

I have two Combo-Boxes like this
I need to create an auto-fill feature for the 1st Combo-Box. It should list the EmployeeID if Search-By Field is specified as Employee-Number. Similarly it should list Employee First Name along with Last Name if the Search-By Field is Employee-Name.
How can I do this? I have no clue, I am doing this for the first time. I am using SQLite, Visual Studio 2010.
Dim mySelectQuery As String = "SELECT " & Search & " FROM EmployeeTable WHERE Status LIKE '" & Status & "'"
Dim myConnString As String = "Data Source=" & Application.StartupPath & "\Database\SimpleDB.db3"
Dim sqConnection As New SQLiteConnection(myConnString)
Dim sqCommand As New SQLiteCommand(mySelectQuery, sqConnection)
sqConnection.Open()
Try
' Always call Read before accessing data.
Dim sqReader As SQLiteDataReader = sqCommand.ExecuteReader()
Dim j As Integer = sqReader.FieldCount
While sqReader.Read()
'''''''''''''''''''''''Here, Don't know how to list the items from the query reult into the combo-box
End While
'Close Reader after use
sqReader.Close()
Catch ex As Exception
'Show Message on Error
MsgBox(ex.ToString)
Finally
'At Last Close the Connection
sqConnection.Close()
End Try
I'm not sure entirely what you are asking but I think this is it.
In the SelectedIndex changed event you would have something similar to the code below. You can add an If statement to check what you are querying for and adjust your query accordingly.
Dim dt as New DataTable
Try
Using sqlConn
sqlConn.Open()
Using cmd As New SqlCommand("your query")
cmd.Connection = sqlConn
cmd.CommandType = CommandType.Text
Dim reader as SqlDataReader = cmd.ExecuteReader()
dt.Load(reader)
End Using
End Using
Catch ex As SqlException
Throw New Exception(ex.Message)
End Try
With yourComboBox
.DataSource = dt
.DataValueField = "columName you want to be the value of the item"
.DataTextField = "columnName of the text you want displayed"
End With
Notice the following properties for the combo-box: AutoCompleteMode, AutoCompleteSource, AutoCompleteCustomSource.
Select the appropriate AutoCompleteMode. See details on the different modes at this link.
For AutoCompleteSource, choose either ListItems (in which case the source will be the items of the ComboBox) or CustomSource. Should you choose CustomSource, set the appropriate source as the value of the ComboBox's AutoCompleteCustomSource property.
This should provide you with enough details to do what you're looking for.
The other requirements you've listed - such as taking the data from an SQLite database or changing between employee name and employee number - won't affect the way you work with the AutoComplete feature.