Opening Access from Excel VBA - ms-access

Edit: The answer to this question can be found within the comments of the accepted answer.
I am attempting to open an Access database from a button click within my excel file. I currently have this code:
Private Sub bttnToAccess_Click()
Dim db As Access.Application
Set db = New Access.Application
db.Application.Visible = True
db.OpenCurrentDatabase "C:\Users\wcarrico\Desktop\wcarrico-CapstoneFinalSubmission.accdb"
End Sub
This seems to work briefly and then Access shuts down almost immediately. If it matters, the Access file has an AutoExec macro that runs through a few tests itself on open.

Don't try to open the Access application then; just create a connection object using one of the Data Access technologies:
- OLE-DB or
- ODBC.
Google "ODBC Connection strings" or "OLE-DB Connection Strings" to get details depending on your particular configuration (and Access filetype).
Probably ADODB is the easiest current library to use for your data access.
Update:
Try Importing the data from Access then using the Data -> From Access wizard. Yu can always use the Macro recoding facility to automatically generate some VBA code for you, that will create some infrastructure for you; I use this regularly when exploring new portions of the VBA object model.
Update - Final resolution of problem, from comments below
That may be because the variable goes out of scope; move the declaration of db outside the function, to module level

The code started Access by creating an application instance assigned to an object variable. At the end of the procedure, the variable went out of scope so Access shut down.
You accepted an answer to use a module-level variable for the Access application instance. In that case, Access remains running after the procedure ends. However if the user exits Excel, Access will close down too.
If the goal is to start Access and leave it running until the user decides to close it, just start Access directly without assigning the application instance to an object variable (Set db = New Access.Application). That db variable would be useful if your Excel code needed it for other purposes. However, it's actually only used to open the db file.
You can use the Run method of WScript.Shell to open your db file in an Access session.
Private Sub bttnToAccess_Click()
Const cstrDbFile As String = "C:\Users\wcarrico\Desktop\wcarrico-CapstoneFinalSubmission.accdb"
Dim objShell As Object
Set objShell = CreateObject("WScript.Shell")
objShell.Run cstrDbFile
Set objShell = Nothing
End Sub

I know this is an old thread, but you will get this error in Excel VBA if you are trying to open an Access database, but you do not have two specific References clicked. (Tools, References on the VBA Editor screen). You need to click 'Microsoft Access 15.0 Object Library' and 'Microsoft ActiveX Data Objects 6.1 Library'.

Remove the New declaration then it works

Actually it is pretty straightforward:
Private Sub bttnToAccess_Click()
db = DBEngine.OpenDatabase("C:\Users\wcarrico\Desktop\wcarrico-CapstoneFinalSubmission.accdb")
End Sub
For this to work you need to declare db as Database at the Module level.
Dim db As Database 'Requires reference to the Microsoft
'Access Database Engine Object Library

Related

Open another instance of Access using VBA

I am using a form in Access to open other access databases that perform various different queries that publish reports. As the databases I am opening use a multitude of tables, queries, and reports that have nothing to do with each other it would be awkward and time consuming to link to them all and tedious to make changes inside the original database.
I am using Dim appAccess As Access.Application to open each one. It creates a 2nd instance of the new accdb which will not become visible. However, if I go into view code in the original database and then go back to the form it opens the new instance perfectly visible and will continue to do so as long as I keep the original database open. If I close the original database and reopen it I have the same issue which can only be resolved by viewing the code again.
As an example of what I am using
Option Compare Database
Dim APP As Access.Application
Sub TEST()
Set APP = New Access.Application
APP.Visible = True
APP.OpenCurrentDatabase "C:\Users\Documents\Database1.accdb"
End Sub
Does anyone know why this is happening?
Add line:
APP.UserControl = True
For more info review https://www.devhut.net/2018/01/21/ms-access-VBA-open-another-database/#:~:text=MS%20Access%20VBA%20%E2%80%93%20Open%20Another%20Database%201,to%20truly%20appreciate%20the%20power%20of%20automation.%20

Access reference library goes missing after opened from newer version

I have built an Access database that is shared on our company network. Most users on the network have Access 2010 installed but some have Access 2016. When the database has been opened by someone with Access 2016 and then subsequently opened by someone with Access 2010 they are getting an error message as the Microsoft Excel 16.0 Object Library is marked "Missing".
I can fix this temporarily by selecting the '14.0 library' but the error recurs as soon as it is opened in the later version again. Is there anything I can do to stop this from happening?
Thanks
You can use late binding, which helps you avoid the issue. Code with late binding works with any appropriate object library, whichever is available.
You need to change the object initializations:
Dim excelApp As Excel.Application
Set excelApp As New Excel.Application
To
Dim excelApp As Object
Set excelApp = CreateObject("Excel.Application")
Note that if you use late binding, intellisense will be unavailable. My usual practice is to develop using early binding, and change it to late binding as soon as it's finished.
Are you sharing an unsplit database or sharing the front end of a split database?
Access is inherently multi user, but one must distribute it correctly. The database must be split into 2 files (this is a feature in the ribbon) and then each user has their own front end file which links to the common single back end file.
Then there should be no changing occurring to references once they are set up for a user's environment.

How can I set user-level security from VBA on a different opened database?

I have a frontend Microsoft Access .mde database that connects to two backends simultaneously. I also give the user the option to link to a sandbox mode backend that resides on their local computer. While I'm developing the frontend, I stay linked to my local version of the sandbox so that I don't mess with the two backends. Sometimes, I want to reset my sandbox to match the data in the backends. The sandbox is a little different in that I combine the two backends together into one. (One of the backends is just log data, so I delete that data after it's in my new sandbox.) I have the process of copying the files and data fairly automated through VBA.
I want to also automate setting the permissions on the new sandbox file after it is copied. The sandbox file should have much more lenient permissions since its data really doesn't matter. I keep getting the error "Object not set." after trying to obtain the Tables collection in VBA in the sandbox file from my developer frontend. I have deduced that I am able to see the Containers and corresponding Documents in the frontend developer file, but I am not able to see them from the frontend developer file when I try to access them programmatically.
I'm assuming that this must be some built-in security feature of Access. Perhaps Microsoft doesn't want to allow a file to modify the security of a different file. Here is some of my code to help you see what I'm doing.
All of these databases utilize the same user-level security .mdw file residing on the server. The database was originally created in Access 2000, but I have since upgraded to Access 2010. However, the I maintain the original Access 2000 file format to be able to utilize the built-in multi-user security.
Public Function CorrectSandbox()
Dim appBackend As Application
Dim appLog As Application
Dim appSandbox As Application
Dim tdf As TableDef
Dim i As Long
Dim doc As DAO.Document
Dim ctr As DAO.Container
'copy the files
mFile.DeleteFile LOCAL_SANDBOX_PATH
mFile.CopyFile PRODUCTION_PATH, LOCAL_SANDBOX_PATH
'copy the log tables
Set appSandbox = OpenSandbox()
Set appLog = OpenLog()
For Each tdf In appLog.CurrentDb().TableDefs
If Left$(tdf.Name, 1) = "_" Then
appSandbox.DoCmd.TransferDatabase acImport, "Microsoft Access", GetAdminPath(eLive), acTable, tdf.Name, tdf.Name, True
'Set permissions for the object accordingly
Set ctr = appSandbox.CurrentDb().Containers!Tables
Set doc = ctr.Documents(tdf.Name) '*** ERROR: Object not set
doc.UserName = "User"
doc.Permissions = 852222
End If
Next tdf
appLog.Quit
appSandbox.Quit
End Function

What is this Access bug? You do not have exclusive access to the database at this time

Tested on Access 2003 Pro (build 11.8321.8324) SP3.
Steps to reproduce:
create a new database.
create a new form.
put a button on the form.
paste the following code in the button's Click event procedure:
Debug.Print Workspaces.Count
Debug.Print CurrentDb.Name
close the code editor and form, saving changes.
do not skip this step: close Access.
re-open Access and your database.
open the form
click the button
click the toolbar button to switch the form to design mode.
You should see the following error dialog:
You do not have exclusive access to the database at this time. If you proceed to make changes, you may not be able to save them later.
Does anyone know what is going on here?
The simple workaround is to call CurrentDb prior to calling Workspaces for the first time:
Debug.Print CurrentDb.Name
Debug.Print Workspaces.Count
Debug.Print CurrentDb.Name
I'll take a shot at demystifying what's going on, but this is just my theory.
The relevant bits of the Access help file are as follows (for CurrentDb):
Note In previous versions of
Microsoft Access, you may have used
the syntax
DBEngine.Workspaces(0).Databases(0) or
DBEngine(0)(0) to return a pointer to
the current database. In Microsoft
Access 2000, you should use the
CurrentDb method instead. The
CurrentDb method creates another
instance of the current database,
while the DBEngine(0)(0) syntax refers
to the open copy of the current
database. The CurrentDb method enables
you to create more than one variable
of type Database that refers to the
current database. Microsoft Access
still supports the DBEngine(0)(0)
syntax, but you should consider making
this modification to your code in
order to avoid possible conflicts in a
multiuser database.
And for the Workspaces collection:
When you first refer to or use a
Workspace object, you automatically
create the default workspace,
DBEngine.Workspaces(0).
It would seem that by creating the default workspace prior to the first call to CurrentDb, you are somehow causing CurrentDb to forget how it should work. It seems that instead of creating a new instance of the current database it just uses the one that's already lying around in the default Workspace.
Of course, this is all conjecture and I'm as curious as you to know the "real answer".

In VBA, cannot use Access.Application object

This does NOT work:
Sub X()
Dim A As Access.Application
Set A = CreateObject("Access.Application")
'Do Stuff
End Sub
However, this DOES work:
Sub X()
Dim A As Object
Set A = CreateObject("Access.Application")
'Do Stuff
End Sub
I know they do virtually the same thing, but can anyone tell me how to make an access.application object? I should add that I have Crystal Reports 11 and on my last upgrade, it may have 'unregistered' some VBA DLLs.
(Update 2009-06-29)
In response to the first 2 questions, I am using MS Access VBA to control some other Access & Excel files. Since this will only ever run on my local machine, I can guarantee that Access will always be installed. I have also referenced the "Microsoft Access 11.0 Object Library" (MSACC.OLB).
I know there's ways around this, i.e. use early binding when coding, and switch to late binding when running it, I just don't understand why the early binding method doesn't work at all on my machine (Of course, the code works fine on another machine with Access).
If you are writing this in Access there is no need to do that as the Application object is already there for you. If you are writing this in Excel or Word then you need to add a reference to the Access Library. Go to Tools/References and look for Microsoft Access XX Object Library
Hello,The code that you say is not working is legal syntax. What error are you getting? When does it occur? Do you know the line of code it happens at?
Just as a side note, this is legal syntax as well: Dim accApp As Access.Application
Set accApp = New Access.Application
But to be clear, the CreateObject Syntax is legal and not the source of the problem.
Try Detect And Repair from the Help menu in MS Access. Worked perfect for me.