Error when opening ADODB recordset using odbc dsn in MS Access - sql-server

I have a MS Access application that has been in use for at least 10 years. Recently I moved my work to a new development machine with Office 365 and SQL Server Express 2019 installed. The machine OS is Windows 10 Pro. In my old machine my application would run just fine. There is a query using a stored procedure that retrieves a piece of data from a table in the SQL Server backend. I call this procedure using a ADODB recordset based on the stored procedure output. All my calls use a connection string based on an ODBC DNS. This connection string works fine on the new machine when relinking tables to the SQL Server backend, but when I use it in the ADODB connection I get an error "[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified". On the old Windows 7 development machine this ran fine. It also runs on the client's machines which are Windows 10 and Office 365. The code that raises the error follows. The error occurs at the open connection line. The connection string is: ODBC;DSN=VROM;Trusted_Connection=Yes;APP=2019 Microsoft Office system;DATABASE=VROM1.
Set con = New ADODB.Connection
con.ConnectionString = DLookup("Link", "tblLinkData", "Use = True")
con.Open
Set rs = New ADODB.Recordset
My question "Is there a setting in SQL Server that could be causing this error?". As far as I can tell both systems are set up the same, but there is obviously something different between the two. Is there another reason this could be working on one system and not another?

Hum, where to start?
Ok, first up, if you using the ODBC panel to create a ODBC connection, then you NEVER were actually using a ADO connection in that DSN config = ODBC!!!!
That means you been feeing ADO a ODBC connection string. you can do this, but at least lets be aware of what is going on.
Next up:
Are you running the SQL browser service? You MUST do that now!. Don't know if you installed a later version of SQL SERVER, but a few versions ago you will find now that you MUST run the browser service.
This one:
The reason of course is that you can (may) have multiple instances of sql server running, and the default instance (SQLEXPRESS) now MUST BE specified. As noted older instances did NOT have this requirement. And to "resolve" the multiple instances, you now must run the SQL browser service. As noted, this was NOT a requirement in the past - it is now. That browser service is what connects the IP/server name to the instance, and you now in most cases have to run this.
There are exceptions, but you don't want much pain.
Next up:
For a VERY long time, it is recommended for Access linked tables you use a DSN-less connection. that way then at deployment time to all workstations, you don't need to setup a DSN on each workstation.
And if you link Access tables using a FILE dsn (not system or user), then upon the table link process, access BY DEFAULT converts all table links to DSN-less. That means once you linked, then you could even delete the DSN - you do NOT need it anymore.
Again: this ONLY holds true if and when you create a FILE dsn, and use that to link the tables. So, that takes care of the DSN-less linked tables.
Note that if you were to modify the DSN, you would have to link, since I just told you by default access creates + uses dsn-less links (assuming you used a FILE dsn to link).
now, you CAN of course use that SAME dsn for ADO, but that means you are feeding ADO a ODBC driver connection!!!
If you want to create a real ADO connection, then you would/could/should say use this:
Dim strCon As String
strCon = "Provider=SQLOLEDB;;Initial Catalog=TEST4; " & _
"Data Source =.\SQLEXPRESS;Trusted_Connection=yes"
Dim conn As New ADODB.Connection
conn.ConnectionString = strCon
conn.Open
Dim rst As New ADODB.Recordset
rst.Open "SELECT * from tblHotels", conn
Do While rst.EOF = False
Debug.Print rst!HotelName
rst.MoveNext
Loop
Now now how I used a "." for localhost. That could be replaced with (local), or in fact the computer (server) name say like this:
strCon = "Provider=SQLOLEDB;;Initial Catalog=TEST4; " & _
"Data Source =ALBERTKALLAL-PC\SQLEXPRESS;Trusted_Connection=yes"
Next up, make sure you enabled the TC/IP connections.
here:
However, since your case all along you actually been using ODBC driver with ADO, then I would not rock the boat.
But, check your settings as per above.
Since linked tables, and quite much everything else is DAO + odbc?
then I would probably not introduce ADO into that application for JUST calling + using sql server store procedures.
I as a general rule would say use this;
with currentdb.tabledefs("qryPT")
.sql = "exec MyProcName"
.execute
end with
Or, if it is to return data, then I would use this:
dim rst as DAO.RecordSet
with currentdb.tabledefs("qryPT")
.sql = "exec MyProcName"
set rst = .OpenRecordSet()
end with
So, I am hard pressed to find a reason to use ADO. Now of course since you been using ADO, then I guess I would continue to do so.
but, check the browser settings. And if the tables were linked using a FILE dsn, then they are dsn-less.
You could try feeding the ADO connection a existing connection from a existing linked table.
eg:
strCon = CurrentDb.TableDefs("dbo_tblHotels").Connect
strCon = Mid(strCon, 6)
Dim conn As New ADODB.Connection
conn.ConnectionString = strCon
conn.Open
Skipping the first 6 chars skips this part:
ODBC;DRIVER=SQL Server;SERVER=ALBERTKALLAL-PC\SQLEXPRESS;
UID=AlbertKallal;Trusted_Connection=Yes;APP=Microsoft Office 2010;
DATABASE=Test4;Network=DBMSLPCNM
So once again we are feeding ADO ODBC connection string.
(of course above connection string is one line).

Related

VBA Connecting to SQL Server 2017 - Error(Unable to complete login process due to delay in opening server connection)

WE use a spreadsheet to collect and distribute various data into sheets for company use.
Use were using MS Excel 2013 and an early version of MS SQL Server
Which worked perfectly without any errors, here is the code from our VBA file:
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
Set cmd = New ADODB.Command
Set rs = New ADODB.Recordset
MyConStr = "Provider=SQLOLEDB;Data Source=sqlserver\SQL;Initial Catalog=MYDB;user id=sa;password=Mon87653day9856"
con.Open MyConStr
Now we have upgraded to SQL Server 2017, and we get the error.
Unable to complete login process due to delay in opening server connection
I have tried looking at pipes and changing the order, still get the error.
I have downloaded the new MSOLEDBSQL driver and still get the error.
I have tried the trusted connection and time out settings and still get the error.
Any one got any ideas?
Edited
I am not sure if this was a mistake in your posting or in your original code, but you are missing the terminating quotation marks at the end of your connection string (I would put this in the comments but don't have a high enough reputation).
Also, in the past, I would have to specify the IP address of the server in order to establish the connection to the server. May be worth a try.

Connecting a Multi User Access Front End to SQL Server Back End

Thank you for your help as always!
I have built an Access database that we intend to distribute to ~100 end users. I am currently running a pilot program for 5 users. I have migrated the tables to SQL 2014 Server but currently the back end of the pilot program is in a shared network folder (location unknown to them). I distributed the Access front end (accde file type) by saving the file on that shared Network and instructing the end users to save a copy to their desktop. The pilot is working fine, if not a little slow.
The issue that I am having is this:
I am able to set up an ODBC Connection on my machine and am able to connect to the SQL Server backend through that connection. However, I am not sure how to get my end users Access to the tables on the server. Do I need to create a user name for each user on the server and give them read and write access? Do I also need to create an ODBC connection on each machine that we plan to install the Front End on? I would prefer to not have to create an ODBC connection on each machine, is it possible to work around this? Thank you!
Access Version: 2013
SQL: 2014
Working on SSMS 2014
-Charlie
A few things:
When you create a linked table, simply use the ribbon import and link – and then ODBC database. Just choose a file DSN. The reason for this is that access by DEFAULT will use a DSN-less connection. In simple terms, this means when you link the tables, then you can distribute your applcatation to each workstation and there no need to setup a SYSTEM/Machine DSN.
So just keep in mind that use the default file DSN – once Access creates the link to SQL server, then such links are DSN-less, and you don’t need any setup on each workstation.
As for creating users on SQL server? Well, you likely don’t need to unless you want some kind of special security for each user. If you using SQL logon, then MAKE sure that during the above linking process you “check” the save password option. Once again, since by default the linked tables are DSN-less, then every user will in fact be using the one and same SQL User/password and thus this will be transparent to each user (they will not have to log on).
If you using windows authentication for SQL logons, then security is setup with the windows system and not SQL server. In this case then each users windows logon will be used to control (permit) use of the SQL server. If you not using a domain controller, then you be using SQL logons, and likely just the one logon that you are using will suffice. Often even in a corporate environment because I don’t want to call up the IT admin folks for each logon and permissions to SQL server, then I still OFTEN choose SQL logons. Thus “once” the IT admin folks give me enough rights to the SQL server, then I am free to create my own logons, or just use the “one same” logon for everyone and thus don’t have to waste time bothering the IT folks.
A few additional final points:
Ignore suggesting to use all kinds of ADO and VBA code and connection strings etc. – they are not required. In fact in most cases you want to AVOID ADO code in your application. And oleDB is being depreciated for SQL server (which ADO tends to rely on).
You STILL as a matter of good deployment want to place the front end program you have on each workstation. Just like you install word on each workstation, or your accounting packages, now that YOU ARE developing software, then you install your software on each workstation like the IT industry done for the last 30 years. You can certainly share data on a shared folder, but you install the actual application (word, Excel, or in this case YOUR applcatation on EACH workstation. And you should compile the accDB to an accDE before any deployment.
So you don’t really need any special code on start up to “connect” or “link” to SQL server if your deployment to such users is on your same network. If you are developer or consultant “offsite”, then you likely need to add some code on start up to re-link to THEIR sql server that no doubt would be different than the one your developing with offsite. So some ability to re-link to a “different” SQL server then the one your are developing with would be required if you not able to develop on site, or that the SQL server you working with is a “copy” or “test” version of the Actual production SQL server being used.
You do not need an ODBC connection on every machine. You can create the connection by using ODBC connection strings via DoCmd.TransferDatabase. This is persistent, so you can just execute the connection/updates on your development copy of the front end and the connection will exist and persist in any end user copies of that that you make.
You do have to deal with the authentication issue. Depending on your security situation you can create a single "database user" and include the username and password to the above connection. If you are in a AD environment you can use that for authentication. Or you create individual SQL accounts for each user or user group. No matter what you do the users will be able to see and edit the tables if Access is to have read/write permission to them. You can secure individual tables by using views to link them to Access instead of the tables themselves.
I would advise against having users make a local copy of the front end. That makes it a nightmare to make sure your users are using the latest version of your front end. Encourage them to make a shortcut instead. Unless you have per-user local temp tables or code that dynamically edits forms/reports there is not much reason not to have everybody using the same front end file. Even in that case create a deployment batch file that creates/overwrites the front end copy for each user.
Sample code that links to SQL server database:
Public Sub LoadDatabase()
Dim MyDB As DAO.Database
Set MyDB = CurrentDb
Dim d As DAO.Recordset
Set d = MyDB.OpenRecordset("SELECT TableName FROM tblLinkTables")
d.MoveFirst
Do While Not d.EOF
DoCmd.DeleteObject acTable, d!TableName
DoCmd.TransferDatabase acLink, "ODBC Database", "ODBC;Driver={SQL Server};Server=MYSQLSERVERNAME;Database=MyDatabaseName;Uid=DatabaseUser;Pwd=DatabaseUserPassword", acTable, d!TableName, d!TableName, False, True
d.MoveNext
Loop
d.Close
Set d = Nothing
End Sub
where the list of tables to link exists on a local table called tblLinkTables with a single field TableName for each table to be linked. This is a very simplified version. The one I actually use has the capability to have different local table names than the SQL tables and also link views and create primary keys (optionally) for them.
The following is one example of how you can obtain a connection to SQL Server. It supports using either a Trusted Connection (where the windows user is authorized access, or you can specify a sqlserver defined userid and password.
' The following are some of the parameters the connection will use.
Global gv_DBS_SQLServer As ADODB.Connection
Global gvstr_SQLServer_Name As String
Global gv_SQLServer_DSN As String
Global gvstr_SQLServer_Database As String
'Call the GetConnection Function
' Pass Name of Server; Database Name; Connection Variable; adUseServer; True if using Password; False if not using a Trusted Connection;
' Sample
If GetConnection(gvstr_SQLServer_Name, gvstr_SQLServer_Database, _
gv_DBS_SQLServer, adUseServer, True, False) = False Then
MsgBox "Unable to connect to SQL Server", vbOKOnly, "No Connection"
End If
Public Function GetConnection(ByVal strDSN As String, _
ByVal strDatabase As String, _
ByRef cnLocal As ADODB.Connection, _
ByVal CursorLoc As CursorLocationEnum, _
ByVal UsePassword As Boolean, _
ByVal blnTrusted As Boolean) As Boolean
Dim strConnectString As String
Dim strDisplay As String
On Error GoTo ERROR_HANDLER
GetConnection = False
Retry_Connection:
If cnLocal Is Nothing Then Set cnLocal = New ADODB.Connection
If cnLocal.State = adStateOpen Then
Debug.Print "Connection already open -- -will not reopen!!"
GetConnection = True
GoTo Proc_Exit
End If
With cnLocal
Debug.Print "Use TRUSTED CONNECTION (ABOVE)"
If blnTrusted = True Then
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"Trusted_Connection=yes"
Else
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"User Id=UUUUUUU;Password=" & DecryptString("PPPPPPPP") & ""
strDisplay = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"User Id=UUUUUU;Password=PPPPPPP"
End If
Debug.Print "Will use Conn String: " & strDisplay
.ConnectionString = strConnectString
.CursorLocation = CursorLoc
.Open
End With
GetConnection = True
Proc_Exit:
Exit Function
ERROR_HANDLER:
Debug.Print Err.Number & vbCrLf & Err.Description
Err.Source = "Module_Connect: "
DocAndShowError
Resume Proc_Exit
Resume Next
Resume
End Function

Script to replicate SQL Server data dynamicaly

I have an access 2010 application with a SQL Server database.
But I need to do an offline version. So I thought I would create a local SQL Server database on their computers then they can run a script to update their data before they go on the road.
NOTE: There won't be any sync. The data in offline mode is only for read-only and any changes will be lost.
I tried with Management Studio like this:
But I realized that the data is hard coded instead of doing inserts from selects.
Is there any easy way to create the script?
What I have so far is my pass through query in access to create the backup of my online database.
Then I have my pass through query to restore the backup to the local server.
The only problem is how can I build the connection string for the second query. It's currently set to this one
ODBC;DRIVER=SQL Server;SERVER=010-068\SQLEXPRESS;UID=marcAndreL;Trusted_Connection=Yes;DATABASE=SMD
but because it's a different database for everyone, it won't work.
How can we build a custom connection string?
I am using SQL Server Express 2012 and Windows Authentication, so using the answer provided here, I find this works for me:
Sub TestCon()
Dim cn As New ADODB.Connection
cn.Open ServerConLocal
End Sub
Function ServerConLocal()
''OleDB Connection
ServerConLocal = "Provider=sqloledb;Data Source=localhost\SQLEXPRESS;" _
& "Initial Catalog=Test;Integrated Security=SSPI;"
End Function
For an ODBC connection string in a Pass-through query, this works for me:
ODBC;Driver={SQL Server Native Client 11.0};Server=localhost\SQLEXPRESS;Database=test;
Trusted_Connection=yes;
Take a look at download-only articles for merge replication. MSDN.

Office VBA ODBC to SQL Server

I have to connect a Word Document to a SQL Server with VBA in order to read and write records. Now, I'M really confused as of the many different ways to connect to a database. There's ADO, ODBC and so on. I've seen very different ways of connecting a SQL Server database.
A co-worker wants me to use ODBC.
So: What is the best way to connect to a SQL Server database using ODBC in Office VBA?
An example for a SELECT and INSERT statement would also be appreciated.
Edit: Isn't there something like "System.Data.SqlClient.SqlConnection" and "System.Data.SqlClient.SqlCommand" in VB .Net/C#?
This example uses ODBC:
'Microsoft ActiveX Data Objects x.x library
Dim cn As New ADODB.connection
Dim rs As New ADODB.recordset
cn.Open "DRIVER={SQL Server};SERVER=srv;" & _
"trusted_connection=yes;DATABASE=test"
rs.Open "SELECT * FROM table_1", cn
This example uses OleDb
'Microsoft ActiveX Data Objects x.x library
Dim cn As New ADODB.connection
Dim rs As New ADODB.recordset
cn.Open "Provider=sqloledb;Data Source=srv;" & _
"Initial Catalog=Test;Integrated Security=SSPI;"
rs.Open "SELECT * FROM table_1", cn
See also: http://www.connectionstrings.com/sql-server-2008
The reason your co-worker probably wants you to use ODBC is that your company delivers standardized ODBC connections for every single workstation.
The good thing here is that you don't have to worry about connection properties except login/password, because it's all set. Imagine ODBC acting between a software (word) and a server, it makes things alot easier when it comes to changes in your company. (Server address may change and IT is able to change settings of ODBC without the end user even knowing about it)
Beste would be to talk to your co-worker and ask about his concerns. Another reason could be that ODBC might be faster than the ado one. I made this experience, too.

MSAccess 2007 changing connection properties in form

I would like some help in creating a form with-in an MS Access front end to select a database/database server for the access backend.
A little history first;
I created a MSAccess 2007 acccdp database, it was designed as a single user to be run locally. (For a university research project with little or no funds for this).
Eventually there was a need to expand the database to be used by several people at once in the same office so what i did;
Install SQLExpress 2008r2 on a desktop.
Used Database Tools > Move Data > Sql Sever to migrate the tables to the new SQL server.
Now I want to create a second test database for development/training etc... Also, I need to adjust the properties for a different database sever (at home).
So I figure I need a form to auto exec (rather than the switchboard) which will allow you to select the database server and Database to join the linked tables to, then if successfully connects to open the switchboard.
I can create the form, but i need help with the vba to adjust the database connection properties.
I am just trying to help this project and am not a programmer in any way.
Thanks in advance
Roger
If your choice is between two connections, you can check if the existing connection is working and if not, switch to the second. However, a button may still be the best bet. This snippet works for me, but it sets the connection timeout to just a second, so the server may be available if you had only waited a little longer, and even with this time out, there is enough of a delay for an impatient person to start clicking.
Function IsSQLServer() As String
''Reference Microsoft ActiveX Data Objects x.x Library
Dim cn As New adodb.Connection
''http://msdn.microsoft.com/en-us/library/windows/desktop/ms676718(v=vs.85).aspx
''Provider=sqloledb
cn.ConnectionString = ServerCon & "Connect Timeout=1;"
On Error Resume Next
cn.Open
If Err.Number <> 0 Then
IsSQLServer = "No;" & Err.Description
Err.Clear
Else
If cn.State = adStateOpen Then
IsSQLServer = "Yes"
Else
IsSQLServer = "Maybe"
End If
cn.Close
End If
Set cn = Nothing
End Function

Resources