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.
I have a project set up with 3 separate tables. I used the built-in designer from Visual Studio.
The tables contain
Students
Courses
Tests in each course
All the tables share a studentnumber.
I have no problem getting and accessing the data true different tableadapters and corresponding bindingsources automatically generated by Visual Studio when I "drag and drop" them on the forms. I also am able to use the query builder to get the data I need from each table.
My problem occurs when I try to access the database manually via connection string.
I get this error:
Cannot attach file local path\HovedDatabase.mdf as database Outcomes because the file is already in use for database local path\HovedDatabase.mdf
This is the code I have:
Private Sub FormPrøver3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'StudentDataSet.StudentTabell' table. You can move, or remove it, as needed.
Me.StudentTabellTableAdapter.Fill(Me.StudentDataSet.StudentTabell)
Me.StudentTabellTableAdapter.Connection.Close()
Get_Data_Manualy_Fag()
End Sub
Private Sub Get_Data_Manualy_Fag()
Try
'Create variabals for inputcontainer
Dim Studnr As String = Me.StudentnrLabel1.Text
'Create a connection to the DataBase
Dim myConn As SqlConnection
myConn = New SqlConnection("Initial Catalog=OutComes;Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\HovedDatabase.mdf;Integrated Security=True")
'Create a Command object.
Dim myCmd As SqlCommand
myCmd = myConn.CreateCommand
myCmd.CommandText = "SELECT Fag FROM Fag3Tabell WHERE Fag = #Studnr"
myCmd.Parameters.AddWithValue("#Studnr", Studnr)
'Open the connection.
myConn.Open()
'Process the answer
Dim myreader As SqlDataReader
myreader = myCmd.ExecuteReader
'Traverse the DataSet and Display :
Dim i As Integer = 0
Do While myreader.Read()
Me.ComboBox1.Items.Add(myreader.GetString(i))
i = i + 1
Loop
'Close the connection
myConn.Close()
'Handle errors
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
I set up a similar project with a similar LocalSQL database. I have done nothing in Visual Studio other than creating the database with the same tables.
Here I have no problem connecting to the database via manual connection string.
My question is: why can't I access the local DB with a connection string in the first project?
You haven't posted your other connection string, but it looks like AttachDbFilename may be the problem. The DB will already be attached, this option is only meant to be used in single-user mode (one connection only).
Best bet is to permanently attach the DB to the LocalDB instance if that is what you are using the whole time.
I have included database in my project(at root).
The connection string
Data Source=|DataDirectory|\TSM_DB.sdf;Password=xxx;Persist Security Info=True;Max Database Size=512
TSM_DB.sdf properties:
Build Action = Content
Copy to Output Directory = Copy if newer
Dataset properties:
Build Action = None
Copy to Output Directory = Do Not Copy
My problem:
When I try to insert data into the database it gets inserted to the database present in Debug folder and not in the database which is included in the project...
And that’s why (obviously) my select statement does not find any record in the database (according to my connection string)...
I think the query (code) is perfectly fine, but some sort of settings need be done.
How do I solve this issue?
EDIT :
Example Select Code (working : when connection string path is Absolute)
Try
Dim cnt_temp
Dim SQLquery As String
Dim myConString As String = My.Settings.TSM_DBConnectionString
con.ConnectionString = myConString
SQLquery = "SELECT * FROM tbl_outward"
Dim DA As SqlCeDataAdapter, Ds As New DataSet, Dtb As New System.Data.DataTable
DA = New SqlCeDataAdapter(SQLquery, con)
DA.Fill(Ds)
Dtb = Ds.Tables(0)
cnt_temp = Dtb.Rows.Count
MsgBox(cnt_temp)
con.Close()
Catch ex As Exception
MsgBox("Error..!", MsgBoxStyle.Exclamation)
End Try
When I try to insert data into the database it gets inserted to the database present in Debug folder and not in the database which is included in the project...
Which is exactly what you told it to do, and is what you want. The database in your project folder is part of the source code. When you test or debug your code, the data changed is part of your test or temporary debug output, not your source code.
When you test your code, would you want the test overwriting your source code? I hope not, that would destroy your source; and when you deploy your project you don't usually deploy your source code. The same is true of your data; the data in your project is part of your application and is not the end-user data. When you install your application your source data gets installed to DataDirectory, which is part of your application and is not user data; the user may not even be able to write to it.
When you uninstall or update your application, DataDirectory gets uninstalled or updated. You don't want to do that to your user's data; would you like it if every time you updated Microsoft Word it deleted every Word file on your drive? That's what would happen if Word stored user data in its equivalent of DataDirectory.
DataDirectory is only for your app's private use. If a user needs this data you should copy it to a user-writable place that won't get deleted, like Environment.SpecialFolder.ApplicationData.
Further explanations at this answer.
VB express 2010
1 form, 1 textbox , 1 button
I created the .mdf sql database file by clicking Project>add new item>service based database> and named it DXDB - table name DXtest and 1 column named test
It seems like the codes works..however when I right click DXtest and click show table data... there is nothing there... =( It seems like it doesnt really insert the data on the database itself...
Here is the complete code
Imports System.Data
Imports System.Data.SqlClient
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim con As New SqlConnection
Dim cmd As New SqlCommand
Dim Tx1 As String
Tx1 = TextBox1.Text
con.ConnectionString = "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DXDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"
con.Open()
cmd.Connection = con
cmd.CommandText = "INSERT INTO DXTest(Test) VALUES(#Tx1)"
cmd.Parameters.Add("#Tx1", SqlDbType.VarChar, 50).Value = Tx1
cmd.ExecuteNonQuery()
con.Close()
End Sub
End Class
The whole User Instance and AttachDbFileName= approach is flawed - at best! When running your app in Visual Studio, it will be copying around the .mdf file (from your App_Data directory to the output directory - typically .\bin\debug - where you app runs) and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the myConnection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The real solution in my opinion would be to
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. DXDB)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\SQLEXPRESS;Database=DXDB;Integrated Security=True
and everything else is exactly the same as before...
I'm a bit puzzled here. I did a form containing a simple datagridview containing data from an MDB file. The connection was alltogether done by Visual Studios wizard so alot of stuff was created automatically. Then I databinded the textboxes to each column in the database and managed to update the database via my own command buttons such as "Update" with this code:
Me.MainTableBindingSource.EndEdit()
Me.MainTableTableAdapter.Update(Me.DBDataSet.MainTable)
Me.DBDataSet.MainTable.AcceptChanges()
This doesn't seem to work with sql. At this point, I've done everything from scratch in this order, added a datagridview and added a database connection with the wizard when connecting the datagridview to a database. Only this time around I created an SQL connection instead.
And Visual Studio created "MainTableTableAdapter", "DBDataSet", "DBDataSet.MainTable".
The SQL server is something which was installed automatically when installing Visual Studio and it does seem to work after creating the table adapter and dataset if there's data in it. In some time I plan to use an SQL Server on the internet which hosts the dataset. So I want to be able to easily edit the source.
The only thing missing now is how to add a row, delete selected row and editing selected row via my own textboxes. More like a fill-in form. Any ideas to put me in the right direction? I've tried googling it and I've found some stuff, but most of it contains stuff on how to create the datasets and etc. And I'm not sure what Visual Studio has done automatically. And I want to update everything just as easily as I did with these three lines of code when I used a local MDB file.
If it's SQL you can do something like this. Here's an example delete function:
Public Shared Function DeleteStuff(ByVal id As Integer) As Integer
Dim query As String = _
"DELETE FROM tbl_Stuff " & _
"WHERE ID_Stuff = " & id & ";"
Dim connection As SqlConnection = YourDB.GetConnection
Dim deleteCommand As New SqlCommand(query, connection)
Dim rowCount As Integer = 0
Try
connection.Open()
rowCount = deleteCommand.ExecuteNonQuery()
Catch ex As SqlException
Throw ex
Finally
connection.Close()
End Try
Return rowCount
End Function
There may be better ways, but you can always pass in SQL queries.
EDIT: Sorry this is more than three lines of code. ;)