My department uses an application created using VBA and Access 2016. It originally pointed to an Access database on one of our servers. After migrating the data to a different server, I now need it pointing to the other SQL Server database on that different server. But I can't seem to make the connection.
I have dbowner permissions on the server in question.
The original code for connection string was as follows:
'Remove the filter, close the log on form, and open the Switchboard
rst.Filter = 0
DoCmd.Close acForm, "frmUserLogOn"
'Open the Main Switchboard
DoCmd.OpenForm "frmMain", acNormal
'Open the InactiveShutDown form in Hidden mode
DoCmd.OpenForm "frmInactiveShutDown", acNormal, , , , acHidden
...
Set conn = CurrentProject.Connection
...
rstLog.Open "tblUserLog", conn, adOpenKeyset, adLockOptimistic
rstLog.AddNew
rstLog!UserID = rst!UserID
rstLog!TimeIn = Now()
rstLog.Update
My new code is as follows:
'DoCmd.OpenForm "frmInactiveShutDown", acNormal, , , , acHidden
'Commented out the above statement
...
'Set conn = CurrentProject.Connection
'==================================================================
'Start of Added Code for SQL Migration
Set conn = New ADODB.Connection
With conn
.ConnectionString = "Provider=SQLNCLI11;Data Source=(My Server Name);Initial Catalog=(My Database Name);User ID=(Username);Password=(Password)"
.Open
If .State = adStateClosed Then
MsgBox "Connection unsuccessful. Could not open connection.", vbInformation, "Error:"
End If
End With
Set rst = New ADODB.Recordset
With rst
.ActiveConnection = conn
.CursorLocation = adUseClient
.CursorType = adOpenStatic
.LockType = adLockOptimistic
.Open "tbl_Users"
End With
'End of Added Code for SQL Migration - See Section 2 for rest of code.
'==================================================================
...
'Section 2 of Code
'==================================================================
'Start of added code for SQL Migration
rstLog.Open "tblUserLog", conn, adOpenStatic, adLockOptimistic
rstLog.AddNew
rstLog!UserID = rst!UserID
rstLog!TimeIn = DateTime.Now()
rstLog.Update
MsgBox "Success! Connection was made successfully.", vbInformation
'End of added code for SQL Migration
'===================================================================
My form has a drop down to select list of users form a table. I added a test user in that table but that test user doesn't show up in the drop down list. Hence, I think the connection is not being made.
Do I have to enter the names for Data Source, Initial Catalog, User ID and Password in quotes? So UserID='Admin'; Password='Test'?
Anyone know what I'm doing wrong?
Basically, you have a version confusion of same named table between local Access frontend database and backend SQL Server database. Currently, your code updates the tblUserLog on the SQL Server backend side and is not the same tblUserLog on the Access frontend side which likely is the one bound to your form. Hence, why you cannot see any update as the server table is never shown.
Simply do one of two things:
Use SQL Server Version: Delete or archive the Access' version and add tblUserLog as an ODBC linked table. Be sure to remove the dbo_ or other schema prefix and keep same name tblUserLog. And since table names do not change, everything such as forms and VBA code should not need to change.
Use Access Version: Keep the local Access table, tblUserLog, and update this one in VBA which requires adding another connection object and running a recordset update on that connection. See below with prefixes of server_ and local_ on ADO objects:
' OPEN SERVER CONNECTION AND SERVER TABLE RECORDSET
Set server_conn = New ADODB.Connection
With server_conn
.ConnectionString = "Provider=SQLNCLI11;Data Source=(My Server Name);Initial Catalog=(My Database Name);User ID=(Username);Password=(Password)"
.Open
If .State = adStateClosed Then
MsgBox "Connection unsuccessful. Could not open connection.", vbInformation, "Error:"
End If
End With
Set server_rst = New ADODB.Recordset
With server_rst
.ActiveConnection = conn
.CursorLocation = adUseClient
.CursorType = adOpenStatic
.LockType = adLockOptimistic
.Open "tbl_Users"
End With
' OPEN LOCAL CONNECTION AND UPDATE LOCAL TABLE RECORDSET
Set local_conn = CurrentProject.Connection
Set local_rstLog = New ADODB.Recordset
local_rstLog.Open "tblUserLog", local_conn, adOpenStatic, adLockOptimistic
local_rstLog.AddNew
local_rstLog!UserID = server_rst!UserID ' NOTICE SERVER DATA USED HERE
local_rstLog!TimeIn = DateTime.Now()
local_rstLog.Update
...
' RELEASE RESOURCES
Set server_rst = Nothing: Set local_rstLog = Nothing
Set server_conn = Nothing: Set local_conn = Nothing
Related
I realized today that when you connect to SQL Server data source in Excel's native connection, it doesn't allow you to enter in a specific username and password. It just asks for server name and database.
In VBA , under the assumption that I wanted to import data from a SQL Server data query into Sheet1, can you please help me understand how to write that code?
For purposes of this exercise:
SQL Server Connection INFO
Server Name: TestingS,1633
Database Name: CarSales
username: car
password: sales
The query I want to run for simplicity sake can be: "select * from table"
I have been doing some research , but am getting a bit lost. I have no problem setting up standard queries with custom SQL via ODBC, but because I need VBA, it's very tricky for me. Please help.
This is an example of MSSQL.
Sub testMSSQL()
'Reference Microsoft ActiveX data object Library 2.8 ~~
Dim cnn As ADODB.Connection
Dim strSQL As String
Dim Ws As Worksheet
Set Ws = ActiveSheet
strSQL = "select * from table"
Set cnn = New ADODB.Connection
'Set the provider property to the OLE DB Provider for ODBC.
'cnn.Provider = "MSDASQL"
'cnn.Provider = "Microsoft.ACE.OLEDB.12.0"
'cnn.Provider = "MSOLAP"
cnn.Provider = "SQLOLEDB.1" '<~~ mssql
' Open a connection using an ODBC DSN.
cnn.ConnectionString = "driver={SQL Server};" & _
"server=TestingS;uid=car;pwd=sales;database=CarSales"
Set rs = New ADODB.Recordset
rs.Open strSQL, cnn.ConnectionString, adOpenForwardOnly, adLockReadOnly, adCmdText
cnn.Open
If cnn.State = adStateOpen Then
Else
MsgBox "Not connected server"
Exit Sub
End If
If Not rs.EOF Then
With Ws
.Range("a1").CurrentRegion.ClearContents
For i = 0 To rs.Fields.Count - 1
.Cells(1, i + 1).Value = rs.Fields(i).Name
Next
.Range("a2").CopyFromRecordset rs
.Columns.AutoFit
End With
Else
MsgBox "No Data!!", vbCritical
End If
rs.Close
Set rs = Nothing
cnn.Close
Set cnn = Nothing
End Sub
I've created a table in a SQL Server 2017 database. Then I've created a form in MS Access 2019 that use an ADO Object as "record source". On the form, there is a Textbox with the controlsource property=Field. Then, when I open the form, everything works as expected (the content of Field shows up in the Textbox, I can move the cursor backwards and forwards and so on) except for one thing: It's not possible to change, add or delete records.
Create a table On SQL Server (use SSMS):
CREATE TABLE Table1 (Field INT PRIMARY KEY)
INSERT INTO Table1 (Field) VALUES (15)
INSERT INTO Table1 (Field) VALUES (12)
In Access Module:
#Const EarlyBinding = -1
#If EarlyBinding Then
' Irrelevant in this context
#Else
Global Const adUseClient As Long = 3
Global Const adLockBatchOptimistic As Long = 4
Global Const adOpenDynamic As Long = 2
#End If
In Access Form's VBA Code:
Private Sub Form_Load()
Dim sqldb as Object, adocom as Object, rs As Object
Set sqldb = CreateObject("ADODB.Connection")
Set adocom = CreateObject("ADODB.Command")
Set rs = CreateObject("ADODB.Recordset")
SQLDB.Open "Driver={SQL Server Native Client 11.0};Server=SQL;Database=Test;Trusted_Connection=yes;"
SQLDB.CursorLocation = adUseClient
rs.LockType = adLockBatchOptimistic
rs.CursorType = adOpenDynamic
adocom.CommandText = "SELECT Field FROM Table1"
set rs = adcom.execute
set Me.Recordset=rs
end sub
This problem is "boiled down" from a much more complex code. The query I pass to SQL Server takes several minutes to execute if I use DAO so the big point is to let SQL Server execute the query (takes < 1 sek).
So what do I have to do to make it possible to add, modify or delete a record?
DML commands like
adocom.execute ”UPDATE Table1 SET Field=25 WHERE Field=15”
works.
But well, the thing is, I want the Access Form to act in exactly the same way with an ADO recordset connected to a SQL Server as it would act if the recordset was handled by a DAO object connected to a backend .accdb-file. So it’s the recordset that should be updatable. The property rs.recordcount is -1 which indicates that the recordset is not updatable. If that property is something else but -1 after the adocom.execute line , then we’re home.
Seems like the .Execute method returns read-only, forward-only cursor recordset.
You have to use theRecordset.Openmethod to get a not read-only Recordset.
This works for me:
Private Sub Form_Load()
Dim sqldb As Object, adocom As Object, rs As Object
Set sqldb = CreateObject("ADODB.Connection")
Set adocom = CreateObject("ADODB.Command")
Set rs = CreateObject("ADODB.Recordset")
sqldb.Open "Driver={SQL Server Native Client 11.0};Server=SQL;Database=Test;Trusted_Connection=yes;"
sqldb.CursorLocation = adUseClient
rs.LockType = adLockBatchOptimistic
rs.CursorType = adOpenDynamic
rs.Open "SELECT Field FROM Table1", sqldb 'changed code
Set Me.Recordset = rs
End Sub
As I told you in my comment above, you should always check the settings of the recordset in locals windows, as they may differ from what you have set!
In your code, the recordsets.LockTypegetsadLockReadOnly, what explains read-only form.
Btw, your code looks like using late-boundADODB, but usesADODB-ConstantslikeadUseClient. They need to be defined seperate if you use late-boundADODB
I have numerous excel files which connect to our Oracle database.
However, the connection details are stored in plain text in the connection details.
These Excels are accessed by numerous different people.
I need to 'pass' the password and username from an external file into the connection in order to protect the database credentials.
The connections are only used by automated jobs on my machine. Therefore, other users don't need to use the connections.
My automated jobs use VBS scripts so a workaround in there would be best.
The portion of VBS which deals with this is
Dim xlApp, xlBook
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open("where workbook is located", False)
xlApp.Run "SampleMacroName()"
xlbook.Save
xlBook.Close False
set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
DisplayAlerts=false
Is there anyway to reference the password and username here?
Ideally we are looking for the simplest solution, so if we could hardcode them in this code that would be acceptable.
I had to delete my connections in the database and use VBA code to replicate my connections in a series of SQL queries. The basis of the code that I am using is:
'Declare variables'
Set objMyConn = New ADODB.Connection
Set objMyRecordset = New ADODB.Recordset
Dim strSQL As String
'Open Connection'
objMyConn.ConnectionString = "Driver={Microsoft ODBC for Oracle}; " & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=***)" & _
"(HOST=*****)(PORT=****))" & _
"(CONNECT_DATA=(SERVICE_NAME = ****))); uid=****; pwd=*****;"
objMyConn.Open
'Set and Excecute SQL Command'
strSQL = "Select distinct * From Temp_Final_Complaints_Report"
'Open Recordset'
Set objMyRecordset.ActiveConnection = objMyConn
objMyRecordset.Open strSQL
'Copy Data to Excel'
Sheets("Complaints Report").Range("A2").CopyFromRecordset (objMyRecordset)
I can now encrypt the module where this is saved with a password.
I've got a simple MS Access 2013 form with some text boxes, each of whose Control Source is set to fields in an ADODB recordset. The recordset may come from either a table in the current accdb project or as the result of a SQL Server stored procedure; this is set by selecting a radio button on the form.
I've confirmed that each of the two recordsets are updateable in vba code but when I use the form it will only allow me to edit fields returned from the SQL Server option; the Access option displays records but acts as if the text box is locked when I attempt to edit it.
This is the code I'm using:
Private Sub cmdLoadData_Click()
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
With rst
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
End With
Select Case BackendOptions
Case 1
' Access
With rst
.ActiveConnection = CurrentProject.AccessConnection
.Open "SELECT Id, FirstName, LastName, Birthday FROM tblADOTest"
End With
Case 2
' SQL Server
Dim cn As New ADODB.Connection
With cn
.ConnectionString = "Driver={SQL Server Native Client 11.0};" & _
"Server=<the server name>;" & _
"Database=<the database name>;" & _
"Trusted_Connection=yes;"
.Open
End With
With rst
.ActiveConnection = cn
.Open "EXEC dbo.GetTestData"
End With
End Select
Set Me.Recordset = rst
End Sub
The stored procedure runs the same SQL as the inline string I'm using for Access.
Any ides on how to make the Access option editable?
helped me solve a similar problem using this:
.ActiveConnection = CurrentProject.Connection
I'm attempting to take Excel 2003 and connect it to SQL Server 2000 to run a few dynamicly generated SQL Queries which ultimately filling certain cells.
I'm attempting to do this via VBA via ADO (I've tried 2.8 to 2.0) but I'm getting an error while setting the ActiveConnection variable which is inside the ADODB.Connection object. I need to resolve this pretty quick...
Requested operation requires an OLE DB Session object, which is not supported by the current provider.
I'm honestly not sure what this error means and right now I don't care. How can get this connection to succeed so that I can run my queries?
Here is my VB code:
Dim SQL As String, RetValue As String
SQL = " select top 1 DateTimeValue from SrcTable where x='value' " 'Not the real SQL
RetValue = ""
Dim RS As ADODB.Recordset
Dim Con As New ADODB.Connection
Dim Cmd As New ADODB.Command
Con.ConnectionString = "Provider=sqloledb;DRIVER=SQL Server;Data Source=Server\Instance;Initial Catalog=MyDB_DC;User Id=<UserName>;Password=<Password>;"
Con.CommandTimeout = (60 * 30)
Set Cmd.ActiveConnection = Con ''Error occurs here.
' I'm not sure if the rest is right. I've just coded it. Can't get past the line above.
Cmd.CommandText = SQL
Cmd.CommandType = adCmdText
Con.Open
Set RS = Cmd.Execute()
If Not RS.EOF Then
RetValue = RS(0).Value
Debug.Print "RetValue is: " & RetValue
End If
Con.Close
I imagine something is wrong with the connection string but I've tried over a dozen variations. Now I'm just shooting in the dark....
Note/Update: To make matters more confusing, if I Google for the error quote above, I get a lot of hits back but nothing seems relevant or I'm not sure what information is relevant....
I've got the VBA code in "Sheet1" under "Microsoft Excel Objects." I've done this before but usually put things in a module. Could this make a difference?
You have not opened your connection yet. I think you need a Con.Open before you assign it to the Command object.
Con.ConnectionString = "Provider=sqloledb;DRIVER=SQL Server;Data Source=Server\Instance;Initial Catalog=MyDB_DC;User Id=<UserName>;Password=<Password>;"
Con.CommandTimeout = (60 * 30)
Con.Open
Set Cmd.ActiveConnection = Con 'Error occurs here.
Cmd.CommandText = SQL
Cmd.CommandType = adCmdText