I recently developed a simple Access 2010 database for a client. It was designed without VBA, just using macros so it wouldn't trigger any security warnings. The only problem was that it uses ODBC linked tables connected to a SQL Server Express database, and I needed a way to reset the tables' connection strings once installed on my client's computer.
I developed a simple VBscript that goes through the linked tables, copies their names into a dictionary, and then recreates the tables with a new data source:
For Each key In tcmw.Keys
Set td = db.CreateTableDef(key)
td.Connect = "ODBC;Description=xxx;DRIVER=SQL Server;SERVER=xxx\SQLEXPRESS;DATABASE=TCM;User=xxx;Password=xxx;"
td.SourceTableName = key
db.TableDefs.Append td
Next
The script seems to work, but when I hover over the linked tables, I see the following data source. It has Trusted_Connection=Yes instead of the specified username and password:
ODBC;Description=xxx;DRIVER=SQL Server;SERVER=xxx\SQLEXPRESS;Trusted_Connection=Yes
That's not what I set the data source to, and I'm not sure why that would be happening. Is there a step I'm missing to get the username and password saved in the linked table definitions?
I don't know positively but I don't think Access saves the credentials in the connection information. I'm using SQL Server 2008 with an Access 2010 front-end and here's the connection information I see when I hover:
ODBC;Driver=SQL Server Native Client 10.0;SERVER=localhost\SSE2008;APP=Microsoft Office 2010;Database=MyDatabaseName;;TABLE=dbo.SQLTableName
This maybe wouldn't work well for really large projects but I actually run code when the user opens the front end that deletes all of the SQL Server linked tables and recreates them using information that I store in a local table. I'm very happy with how it works but this project only has 22 tables.
I see you mentioned that you use only macros and no VBA in your project. I'm skeptical that you'll be able to make your project work reliably without using some code, at least to handle your linked tables. The way I remember I went the route I did because I had a lot of frustration making linked tables maintain their connection information. In my case I wasn't using Trusted Connections (or Windows authentication). Instead I was using SQL Server authentication which seems to be less resilient when it comes to maintaining connection information without user intervention.
Related
If I have a tool that writes data to Access but one of the tables is a linked table, how exactly is the data written to that linked table? Does the data get off-handed to Access and then within Access, Access handles the writing of the data? Or is a kind of link provided to the tool and then the tool writes directly to the table?
The reason for asking is that I've encountered times where some automated tools that I work with will or won't write to a linked table and I'm curious of how to ensure that data is always written.
Usually, all data is written via the Access Database Engine, unless you're doing something weird.
In most situations, it works like this:
Tool submits a query via OLEDB/ODBC/DAO to the Access Database Engine (DAO360.DLL/ACEDAO.DLL)
Access Database Engine determines which data should be read/written to where (to the file/remote data source)
Access Database Engine uses the connect property of the linked table to try and open a connection if necessary, and creates a new query or multiple queries in the appropriate SQL dialect
Access Database Engine submits query/queries via the opened connection
However, this can go wrong:
The tool doesn't actually use the Access Database Engine at all, but tries to directly write the file (via UCanAccess/MDBTools/proprietary driver), and those don't support linked connections at all
The connection string in the linked table requires an ODBC driver, password, resource, or something else that's not present or not in the right place
The linked table requires some sort of implicit authentication (e.g. SharePoint), and this doesn't happen
The data source used by the linked table requires a specific lock type (e.g. dbSeeChanges for opening a Dynaset-type recordset on SQL server) which is not used by the tool
And of course, many, many more things can go wrong (in fact, I crashed Excel in an attempt to test reading a linked SharePoint lists while writing this answer).
I am in charge for migrating old Access 2007 project to MS SQL server 2008 Express. The first stage is to move all the data from MS Access database to SQL server while keeping the Access forms and reports at the client.
So, the data are now moved, an SQL server user (for accessing only that particular database) created, and the tables are linked the Access database via ODBC connection. However, there's one nuisance that should be somehow solved: the Access regularly asks for the user password, when opening the Access database.
The users on server PC and client PC both log onto their local machines, ie their users are not verified on independent domain server.
I see there are several ways how to solve this:
1) Configure the integrated security model so that the user can log on, being automatically authorized by his Windows login (ie, use "trusted connection"). I am not sure how this could be done, given that the server PC does not recognize the user from client PC. If I try to do this now, I get error that the user is connecting from untrusted domain.
2) Store the SQL server user password at client side. I am not sure this is possible, though. I am aware keeping password in some config file, or stored obfuscated in application configuration should be considered lowering security, but this is acceptable for the given setup.
3) Perhaps some other way how to link the SQL server tables into Access?
The best solution is obviously to use Windows security.
If that is not suitable, here is a possible alternative trick, exploiting the fact that Access remembers all opened connections until the program is closed:
copy the connect string of one of your tables
create a passthru queries "ptqConnect" and enter any fast SQL statement in it, like SELECT 1
paste the connect string of into the PTQ Connect property, and make sure you add the PWD=something; in it.
in the startup procedure of your app make sure you call that PTQ. Something like DCount("*", "ptqConnect") will do.
That's it. Since Access remembers opened connections until you close it, even if you close the db, your other tables will now open without any fuss, even if no password is stored in the linked tables Connect string.
If you don't want to expose the connection string that includes the PWD, you could as well initiate a connection from VBA and hide the code by delivering a MDE or just password protecting the code.
You can find an explanation of this behaviour here.
Inform the users your organization's security policy prohibits storing passwords. Therefore they must provide their password each time they open the database. Explain that this policy will deny an unauthorized user the ability to open the database from an authorized user's machine. If the password were stored in any fashion, a miscreant could simply sit down at an unattended machine and open the database.
Since you can't use a trusted connection, this is the safest way to do it. Yes, the users will have to supply their password each time they open the database, but that's what it takes to keep the data safe.
Edit: Since your option #2 is acceptable, you can just store the uid and pwd in the connection strings for the ODBC-linked tables.
Here is an example copied from connectionstrings.com
Driver={SQL Server Native Client 10.0};
Server=myServerAddress;
Database=myDataBase;
Uid=myUsername;Pwd=myPassword;
I split the single line string for browser display. You'll need to also identify which table each of the links points to; examine your current link connection strings to see how that is done.
The uid and pwd will be plain text, and visible to anyone who can view the connection properties. But I didn't see any indication those are concerns for you.
I have had this issue, with Access 2010, linking to SQL Azure, but it was very simple. When linking the tables, there is an tick box option with each table to save the password.
Relinking your tables and checking this option would sort the issue. It does give you warnings that this may not be secure, but not all databases contain confidential data.
Just ran into this problem connecting remotely to my workplace sql server using Access. I have Access 2013, but I don't think it has made any changes to something so basic as as ODBC connection from 2010. Since it is not a trusted connection, yes, you will have to log into the server each time you connect to the database. This is just basic security; can't think why you would ever want an app to just connect from an untrusted network unchallenged. So, I expect to have to log in when opening the database.
What was driving me crazy, however, was that each and every time I tried to open a table, I was asked for the password, and not just once, but twice, and I have to use a 13 character password that was randomly generated at creation! So, needless to say, that was completely unacceptable.
Access keeps the connection information in the sys table MSysOBjects, but I doesn't store the password, at least not there. I use an access DB stored on a cloud server synced with my desktops so I can open a local copy rather than having to remote in to my work desktop. It's much faster this way.
But, using the db in Access as a local file means that I have keep a close eye on the DSN connection names. As long as they are absolutely identical on all computers, it works great. So, if named my DSN "ProductsDBIII" when I created it at work in the ODBC32 Windows tool, then I need to use that same name when creating it at home. The actual connection string will be different, but Access doesn't care about that. However, here's the trick: when I first the DB from home, for instance, after a day at work, then I have to refresh the connections in Access's Linked Table Manager. Just check the tables/views you need, or "Check All", and go. Access will make the connection--probably prompting you for the log in--and then quickly refresh the "connect" string field in the MSysObjects table because they will be different, at least if switching from trusted access.
Voila, no more single or double challenges every frickin' time I open a table. I will get asked once when I first make a connection the first time I open a table from the remote DB, but that's it.
Hope this helps someone.
Jim
Re the use of Passthrough QAuery to set ODBC connection.
The form quoted as the startup form in the Database options will fire BEFORE autoexec.
So that form cannot/should not quote linked tables,
or
Leave that none; and set the form in autoexec.
Otherwise you will still be prompted for pwd for the ODBC connection
A typical problem scenario is using a Switchboard form with the table in the linked database
I am trying to connect MS Access to a MySQL database backend - using the windows "Set up data sources (ODBC)" command allows me to connect to my database fine, but will not save the DSN file for some reason.
I've tried to get around it by manually creating a DSN file which looks like (with the actual data instead of the ***):
[ODBC]
DRIVER=MySQL ODBC 5.1 Driver
USER=****
PASSWORD=****
SERVER=**.***.**.**
DATABASE=cl39-beech
However Access throws up the message
ODBC--call failed.
[microsoft][odbc driver manager] data source name not found and no default driver specified.
Any thoughts on how to get around the problem(s)? I'm not too worried about the first one if I can manually create the DSN file, but need to work out where the second is going wrong!
Simply create the working link from Access like you did in your first step. When the ODBC manager from Access launches then simply create a file data source.
Check that the linked table works by opening the linked table in Access to ensure the connection works and you see data.
Now, simply grab/pull out the connection string saved for that table like this in the debug window (hit ctrl+g to launch VBA IDE and jump to command line).
? currentdb.TableDefs("dbo_customers2").Connect
The debug window will then out put the correct connection string. (so in above, replace what I have with the name of the WORKING linked table).
It is the above connection string result that you can use to re-link a table.
A suggested code example for the above string to re-link tables can be found here.
So don’t bother with trying to use a DSN, as there is often a zillion issues such as where you have to place the file to work etc. The above approach means no DSN is required.
edit:
Edit:
In most cases, you likely don’t need any code. Remember, once you linked the Access tables, then the DSN is in general NOT required. Access linked tables “remember” their settings.
So you really only need such code if you not going to “manually” use the ODBC manager from access to link the tables.
Thus, the code ONLY need to run “one time”. So you on your development machine simply place the code in a standard code module and while in the VBA editor hit F5. As noted, if you ALREADY linked the tables, then you don’t need the DSN anymore anyway (it is only used “during” the re-link process and the settings in that DSN are transferred to each linked tables.
So you don’t need to run the code in some form – it is a “one time” thing you do much like designing a form. You don’t re-design forms on application startup, nor do you need to run some re-link code ONCE the tables have been linked.
In most cases such re-link code is ONLY required if you going to CHANGE the back end database (say from developer back end to the actual production back end database). And thus I suppose you could make a form with a button on it to re-link, but as a general rule you don’t need that code to run each time the application runs.
Once tables are linked then your forms and reports etc. should work as if such tables were regular “local” access tables. So this re-link code is really a “substitute” for you doing the manual linking to the SQL server tables. However ONCE you done a “manual” link, then the original DSN is not required. The re-link code thus in “most” cases is to allow you to re-link the front end database to a back end database of your choice, or in those cases in which you are supporting a client “far away”.
If you are developing “off site” then your linked tables are to your local copy of MySQL. When you send a updated “next great” version of your application to the customer site, then your table links are wrong, and on startup you need to run that re-link code to correctly link the tables to their back end. A “great” way to do this is to ALWAYS have a text file in the same directory as the application. Your application on startup can read that text file, and if the connection string is DIFFERENT then the existing connection, then you call + run your re-link code with this new connection string. Thus you don’t have to be on the customer’s site to roll out updated software. Next time the application runs, the connection strings will match and thus a re-link will NOT be required on startup. So re-linking is a “one time” type of deal here.
There are a BILLION different use cases here. What works for me may well not work for you. It not clear if you are working “on site” (so re-linking of tables is likely NOT required), or you developing off site with your own copy of MySql running (and thus you linked tables point to the wrong server). Or you are developing on site, but DURING development, your front end tables are linked to a “test” copy of the database as to not accidently “mess” with the production data.
So the code belong in a standard (non class) code module. As to when you need to run such code will depending on the billion different possibility’s (so it kind of like asking me to tell you where your shoes are in the morning – I have no idea and never could have an idea). But I can tell you that you should put shoes on when you go outside!
So if your linked tables are now working, then your application should be compiled to a accDE, and then that accDE should be distributed to each computer that requires this application. If they are on the same network etc., then no code or re-linking of the tables is required. On the other hand, if you are developing off site, or the application has to be distributed to several different companies then likely EACH company will have a different server location as to where MySQL is running and thus you need to re-link in each of those cases.
So it is possible that you may well not need ANY re-linking code. If you are “on-site”, then once you linked those tables, then your application should run on ANY computer without needing any re-linking code or having to run this re-link code.
So once tables are “linked”, access remembers that setting and it is permanent.
Can anyone confirm whether linking to tables in a Microsoft Access .accdr files is possible?
I have a split MS-ACCESS application with the frontend in a .accdr file and the tables in an .accdb file backend on a server. For reasons that I explain below, I need the frontend to connect to a table in a second backend file (also on the server) that has an .accdr extension.
I found no documentation that explicitly states that .accdr files are not allowed as as a backend database, however, the linked table manager does not seem to allow it, and the DoCmd.DatabaseTransfer method throws an error.
My workaround is to temporarily rename the .accdr server file as an .accdb, link to the tables in it to make the data changes, then rename it back to .accdr. But if I don't HAVE to do this, I would prefer to connect directly.
Reason:
To make sure that each client gets the most recently updated copy of the frontend .accdr, I created a batch script that first copies the frontend from the server to their local machine before launch. It's a short time penalty (the frontend is about 8 MB) each time they load the application, but the batch script makes sure that the client is ALWAYS up to date. (If performance became an issue I would of course have the batch script verify MD5 sums before downloading, but it hasn't come up yet.)
I don't have many clients connecting at the same time (only about 2 or 3 concurrent connections), but they can connect from any of thousands of computers on campus, so I found this the easiest way to make sure that no matter where they connect from, they will get a fresh copy of the FrontEnd.
Unfortunately, I made a few tables local to the frontend because they allow individual users to set parameters locally during a session. Now, of course, I have a case where an individual user needs to update these local tables so that all the other users will get this same data. (Previously, I had just been making these changes manually upon request, but this user quite reasonably needs to be able to do it herself.)
So, the local frontend .accdr file needs to connect to the server copy of the same frontend .accdr file to make a few data adjustments in a table. That's the reason. I know it's weird.
Thanks,
Damon
Turns out it is possible to use .accdr as a backend. I think i was specifying the wrong connection or something. I used this code snippet with the strConnect = path_to_mydb.accdr:
Public Sub ConnectOutput(dbsTemp As Database, _
strTable As String, strConnect As String, _
strSourceTable As String)
Dim tdfLinked As TableDef
' Create a new TableDef, set its Connect and
' SourceTableName properties based on the passed
' arguments, and append it to the TableDefs collection.
Set tdfLinked = dbsTemp.CreateTableDef(strTable)
tdfLinked.Connect = strConnect
tdfLinked.SourceTableName = strSourceTable
dbsTemp.TableDefs.Append tdfLinked
End Sub
You could easily add the tables that are local to your front-end to the backend. Just copy/paste them from one to the other, delete them from the front-end and link them to the backend version. Takes all of 5 minutes, no VBA code necessary.
Regarding the accdr as a backend question, then yes, accdr is meant to be a open by a the Runtime version of Access. Opening an .accdr file with the standard version of Access simulates the Runtime mode. The only difference between the standard version and the free Runtime version is that you can't access the design tools and the standard ribbon from a Runtime application (you need to create your own).
So renaming a accdb file into accdr only tells access to open the database in Runtime mode. It doesn't change the database itself at all.
So you can use an accdr file as a back-end without problem.
Pro tip: if you want your setup to scale a bit (easily up to 50 concurrent users) and have better performance, open a database to a dummy table from the front-end to the back-end. This will keep the connection open while the front-end is running and keep the lock file open on the database, resulting in better -and more reliable- performance.
I've created a database in access 2007 that needs to be used by 3 users. I'm stuck because I don't know whether to place a copy on each users' computer or to place it on their SQL server. Placing it on the server would mean one access point which is desirable for data consistency but I don't know whether I need ActiveX. Don't know how to use it either. If I place it one each computer how do I work around the master file updates? Can somebody please break it all down, I'm a NEWBIE!!
Your question seems rather confused to me. You mention a SQL Server, but you don't say your application uses SQL Server for its data storage.
Thus, I can only assume that you have a single MDB or ACCDB file with your data tables and forms and reports all in the one file.
The only proper way to distribute this app is:
split it into front end (forms/reports/etc.) with linked tables that point to the back end (data tables only).
place the back end on your file server and relink your tables to point to the new location of the back end.
give a copy of the front end to each of the 3 users, who will run it from their desktop computers. If you're concerned about distributing changes to the front end, something like Tony Toews's front-end updater is very useful.
Others have jumped in to say that you should put the data in SQL Server, but most 3-user Access apps don't need the power of SQL Server. If you're not given administrative permissions on your SQL Server, it could be quite difficult to continue to alter your application's database.
On the other hand, if your database is going to grow to 1GB or more, or if you have strict security requirements, or if the data in your database is so important as to need completely failproof backups, then SQL Server would be a reasonable data store.
For most homegrown apps, not so much.
The "best" way I've worked this out is using Linked Tables in Access to go to SQL Server (since you stated you have that..?).
Using access as a front end in this scenario isn't the best thing you can do, but with 2007, it's a bit better than if you were a few versions back. Check out this article for info on linking Access into SqlServer:
Import or link to SQL Server data
One easy way is to use the EQL Data plugin: http://eqldata.com
That way you can give a copy of the database to each user, but users can sync the database with other users whenever they want. You can also access your tables and queries on the web.