VB.NET ADODB MS SQL Server Open Recordset - sql-server

After I open a SqlConnection, I try to open a recordset like I did it thousands times before in VBA. Yes, I know that there are differences between VBA and VB.NET, but maybe it's to simple to see it.
Public Class Form1
Const m_cstrCnnString As String = "MyCorrectCnnString"
Dim cnn As SqlConnection
Dim rcs As New ADODB.Recordset
Private Sub MyConnection()
cnn = New SqlConnection(m_cstrCnnString)
cnn.Open()
'so far it works, my cnn.State is 1
rcs.Open("SELECT * FROM dbo.myTable", cnn) 'this line doesn´t work
End Sub
I tried the rcs.Open with and without CursorTypeEnum, LockTypeEnum, but I always get the same error:
System.Runtime.InteropServices.COMException: The arguments are of the wrong type, are out of scope, or are inconsistent with each other.
Background: Win10, Connection to a MS SQL Server Express by VB.NET.
First I import System.Data.SqlClient
Microsoft ActiveX Data Objects 6.1 Library is activated.
Also I tried it with Microsoft ActiveX Data Objects Recordset 6.0 Library.
And I'm new in VB.NET

There's some high-level stuff I need to cover before we can get into the details of what this code should look like.
First, if you're using VB.Net, you should not be opening a RecordSet object. Recordset is from ADO, which is not the same as ADO.Net. You definitely can't use an ADO.Net SqlConnection to open a classic ADO RecordSet. Again: these are two completely different libraries. The classic library exists in .Net only for backwards compatibility and to aid in porting forward old code. It should not be used for new development.
Additionally, when you move forward to ADO.Net you need to be aware of a feature called Connection Pooling. This feature takes care of caching connection objects for you, such that it's counter-productive (uses more RAM and makes things slower) to try to keep a single connection option ready for use throughout the application. Instead, it really is better to create a new connection object for most queries.
Finally, classic ADO had a problem with properly closing resources, such that some of those older applications could occasionally even lock out the database. .Net provides a way to handle this such that you are sure everything is closed and disposed properly and promptly: a Using block.
The weakness of this mechanism is DataReader objects (which replace RecordSet) need the connection to remain open for the life of the reader. This makes it hard to build a good data abstraction to hide all the boiler plate code that goes with data access.
The best pattern I've seen for offering the best of both worlds requires some moderate and advanced VB.Net language features (lambda methods, iterator blocks, and IEnumerable) that are unfamiliar to many traditional VB coders. It's going to require me to go a lot deeper than normal in this answer. That said, once you wrap your head around it, the result is really nice.
To show what this might look like, I need an example that's a little more concrete. We'll pretend you have an Employee table with columns for ID, FirstName, and LastName, and a class Employee with properties of the same name:
Public Class Employee
Public Property ID As Integer
Public Property FirstName As String
Public Property LastName As String
Public Shared Function FromDataRecord(record As IDataRecord) As Employee
Return New Employee() With {
ID = record("ID"),
FirstName = record("FirstName"),
LastName = record("LastName")
}
End Function
End Class
That's right: VB sometimes uses braces now. The Shared method at the end is optional, but it will help make some of what comes next easier to follow. Here is what modern ADO.Net code might look like. Pay special attention to the use of Private and Public
Public Module DB
Private Shared Property ConnectionString As String = "MyCorrectCnnString"
Private Iterator Function GetData(Of T)(SQL As String, transform As Func(Of IDataRecord, T), addParameters As Action(Of SqlParameterCollection)) As IEnumerable(Of T)
Using cn As New SqlConnection(ConnectionString)
Using cmd As New SqlCommand(SQL, cn)
If addParameters IsNot Nothing Then addParameters(cmd.Parameters)
cn.Open()
Using rdr As SqlDataReader = cmd.ExecuteReader()
While rdr.Read()
Yield transform(rdr)
End While
End Using
End Using
End Using
End Function
Public Function GetEmployees() As IEnumerable(Of Employee)
Dim SQL As String = "SELECT * FROM dbo.Employee"
Return GetData(SQL, Employee.FromDataRecord, Nothing)
End Function
Public Function GetEmployeeById(ID As Integer) As Employee
Dim SQL As String = "SELECT * FROM dbo.Employee WHERE ID= #ID"
Return GetData(SQL, Employee.FromDataRecord,
Sub(pc) pc.Add("#ID", SqlDbType.Integer).Value = ID
).FirstOrDefault()
End Function
Public Function GetEmployeesByLastName(LastName As String) As IEnumerable(Of Employee)
Dim SQL As String = "SELECT * FROM dbo.Employee WHERE LastName= #LastName"
Return GetData(SQL, Employee.FromDataRecord,
Sub(pc) pc.Add("#LastName", SqlDbType.NVarChar, 25).Value = LastName
)
End Function
End Module
Now the main part of the application NEVER deals in SQL directly, or even has to know there's a relational database involved. It's just calling methods on a regular module, such that the code in your form for reading data looks more like this:
Dim employees = DB.GetEmployeesByLastName(TextBox1.Text)
DataGridView1.DataSource = employees
You make similar methods in the new Module for writing INSERT/UPDATE/DELETE queries to save changes. These methods will end up calling the cmd.ExecuteNonQuery() method, but they should NEVER accept an SQL statement string as input.
As an application grows you might have a number of classes with FromDataRecord() methods, such that you instead refactor these methods to their own Module. You might also end up with enough Public methods in the DB Module to divide them up into a number of related Modules. At this point, these Modules would all go into a separate class library project (using Friend in some places instead of Private).

Related

Why is my vb code not updating the ms access database (only cached temporarly)

I am doing a small system using Ms. Access (the database has more than 10 tables ) connecting to visual studio. I made a public class for opening the connection to the database so I can use it in every form. Everything is working and I can get the data from the database But any inserting or deleting data in forms, the database in ms access not getting the update. I can see the new records in forms but nothing in the database.
Imports System.Data.OleDb
Public Class dbconnectClass1
'create db connection
Private DBcon As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=dental_clinic.accdb;")
'prepare db command
Private dbcmd As OleDbCommand
' db data
Public DBDA As OleDbDataAdapter
Public DBDT As DataTable
'query parameters
Public params As New List(Of OleDbParameter)
'query statics
Public recordcount As Integer
Public Exception As String
Public Sub ExecQuery(query As String)
'reset query status
recordcount = 0
Exception = ""
Try
'open connection
DBcon.Open()
'create db command
dbcmd = New OleDbCommand(query, DBcon)
'load params into dbcommand
params.ForEach(Sub(p) dbcmd.Parameters.Add(p))
'clear params list
params.Clear()
'excute command and fill dataset
DBDT = New DataTable
DBDA = New OleDbDataAdapter(dbcmd)
recordcount = DBDA.Fill(DBDT)
Catch ex As Exception
Exception = ex.Message
End Try
'close the database connection
If DBcon.State = ConnectionState.Open Then DBcon.Close()
End Sub
'include query and command parameters
Public Sub addparam(name As String, value As Object)
Dim newparam As New OleDbParameter(name, value)
params.Add(newparam)
End Sub
End Class
This my code inside the forms:
Public Class NewExpense
Private access As New dbconnectClass1
' a varuble having the appointment Id to connect between 2 forms
Private appointmentNo As Integer
Private Function NoError(Optional report As Boolean = False) As Boolean
If Not String.IsNullOrEmpty(access.Exception) Then
If report = True Then MsgBox(access.Exception)
Return False
Else
Return True
End If
End Function
Private Sub Savebuttum_Click(sender As Object, e As EventArgs) Handles
Savebuttum.Click
Dim oDate As DateTime = Convert.ToDateTime(DateTimePicker1.Value)
access.addparam("#expensenme", expensenmtXT.Text)
access.addparam("#expensedetail", ExpenseDetailTXT.Text)
access.addparam("#expenseamount", ExpenseAmountTXT.Text)
access.addparam("#expensedate", oDate)
access.addparam("#expensepaidTo", paidtoTXT.Text)
access.ExecQuery("INSERT INTO Expense (Expenses_name, expense_details,
expenses_amount, ExpenseDate_Paid, ExpensePaid_To) Values (#expensenme,
#expensedetail, #expenseamount, #expensedate, #expensepaidTo);")
'report on errors
If Not String.IsNullOrEmpty(access.Exception) Then
MsgBox(access.Exception) : Exit Sub
'success
access.DBDA.Update(access.DBDT)
MsgBox("Expense Has been Added Successfully")
End Sub
End Class
Hum, you have this:
params.ForEach(Sub(p) dbcmd.Parameters.Add(p))
Great, we add the parmaters - looks good to go!!!
then, next line CLEARS all the work above!!! (the parameters are removed!!!!)
'clear params list
params.Clear()
Next up? Many will build a connection object, then a reader, and then a adaptor. But you ONLY need a data adaptor if you going to update a data table. if you just going to execute a command, then you don't need the data table, and you don't need a adaptor FOR that table. Adaptor = ability to modify a existing datatable (or dataset).
You are MUCH better to use the command object.
Why?
Because the command object has a connection object (don't need a separate one)
Because the command object has a data reader for you (no need for a whole data adaptor to JUST fill a table. And remember, you don't need a whole data adaptor UNLESS you are going to send/update a data table back to the database.
And because the command object has the command text, then you don't even need a variable for that!!!
And because all objects are in "one object", then really all you need is something to handy get you the connection.
So, for your insert example, we really don't gain by having that object, do we?
Ok, so here is your insert code without using those extra objects:
so in the following, I declare ONE variable, - the sql command object.
And do the insert
And as FYI? Your save button is not a save - but a insert button - every time you hit it, you will insert a new row. Lets deal with that issue in a bit.
So, here is our code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using cmdSQL As New OleDbCommand("INSERT INTO Expense
(Expenses_name, expense_details,expenses_amount, ExpenseDate_Paid, ExpensePaid_To)
Values (#expensenme,#expensedetail, #expenseamount, #expensedate, #expensepaidTo)",
New OleDbConnection(My.Settings.TESTOLEDB))
With cmdSQL.Parameters
.Add("#expensenme", OleDbType.WChar).Value = expensenmtXT.Text
.Add("#expensedetail", OleDbType.WChar).Value = ExpenseDetailTXT.Text
.Add("#expenseamount", OleDbType.Currency).Value = ExpenseAmountTXT.Text
.Add("#expensedate", OleDbType.DBDate).Value = DateTimePicker1.Value
.Add("#expensepaidTo", OleDbType.WChar).Value = paidtoTXT.Text
End With
cmdSQL.Connection.Open()
cmdSQL.ExecuteNonQuery()
End Using
So things in above:
We have strong data typing and converstion.
Because of this, note how I did NOT have to create a separate date/time variable here.
Note the SAME for "money" or so called currency conversion - again strong data type by using parameters this way.
And is this a date only, or a date+ time value? If it is date, then
.Add("#expensedate", OleDbType.DBDate).Value = DateTimePicker1.Value
If it was/is a date + time, then this:
.Add("#expensedate", OleDbType.DBTimeStamp).Value = DateTimePicker1.Value
So, notice how all your object stuff REALLY did not help one bit, and in fact you did not really save code, and above actually had LESS variables defined to do the whole job.
Now, back to the insert issue/problem. (you save is doing a insert). But what about editing existing records?
So, I would suggest you work out the problem this way:
You create/get/have/assume a data row for the form.
The form takes the data row, fills the controls. You edit, and when you hit save, the data row is sent back to the datbase. So, once this works, then to add? Well, the add code will CREATE a new data row, save to database and THEN you send that new data row to the above eixsting form that can edit a data row, and can save a data row. So the form now is able to deal with both issues (adding vs editing existing). If the user dont' want the row, then you offer a delete button.
And REALLY nice is a data row means you don't deal with SQL, and don't deal with parmaters!!
So the code (desing pattern) I use is thus this:
dim da as oledbDataAdaptor
dim myTable as DataTable = MyRstEdit("SELECT * from tblHotels WHERE ID = " & lngID,da)
dim MyDataRow as DataRow = myTable.Rows(0)
' code to fill controls
txtHotelName.Text = MyDataRow("HotelName")
txtCity.Text = MyDataRow("City")
' etc. etc. etc.
Now to save? Well I put the values back into that DataRow like this:
MyDataRow("HotelName") = txtHotelName.Text
MyDataRow("City") = txtCity.Text
MyDateRow("BookingDate") = txtTimePick1.Value
da.Update(MyTable)
Notice how I don't have parameters, and even strong data type checking occurs for say the above Date/Time booking date column.
And the above is nice, since I don't have to deal with ANY parmaters to udpate a row of data.
The MyRstEdit routine looks like this and returns byREf a "da" (data adaptor).
Public Function MyrstEdit(strSQL As String, Optional strCon As String = "", Optional ByRef oReader As SqlDataAdapter = Nothing) As DataTable
' Myrstc.Rows(0)
' this also allows one to pass custom connection string - if not passed, then default
' same as MyRst, but allows one to "edit" the reocrdset, and add to reocrdset and then commit the update.
If strCon = "" Then
strCon = GetConstr()
End If
Dim mycon As New SqlConnection(strCon)
oReader = New SqlDataAdapter(strSQL, mycon)
Dim rstData As New DataTable
Dim cmdBuilder = New SqlCommandBuilder(oReader)
Try
oReader.Fill(rstData)
oReader.AcceptChangesDuringUpdate = True
Catch
End Try
Return rstData
End Function
So, now in vb.net, I actually find it is LESS code then even writing + using recordsets in MS-Access VBA code.
However, BEFORE you go down ANY of the above road?
Have you considered using the vb.net data binding features. Data-binding in vb.net means that you do NOT write ANY of the above code. it means that vb.net will do all of the dirty work, and write and setup ALL OF the code for you to edit data on a form. The end result is you don't write any code to update a table.
You do have to use + create a "data set". Once done, then you just drag controls onto the form, and you even get this. So you just drop in a dataset, table adaptor, Binding navagator, and you get this:
Note now the tool bar at the top (and you can place it on teh bottom if you wish). So you get this:
So that WHOLE form was created without having to write ONE line of code. And you can see we have navigation, edits and saves and even the ability to add. So, you can build up a editing form - and it thus becomes similar to say working in MS-Access and ZERO lines of code is required to build the above form.
However, if you ARE going to roll your own code? Then use a data row. That way you can shuffle data to/from the table, and NOT have to use parmaters and SQL update and insert statements - but ONLY have nice clean code in which you shove, or get values from that data row. .net will "write" all the update stuff for you.

How to Unit Test private methods that update a database, without actually updating the database - in a WinForms VB.Net legacy code app?

I've started working on a legacy code (i.e. no unit tests) Windows Forms app written in VB.Net and I've been asked to start introducing unit tests as I make changes. I have not done much unit testing before and I am unsure how to test a recurring pattern I see in the methods. Here is my attempt to outline a simplified typical example:
Private Sub cmdButton_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles cmdAprv.Click
'The event is Private and it then calls multiple other private methods
'but I will simplify drastically for this example:
If <conditions> Then
InsertEmployee()
End If
End Sub
Private Function InsertEmployee() As Integer
'Typically, the functions are quite long with lot of code initializing
'variables, but I will simplify drastically for this example:
Dim _name As String = "[]"
Dim _departmenmt As String = "Engineering"
Dim _salary As Double = 2000
'Then at the end there may be multiple database updates like this one:
Dim connectionString As String = "<Call a Function to get ConnectionString details>"
Using conn As New SqlConnection(connectionString)
Using cmd As New SqlCommand("INSERT INTO Employees (Name, Department, Salary) VALUES (#Name, #Department, #Salary)", conn)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("#Name", _name)
cmd.Parameters.AddWithValue("#City", _departmenmt)
cmd.Parameters.AddWithValue("#City", _salary)
conn.Open()
Dim i As Integer = cmd.ExecuteNonQuery()
conn.Close()
Return i
End Using
End Using
End Function
There is a lot of code in Private methods like this. To make these methods accessible to the testing project, I reckon I can downgrade the Function's accessibility protection from Private to Friend (VB.Net “Friend” = C# “internal” access modifier) and then use InternalsVisibleTo Attribute to mark the unit testing assembly as a friend assembly.
But I’m really not sure what to do with the Database INSERT or UPDATE code to make the function testable? One requirement I have is that the Unit Tests must not actually modify the database.
Can anyone show me a good example of refactoring a method like this for unit testing?
This is of course opinion-based. But here is what I do with legacy un-testable methods.
In your tested project, as you said, introduce InternalsVisibleTo
In your tested project introduce unit test - specific methods that will be only available for DEBUG configuration
#If DEBUG Then
Friend Function InsertEmployee_UT() As Integer
' call your method here
End Function
#End If
This is the principle. In fact, wrap your InternalVisibleTo with #If DEBUG Then
Build and perform your unit tests only in DEBUG configuration, and call the UT-functions that will not exist in RELEASE/Production code
Now Lets talk about breaking from the database. While calling DB can be a different sort of test, like Functional Test, you're right. Preferably, you can run your unit test without DB connection. What to do
Separate db calls into a single provider and pass Interface into the method. Yes, you need slight method change
Friend Function InsertEmployee(provider As IEmployeeData) As Integer
With this, in your unit test you can mock your provider and then examine. You can actually set this provider during construction or a property, then you don't even need to pass it to each method.
You can pass a callback As Function(Of . . ) or callback As Action(Of . . )
This way you also can separate functionality of retrieving data and calling for it.
These changes are not very intensive and can be done relatively quickly. And you will be able to do your testing. Changing private methods is safe, you can do it in any form or shape.

Exception with sqlite database "no such table"

First of all I´m developing a database with autosuggest box. I´ve created a database with DB Browser and imported data. I was reading documentation in C# how connect database and retrieve data. The issue is show up an exception error:
enter image description here
I´ve connected the database in properties with content option. I paste the code:
Public NotInheritable Class METARTAF
Inherits Page
Dim dbpath As String = Path.Combine(ApplicationData.Current.LocalFolder.Path, "airportsdb.sqlite3")
Dim conn As SQLite.Net.SQLiteConnection = New SQLite.Net.SQLiteConnection(New WinRT.SQLitePlatformWinRT(), dbpath)
Dim airportinfo As List(Of String) = Nothing
Public Sub New()
' This call is required by the designer.
InitializeComponent()
End Sub
Private Sub AutoSuggestBox_TextChanged(sender As AutoSuggestBox, args As AutoSuggestBoxTextChangedEventArgs)
Dim datairport As New List(Of String)
Dim retrieve = conn.Table(Of flugzeuginfo)().ToList
If args.Reason = AutoSuggestionBoxTextChangeReason.UserInput Then
If sender.Text.Length > 1 Then
For Each item In retrieve
datairport.Add(item.IATA)
datairport.Add(item.ICAO)
datairport.Add(item.Location)
datairport.Add(item.Airport)
datairport.Add(item.Country)
Next
airportinfo = datairport.Where(Function(x) x.StartsWith(sender.Text)).ToList()
sender.ItemsSource = airportinfo
End If
Else
sender.ItemsSource = "No results..."
End If
End Sub
Private Sub AutoSuggestBox_SuggestionChosen(sender As AutoSuggestBox, args As AutoSuggestBoxSuggestionChosenEventArgs)
Dim selectedItem = args.SelectedItem.ToString()
sender.Text = selectedItem
End Sub
Private Sub AutoSuggestBox_QuerySubmitted(sender As AutoSuggestBox, args As AutoSuggestBoxQuerySubmittedEventArgs)
If args.ChosenSuggestion Is Nothing Then
stationidtxt.Text = args.ChosenSuggestion.ToString
End If
End Sub
Anyone could help about this?
Before you query or insert into a table, you should CREATE it. This tells SQLite what columns you have and suggests datatypes (on other rdbms's you get actual data type enforcement but SQLite does not do that). If this is your problem, you will want to spend some time with the SQLite documentation on data types and the ability to hook them into your application.
On the other hand, as you seem to be trying to retrieve data, this suggess one of two things is wrong. Either you care connecting to the wrong db (in which case SQLite will usually helpfully create an empty db for you!) or else you are specifying the wrong table.

public function to create and open a database connection

I have a client/server desktop application that I am having some database connection issues with on some of my clients pc's. When I wrote the app, I didn't know any better so I created and opened 1 database connection on application startup, and used that same connection all throughout the app. I know realize this is a bad idea since shaky network connections and it seems antivirus programs are causing these connection to be dropped at times, leading to some errors. I have hundreds of places in code where I need to go back and create/open/close the connection at the time they are being used.
The question is, is there any way to create a public function in which I can do just that, and then do a global find and replace to replace the connection name with the new function name?
something like:
Dim qry As NpgsqlCommand
sqlUpdateItem = "update table set field = value where id = 1"
qry = New NpgsqlCommand(sqlUpdateItem, con)
qry.ExecuteNonQuery()
to
Dim qry As NpgsqlCommand
sqlUpdateItem = "update table set field = value where id = 1"
qry = New NpgsqlCommand(sqlUpdateItem, newCon())
qry.ExecuteNonQuery()
public function newCon()
Dim con As New NpgsqlConnection(connectionString)
con.Open()
Return tcon
End Function
I tried this but no luck. I'm just looking for any possible solutions that don't involve me updating several lines of code in hundreds of places throughout my app. The nice thing is I would only need to do this for all commands, since I can pass a brand new connection into a data adapter and it will handle the opening/closing.
Here's an example of how I'd recommend you attempt it.
Enable option strict in your project. It's better to have your errors at compile time than at runtime.
Use a using statement to safely dispose of the database classes even if you get an exception.
Private _connectionString As String = "blah"
Public Function GetDbConnection() As NpgsqlConnection
Dim con As New NpgsqlConnection(_connectionString)
con.Open()
Return con
End Function
Public Sub DoMyQuery()
Using conn = GetDbConnection()
Using qry = New NpgsqlCommand("update table set field = value where id = 1", conn)
qry.ExecuteNonQuery()
End Using
End Using
End Sub

Querying Access database vb.net

I am trying to figure out how to query an access database to take info from the database and put it into a class array. I know how to do some querying using basic LINQ, but not sure how to do it the way I want it to. I have a character class I am using, I am storing all the character traits in a database. I want to query the database and add that info to a class array. Any help would be greatly appreciated.
Here at the class private variables which are the same traits in the database:
Public Class Character
Private _strName As String
Private _intLevel As Integer
Private _intHealth As Integer
Private _intDamage As Integer
Private _intScore As Integer
First of all. I have to say this is not a good question.
Actually what you are saying is...: Please build me the dataconnections for this acces database and a visual studio form.
But because I'm in a good mood, That's what I did for you.
I created a little database file in acces.I saved it into a folder called database. Which is located in the project directory.
I made 2 classes. 1 CharactersForm, and 2 Gateway
the gateway is to make an connection to your Acces database.
The CharactersForm is the form what you see when you debug
Here is the CharactersForm class.
Make sure you drag and drop a listbox and a button
Call the listbox ListBoxCharacters.
Call the button InladenButton. Or call it whatever you want, But make sure it will fit the code given.
Option Explicit On
Option Strict On
Option Infer On
Public Class CharactersForm
Dim _CharactersGateway As New Gateway
Private Sub InladenButton_Click(sender As Object, e As EventArgs) Handles InladenButton.Click
_CharactersGateway.LoadDataTableCharacters()
ListBoxCharacters.DataSource = _CharactersGateway.CharactersDataTable
ListBoxCharacters.DisplayMember = "Name"
End Sub
End Class
The Gateway Class ( to make connection to your acces file)
If somehow visual studio cannot reach the database then it means the connectionstring is not correct. Make sure the connection string is exactly as where your accesfile.accdb is located
Option Explicit On
Option Strict On
Option Infer On
Imports System.IO
Imports System.Data.OleDb
Public Class Gateway
Public Shared AppPath As String = Application.StartupPath()
'\Debug
Public Shared DirectoryUp1 As String = Path.GetDirectoryName(AppPath)
'\bin
Public Shared DirectoryUp2 As String = Path.GetDirectoryName(DirectoryUp1)
'\CharactersStackOverFlow
Public Shared DirectoryUp3 As String = Path.GetDirectoryName(DirectoryUp2)
'\CharactersStackOverFlow
Public Shared AccesDatabaseFilePath As String = DirectoryUp3 & "\DataBase\Characters.accdb"
Dim ConnectionString As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " & AccesDatabaseFilePath)
Public Property DataSetCharacters As New DataSet
Public ReadOnly Property CharactersDataTable As DataTable
Get
CharactersDataTable = DataSetCharacters.Tables("Characters")
End Get
End Property
Public CharactersDataAdapter As OleDbDataAdapter
Public Sub LoadDataTableCharacters()
CharactersDataAdapter = New OleDbDataAdapter("SELECT * FROM Characters", ConnectionString)
CharactersDataAdapter.Fill(DataSetCharacters, "Characters")
Dim kamersCommandBuilder As New OleDbCommandBuilder(CharactersDataAdapter)
End Sub
End Class
This is as Yuriy Galanter said. You need the OleDbConnection.
If you are using office 2010 and you get thsi warning ::
'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine
You need to download the 2007 Office System Driver. It works also for 2010 don't ask me why.
Type '2007 Office System Driver' in google. And from microsoft you can download and install it.
ALL DONE!
if you run the program and press the load button. The names of your characters will come in the listbox.
If you want to put values of the fields of the database in variables. Then it's just about making a for loop and put them in dimmed variables. That is something I'm sure you can do yourself. The connection to the database and the loading in the program is already sorted out now!
Good luck
Jonathan

Resources