I have an Access Database connected(linked table) to an Oracle database.
I wrote some Select queries. Everytime I run it, I get an "Oracle ODBC Driver Connect" input box.
Is there way to write a vba macro to enter username and password (auto fill) and Enter Ok.
Trying to set up an auto run for macros in this Access db.
Any help is appreciated.
As pointed out, when you link the tables, you are given an option to save the password in those table links. If you missed this step, then you will get that ODBC prompt.
THIS HAS ZERO to do with you writing select queries. The simple matter is try clicking on one of the linked tables you use in such quires. Either you get an ODBC prompt or you do not.
If you do, then of course you going to get such a prompt when you write a query. YOU WANT to FIRST get the table links working without an ODBC prompt and THEN write those queries based on the linked tables.
So get the linked tables working first. Forget about and don’t’ worry about your queries you are writing. Until such time that a simple click on (opening) a linked table works and does not throw out the ODBC prompt, then you are looking at the WRONG problem.
Once you get your linked tables working without a prompt, then your queries will also work without a prompt.
So you have two choices to fix this problem.
Simple re-link your tables, and ensure that you select [x] check box during re-link to save the password.
The prompt you missed and want to select is this one:
Now if your tables are already linked and you run the linked table manger, you WILL NOT get this prompt anymore. So you have to delete the table links, and re-create.
Of course deleting the table links can often result in the linked table names being changed, and that can be a pain, especially if you have a LOT of linked tables. Only you can make this judgement call as to what is less work. If you have just a few tables, then just delete them, and use the external data -> then in the import and link secton, choose ODBC and you can add the tables, but REMEMBER to select (check) the above save password box as per above that you missed.
Now, most people over time wind up with some table re-link code VBA. So if you have suc re-link code already working and handy, then simply re-run that code with the user/password included in the connection string you use in that code. Of course if you don't have such code, then the above linked table manager in Access is a code free solution and is obviously your best choice and course of action.
So in place of above, you can find some table re-link code that will force (save) the user/id in the table links for you.
However, if you don’t want to delete + re-create all those tables, and you don’t have already setup some re-link code, there is also another (3rd) choice.
In your application start-up code simple execute a one-time logon. If you do this, then the ODBC prompt will not appear when you use the linked tables and hence also not appear when you attempt to run/build/use a query based on those linked tables.
The code to execute a one-time logon will look like this:
Function TestLogin(strCon As String) As Boolean
On Error GoTo TestError
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Set dbs = CurrentDb()
Set qdf = dbs.CreateQueryDef("")
qdf.connect = strCon
qdf.ReturnsRecords = False
'Any VALID SQL statement that runs on server will work below.
' this does assume user has enough rights to query built in
' system tables
qdf.sql = "SELECT 1 "
qdf.Execute
TestLogin = True
Exit Function
TestError:
TestLogin = False
Exit Function
End Function
Above code run ONE time on start-up of your application will thus eliminate the ODBC prompt(s) when you click on a linked table. And of course once that issue of linked tables is resolved, then of course creating or clicking on your query or running those quires will now ALSO work without the prompts.
You can NOT auto fill that prompt, you have to take CORRECT steps in the first place to PREVENT that prompt from appearing. So to answer your question?
No, you can't write code to enter the requested prompt, but if you link your tables with the password saved, or execute the above logon code, the prompt will NOT appear in the first place.
Related
My current team of 20 people uses an access database front end on their desktop. The backend of the access database is on a network drive. I have been asked to create an access database front end with MYSQL as the back end.
I have installed the MySQL workbench and the ODBC connector on my computer. I have created the schema and tables and I have connected the front end of the database connected to the MYSQL table I created in workbench. My question is
How do I deploy this for the team to use. I believe I can move the front end of the access dB to the network drive and the team can copy it to their desktop. But what do I do about the backend?
Does the team need to have the ODBC connector installed on their computers?
Should I move the MySQL workbench to the network drive?
PS: I am a new developer and just learning about databases and I am only familiar with the access database please go easy on me.
Thanks.
SO is for questions about coding, so this is OT. However:
One method is described in my article:
Deploy and update a Microsoft Access application with one click.
The old backend, you can archive. It will not be used anymore.
Yes.
Probably not. It is only for you, should you need to modify the
MySQL database.
Well, first up, you STILL need and want to deploy the application part called the front end (FE) to each workstation.
So, after you migrate the data to MySQL, then of course you will use the access linked table manager, and now link the tables to MySQL. How this works is really much the same as you have now. The only difference is that you linked tables now point to the database server (MySQL). From the application point of view, it should work as before.
Like all applications, be it Outlook, Excel, accounting packages? You STILL deploy the application part to each workstation. So just because YOU are now developing and writing software with Access does not mean out of the blue that you now for some strange reason STOP deploying the FE part to each workstation. In fact, you should be deploying a compiled version of your application (a accDE).
A few more tips:
WHEN you link the FE, MAKE SURE you use a FILE dsn. The reason for this is Access converts the links to DSN-less for you. What this means is that once you link the tables, then you are free to deploy the FE to each workstation and it will retain the linked table information WITHOUT you having to setup a DSN connection on each workstation. You will also have to of course deploy the MySQL ODBC driver to each workstation as that is not part of Access nor it is part of your application.
So just because you are now developing software does not suggest nor get you off the hook of deploying that application to each workstation. So, your setup you have now with a FE on each workstation does NOT change one bit.
For the most part, after you migrate the data to MySQL, then likely setup your relationships (say with MySQL workbench) there are several other things you need to keep in mind.
All tables now need a primary key. You likely have this, but Access with a access back end did and could work on tables without a PK. However, for SQL server/MySQL etc., then all tables need that PK.
Next up:
If you have any true/false columns, you MUST set a default up for that column. If such true/false columns have a default value or allow nulls, this will confuse access - so ensure that true/false columns can't have nulls and have default (useally 0) setup on the server side.
Add a "rowversion" column. This is not to be confused with a datetime column. In SQL server this rowversion column is of timestamp data type (a poor name, since the column has zero to do with time - it is simply a column that "versions" the row. This will also eliminate many errors. I don't know what this type of column is called in MySQL, but all tables should have this column (there is zero need to see/use/look at this column on your forms - but it should be part of the table.
All of your forms, reports and code should work as before. For VBA recordset code, you need this:
dim rst DAO.Recordset
dim strSQL as string
strSQL = "SELECT * from tblHotels"
set rst = currentdb.OpenRecordSet(strSQL).
You likely in the past had lots of code as per above.
You now need:
Set rst = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)
You can generaly do a search and replace (find each .OpenRecordSet, and add the dbOpen and dbSee to each line of code you find. (I put the dbOpenDynaset, dbSeeChanges in my paste buffer. And then do a system wide search. It takes a few minutes at most to find all .openRecordSets
At this point, 99% of your code, forms and everything should work.
The ONE got ya?
In access be it on a form or in VBA recordSet code? When you create a new row, or start typing on/in a form? Access with access back end would generate the PK at that point. There was/is no need to save the record to get the PK value. This need is rare, and in a large application I only had about 2 or 3 places where this occured.
So, if you have code like this:
dim rstRecords as RecordSet
dim lngPK as Long ' get PK value of new record
Set rstRecords = CurrentDb.OpenRecordset("tblHotels")
rstRecords.AddNew
' code here sets/ add data/ set values
rstRecords!HotelName = "Mount top Hotel"
rstRecords!City = "Jasper"
' get PK of this new record
lngPK = rstRecods!ID ' get PK
rstRecords.Update
So, in above code, I am grabbing the PK value. But with server systems, you can NOT get the PK value until AFTER the record been saved. So, you have to change above to
rstRecords.Update
rstRecords.Bookmark = rstRecords.LastModified
' get PK of this new record
lngPK = rstRecods!ID ' get PK
Note how we grab/get the PK AFTER we save.
The bookmark above simply re-sets the record pointer to the new record. This is a "quirk" of DAO, and WHEN adding new reocrds, a .Update command moves the record pointer, and thus you move it back with the above .LastModified. You ONLY need the .LastMOdifed trick for NEW reocords. For existing, you already have the PK - so it don't matter.
This type of code is quite rare, but sometimes in a form (and not VBA reocdset code), some form code we might use/need/get/grab the PK value. In a form, you can do this:
if me.dirty = true then me.dirty = false ' save reocod
lngPK = me.ID ' get PK
So, once again, in the above form code, I make sure the record is saved first, and THEN I grab the PK value as above. Of course this is ONLY a issue for NEW records. (and you don't have to use the bookmark trick - that's only for recrodsets - not bound forms.
So, just keep in mind in the few cases when you need the PK value of a NEW record, you have to do this AFTER you saved the recordset (update) or in the case of a form, after you forced a form record save. This requirement is only for new records and ALSO only when your code needs to get/grab the new PK value.
Other then the above two issues? All the rest of your existing code and forms should work as before.
I'm working on an Access 2003 database, divided into front and back ends. I've attempted to compact and repair the database, which appears to do nothing.
After running various export processes I noticed that some of the columns reported as transferred didn't seem to tally with what was displayed in the design view.
Public Sub Test()
Dim db As Database
Dim td As TableDef
Dim f As field
Set db = CurrentDb
Set td = db.TableDefs("TBL tablename")
For Each f In td.Fields
Debug.Print f.Name
Debug.Print f.Properties("ColumnHidden").value
Next f
Set f = Nothing
Set td = Nothing
Set db = Nothing
End Sub
Further tests ascertained that the table actually had several fields, some of which were replication fields (the database had previously been replicated, but not anymore). More importantly, some of the fields were required data fields, containing data necessary to the project.
I have some questions regarding this:
Is there a setting in the background that allows the field to be hidden in design view?
If not, is this a good indicator of corruption?
Update
I've tested the theory further by writing a query to pull the data back, which also works fine:
...and the table design...
Update (06/06/2016)
I've written a process to extract as much data as possible from the database and drop it into a new one. Though I don't think Microsoft Access is a suitable platform for this application, at present it will have to suffice. In the future, I will attempt to move it to SQL Server to stablise its operation, but in the meantime it will have to serve as is.
I've posted the solution I used to do this here.
I'm going to accept the fact that this database is corrupt. There were too many issues boiling up, including:
Missing fields in tables
Tables not copying to other databases
Inability to compact and repair the database (the C&R would return instantly without doing anything)
Inability to remove the replication applied to the database
I am working on MS ACCESS 2003, i need to call oracle stored procedure through ms access. I am using pass through query to call the procedure. I have created user DSN with Microsoft driver for ODBC and successfully able to call the procedure.
ODBC;DSN=DSN_NAME;UID=USER_NAME;PWD=*******;DBQ=MY_SERVER
But my worry is to save the password in pass through query, some times password changes then i have to change the connection string for that pass through query every time.
Is there any other way to calling the procedure via pass through query without changing the connection string when password gets change or is there any code in vba to doing the same. I am looking for dynamic way where calling procedure would be easy without changing password to each and every pass through query by going to its properties.
Thanks !!
Yes this is possible however you need to know or in other words be able to retrieve the password somehow within your application. In a production line application you would use the user(login) password to create a connection string to access the back-end tables.
The structure would look similar to this:
Create a module to host connection related public functions.
Create new function GET_CONNECTION_STRING() as String: Which will return your connection-string including logged in user's password.
loop through the table definitions/ query definitions in your database and update the .connect property.
In most cases you would change the .connect property and use the .RefreshLink to refresh/connect manually.
You need to add a new reference to use DAO object. (Microsoft dao objets, or activex data obects or ado objects whichever type you want to use)
some startup code:
dim db as dao.database
set db = currentdb
dim tdf as dao.tabledef
For Each tdf In db.TableDefs
If tdf.connect <> vbNullString Then
tdf.connect = GET_CONNECTION_STRING & ";TABLE=" & tdf.name
'if you want to manually refresh uncomment below line
'tdf.refreshlink
End If
End If
Next tdf
adding above function to a startup macro will ensure all the linked tables (queries you need to perform extra) are updated with the newest connectionstring.
try and post your code when you are stuck.
Any linked table(s) and that of including “saved” pass-though quires in Access does NOT require the password to be included in that string. If you leave out the password, then a SINGLE logon to the Oracle database will THEN allow ALL linked tables and pass though quires to run and do so without a password.
The first step is to setup your tables as DSN less, and DON’T include the password (you likely best to delete existing linked tables).
To link using above but NOT include pass-word means you FIRST will have to execute a logon into the database. Once done, then you can link your tables and pass-though quires. So a one time link of tables as DSN less and you are off to the races.
Once above is done, then any and all connections (including pass-though query) will all work and work without having to include the user name.
The above thus means you don’t have to re-link for different users logging into the database.
To run a pass-through query, you can then use this one line of VBA code:
CurrentDb.Execute.QueryDefs("MyPassQuery").execute
How to link with DNS-less is outlined here:
http://www.accessmvp.com/djsteele/DSNLessLinks.html
How to “cache” the user logon, and NOT require user + logon in the linked connections or ones used for pass-though is outlined here:
Power Tip: Improve the security of database connections
http://blogs.office.com/b/microsoft-access/archive/2011/04/08/power-tip-improve-the-security-of-database-connections.aspx
So you can on startup execute the logon one time, or prompt the user for a logon, and from that point on your application and pass-=though queries will run without required a password. And this ALSO means you can have different users logon and NOT have to re-linked the existing tables (and pass-though quires).
What i have is the Issues template from microsoft which is all i really need for its purpose. I have converted it so that is now no longer a web database by exporting objects as client objects.
I want to split this database so that not only multiple users can utilise it at the same time but also so it performs better.
When i split the database the macros linked to the tables go to the backend so when the front end needs to use them it errors.
Below is and example of the add comments macro that gets called when the add comment button is pressed on the front end.
And this is the macro embedded to the button
Can these be converted to VBA and interact with the backend the way it is meant to and if so where would i start. I have looked for an answer but all i find is people saying "it is fine now i have gone vba route" or similar but not actually showing it working.
Below is the converted data macro to VBA. It isn't 100% there yet as I have hard-coded the userID but this will be fixed later today, but I hope it gives a good understanding of how to convert data macros to VBA because this was a learning experience for me.
Private Sub cmdAddaComment_Click()
Dim db As dao.Database, theComments As Recordset
Set db = DBEngine.Workspaces(0).Databases(0)
Set theComments = db.OpenRecordset("Comments")
theComments.MoveLast
theComments.AddNew
theComments!IssueID = Me.ID
theComments!CommentDate = Now
theComments!Comment = Me.txtAddComment
theComments!UserID = 2
theComments.Update
Me.txtAddComment = ""
DoCmd.RepaintObject acForm, "IssueDetail"
End Sub
Before doing this, make a backup of your database. You can do that by closing down the database, then locate the .accdb file on your computer, and press Ctrl+C and Ctrl+V
You can do your own split like this:
Create a new, blank database.
Import everything EXCEPT THE TABLES from the old database
In the new database, create links to the old database tables. To do that, click on External Data - Import & Link, and then click on Access. Select the Link option, then locate the old database, and select all the tables you want to link. Note that if you see any tables that are named like "MSYS", do NOT import those. Those are system tables, and Access will handle those internally.
Now delete everything EXCEPT THE TABLES from the old database.
Your new database is now "linked" to the old database's tables, but all Forms, Reports, etc are in the new database.
If you want to split an Access DB, you have to separate TABLES from all the rest.
Queries, Macros, Forms, Reports and VBA code have to stay on the frontend, and only tables on the backend.
What you are missing are the LINKS from the frontend to the backend tables.
To do that you need to create a copy of your DB, renaming it "BE.mdb" (or accdb), delete all your objects except tables from BE.mdb.
Now on the original mdb, you need to delete every table and add a link for every deleted table to the BE.mdb corresponding table. This can be done from the Import menu, choosing "link table" instead of "Import table".
I have imported a table in Access 2007 through Oracle ODBC. My problem is that sometimes the tables change structure in Oracle (eg new columns are added) and when that happens Access doesn't automatically pick up the changes in its linked table.
Instead it keeps using the old structure and even worse some rows simply won't show up in the Access queries (I don't know why?).
The other problem is that I don't have any control over the Oracle DB so the changes can happen any time. Manually updating the linked tables all the time is too much of a hassle. Is it possible to somehow set Access up to notify me of the changes? I mean, somehow Access must be able to tell that something has changed - the question is; can it tell me?
Regards,
John
Run this function - you can either link it to a form Open event, or just run it when you need to refresh the data
Sub relinkTables()
Dim tdf As DAO.TableDef
For Each tdf In CurrentDb.TableDefs
' check if table is a linked table
If Len(tdf.Connect) > 0 Then
tdf.Connect = "your odbc connection string to the DSN or database"
tdf.RefreshLink
End If
Next
End Sub