If you work with Access databases, forms, or reports, you'll find many opportunities for customizing Access using VBA to streamline your work and that of your colleagues. Depending on the purposes for which you use Access, you might program Access to automatically extract data sets you need, to create custom reports on a regular schedule, and to perform many other tasks.
Even if your work in Access consists simply of entering data into databases and checking that it is correct, you may be able to program VBA to make mundane tasks less onerous. For example, you might use VBA to simplify the process of data entry or to validate the data that the user enters to avoid problems further down the line.
This chapter first shows you how to get started with VBA in Access because Access implements VBA in a different way from the other applications this book has discussed. You'll then come to grips with the Access object model and learn about its most important creatable objects. After that, the chapter shows you how to open and close databases, set startup properties for a database, work with the Screen object, and use the DoCmd object to run Access commands.
The next chapter discusses how to manipulate the data in an Access database via VBA.
In this chapter you will learn to do the following:
Access implements VBA differently than the other Office applications do. Here are the main differences:
The following sections provide a complete, start-to-finish example of how to work with VBA in Access. You create a module, then write a procedure in that module, and finally, use the Macro Designer to create an Access-style macro whose sole purpose is to start the execution of the VBA procedure.
This chapter shows you how to create “macros” in Access, so first you need to ensure that macros are, in fact, enabled in Access. Follow these steps to enable Access macros:
To create a module where you can write VBA code, open an Access database and click the Ribbon's Database Tools tab. Click the Visual Basic button on the Ribbon (or simply press Alt+F11).
The VBA Editor opens. Choose Insert Module in the VBA Editor or right-click the project's name (it's boldface) in the Project Explorer pane, and choose Insert Module from the shortcut menu.
After creating a VBA module in the VBA Editor, you can create a function within it as described earlier in this book. The following example creates a function named Standard_Setup that simply displays a message box to indicate that it is running (the next section uses this macro as an example):
Public Function Standard_Setup() 'put your choice of commands here MsgBox "The Standard_Setup macro is running." End Function
You can test this code as usual by clicking somewhere inside the procedure, then pressing F5.
After creating the function, switch back to Access by pressing Alt+F11 or clicking the View Microsoft Access button on the far left of the Standard toolbar in the VBA Editor. Of course, you could also use the traditional Windows Alt+Tab shortcut.
Although this and the next chapter focus on automating Access via the more flexible and powerful VBA language, some readers may be interested to know how to work with the Macro Designer tool. So we'll explore it briefly before moving on to VBA examples.
Recall that a user can't directly trigger a VBA procedure interactively from the main Access interface (although you, the programmer, can press F5 to test procedures in the VBA Editor). You'll find no Macros dialog box like the one in Word and other Office 2013 applications. True, there is a Run Macro button on the Database Tools tab of the Access Ribbon, but this feature cannot directly trigger a VBA procedure. (It only triggers an Access-style macro.)
For a user to run a VBA procedure, you have to create an Access-style macro that was built using Access's Macro Designer. You use the RunCode action (command) to call the VBA procedure. We'll see how to do that now:
The user can execute Access-style macros when the Macro Designer is closed. Just doubleclick test in the All Access Objects list (the pane on the left side of the main window). It may be necessary to click the small down arrow at the top of this pane and choose Show All.
Or the user can click the Database Tools tab of the Ribbon, then click the Run Macro icon on the Macro section (it too has a red exclamation point). Access's Run Macro dialog box opens. Select test as the macro name you want to run, then click OK to close the dialog box and execute your macro.
THREE WAYS TO EXECUTE AN ACCESS-STYLE MACRO
To sum up, a user can execute an Access-style macro only three ways:
Add a button to the Quick Access Toolbar by following these steps:
Note that you can't trigger a macro from a keyboard shortcut (Access doesn't permit you to create custom keyboard shortcuts).
Given that VBA is far more powerful than the Access-style macros, you might want to convert an Access-style macro into VBA to enhance it. You can have Access automatically translate Access-style macros into VBA functions. Follow these steps:
'------------------------------------------------------------ 'test1 ' '------------------------------------------------------------ Function test1() On Error GoTo test1_Err Run_SampleProcedure test1_Exit: Exit Function test1_Err: MsgBox Error$ Resume test1_Exit End Function
If you opted to avoid the error trapping and commenting, it's simpler:
'------------------------------------------------------------ 'test1 ' '------------------------------------------------------------ Function test1() Run_SampleProcedure End Function
To set up preconditions for an Access session, you can use an AutoExec macro. When Access starts running, it checks to see if there is a macro named AutoExec. If so, that macro is executed (runs) automatically when Access opens. This AutoExec feature is also available in other Office applications, like Word.
For example, you might choose to maximize the application window, open a particular item (for example, a table), or display a particular record. Note that AutoExec must be the name of an Access-style macro, not a VBA procedure.
By the way, you can prevent an AutoExec macro from running when you open a database by holding down the Shift key while the database opens.
To create an AutoExec macro, start a new macro as described in the previous section, add to it the actions that you want the macro to perform, and save it with the special reserved name AutoExec. The macro then runs the next time you open the database.
We'll now turn our attention to regular VBA programming, but if you're interested in learning more about the Macro Designer, see the tutorial on this web page:
http://blogs.msdn.com/access/archive/2009/07/28/meet-the-access-2010-macro-designer.aspx
Until now, you've mostly created traditional subs when writing or recording a macro. And for consistency, the Access VBA code examples in this chapter and elsewhere will also be subs.
But beware. If you want to permit the user to execute Access VBA procedures, they must be turned into functions. Just replace the word Sub with Function in your code. VBA will then automatically change the line at the end of your procedure from End Sub to End Function. Easy enough.
So, just remember that in this way, and many others, Access differs from other Office applications. When you're writing a VBA macro in Access, there's no good reason to create Access VBA code in a subprocedure rather than in a function because a sub cannot be triggered directly in Access.
Only functions can be directly triggered, as the example in the previous section illustrated. If you feel you must create a Sub, the only way to execute it is to create a function that, in turn, has the single job of executing your subprocedure. So what is the point?
This function triggering indirection is clumsy, but it can be made to work if for some unimaginable reason you want to use a sub procedure. Here is a simple example:
Sub SampleProcedure() MsgBox "The subprocedure named Sample Procedure is running." End Sub
Public Function Run_SampleProcedure() Call SampleProcedure End Function
When you launch the VBA Editor in Access (by pressing Alt+F11 or clicking the Visual Basic button on the Ribbon's Database Tools tab) and then insert a code module you'll notice that Access automatically enters an Option Compare Database statement in the General Declarations area of the Code window.
As an aside, recall that if you've selected the Require Variable Declaration check box on the Editor tab of the VBA Editor Options dialog box (Tools Options) to make the VBA Editor force you to declare all variables explicitly, you'll see an Option Explicit statement in the General Declarations area as well.
Access supports three different ways of comparing text strings: Option Compare Database, Option Compare Binary, and Option Compare Text. Here's what these options mean:
It's not crucial to understand how the Access object model fits together in order to work with VBA in Access, but most people find it helpful to know the main objects in the object model. And sometimes the code examples in the Help system's object-model reference can be invaluable—showing you how and where to employ objects in your own programming.
To explore the Access object model, follow these steps:
Access exposes (makes available for your use in code) various creatable objects, meaning that you can employ most of the important objects in its object model without explicitly going through (mentioning in your code) the Application object.
For most programming purposes, these creatable objects are the most commonly used objects. The main creatable objects in Access are as follows:
The following sections show you how to open and close databases. You can use the CurrentDb method to return the current database, open a database and treat it as the current database, or even open multiple databases at once. You can also create and remove workspaces.
To work with the database that's currently open in Access, use the CurrentDb method on the Application object or an object variable representing the Application object. The CurrentDb method returns a Database object variable representing the currently open database that has the focus.
The following example declares an object variable of the Database type named myDatabase and then uses the CurrentDb method to assign the active database to it:
Dim myDatabase As Database Set myDatabase = Application.CurrentDb
In Access, you can choose from among several ways of opening and closing a database. This section discusses the simplest method of opening and closing a database—by treating it as the current database. This method is similar to opening and closing a database when working interactively in Access. See the next section for another method of opening and closing databases that lets you have two or more databases open at the same time.
To open a database as the current database, use the OpenCurrentDatabase method of the Application object. The syntax is as follows:
expression.OpenCurrentDatabase(Filepath, Exclusive, bstrPassword)
Here are the components of the syntax:
To close the current database, use the CloseCurrentDatabase method with the Application object. This method takes no arguments.
You can run the CloseCurrentDatabase method from the current database, but you can't do anything after that because the code stops after VBA executes the CloseCurrentDatabase method and the database containing the code closes. To close the current database and open another by using the OpenCurrentDatabase method, you must run the code from outside the databases involved—for example, by using automation from another application. Chapter 30, “Accessing One Application from Another Application,” describes this technique.
PREPARE THE NORTHWIND DATABASE TO USE WITH THIS BOOK'S EXAMPLES
To test and experiment with some of the Access code examples in this and the following chapters, you need to do a little preliminary housekeeping. Put simply, we all need to be experimenting with the same database so we get the same results.
Traditionally, when authors have written about Access, they've employed a sample database named Northwind that Microsoft included with Access. Northwind is a full-featured and therefore useful example database. It can be particularly valuable when you want to experiment with Access but don't want to use your own database (both to keep it safe and because your database might not have some of the features that Northwind has).
I'll use Northwind in some of the examples in this book so that all readers can be working with the same data and the same structures. Therefore, before you test some of the upcoming code examples, please put a copy of Northwind.accdt in your C:Temp directory so the example code in this book can locate it. If you don't have a C:Temp directory, create one.
You may already have Northwind on your hard drive. To see if you do, press the Start button to display the Windows 8 Modern home page, and type Northwind.accdt. Then click the Files search option in the right pane. If it shows up in the search, right-click it, choose Open File Location, then copy it and paste it into your C:Temp directory.
Then double-click this Northwind.accdt file. It will open in Access. Give the database the name Northwind and save it to C:Temp. You want to end up with a file named Northwind.accdb in your C:Temp directory.
If you don't find Northwind.accdt on your hard drive, you can download it from Microsoft's website:
http://office.microsoft.com/en-us/templates/TC012289971033.aspx
The downloaded file will be named TS01128997.accdt. At some point Windows may ask your permission to download or install an ActiveX object. Agree to that. Don't worry; just double-click 01228997.accdt to open Northwind in Access. You'll see the File New Database dialog box open. In the File Name field, change the name to Northwind.accdb and click OK to close the File New Database dialog box and save Northwind.accdb to C:Temp. As I said earlier, you want to end up with a file named Northwind.accdb in your C:Temp directory.
Now the code examples in this book can reference this file path to open Northwind:
filepath:="C:TempNorthwind.accdb"
Next you'll want to remove the default login dialog box so you can work with the database more easily from code. Open Northwind.accdb by double-clicking its name in Windows Explorer.
By default a login dialog box appears asking you to select one of the “employees” from this imaginary company. Click the Login button to close the dialog box and see Northwind in Access.
If it's not already open, click the >> symbol in Access's left pane to open the Navigation pane. Locate the Supporting Objects entry in the Navigation pane and click it to expand it. Scroll down until you locate the macro named AutoExec. Right-click AutoExec, choose Cut from the context menu, and then close Access.
Now that login dialog box won't interrupt you any more when you open the Northwind example database.
There's an additional requirement when you're writing code that communicates between Office applications. You can't simply declare an object variable to point to an application object, like this:
Dim myAccess As Access.Application
This code will run only if you first provide a reference in the host application. For example, if you're trying to manipulate Access from VBA code within a Word macro, you need to set a reference in Word's VBA Editor.
The following example illustrates a way to contact and manipulate Access from another VBA host—for example, from Excel or from Word. But before you can execute this code from Word or some other application, you must first choose Tools References in the Word VBA Editor, then select Microsoft Access 15.0 Object Library from the drop-down list. For this example, you must also have a database currently loaded and running in an instance of Access.
This next example declares the object variable myAccess as the Access.Application type and the object variable myDatabase as the Object type. The example uses the GetObject method to assign to myAccess the copy of Access that's running, uses the CloseCurrentDatabase method to close this database, and then uses the OpenCurrentDatabase method to open another database, namely Northwind, in Exclusive mode. The final statement uses the CurrentDb method to assign the open database to the myDatabase object variable:
Dim myAccess As Access.Application Dim myDatabase As Object Set myAccess = GetObject(, "Access.Application") myAccess.CloseCurrentDatabase myAccess.OpenCurrentDatabase _ filepath:="C:TempNorthwind.accdb", Exclusive:=True Set myDatabase = myAccess.CurrentDb
When you test this code by executing it in the Word VBA Editor, you'll know it works because whatever database was open in Access will be replaced by Northwind (see the “Prepare the Northwind Database to Use with This Book's Examples” sidebar). Also note that when running this code, you might get an error message saying “User-defined type not defined.” And the Editor will highlight this line of code:
Dim myAccess As Access.Application
This means that the editor can't locate the object named Access. For reasons unknown, a newly added library is sometimes deselected in References. To fix this problem, just repeat the steps described previously to use Tools References to add a reference to the Microsoft Access 15.0 Object Library again.
Instead of using the OpenCurrentDatabase method to open a database as the current database, you can use the OpenDatabase method of the Workspace object to open another database and return a reference to the Database object representing it. The syntax for the OpenDatabase method is as follows:
Set database = workspace.OpenDatabase (Name, Options, ReadOnly, Connect)
CREATING NEW DATABASES, FORMS, AND REPORTS IN ACCESS
The discussions of the other Office applications in this part of the book (Part 6) have emphasized creating and saving new files—for example, creating new documents in Word or new workbooks in Excel and saving them under suitable names and in the appropriate formats.
Access, too, has its own VBA commands for creating new databases, forms, reports, tables, and other objects programmatically:
While creating a new database programmatically is quite feasible, it is not only complex but also something that you probably won't need to do often, if ever. In most cases, the goal of your Access VBA programming will be to manipulate existing databases and objects that you have built manually.
Here are the components of the syntax:
The following example “opens” the Northwind database in a special sense: it's opened behind the scenes for our code to contact it and have access to its data, structure, and other features. But it is not opened in Access where the user can see it. In other words, an instance of the database is fully exposed to our code, but there's no user interface. There's no display in Access of the Northwind database. For this reason, I've included a message box in the code example to prove to you that the code example has actually opened Northwind and fetched some data from it.
Also, when you use this invisible database technique, it's a good idea to finish up by closing any recordsets or other objects you've opened, as well as closing the database instance itself. This way, unattached and useless entities aren't left floating in your computer's memory.
This example will not work if you have Northwind open in Access. You must test this code while a different database is open in Access.
This example declares a Workspace object variable named myWorkspace and a Database object variable named myDatabase, assigns to myWorkspace the first Workspace object in the Workspaces collection (the default workspace), and assigns to myDatabase the database Northwind.accdb, which it opens in Exclusive mode with read/write access.
To show you that Northwind did come into existence, we fetch the City data from the first record in the Customers table. Finally, we display the city name, then clean up memory by closing both the recordset and the database instance.
You can try this by entering this code in a module in the Access VBA Editor, but just do this while some database other than Northwind is open in Access. Press F5, and you'll see the city data.
Sub test() Dim myWorkspace As Workspace Set myWorkspace = DBEngine.Workspaces(0) Dim myDatabase As Database Dim RecSet As Recordset Set myDatabase = myWorkspace.OpenDatabase _ (Name:="C: emp orthwind.accdb", _ Options:=True, ReadOnly:=False) Set RecSet = myDatabase.OpenRecordset("Customers", dbOpenDynaset) MsgBox RecSet!City RecSet.Close myDatabase.Close End Sub
To close a database that you've opened by using the OpenDatabase method, use the Close method of the object variable to which you've assigned the database. For example, the following statement closes the database assigned to the object variable myDatabase:
myDatabase.Close
To keep different databases in separate sessions, you can create a new workspace as needed and remove it when you have finished working with it.
To create a new workspace, use the CreateWorkspace method of the DBEngine object.
The syntax is as follows:
Set workspace = CreateWorkspace(Name, UserName, Password, UseType)
Here are the components of the syntax:
The following example declares an object variable named myWorkspace of the Workspace type and assigns to it a new Jet workspace named Workspace2. The example makes the admin account the owner of the new workspace:
Dim myWorkspace As Workspace Set myWorkspace = CreateWorkspace(Name:="Workspace2", _ UserName:="admin", Password:="", UseType:=dbUseJet)
After creating a new workspace, you can use it to open a new database (as described earlier in this chapter).
Before removing a workspace from the Workspaces collection, you must close all the open connections and databases. You can then use the Close method to close the Workspace object. For example, the following statement closes the Workspace object identified by the object variable myWorkspace:
myWorkspace.Close
If you've used VBA in the other Office applications, you've probably written code that works with whichever object is currently active. For example, in Word you can use the ActiveDocument object to work with the active document or the Selection object to work with the current selection. In PowerPoint you can work with the ActivePresentation object to work with whichever presentation happens to be active.
In Access, you can use the Screen object to work with the form, report, or control that has the focus. The Screen object has various properties, including the following:
To avoid errors, you should check which object is active before trying to manipulate it by using the Screen object. The following example uses the these listed error numbers to determine whether a form, report, datasheet, or data access page is active and then displays a message box identifying the item and giving its name:
On Error Resume Next Dim strName As String Dim strType As String strType = "Form" strName = Screen.ActiveForm.Name If Err = 2475 Then Err = 0 strType = "Report" strName = Screen.ActiveReport.Name If Err = 2476 Then Err = 0 strType = "Data access page" strName = Screen.ActiveDataAccessPage.Name If Err = 2022 Then Err = 0 strType = "Datasheet" strName = Screen.ActiveDatasheet.Name End If End If End If
MsgBox "The current Screen object is a " & strType & vbCr _ & vbCr & "Screen object name: " & strName, _ vbOKOnly + vbInformation, "Current Screen Object"
If you test this, use the Create tab on the Ribbon (and click the Form icon) to ensure that there is a form active in Access.
The DoCmd object enables you to execute normal Access commands, such as Find or Rename, in your VBA code.
To run a command, you use one of the methods of the DoCmd object. Table 28.1 lists the 66 DoCmd methods available in Access 2013 and explains briefly what they do.
The following sections include examples showing how to use some of the methods described in Table 28.1.
To open a form, use the OpenForm method of the DoCmd object. The syntax is as follows:
expression.OpenForm(FormName, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs)
Here are the components of the syntax:
The following example uses the DoCmd object to open a form in the Northwind sample database (you must have this database open in Access for this to work). Press Alt+F11 to open Access's VBA Editor, and then type in this code. When you execute the code by pressing F5, Access displays the first record for which the Employee field matches Jan Kotas:
Sub test () DoCmd.OpenForm FormName:="Sales Analysis Form", View:=acNormal, _ WhereCondition:="Employee ='Jan Kotas'" End Sub
To print an object, use the PrintOut method. The syntax is as follows:
expression.PrintOut(PrintRange, PageFrom, PageTo, PrintQuality, Copies, CollateCopies)
Here are the components of the syntax:
The following example prints one copy (the default) of the first page in the active object at full quality without collating the copies:
DoCmd.PrintOut PrintRange:=acPages, _ PageFrom:=1, PageTo:=1, CollateCopies:=False
Be sure to trap this code for an error in case you've requested a printout of something that doesn't exist—such as a range of 1 to 4 for a single-page form. In fact, it's always a good idea to trap errors in code that contacts peripherals such as printers or hard drives. What if the printer isn't turned on or the hard drive is full? Your code should anticipate and manage situations like these.
To run an Access-style macro, use the RunMacro method. The syntax is as follows:
expression.RunMacro(MacroName, RepeatCount, RepeatExpression)
Here are the components of the syntax:
The following example runs an Access-style macro named RemoveDuplicates:
DoCmd.RunMacro "RemoveDuplicates"
Get started with VBA in Access. Access allows you to write macros in a VBA Editor using VBA code. But it also features a legacy Macro Designer utility (formerly known as the Macro Builder) with which you create an entirely different kind of macro, what we've been calling an Access-style macro.
Master It The term macro is used in a special way in Access (referring to only one of the two types of custom procedures Access permits you to construct: VBA and Macro Designer). This usage of macro is unlike the way the term macro is used in other Office applications, not to mention all other forms of computing. Describe what Access means by the term macro.
Open and close databases. Access permits you to open a database in several ways.
Master It Two common commands that open a database in Access are OpenCurrentDatabase and OpenDatabase. What is the difference between these two commands?
Work with the Screen object. You became familiar with using ActiveDocument objects in Word to access the document that currently has the focus. Or you used the ActivePresentation object to work with whichever presentation happened to be active in PowerPoint. Access, however, employs the Screen object as the parent of whatever object has the focus.
Master It The Screen object represents the screen object that currently has the focus in Access (that is, the object that is receiving input or ready to receive input). Three types of common Access objects can have the focus when you employ the Screen object. What are they?
Use the DoCmd object to run Access commands. Many of the tools that Access makes available to users, such as printing a report or maximizing a window, are also available to the programmer via the methods of the DoCmd object.
Master It The DoCmd object has 66 methods in Office 2013. Describe the purpose of the DoCmd object's Beep method.
18.118.171.147