Convert xls to xlsx without interop - vb.net

I have a computer(actually several machines) on my companies network that do not have office installed. I need to develop a vb.net program that will parse information from a spreadsheet which is usually in an .xls format. I don't feel that there are many options for reading data from an .xls document without the interop. If so what are some options?
If I could even convert an .xls to .xlsx programmatically without the interop, that would be an option too. I could then use ClosedXML to parse from a xlsx. Or is there a way to read an .xls file with ClosedXML that I'm not seeing?
Any help would be great as I am having trouble finding the answer to this one.

You don't need to use com interop to read from an Excel file. You can use OleDb (although you might need to install the office data connectivity components)
Imports System.Data.OleDb:
Public Shared Function ReadExcelWorkSheet(ByVal sheetName As String, ByVal connectionString As String) As DataTable
Dim sql As String = String.Format("SELECT * FROM [{0}$]", sheetName)
Dim dt = New DataTable()
Using conn As OleDbConnection = New OleDbConnection(connectionString)
Using cmd = New OleDbCommand(sql, conn)
conn.Open()
Using adapter = New OleDbDataAdapter(cmd)
adapter.Fill(dt)
End Using
End Using
conn.Close()
End Using
Return dt
End Function
Where connection string is for xlsx files:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES";
or for xls files:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myOldExcelFile.xls;Extended Properties="Excel 8.0;HDR=YES";
more info on the connection strings here

You can read it via ADO.Net. I'd need to see your existing code, but this should allow you to open it without Excel.
System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;
Extended Properties='Excel 12.0 Xml;HDR=YES';")

Related

Additional information: There is already an open DataReader associated with this Command which must be closed first. vb.net

Dim cat As New Catalog()
Dim con As New OleDbConnection()
Dim cmd As New OleDbCommand
Dim ds1 As New DataSet
Dim conn As ADODB.Connection
' Open the Access database.
conn = New Connection
conn.ConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;" &
"Data Source=" + openExcel + "\Test" + ".mdb; Persist Security Info=False"
con.ConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;" &
"Data Source=" + openExcel + "\Test" + ".mdb; Persist Security Info=False"
conn.Open()
xlWorkSheet1.Columns(5).Insert
Dim cellValue As String = ""
Dim newValue As String = ""
Dim sh1 As String = ""
Dim qty As String = ""
Dim matchText As String = ""
Dim sql As String = ""
con.Open()
sh1 = LTrim$(xlWorkSheet1.Cells(i, 1).Text)
sql = "SELECT Num_ber, Q_ty FROM good WHERE Na_me LIKE 'staff%' And Ty_pe = 'ORD'"
Dim cmd As New OleDbCommand(sql, con)
Dim myReader As OleDbDataReader = cmd.ExecuteReader()
conn.Execute(sql)
myReader = cmd.ExecuteReader() ' HERE'S THE PROBLEM
xlWorkSheet1.Cells(1, 5) = myReader.GetString(0)
xlWorkSheet1.Cells(1, 11) = myReader.GetString(1)
myReader.Close()
conn.Close()
conn = Nothing
**I wanted to retrieve a specific value from mdb and then write it to excel.
Here's my code, I got this error so many times and I can't find it out. Can anybody help me? Thanks.**
[1]: https://i.stack.imgur.com/6Fuvg.png
Ok, you first have to decide when usng .net what "provider" you are going to use, AND THEN decide what kind of data objects you want to use.
You can use a oracle provider, a sql server provider, or in this case, since we using Access, then we can use EITHER oleDB, or ODBC. Either choice is fine. Most use oleDB providers for Access, but often ODBC is a good choice, especially if down the road you plane to swap out Access for say SQL server.
What the above means in plain English?
You don't want to adopt the external ADODB code and library. That code is NOT .net, and thus you REALLY but REALLY do not want to write your .net code that way. ADODB was written LONG before .net, and is what we call un-managed code (non .net). I strong, but strong suggest you do NOT add a reference to ADODB to your project, and I beyond strong recommend you avoid introduction of a non .net library for doing this!!! We certainly can adopt the oleDB provider in .net, but we will NOT have a direct reference to JET/ACE (the access database engine) in our applcation. As noted, there are some exceptions to this suggesting, but they don't apply to you and here.
Next up:
The design pattern in .net is to create the connection, get the data, and CLOSE the connection. This "pattern" will then be 100% sure that the data base is always closed, and you NEVER have to worry about if the connection is open, closed, or even if you forgot to close the connection!!! So, do this correct, and some "open" connection will never bite you, or will you have to worry about this issue.
You can in some operations keep the connection open for performance, but lets learn to walk before we run so to speak.
next up:
We certainly do NOT want to place and have connection strings all over in our code. Not only is this going to wear out your keyboard, but if you ever need to change the connection, then you going to have to hunt down all that code.
Best to let Visual Studio save that connection in ONE location, and MORE important MANAGE this for you!!!
Next up:
Do you ONLY need to work with mdb files, or do you plan/need to work with accDB files? This is a HUGE issue, and one that you cannot ignore.
next up:
Are you going to use the x32 bit version of the Access database system, or the x64 bit version?
Since your example posted code uses JET (access data engine for mdb files ONLY x32 bit version)?
Then this ALSO means you MUST (and I repeat MUST) force your .net project to run as x32 bits. You cannot use "any cpu", and you cannot use x64 bits, you MUST choose x86 bit size for your .net project. Failure to do so will result in the project not working.
Ok, with the above information?
First up, force/set/be 100% sure your project is set to run as x32 bits.
That setting is this one:
and remove the reference you have to ADO if you created one.
Ok,
next up:
Create the connection to the database.
Project ->properties.
This here:
And then:
and then
Now, you can browse, and select the access mdb file.
But, you MUST not skip the next step - you have to choose JET (older, mdb files), or choose the newer ACE (for accDB format files).
So, this:
now this:
As noted, you choose JET or ACE here.
now, we have this and you can use test connection.
BUT BE VERY careful!!!!
If you are using vs2022, then keep in mind vs2022 is the FIRST version of VS that is now x64 bits. As a result, vs can't pass the test connection!!! Your connection is in fact ok, but will fail with vs2022.
If you using a previous version of VS (before 2022), then the test connection button should work. and you see this:
Ok, now that we have a valid working conneciton setup, we can now write code, and we will NOT use ADODB!!!!
The typical code pattern to read and load a data table (like a access VBA recordset) will be like this:
Now, I became RATHER tired of writing that same using block over and over. So, in a global module, I have this code now:
Public Function MyRst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using conn As New OleDbConnection(My.Settings.AccessDB)
Using cmdSQL As New OleDbCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
So, now with the above handy dandy helper routine?
Your code becomes this:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Sql As String =
"SELECT Num_ber, Q_ty FROM good WHERE Na_me LIKE 'staff%' And Ty_pe = 'ORD'"
Dim rstData As DataTable = MyRst(Sql)
Debug.Print("Na_me is " & rstData.Rows(0).Item("Na_me"))
End Sub
Or, display all return rows from that data table
Debug.Print("Na_me is " & rstData.Rows(0).Item("Na_me"))
For Each OneRow As DataRow In rstData.Rows
Debug.Print("na_me = " & OneRow("Na_me"))
Next
So, you really don't need (or want) a reader anyway. Just load the results into a nice clean, easy to use data table, and from that you can loop the table, grab rows, or do whatever you want.

Set password for SQLite v3 database

My application uses a database stored in a file available via network. So far, I've been using a MS-Access file (.accdb), but I'm trying to migrate to SQLite Version 3 (.db3).
I added SQLite NuGet package to my project and created a SQLite database using SQLiteStudio. I refactored my database objects to work with System.Data.SQLite.SQLiteConnection instead of System.Data.OleDb.OleDbConnection and it worked well.
However, my previous accdb database was password protected, and I don't know how to apply a password over my current SQLite database.
Can anyone teach me ho to do it? Thanks in advance!
I followed the link which Wudge kindly appointed in comment above, and it works, but I'd rather clarify what need to be done:
To set a password to an unprotected database:
Dim conn = New SQLite.SQLiteConnection(
"Data Source=C:\yourFolder\yourDB.db3;Version=3;")
conn.Open()
conn.ChangePassword("password")
conn.Close()
To open a password-protected database:
Dim conn = New SQLite.SQLiteConnection(
"Data Source=C:\yourFolder\yourDB.db3;Version=3;")
conn.SetPassword("password")
conn.Open()
conn.Close()
or
Dim conn = New SQLite.SQLiteConnection(
"Data Source=C:\yourFolder\yourDB.db3;Version=3;Password=password;")
conn.Open()
conn.Close()
To remove password from a password-protected database:
Dim conn = New SQLite.SQLiteConnection(
"Data Source=C:\yourFolder\yourDB.db3;Version=3;Password=password;")
conn.Open()
conn.ChangePassword(String.Empty)
conn.Close()
PS. The open source database manager SQLiteStudio is able to open files which were password-protected that way, as long as you choose System.Data.SQLite instead of Sqlite 3 as your database type. (Requires v 3.1.1, the current version).

Read from NTX files with Vb.NET

I'm trying to read from some DBF files that use NTX files for indexing within VB.NET. Currently, I'm having to read directly from the DBF files using OLEDB, which is ridiculously slow due to dbase's flat file method of data storage. So, I'm wondering if someone could tell me how to access the DBF files through their NTX index files within VB.NET.
If I need to download a third party library I'm okay with that, But I don't have money to pay for a third party library if it costs money. It would need to be free.
This is what I'm currently using to access the DBF Files.
Private Shared ConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & My.Settings.DataPath & ";Extended Properties=dBase IV"
Public Shared dBaseConnection As New System.Data.OleDb.OleDbConnection(ConnectionString)
Dim dBaseCommand As New System.Data.OleDb.OleDbCommand("SELECT * FROM `PAGES.NTX` WHERE `PAGE_NUM` BETWEEN 241 AND 270", dBaseConnection)
Dim dBaseDataReader As System.Data.OleDb.OleDbDataReader = dBaseCommand.ExecuteReader(CommandBehavior.SequentialAccess)
This however still reads directly from the DBF file and ignores the NTX indexing. Any help?
Note: I cannot "choose" to use SQL for this project as the DataBases are ones created and maintained by another application (One of considerable age). I need only access them for the data stored within.
Download Advantage .NET Data Provider
This is the only example I could find. Since I do not have the files to test with this is only an example:
'Set the TypeTable to NTX
Dim conn As New AdsConnection("data source=c:\data;" + "ServerType=remote|local; TableType=NTX")
Dim cmd As AdsCommand
Dim reader As AdsDataReader
Dim iField As Integer
Try
' make the connection to the server
conn.Open()
' create a command object
cmd = conn.CreateCommand()
' specify a simple SELECT statement
cmd.CommandText = "select * from departments"
' execute the statement and create a reader
reader = cmd.ExecuteReader()
' dump the results of the query to the console
While reader.Read()
For iField = 0 To reader.FieldCount - 1
Console.Write(reader.GetValue(iField) + " ")
Next
Console.WriteLine()
End While
conn.Close()
Catch e As AdsException
' print the exception message
Console.WriteLine(e.Message)
End Try

Import data from Excel to SQL Server 2008

I'm doing a redesign on a site that uses VB.Net. The system will get a fair bit of data from Excel 97-2003 files, which are uploaded by a third party, then uploaded to SQL 2008. Here's the problem, the files that are uploaded have the extension .P. I've used the below code to try and grab the data and upload to the database.
Dim xlApp As New Excel.Application
xlApp.Workbooks.Open(Filename:=Server.MapPath("~/ExtractFiles/10-31-13.P"))
xlApp.ActiveWorkbook.SaveAs(Filename:=Server.MapPath("~/ExtractFiles/10-31-13.xls"), FileFormat:=51)
If Not xlApp Is Nothing Then
xlApp.ActiveWorkbook.Close()
xlApp.Quit()
xlApp = Nothing
End If
PrmPathExcelFile = Server.MapPath("~/ExtractFiles/10-31-13.P")
plmExcelCon = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + PrmPathExcelFile + ";Extended Properties=""Excel 12.0;HDR=YES;IMEX=1""")
cmdLoadExcel = New System.Data.OleDb.OleDbDataAdapter("select * from [10-31-13]", plmExcelCon)
Dim dt As System.Data.DataTable
dt = New System.Data.DataTable
cmdLoadExcel.Fill(dt)
plmExcelCon.Close()
When the code hits the line cmdLoadExcel.Fill(dt), I'm only getting an error that says "External table is not in the expected format.". I'm assuming that this has to do with the fact that I'm trying to change the file extension. However, I can't seem to open the file with the extension .P.
Is there a method I'm overlooking here? Or is this just not possible when working from a file with a custom extension.
Alright, I found the answer thanks to the hint by varocarbas. For future reference, double check the OledbConnection against the Excel file type. After I put in the following changes it worked:
plmExcelCon = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + PrmPathExcelFile + ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1""")
cmdLoadExcel = New System.Data.OleDb.OleDbDataAdapter("select * from [10-31-13$]", plmExcelCon)
First, to work with my version of Excel, I needed to use ACE.OLEDB.12.0 and Excel 8.0. Second, I had to add a simple '$' to the end of the table select, otherwise it wouldn't be able to find the right worksheet.

Can't open SQLCompact database

I am working with a SQL compact database and I am able to test the connection when I import it and copy the exact file path to my code, but it still says that it hasn't been opened. What am I doing wrong? Are there any shortcuts available if I have already added the database to my project?
Thanks!
Imports System.Data.SqlServerCe
Module Module1
Sub Main()
Dim constring As String = "Data Source=C:\Users\test\Desktop\MyDatabase1.sdf"
Dim conn As New SqlCeConnection(constring)
Dim cmd As New SqlCeCommand("SELECT * FROM ACCOUNT")
conn.Open()
Dim reader As SqlCeDataReader = cmd.ExecuteReader()
While reader.Read()
Console.WriteLine(reader)
End While
End Sub
End Module
You need to assign the connection to the command:
Immediately after this line:
conn.Open()
add:
cmd.Connection = conn
Alternatively, you can add the connection to the command's constructor:
Dim cmd As New SqlCeCommand("SELECT * FROM ACCOUNT", conn)
One of the main advantage of using SQL server CE (3.5) is to have Linq to SQL. You should make use of strongly typed database, and of DataContext. if you do so, then creating a new DataContext is ONE line of code, not 8. And if your DataBase file does not exist, the CreateDataTable method of your DataContext will create them for you. Dig a little into this, because using SQL Server CE like an old fashion OLEDB data provider is... well... not optimal :-)