This is my function:
Public Function DBConnection(ByVal path As String)
' This function makes the database connection and returns the object
' to reference it.
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + path + ";")
cn.Open()
Return cn
End Function
As you can see, I want to initialize a database connection and return it so I can use it in my forms. This function is in a module and my variables are as follows:
Public cn As OleDbConnection
Public cmd As OleDbCommand
Public dr As OleDbDataReader
But I'm not sure how I can use this in my forms, do I just call the function DBConnection and then proceed with my SQL statements? Or do I have to do something else? Help would be very much appreciated, cheers.
Also, I need some opinions. My application relies on a MS Access database. Is it better to initialize the connection on Form_Load and then close the connection when the user closes the program, or open and close the connections as the queries are run? I'm planning to use some database queries on multiple forms hence the reason I was putting it into a module, but I'm not 100% on how I should proceed with this.
Thanks.
From: How to bind Microsoft Access forms to ADO recordsets
Private Sub Form_Open(Cancel As Integer)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
'Use the ADO connection that Access uses
Set cn = CurrentProject.AccessConnection
'Create an instance of the ADO Recordset class, and
'set its properties
Set rs = New ADODB.Recordset
With rs
Set .ActiveConnection = cn
.Source = "SELECT * FROM Customers"
.LockType = adLockOptimistic
.CursorType = adOpenKeyset
.Open
End With
'Set the form's Recordset property to the ADO recordset
Set Me.Recordset = rs
Set rs = Nothing
Set cn = Nothing
End Sub
A couple things. That function will open a connection every time it's called. You better make sure you are closing the database as well, or that will start eating up memory.
You might look at some other options (such as using NHibernate or another ORM.)
However, if you stay with this model, you could then use the cn that is returned to access your database.
Related
I'm using Access 2013 as a front end with a SQL Server back end, and I'm trying to bind an ADO Recordset to a form, however, the Recordset will only open as Static. So I can see all the records in a datasheet, I just can't edit them.
I can use the connection object to execute an update query, so I don't think that is the issue. I've tried using Dynamic, Keyset and Forward-Only and locking as Batch Optimistic, Optimistic, and Pessimistic to open the Recordset, but still opens as static.
Below code is condensed, but essentially the same, and most importantly, still doesn't work.
Public Sub TestConnect()
Dim objConn As ADODB.Connection
Dim objRS As ADODB.Recordset
Set objConn = New ADODB.Connection
objConn.ConnectionString = "Data Provider=sqloledb;Provider=Microsoft.Access.OLEDB.10.0;Server=REDACTED;Database=REDACTED;Trusted_Connection=Yes"
objConn.CursorLocation = adUseClient
objConn.Open
Debug.Print objConn.state = adStateOpen
Set objRS = New ADODB.Recordset
objRS.CursorLocation = adUseClient
objRS.Open "SELECT * FROM Table1;", objConn, adOpenDynamic, adLockOptimistic
Debug.Print objRS.CursorType
objRS.Close
objConn.Close
End Sub
I've tried looking at a few place, such as https://learn.microsoft.com/en-us/office/vba/access/Concepts/ActiveX-Data-Objects/bind-a-form-to-an-ado-recordset and MS Access Form Bound to ADO Disconnected Recordset, but I'm not having any luck identifying where my issue is.
Any help would be amazing, I'm tearing my hair out here. Thanks!
We have a SQL Server Backend with MS ACCESS 2016 Front. We have a general purpose ADO connection object that we use to send SQL commands off to our DB. When we have SQL that returns something, we were using code to build a passthru query object, which was a handly way to get SQL output into the frontend.
We are now in a situation where we have some really complex SQL that returns an output, but consists of several statements, including the construction of several temp tables on the server. We can't use the "build a passthru query object" method because passthrus can't handle multiple SQL Statements, and we can't send the SQL statements one at a time because the temp tables get destroyed after the query finishes.
At present, we are now using our ADO objects to get the output into an ADO recordset, then saving the recordset down as an .XML and then finally importing the .XML file into the DB. But this is a lot of I/O and it goes slow for large outputs.
Is there any better (faster) way to get the output of our complex SQL into a local table in the MS Access Frontend?
Heres a snippit of our vba class object:
Private Const DB_CONNECTION_STRING As String = "<our connection string>"
Private conn As ADODB.Connection
Private cmd As ADODB.Command
Private recAff As Long
______________________________________________________________
Private Sub Class_Initialize()
Set conn = New ADODB.Connection
Set cmd = New ADODB.Command
conn.Open DB_CONNECTION_STRING
With cmd
.ActiveConnection = conn
.CommandTimeout = 0
End With
End Sub
...
<more properties/methods>
...
Public Sub LocalizeOutput(fetchSQL As String, InputTableName As String)
'If the InputTableName does not exist, a new table will be created. All fields will be datatyped as Text
'Otherwise, if the InputTableName does exist, data will be appended. Caller is responsible for handling errors
Dim rs As ADODB.Recordset
Dim XMLFilePath As String
Dim domIn As Object
Dim domOut As Object
Dim domStylesheet As Object
XMLFilePath = Environ("TEMP") & "\TableImport.xml"
fetchSQL = "SET NOCOUNT ON; " & vbNewLine & fetchSQL
Set domIn = CreateObject("Microsoft.XMLDOM")
domIn.async = False
'Execute the query
With cmd
.CommandType = adCmdText
.CommandText = fetchSQL
Set rs = .Execute(recAff)
End With
Dim tbl As TableDef
'Save off the output as xml file
If FileExists(XMLFilePath) Then
Call FileDelete(XMLFilePath)
End If
rs.Save XMLFilePath, adPersistXML
'Write the XML Transformation File
Call WriteXSLTransform(InputTableName)
'Convert the ado_xml file into an Access readable xml file
domIn.Load XMLFilePath
Set domStylesheet = CreateObject("Microsoft.XMLDOM")
domStylesheet.Load Environ("TEMP") & "\ADOXMLToAccess.xsl"
Set domOut = CreateObject("Microsoft.XMLDOM")
domIn.transformNodeToObject domStylesheet, domOut
'Set domIn = Nothing
Call FileDelete(XMLFilePath)
'Save the output
domOut.Save XMLFilePath
'Import the saved document into Access
Application.ImportXML XMLFilePath, acAppendData
'clean up
Call FileDelete(XMLFilePath)
Call FileDelete(Environ("TEMP") & "\ADOXMLToAccess.xsl")
Set rs = Nothing
Set domIn = Nothing
Set domOut = Nothing
Set domStylesheet = Nothing
End Sub
I am trying to read data from oracle using adodb connection object from excel.But I am getting an error " oracle -160000 database was set to read only access".Please let me know how to resolve this.
Look at the recordset open method's LockType parameter and use adLockReadOnly. I'm not familiar with Oracle. You may also need to CursorType parameter to adOpenForwardOnly.
Example:
Dim lobjADOConnection As ADODB.Connection
Dim lobjADOData As ADODB.Recordset
Dim lstrSQL As String
Set lobjADOConnection = New ADODB.Connection
lobjADOConnection.Open ...
Set lobjADOData = New ADODB.Recordset
lstrSQL = "<your query here>"
lobjADOData.Open lstrSQL, lobjADOConnection, adOpenForwardOnly, adLockReadOnly '<===here
If Not lobjADOData.BOF Then
lobjADOData.MoveFirst
Do While Not lobjADOData.EOF
DoEvents
.
.
.
or if you just want to dump the data into a worksheet
Dim lobjTargetSheet As Worksheet
Set lobjTargetSheet = ThisWorkbook.Sheets("<SomeSheetName>")
With lobjTargetSheet
.Select
.Range("1:" & .UsedRange.Rows.count + 1).Delete xlUp
.Range("A1").Select
.Range("A1").CopyFromRecordset lobjADOData
End With
I'm trying to read a particular column value from a SQL result table. I know we use RowCount in c#. But I don’t know how it is done in vb6.0
For example a c# program code:
adapter.Fill(ds);
adapter.Dispose();
con.Close();
rowCount = ds.Tables[0].Rows.Count;// ds is dataset and I read that record set is used instead of dataset
if (rowCount > 1)
{
ab = ds.Tables[0].Rows[0][3].ToString();
ad = ds.Tables[0].Rows[0][8].ToString();
}
In VB6 you have a choice of ADO, DAO or RDO. ADO is newer of the three technologies, and the one MS recommends.
ADO Example
Sub Example()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
' Ready objects for use.
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Connect.
cn.Open "Driver={SQL Server};Server=My_Server_Name;Database=Master;Trusted_Connection=yes;"
' Fetch a recordset.
rs.Open "SELECT TOP 10 Name FROM sys.Objects", cn, adOpenStatic, adLockReadOnly
' Display value, and total recordcount.
MsgBox rs.Fields(0).Value
MsgBox rs.RecordCount
' Close and release objects.
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
The ADO Recordset object has a RecordCount property. Watch out! Certain cursor types do not populate this property. See the link for more on this.
ConnectionStrings.com is a great resource for finding the right connection string for you.
For this example to work you will need to add a reference to the Microsoft ActiveX Data Objects library.
I'm trying to build a VBA form that runs a SQL Server stored procedure to cache data before it does anything else. Ideally I'd prefer not to use an Excel data connection because then I can't export it to a new workbook with a minimum of fuss - it'd be nice to contain all of the information in the form's file.
The main way I know to connect VBA to a database is using code along these lines:
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
cnn.Open ConnectionString
rst.Open QueryText, cnn, adOpenDynamic
/*Whatever you're doing to the data goes here*/
rst.Close
cnn.Close
The problem I'm running into is that the caching proc doesn't return a dataset (not even a blank one), and this type of connection seems to throw a tizzy if there is no data returned. And I'd prefer not to modify the proc if I don't have to.
Is there a feasible solution, within these constraints? Or am I just being too whiny and should suck it up and use an Excel data connection or something?
I think you are looking for an ADODB.Command. Try something like this:
Dim cnn As New ADODB.Connection
Dim cmd As ADODB.Command
cnn.Open ConnectionString
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = cnn
.CommandText = "EXEC spNameHere param1"
.CommandType = adCmdText
.Execute
End With