VB.NET Appending table to a database from DataTable object - vb.net

I am trying to convert some old VB6 code into VB.NET. The old code used DAO and now I am trying to replicate it in ADO.NET/OleDB. I have made some advances (I think...) but now I can't figure out how to add the DataTable object into the database.
Here is the old VB6 code, td is a TableDef object from DAO:
If fso.FileExists(loc) Then
Set td = m_db.CreateTableDef("Ratings")
td.Connect = "Excel 8.0;HDR=Yes;IMEX=2;DATABASE=" & loc
td.SourceTableName = "Sheet1$"
m_db.TableDefs.Append td
bFileNotExists = False
Else
bFileNotExists = True
End If
From what I understand this is reading Sheet1 from the Excel file 'loc' and then appending it to m_db, a DAO database object. This is what I have so far, and please correct me if you see any mistakes as I'm just getting started with this sort of thing -
If fso.FileExists(loc) Then
oleCon = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & loc & ";Extended Properties=""Excel 8.0;HDR=Yes;")
oleCon.Open()
oleAdapter = New OleDbDataAdapter("SELECT * FROM [Sheet1$]", oleCon)
oleAdapter.Fill(dt)
bFileNotExists = False
Else
bFileNotExists = True
End If
So instead of the TableDef, I am taking the data from the same sheet and putting it in a DataTable object (dt). I hope this is correct so far. Now my question is how to replicate the m_db.TableDefs.Append td line from above. Thank you!

The thing is, that you have to pre-load the 'dt' with the configuration in the Excel-file, in order for the TableAdapter to work out. This is as far as I know. There's many paths you can take, including first creating columns and then loading row-by-row, or loading the Excel-sheet in as a DataTable itself and add this to a DataSet.
Suggestions:
Start using CamelCase programming notation. This really helps out and prevents errors.
Read up on ADO.NET, for example by following some tutorials.
Drop OleDb handling, ADO.NET suffices.
Realize the differences between VB.Net and VB6, and prepare to learn some more object-oriented programming

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.

How to use If .eof OR .bof condition in vb.net?

I am converting vb6 application into vb.net and in it .eof and .bof are used as condition. I am not understanding how to carry out these conditions in vb.net
sSql = "Select * From SPCsetup"
Set dbConn = New ADODB.Connection
Call openDBconn(dbConn)
Set rsConn = dbConn.Execute(sSql)
If rsConn.EOF Or rsConn.BOF Then
bFlag = False
Else
bFlag = True
End If
Well, first off, ADODB is a COM component so you could in theory just keep on using it. But it’s not really recommended as while it does have some beers and whistles they are not without their own problems. Ado.Net exist for a reason and it’s not just because they like writing new code to do the same thing.
Secondly if you use a datareader then bof (before first record) is somewhat relevant, but if you use a dataadapter to fill a table it’s not. It either has records or it doesn’t. If you want/need to continue using something like a record set, then that would be a datreader...there isn’t a BOF, but you don’t really need it. You find out nothing was returned, by the fact that nothing was returned.
sSql = "Select * From SPCsetup"
Using dbConn = New SqlConnection(connctionString)
dbConn.Open()
Using dbCmd = dbConn.CreateCommand()
dbCmd.CommandText = sSql
Using dbReader = dbCmd.ExecuteReader
bFlag = false
While dbReader.Read
bFlag = true
'Do something
End While
End Using
End Using
End Using
As noted from your other posts, you can (and should) do one of two things:
Create your own recordset class. It will take likely less then 30 minutes. You can then use your existing code with VERY little changes.
And you ALSO really (but really really) needed to share with everyone here WHAT KIND of data object you going to use, or are planning to use or are currently using in vb.net. (or ASK what kind of data object you should use).
Are you using a dataset?
Are you using a datatable?
Are you using a iList?
.net has a GAZZILLION choices, ranging from “iList”, and a bunch more I NOT listed out here. So we have little clue as to WHAT you currently using.
I am going to take a BIG FAT WILD guess and assume datatable.
Assuming we using a datatable, then you code would be something like:
Dim tblHotels As New DataTable
Dim strSQL As string = "select * from tblHotels"
Dim DataReader As New SqlDataAdapter(strSQL, My.Settings.SQLCon1string)
DataReader.Fill(tblHotels)
If tblHotels.Rows.Count = 0 Then
bFlag = False
Else
bFlag = True
End if
So, in place of
If tblHotels.EOF then
You would then have:
If tblHotels.Rows.Count = 0 Then

How to use VB to create Excel style and format data sheet?

I want to write a program which will replace my current paper based record. My current paper record is basically many column and rows with different width, height, and other properties. I know how to write a VB program that can save the information, but I don't know how to make the VB program to generate a xls datasheet to which would exactly like my paper record.
Would someone please give me the information about that?
Thanks :)
I would recommend http://epplus.codeplex.com/releases/view/42439.
It is very easy to use and integrates flawlessy in vb.net.
I am not providing code as a sample because the samples which are included in the package are very good.
As a hint: Internally I would use a Data-Table to store your values and then use a separate module to load/store it to excel.
An excel file could be thougth as a simple database where each sheet is a different table.
Assuming you have Excel on your machine, you could create an empty XLS file and then use OleDB to fill the worksheets.
Sub WriteToExcel()
Dim con As String con = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\temp\test.xls;" & _
"Extended Properties='Excel 8.0;HDR=No;'"
Using c as OleDbConnection = new OleDbConnection(con))
c.Open()
Dim commandString as String = "Insert into [Sheet1$] (F1, F2, F3) " & _
"values('Column1Text', 'Column2Text', 'Column3Text')"
Using cmd As OleDbCommand = new OleDbCommand(commandString))
cmd.Connection = c
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
other options include OpenXml (which I'd have thought is the "recommended" way to do it but which brings with it a learning curve) or at the other end of the scale (in terms of crudeness) write your data in a comma-separated (csv) format and manually import it into Excel

how to query/get data from Datasource in VB.NET

i am building a database application in vb.net and i started by adding a data source from the DATA in the toolbar. my connection is good and it shows all my tables in the data source panel.
i also see new classes related to my database, like
sakilaDataSet
sakilaDataSet.customerDataTable
...
and so on.
how do i query and use these ? i googled a lot and i am not able to get this.
Dim cust As sakilaDataSet.customerDataTable = New sakilaDataSet.customerDataTable
Dim row() As System.Data.DataRow = cust.Select("customer_id=5")
MsgBox(row.Count)
My last try was with the above code, but the row.count always turns out to be zero.
You need to open a connextion to the DB. Here are some options:
You could use EntityFramework, which provides a nice way to access data and control it by mapping to entities (classes). For this, in VisualStudio create a ClassLibrary project, add an item ADO.NET Entity Data Model. This will open a wizard that will help you connect to the DB, map the objects in the DB to entities and access the entities by a reference to an entity context. The basics are easy.
Other option is to use an OLEDB provider, which is a classic way to access DB. An example to open an Access DB of employees:
Dim connString As String = "provider= microsoft.jet.oledb.4.0; " & _
"data source=Employee.mdb;"
Dim conn As New OleDbConnection(connString)
Try
conn.Open()
Finally
conn.Close()
Console.WriteLine("Connection Closed")
End Try
Visit http://www.connectionstrings.com/ to get a list of common connection string for many DB. Other useful links:
EntityFramework:
http://www.codeguru.com/csharp/csharp/net30/article.php/c15489
http://www.asp.net/entity-framework/tutorials
OLEDB:
http://oreilly.com/catalog/progvbdotnet/chapter/ch08.html
http://www.homeandlearn.co.uk/net/nets12p2ed.html
http://www.sourcecodester.com/tutorials/net/database-programming-made-easy.html
Hope this helps.
What i wanted to achieve was not to use connection strings again. After adding the data source in VB.net, it makes Data Classes and Adapters, which i can use directly to access the database, as follows :
Dim staff As sakilaDataSet.customerDataTable = New sakilaDataSetTableAdapters.customerTableAdapter().GetData
Dim rows() As sakilaDataSet.customerRow = staff.Select("email='" + email.Text + "'")
This website http://visualbasic.about.com/od/usingvbnet/a/begdbapp7.htm had a good tutorial where it talked about what happens when you use the data sources window and how to use it in your code after that.
I know it's an old question, but it was very high in Google results, and it was more of a "This is how you should have done it" answer instead of actually answering with what it seems like you asked

Using TableAdapter to insert rows into a dataset does not do anything

I have a question similar to this one, but reading the (accepted) answer didn't give me much insight, so I'm hoping to state it more clearly and get a clearer response back.
I'm attempting to insert a data row into a table. I'm using TableAdapter's custom "insert nonQuery" that I wrote (it works, I tested) to accept some parameters. I'm fairly new to this business of communication with a database via .NET and what I'm doing is probably wrong by design. My questions are why is it wrong and what's the right way to do it? Both are equally important, IMO.
Here's some sample VB code I wrote:
Dim arraysTableAdapter As New UnitTestsDataSetTableAdapters.ArraysTableAdapter
Try
arraysTableAdapter.InsertArray("Test Array", 2, 1, 2, "Test user")
Catch ex As SqlException
MsgBox("Error occured when trying to add new array." _
& vbNewLine & vbNewLine _
& ex.Message)
End Try
...and that's pretty much it. There is no exception raised, my table does not get a new row inserted. Everything is just the way it was before I called the InsertArray method. When I test my query in the QueryBuilder with the same parameters, a new row gets added to the database.
Now, I do understand some of the reasons this would not work. I understand that I need to create and select a row in my DataSet (no idea how to do it) in order to tell the TableAdapter what it's adding the data to. Or at least I got that impression from reading the vast abyss of forums.
I would really like to use TableAdapter at some point, because it knows that .InsertArray exists and it knows which parameters it likes. I could try and do it using
Dim con As New SqlConnection
Dim cmd As New SqlCommand
con.ConnectionString = connString
con.Open()
cmd.CommandText = "INSERT ...... all that jazz"
but it's not nearly clean enough for how clean I like my code to be. So, is there any way to do what I'm trying to do the way I'm doing it? In other words, how do I use the neat structure of a TableAdapter to communicate to my DataSet and put a new row in it?
Thanks in advance!
There were two things that were wrong:
(minor issue) I did not have a DataTable filled from the TableAdapter (see code below)
(major, sneaky issue) My method worked from the very beginning. There is nothing extra to be added except for the line above. However, the ConnectionString of arraysTableAdapter was pointing my program (automatically, by default) to a wrong location. Once I manually set the ConnectionString, it worked perfectly.
Here's my complete code:
Dim connString As String = "Some correct connection string"
Dim arraysDataTable As New SpeakerTestsDataSet.ArraysDataTable
Dim arraysTableAdapter As New UnitTestsDataSetTableAdapters.ArraysTableAdapter
'Set the correct connection string'
arraysTableAdapter.Connection.ConnectionString = conn
'Fill table from the adapter'
arraysTableAdapter.Fill(arraysDataTable)
Try
arraysTableAdapter.Insert("Test", 2, 1, 2, Now, Now, "Me")
Catch ex As Exception
MsgBox("Error occured when trying to add new array." _
& vbNewLine & vbNewLine _
& ex.Message)
End Try
The accepted answer in the question you linked to is correct, but sometimes saying it in different words helps:
A TableAdapter is used to communicate between a DataTable (there can be one or more DataTables in a DataSet) and a database. It can pull data from a database and add it to a DataTable and it can send data from a DataTable to the database. It's purpose is to create and execute the SQL code required to make this communication work.
You are trying to use the TableAdapter to directly add data to your DataTable. This will not work. Instead, you should use the methods that come with the DataTable to add a new row to the DataTable and then (if necessary) use your TableAdapter to send that row to a database.
For instance, with a Dataset called DataSet1 that contains a DataTable called DataTable1 that has three text columns you can add a record like this:
Dim d As New DataSet1
d.DataTable1.AddDataTable1Row("value1", "value2", "value3")
That AddDataTable1Row method is automatically created for you, and I think is what you are looking for.