How to generate a new MS access file programmatically - vb.net

I have looked far and wide, in the deepest darkest corners of the internet, but for the life of me, I can not find the correct way to open a NEW Access file and then using vb.net to write data in the database..
The keywords here are NEW database, I don't want to open an existing file.
Is this even possible?
Thanks in advance!

I have finally found the way, thanks to a co-worker of mine
Neither ADO.NET nor ActiveX Data Object (ADO) provides the means to create Microsoft
Access Database. However, we can create Access databases by using the Microsoft Jet OLE DB
Provider and Microsoft ADO Ext. 2.7 for DDL and Security (ADOX) with the COM Interop
layer. To do so, select References from the Project Menu, choose the COM tab, and add a
reference to Microsoft ADO Ext. 2.7 for DDL and Security; then you can use this function.
When you have done this, use the following snippet to create a database
Public Class Form1
Private Sub btnLoad_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnLoad.Click
CreateAccessDatabase("C:\test\testDB.mdb")
MsgBox("Database created")
End Sub
Public Function CreateAccessDatabase( ByVal DatabaseFullPath As String) As Boolean
Dim bAns As Boolean
Dim cat As New ADOX.Catalog()
Try
Dim sCreateString As String
sCreateString =_
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
DatabaseFullPath
cat.Create(sCreateString)
bAns = True
Catch Excep As System.Runtime.InteropServices.COMException
bAns = False
Finally
cat = Nothing
End Try
Return bAns
End Function
End Class

Related

Change connection string of access database in visual studio 2022

Ok so, basically i want to connect an access database (.mdb file) to my project. Now yes i have indeed connected it through the "data origin" wizard but the problem is that when i transfer the exe AND the database to another pc, it doesn't find it (obviously).
Dim appPath As String = My.Application.Info.DirectoryPath
Dim txtconnesione As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & appPath & "\Magazzino.mdb"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TableMagazzinoBindingSource.DataSource = txtconnesione
Me.TableMagazzinoTableAdapter.Fill(Me.MagazzinoDataSet.TableMagazzino)
End Sub
appPath is basically where the program gets started.
With this code it actually shows me the whole grid but it's empty, just like this:
i didn't used a connection string and i didn't copy it in the project (sorry for bad english, if you don't understand i'll try to explain better)

Crystal report Viewer keeps on Asking for Logon ID and Password at runtime

Situation:
I made application using vb.net ,ms access and crystal report
When I run it my computer, I don't encounter any problem at all , but when I install and run it on other computer, crystal report asks for login ID and password
I have 2 tables in the report
The main report and the sub report
the Datasource for my rpt file is:
Datasource:C:\User\Documents\report.accdb
some suggests doing something like this:
myreport.SetDatabaseLogon.("user","password")
But I dont know how to use it and where to input the code
Anyone Familiar with this ? Thank you
I just wanted to provide you with the code that I used when I needed to connect to crystal reports embedded within my Visual Studio project.
Please disregard if you are not using the same method.
In my example, I connect to a SQL database so that the stored procedure my crystal report is using can be loaded.
I always used these subroutines to create a crystal report connection and configure the report with proper settings.
I'm not sure if you can set the connectioninfo with just a userID and password, but I figured this code might give you some ideas about what your code is missing.
If you need more help, please provide code snippets so we can help further diagnose.
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared
'Crystal Report Here
Private mycrystalreport1 As CrystalReport1
Private Sub ConfigureCrystalReports()
Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
mycrystalreport1 = New CrystalReport1()
Dim reportPath As String = Application.StartupPath & "\" & "CrystalReport1.rpt"
mycrystalreport1.Load(reportPath)
CrystalReportViewer1.ReportSource = mycrystalreport1
myConnectionInfo.ServerName = "SQL" 'OR WHATEVER SERVER NAME IS
myConnectionInfo.DatabaseName = "DATABASE_NAME"
myConnectionInfo.UserID = "USER_ID"
myConnectionInfo.Password = "PASSWORD"
SetDBLogonForReport(myConnectionInfo, mycrystalreport1)
End Sub
Private Sub SetDBLogonForReport(ByVal myConnectionInfo As ConnectionInfo, ByVal myReportDocument As ReportDocument)
Try
Dim myTables As Tables = myReportDocument.Database.Tables
For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In myTables
Dim myTableLogonInfo As TableLogOnInfo = myTable.LogOnInfo
myTableLogonInfo.ConnectionInfo = myConnectionInfo
myTable.ApplyLogOnInfo(myTableLogonInfo)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ConfigureCrystalReports()
'CAN SET PARAMETERS FOR A STORED PROCEDURE OR LOCAL VARIABLES IN CRYSTAL HERE
End Sub
Hopefully, this can provide you with some insight as to how crystal reports can take in a username and password.
Change your report to use ODBC. Makes it easier to check the database connection on each PC.
I'm guessing that the 2nd PC doesn't have the required database drivers to connect to accdb, but that's just a guess.

Examples of maintaining memory with database connections for VB.net

I have a particular problem in database connection disposal and despite there being a lot of back and forth over disposal of connections, datasets, and datatables I can't quite wrap my head around it as a new VB coder. My project has a form with a simple "Import Database" button which opens a connection. Lets assume I have a database with several Datasets and datatables that take up a bunch of memory so I have to be careful how I open and close things. I have a button to close the database when done with it. The code briefly looks like this and does not throw me errors (i.e. I can connect, get the right data and then close the database without an error being thrown)
Public ConnectedDB as DataBaseOps
Class Form1
Private Sub ImportDatabaseButton(sender as object, e and eventargs) handles ImportDatabasebutton.click
'Open filedialog and return the path, etc.
strPATH = OpenFileDialogMaster(...my filters here...)
ConnectedDB.OpenDatabase(strPath)
End Sub
Private Sub populateDSDT(....)
'...populate my datasets which then populate my datagrids
ConnectedDB.PopulateMyDataSet()
'...populate my datagrids
End sub
Private Sub CloseDatabaseButton(sender as object, e and eventargs) handles CloseDatabaseButton.click
ConnectedDB.CloseDatabase()
'Can I put something here to clean up the DatabaseOPs class?
End Sub
End Class
Now in a separate class
Private Class DataBaseOps
Public OpenCon As OleDb.OleDbConnection
Public Sub OpenDataBase(strPath as String)
'My.Settings.ConnectionString is a variable in App.Config
OpenCon = New OleDb.OleDbConnection(My.Settings.ConnectionString & strPath)
OpenCon.Open()
End Sub
Public Sub PopulateMyDataSet()
'...Populate my datasets and tables based on data from the database
'...Note that for the adapters I include "Using" to help keep those clean when I no longer need them
End sub
Public Sub CloseDatabase()
Try
OpenCon.Close()
Catch ex As Exception
MessageBox.Show("No Database file loaded.")
End Try
End Sub
Overrides Sub Finalize()
'...Datasets get .Dispose() which is a topic of its own elsewhere.
OpenCon.Dispose()
End Sub
End Class
Keep in mind there are other ways of doing this but the key factor here is to open the connection, keep it open to populate datagrids, do some other work in the database, and then close it releasing the connection and datasets memory.
My problem is I've tried various means to limit the scope of "ConnectedDB" and its datasets including putting a Finalize() sub into the process in an attempt to remove it from memory. I also toyed with scoping but neither of these ideas work perfectly and it seems to retain items in memory.
Using my general code what can I do to clean up the memory resource here? As a relatively new VB.net coder, am I missing something obvious (like I could maybe inherit one class to the other instead of calling them?)
Keep your connections local to where they are used. Then you can use Using...End Using blocks to ensure that they are closed and disposed.
Thanks to Duncan Edwards Jones for this quote.
"A database connection is like a refrigerator door - You only open it
when you need something, you only take out what you need, and you
close it as soon as you have taken out what you need. "
A DataSet can hold more than one DataTable. I am not sure why you would need more than one DataSet.
Class Form1
Private ConnectedDB As DataBaseOps
Private ds As DataSet
Private Sub ImportDatabaseButton(sender As Object, e And eventargs) Handles ImportDatabaseButton.click
Dim OpenDial As New OpenFileDialog
'Open filedialog and return the path, etc.
Dim strPATH = OpenDial.FileName
ConnectedDB = New DataBaseOps(strPATH)
End Sub
Private Sub populateDSDT()
'...populate my datasets which then populate my datagrids
ds = ConnectedDB.PopulateMyDataSet()
'...populate my datagrids
End Sub
End Class
Public Class DataBaseOps
Private DBFile As String
Public Sub New(file As String)
DBFile = file
End Sub
Public Function PopulateMyDataSet() As DataSet
Dim ds As New DataSet
Using OpenCon As New OleDb.OleDbConnection(My.Settings.ConnectionString & DBFile)
OpenCon.Open() 'But don't do this until directly before the .Execute...
'...Populate my datasets and tables based on data from the database
'...Note that for the adapters I include "Using" to help keep those clean when I no longer need them
End Using
Return ds
End Function
End Class
Add this two lines in your Finalize method after OpenCon.Dispose()
GC.Collect()
GC.WaitForPendingFinalizers()

Unrecognized database format when filling DataAdapter

I am trying to use listboxes to categorize data and I am trying to use SQL to do so.
form picture
that link is what the form looks like know and what i'm trying to do - to use the listboxes to view the records by student year.
For the first list box here is the code for the first listbox to sort the data by year:
Imports System.Data.OleDb
Public Class viewStudent
Private Sub viewStudent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'ProjDataSet1.Details' table. You can move, or remove it, as needed.
Me.DetailsTableAdapter1.Fill(Me.ProjDataSet1.Details)
' OleDbDataAdapter1.Fill(DataSet11)
End Sub
Private Sub lstYear_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstYear.SelectedIndexChanged
Dim Year, SQLString As String
Dim dtDetails As New DataTable()
Dim dbDataAdapter As OleDbDataAdapter
Dim ConnectString As String = "Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source = proj.accdb"
Year = lstYear.Text
SQLString = "SELECT * FROM Details WHERE Year = " & "'" _
& Year & "'" & ""
dbDataAdapter = New OleDbDataAdapter(SQLString, ConnectString)
dbDataAdapter.Fill(dtDetails)
grdRecords.DataSource = dtDetails
End Sub
End Class
But i get the error in the link below:
error
Can someone help to fix this?
Thank you!
The "Microsoft.Jet.OLEDB.4.0" provider is the older 32-bit provider that can only work with .mdb database files. To work with an .accdb database you need to use the newer "Microsoft.ACE.OLEDB.12.0" provider.
Since you have the 64-bit version of Access 2013 installed you already have the 64-bit version of the ACE provider. All you need to do is
Modify the properties of your .NET project to run as a 64-bit application (ref: here), and
Change the connection string in your code to use Provider=Microsoft.ACE.OLEDB.12.0.

Running SQL query from Module with a function call from my Form

I have a form set up where I want to run the function PopulateGrid on it's Form_Load event. I have initialized the DB connection as follows:
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
LoadConfigFile()
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & config("DatabasePath") & ";")
cn.Open()
End Sub
Now, I want to run the PopulateGrid function directly after I connect to the database as shown above. I'm confused as to how I'd use a database query in a module when the database is initialized in my main form. Would simple setting the variable cn to public work? Or do I have to do something more complex?
Thanks.
You should modify your module to accept the OleDbConnection as a parameter and then just pass the cn variable to the query method. Setting cn to public would not be a good design because it would be introducing a dependency on the form/ui in the module that is unnecessary.