VB.NET looping through Access Database - database

In a VB.NET how can I loop through an an Access database without loading it to a DataGridView or loading it to a DataGridView and unload it after a comparison function finshed its work?

Using DataReader you can loop thru data, one row at a time without necessity of loading entire result set into DataTable/GridView.
Example usage (from http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdatareader(v=vs.90).aspx)
Public Sub ReadData(ByVal connectionString As String, _
ByVal queryString As String)
Using connection As New OleDbConnection(connectionString)
Dim command As New OleDbCommand(queryString, connection)
connection.Open()
Dim reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
Console.WriteLine(reader(0).ToString())
End While
reader.Close()
End Using
End Sub
You pass connection string to your MS Access Database, and SELECT query to run. Example outputs data from the 1st column to console - but you can replace it with your own logic

Connect to the Access database.
Fetch the records using your SELECT… query.
Load the result into a List of your Custom class object (e.g: Customer) /Data Table /Data Set.
Write a loop (For / For Each) to iterate through each record and do the comparison with whatever you want to.
Try this yourself. If you encounter any errors, post that as a seperate question with relevant details.

Related

With only the Select and View Definitions permission on a view, can SQL queries be sent from Excel without needing to type the query each time?

I have views that my users often only need to check for one particular person at a time. To do this, they do the following in Excel 365 desktop:
Open a blank workbook
Click on the 'Data' ribbon
Click 'Get Data'
Click 'From Database'
Click 'From SQL Server Database'
Fill in the 'Server' and 'Database' fields
In the advanced options, type SELECT * FROM [VEIWS].[VIEW_NAME] WHERE [EMP.ID] = '123456'
Click OK.
This is tedious for my users. If they want to check another person, they have to repeat the entire process. I'd love for them to just be able to use the query editor and change the only line that matters (see step 7), but they've only got the Select and View Definitions permission, which causes the query editor to complain. I'm afraid that I don't have the specific error message, but it's certainly to do with permissions.
Is there a less-repetitive way to do this from Excel? In an ideal world, I'd just make a sheet that lets them type in the EMP.ID immediately and then fetches the info. I think that it can be done with macros, but they're never my first choice and seem to require that I save passwords in the workbook.
Note that my users can't just fetch the entire view and filter it down in Excel. There are too many rows for Excel to handle.
I have no idea what permissions error you’re hitting, but people commonly use Windows credentials instead of Database credentials and get stuck. Power Query saves credentials on each computer, so you are relying on them signing in correctly. The first time someone connects to a data source, they are prompted for credentials. The default is for a Windows credential, and likely they need to enter a Database credential. If they get this wrong, they have to go into the Data Source settings to edit or clear the credential to fix it.
As far as changing the value in the SQL, you can easily have a parameter in Excel that changes the EMP.ID value in your query. Ken Puls has a nice write up on the process here. Reply back if you’re stuck.
You could use a SSAS Cube with a PivotTable in Excel with a filter on EMP.ID.
I guess it is not possible to change the query in Excel without Power Query Editor and I think it was not intended to do so (regulary).
If it does not need to be Excel you cloud just use SSMS or any similar alternative.
did you try to Un-tick the box that says "Require user approval for new native database queries" ?
you can set the ID as a parameter as suggested above... check my sample file for running an SQL query with a parameter. Sample File
also you can automatically refresh the worksheet with something like :
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("datachange")) Is Nothing Then Exit Sub
Application.EnableEvents = False 'to prevent endless loop
'Application.Goto Reference:="Tum_Santiyelerin_Satinalinan_Malzemeleri"
Range("EMP_ID").ListObject.QueryTable.Refresh BackgroundQuery:=False
ActiveWorkbook.RefreshAll
Application.EnableEvents = True
End Sub
I had a similar requirement in the past. My solution was to use the QueryTables object to send a query to the database using user-supplied data from a cell on the worksheet. It does use a macro, but I didn't have to save the credentials in the workbook.
This solution requires an ODBC driver for SQL Server.
(I seem to recall that I also had to check the references in Visual Basic - in toolbar Tools>References - but it was a while ago and I don't remember the exact details.)
Add the vb code below to a new workbook. Then if you enter the [EMP.ID] value in cell A1 of Sheet1 and run the macro 'ReadData', it will pull out the records and display them starting in cell A3.
Save the workbook as macro-enabled .xlsm and it can be shared with your users. (You could also assign the macro to a keyboard shortcut or command button to speed things up for your users.)
(This approach attempts to connect to the database using a trusted connection, i.e. using windows log-in credentials. I also use another database which requires separate credentials. I have another example below for that scenario.)
The vb code for the macro is below. Check the connection string that it has the correct driver and server IP address etc. and that the query string it reading the correct table.
Sub ReadData()
''' read database using filter supplied in cell A1
Dim ConnectionString As String
Dim QueryString As String
' Create connection string using credentials
ConnectionString = "ODBC; DRIVER={SQL Server}; SERVER=XX.XX.X.XXX; DATABASE=XXXXXXXXX; SCHEMA=dbo; REGION=yes;"
' Create query string to read data using value of cell A1
QueryString = "SELECT * FROM [VEIWS].[VIEW_NAME] WHERE [EMP.ID] = '" & Range("Sheet1!A1").Value & "'"
' The lines below can be un-commented if you get errors - it might help with debugging
'Range("Sheet1!C1").Value = ConnectionString
'Range("Sheet1!C2").Value = QueryString
' This code sends the query to the database and drops the results starting at cell A3
With Sheets("Sheet1").QueryTables.Add(Connection:=ConnectionString, _
Destination:=Range("Sheet1!A3"), Sql:=QueryString)
.RefreshStyle = xlOverwriteCells ' this stops excel from inserting new columns when the query is re-run
.Refresh False
End With
' Remove connections to avoid wasting memory
For Each con In Sheets("Sheet1").QueryTables
con.Delete
Next
End Sub
When the database requires different credentials
For this I created a user form to get the username and password, which I then incorporated into the connection string.
The steps I followed were:
In a new workbook, go to Visual Basic and create a new user form. Re-name it LoginForm
Create 2 text boxes on the form, named Username and Password. (You can also add labels and set the PasswordChar to '*' to make it look more like a login window.)
Create a command button ('OK' or 'Done'). Right click on it and select View Code. Enter the line Me.Hide in the code window so it looks like:
Private Sub CommandButton1_Click()
Me.Hide
End Sub
The vb code for the macro changes to :
Sub ReadData()
''' read database using filter supplied in cell A1
Dim ConnectionString As String
Dim QueryString As String
' First time you run, need to show form to get credentials
If LoginForm.Username = "" Or LoginForm.Password = "" Then LoginForm.Show
' Create connection string using credentials
ConnectionString = "ODBC; DRIVER={SQL Server}; SERVER=XX.XX.X.XXX; DATABASE=XXXXXXXXX; SCHEMA=dbo; REGION=yes; uid=" _
& LoginForm.Username & "; pwd=" & LoginForm.Password
' Create query string to read data
QueryString = "SELECT * FROM [VEIWS].[VIEW_NAME] WHERE [EMP.ID] = '" & Range("Sheet1!A1").Value & "'"
' The lines below can be un-commented if you get errors - it might help with debugging
'Range("Sheet1!C1").Value = ConnectionString
'Range("Sheet1!C2").Value = QueryString
' This code sends the query to the database and drops the results starting at cell A3
With Sheets("Sheet1").QueryTables.Add(Connection:=ConnectionString, _
Destination:=Range("Sheet1!A3"), Sql:=QueryString)
.RefreshStyle = xlOverwriteCells ' this stops excel from inserting new columns when the query is re-run
.Refresh False
End With
' Remove connections to avoid wasting memory
For Each con In Sheets("Sheet1").QueryTables
con.Delete
Next
End Sub
Now, the first time the user runs the code, it will prompt them for username and password, but for the rest of their session it will keep using these values. They will not be saved when the workbook is closed. (If the macro hits an error they will probably be asked for credentials again next time it is run).
Hopefully this helps you. I did this work some time ago and I may have forgotten if there were any other set-up requirements needed.

[VB.NET][ACCESS] How do I check for if a database exists?

I cant find anything online to help.
I want to create a table if it doesnt already exist, or populate a listbox with what is stored in said table if it DOES exist. All I have so far is the populate and create table subroutines, but have no idea how to check the database so far.
Thank you
Checking if an MSAccess DATABASE exists or not is pretty simple because it is just a single file. So using File.Exists is enough
Suppose that your MDB file is
Dim accessFilePath = "D:\temp\myDatabase.mdb"
If File.Exists(accessFilePath) Then
... file exists
End if
Of course getting the content of the file (in terms of TABLES and QUERY) is a different thing and requires to open the connection and get the SCHEMA informations
Dim cnnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & accessFilePath
Using con = new OleDbConnection(cnnString)
con.Open()
Dim schema = con.GetSchema("Tables")
For Each row As DataRow in schema.Rows
Console.WriteLine(row.Field(Of String)("TABLE_NAME"))
Next
End Using
See how GetSchema works and what are its possible parameters and results

Populating a DataGrid using a Parameterised SQL Server Stored Procedure

I'm a newb to Visual Studio and VB and need a little help.
I've created a project in Visual Studio 2012 Express with:
a Data Connection to a SQL Server DB
within that a Data Set
a Data Source/TableAdaptor which is linked to
a Stored Procedure.
It seems difficult to see what Data Connections, Data Sets, Data Sources and Table Adaptors have been created and I'm slightly confused why 1 and 2 aren't the same thing.
The Stored Procedure accepts parameters and provides results based on those parameters.
In preview - it all works fine.
Now, I'm trying to populate a Data Grid with the data from the Data Source using supplied parameters when a button is pressed. This is where I'm falling down. I've instantiated the TableAdaptor
Private Sub btnReport_Click_1(sender As Object, e As RoutedEventArgs) Handles btnReport.Click
Dim tableAdapter As New JBDataSet.p_Utility_UnLocked_TasksDataTable()
Me.MyDataGrid.DataSource = tableAdapter.GetData("Report", "1234")
End Sub
I think the first line (Dim) correctly instantiates the tableAdapter but I know the second line is incorrect. I've looked all over and cannot find out what I need to do.
What's the compile-time type of tableAdapter? Just hover over it in VS and check.
My guess is that it's a DataTable:
Dim tableAdapter As New JBDataSet.p_Utility_UnLocked_TasksDataTable()
Because the object you are referencing is called Tasks DataTable.
You usually use DataAdapter like this:
Dim queryString As String = _
"SELECT CustomerID, CompanyName FROM dbo.Customers"
Dim adapter As SqlDataAdapter = New SqlDataAdapter(queryString, connection)
Dim customers As DataSet = New DataSet
adapter.Fill(customers, "Customers")

VB.NET - Any way to get a nice clean list of all of the column names from a mdb? (Access Database)

I have a table in a Access Database that I'm loading into a VB.NET program, and I want a way to get the name of each of the columns into a list of Strings. Googling has shown that this is much easier with a SQL database, but that doing so in Access is much more difficult.
I came across this question Is there a query that will return all of the column names in a Microsoft Access table? Which gives a way to do it, but when I try the code it just populates my list with a bunch of "System.Collections.Generic.List'1[System.String]"
This is my adapted code. Any suggestions for a fix or a better way to do it?
Public Function GetColumns(ByRef database As String, ByRef table_name As String, ByRef columns As List(Of String)) As Integer
Dim com As OleDbConnection
Try
com = New OleDbConnection(database)
com.Open()
Catch ex As Exception
Return 1
End Try
Dim restrictions As String() = New String() {Nothing, Nothing, table_name, Nothing}
Dim dt As DataTable = com.GetSchema("Columns", restrictions)
com.Close()
For Each DR As DataRow In dt.Rows
columns.Add(DR("Column_Name").ToString)
Next
For Each holding As String In columns
Console.WriteLine(columns)
Next
End Function
Edit: Hah, I hate when I make stupid mistakes elsewhere in the function and it makes me think the meat of the function isn't working write. My for each loop isn't printing the right string. Should be Console.WriteLine(holding)
Console.WriteLine(columns)
change to:
Console.WriteLine(holding)
Then possibly kick yourself in the head for not spotting it =D ;-)
Try changing
For Each holding As String In columns
Console.WriteLine(columns)
Next
to
For Each holding As String In columns
Console.WriteLine(holding)
Next

How do I get a string from an Access database?

I've been handed an Access database with 3 columns: Name, category, e-mail. What I'm trying to do is get out, as strings, all of the e-mails that match a given category.
I have a slight understanding SQL as I'm in the process of learning it. I've managed to churn out this bit of code, which populates a visual grid with the first names
Dim comm As New OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source=.\AddressBook.mdb")
Dim addda As New OleDbDataAdapter("SELECT FirstName FROM Contacts", comm)
Dim dd As New DataTable("Name")
addda.Fill(dd)
DataGridView2.DataSource = dd
So I feel I'm getting fairly close, but I can't figure out how to get that list of first names to go into a string (or array of strings). All of the online tutorials and books I find seem to go over just displaying the data in a dataview.
Point in the right direction?
try this:
Dim Names As New List(Of String)
Using comm As New OleDbConnection("Provider...")
comm.Open()
Using cmd As New OleDbCommand("SELECT FirstName FROM Contacts", comm)
Using reader As OleDbDataReader = cmd.ExecuteReader
While reader.Read
Names.Add(reader("FirstName").ToString)
End While
End Using
End Using
End Using
The Using format will automatically dispose of your data objects.
I'm sure LarsTech's response will work, but going back to your original example, you can always loop through your DataTable (dd), looking at the DataRow collection.
Dim Names As New List(Of String)
For Each R As DataRow In dd.Rows.Count
Names.Add(R.Item("FirstName").ToString)
Next
Then you can just check the count of Names and if it's greater than 0, iterate over that collection.

Resources