196

Microsoft Access for Beginners

Embed Size (px)

DESCRIPTION

This book is an introduction to Microsoft Access intended for people who have never used the program before and might even be unfamiliar with databases in general. It presents the basic concepts of relational database systems as well as specific things that can be accomplished with Microsoft Access. All areas, including table design and data entry, reporting and automation are covered with the beginner in mind. The goal is to help you understand database concepts and build a good foundation on which to continue learning and designing your own applications."Microsoft Access for Beginners" is more than a step by step tutorial; its purpose is to show you how to use Access well. This book has been thoroughly reviewed and updated for Office Access 2010. The second edition has been expanded with an introduction to Visual Basic for Applications, the programming language behind Microsoft Access which equips you to create fully functional and robust applications with Access.Acknowledging that there are still many users of the previous Access versions, this book continues to support multiple versions of the software with a focus on Access 2007 and Office Access 2010.

Citation preview

Page 1: Microsoft Access for Beginners
Page 2: Microsoft Access for Beginners

Microsoft Access for BeginnersCopyright © 2013 - Andrew ComeauAll Rights Reserved

For information regarding this book, please contact:

Andrew ComeauP.O. Box 770253Ocala, Florida [email protected]://www.AndrewComeau.com

Microsoft and product names including Microsoft Access, Microsoft Excel and Microsoft SQL Server are registered trademarks of Microsoft Corporation in the United States and other countries.

Proper names and contact information used as examples in this book including company and individual names are fictitious. No association with any real organization or individual is intended or should be inferred.

Page 3: Microsoft Access for Beginners

Contents

Introduction..............................................................................................................................................1Using the Sample Database....................................................................................................................3Interface Guide........................................................................................................................................6Chapter I - Creating the Database...........................................................................................................9

A Different Set of Tools.......................................................................................................................9Creating a New Database.................................................................................................................12Conclusion.........................................................................................................................................16

Chapter II - Organizing the Data............................................................................................................17A Structure for Your Data..................................................................................................................17Database Normalization Overview....................................................................................................27Conclusion.........................................................................................................................................30

Chapter III - Building the Tables............................................................................................................31Introduction........................................................................................................................................31Creating a Table................................................................................................................................31Relating Tables..................................................................................................................................42Conclusion.........................................................................................................................................44

Chapter IV - Writing the Queries...........................................................................................................46Introduction........................................................................................................................................46Background.......................................................................................................................................46The LeadsList Query.........................................................................................................................48Conclusion.........................................................................................................................................57

Chapter V - Understanding SQL............................................................................................................58Selecting Data...................................................................................................................................58Modifying Data...................................................................................................................................63Conclusion.........................................................................................................................................67

Chapter VI - Designing the Forms.........................................................................................................68Introduction........................................................................................................................................68A Word about VBA............................................................................................................................69Data Sources.....................................................................................................................................69Creating the Form.............................................................................................................................71Additional Controls............................................................................................................................80Conclusion.........................................................................................................................................90

Chapter VII - Generating the Reports....................................................................................................91Introduction........................................................................................................................................91From Forms to Reports.....................................................................................................................91Creating a Report..............................................................................................................................91Sample Reports.................................................................................................................................94Managing the Interface....................................................................................................................101Conclusion.......................................................................................................................................102

Chapter VIII - Automating the Interface with Macros..........................................................................103Introduction......................................................................................................................................103Access 2007 and Earlier.................................................................................................................103Access 2010....................................................................................................................................108Conclusion.......................................................................................................................................111

Chapter IX - Introducing Visual Basic for Applications........................................................................113Introduction......................................................................................................................................113What is Visual Basic for Applications?............................................................................................113The VBA Environment.....................................................................................................................117Variables..........................................................................................................................................123

Page 4: Microsoft Access for Beginners

Contents (continued)

Procedures......................................................................................................................................130Arrays and Enumerations................................................................................................................138Operators.........................................................................................................................................145Using DoCmd..................................................................................................................................148Decision Structures.........................................................................................................................151Program Loops................................................................................................................................156Error Handling.................................................................................................................................162Algorithms........................................................................................................................................168

Appendix I - "Where do I go from here?".............................................................................................173Appendix II - Using Lookup Fields.......................................................................................................175Appendix III - Glossary........................................................................................................................180Suggested Reading and References..................................................................................................190

Books...............................................................................................................................................190Links................................................................................................................................................190

Page 5: Microsoft Access for Beginners

Microsoft Access for Beginners

IntroductionThis book started out as a series of articles on my website at Drewslair.com. I decided to write the series after answering questions about Microsoft Access as a result of my work with it and talking to people who didn't understand exactly what Access was or how it compared to other programs in Microsoft Office. I've seen many examples of databases created by people who approach Access in the same way as they would use Excel, setting up one table to hold everything and duplicating data as necessary.

It's understandable that many people try to use Access this way as more people are familiar with the spreadsheet concept than database concepts. Access presents tables that look something like the spreadsheet format that people are used to and, since it's offered as part of the Microsoft Office suite, it's easy to see it in relation to the other programs and overlook its power as a standalone product.

Microsoft Access is significantly different than any of the other Office applications, however. While programs like Word and Excel focus on documents, Access files are database applications that contain a variety of objects such as tables, forms and reports, all of which work together to organize and manage your data. The most sophisticated Access databases function as programs in and of themselves with user interfaces made up of forms, reports and custom menu systems. Access is even used by some programmers to design sophisticated, standalone systems for fields such as document management, customer relations and inventory tracking.

Before you design the next software sensation however, you need to learn some basic database and design concepts so you can use Access to its full potential. I consider this book to be a mid-level introduction to Microsoft Access as I don't spend a lot of time on step-by-step instructions. Instead, I introduce you to the basics of the program and provide enough information so you will understand how to correctly create tables and design queries to read from them. Then I show you what you can do with forms and reports. I also provide an introduction to SQL so you will better understand what queries do. I don't provide exhaustive detail on every feature but I do show you how to use Access well.

Most books about a program like Access focus only on the latest version but I take a different approach. As of this writing, the current version of Access is Office Access 2010. I primarily focus on the 2007 and 2010 versions but I also realize that there are still people using earlier versions so I've tried to ensure that these users will find the book helpful as well. Most of the concepts I write about here are common to all versions of the program and, where necessary, Igive specific instructions by version.

Page 1

Page 6: Microsoft Access for Beginners

Microsoft Access for Beginners

A Word on Design Wizards

For many of the objects in Access such as tables and forms, there are wizards that you can use to quickly create an object by answering a few questions and making a few selections. Microsoft Access even enables quick, wizard-based design of entire applications. The result is a ready-made solution designed to do exactly what you specified, whether that's what you wanted or not. In this book, I rarely mention the wizards because I don't use them for anything significant when designing a database. I don't believe that they are good tools for creating professional applications.

If you want to 'create' something you know nothing about and spend a lot of time thinking that itdoesn't meet your needs, then use the wizards. You don't need my help on that. On the other hand, if you want to take ownership of the project and be able to support it, do it yourself. You'lldevelop your skills that way and it's a lot more fun. Eventually, you will have a library of your own work that you can consult whenever you want to figure out how to do something. The Job Search Plus demo is an example of what can be done without design wizards. Throughout thisbook, I will show you how to create things on your own so you will learn how to design programs with Microsoft Access.

For More Information

This book is mainly about Microsoft Access and the principles behind its use. While knowing how to design robust database applications with Access is a very useful skill, it's only the beginning when it comes to mastering database design and programming. If you would like a broader perspective on the software options and principles in database design, please check out my other book; Your First Guide to Database Design. This book presents the basic concepts behind database design and provides examples of everyday activities that can be organized more effectively with the right database solution. The book also provides details on other database software including MySQL and Microsoft SQL Server. For more information, you can download a simple the book from Amazon.com, Barnes and Noble or my own site at AndrewComeau.com.

I welcome your comments and questions concerning the material presented here. You can e-mail me with any comments at [email protected].

Enjoy!Andrew ComeauOctober 2013

Page 2

Page 7: Microsoft Access for Beginners

Microsoft Access for Beginners

Using the Sample DatabaseThroughout this book, you'll see references and screenshots from a sample application that I adapted for use here. Job Search Plus is a program that I designed to help individuals organize all the information related to a job search including job lead details, company and contact information and search activities. It also features flexible reporting and an interface thatdemonstrates how Access can be used to design a professional application. The full program is available as a free download from AndrewComeau.com with multiple versions in order to accommodate people running different versions of Microsoft Access. There's even a version that includes the free Access runtime for those who do not have an Access installation.

You can find more information, an online manual and download links to all versions of the program at:

http://www.andrewcomeau.com/pages/jsmanual.htm.

The online manual contains links to the download files, installation instructions and a complete overview of the program.

Macro Security and Trusted Locations

Starting with Access 2003, Microsoft took extra steps to guard against the possibility of malicious code being distributed as part of Microsoft Access files. Access now notifies the userwhen opening a file of the possibility of malicious code. Depending on your version and settings, Access will even deactivate this code by default. As the sample database depends onVBA code for its operation, you need to be aware of the steps to allow the code to run.

Access 2003

Access 2003 had some relatively simple precautions against potentially unsafe code. Assuming that all the service pack updates are installed, you might just see a message like this when opening the sample database.

Page 3

Page 8: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure S.1 - Access 2003 unsafe code warning

Clicking on the Open button will open the database and run the necessary code. You can turn off this warning if you like by changing the macro security options under the Tools >> Macro >>Security menu. In the example in Figure S.2, I have the security set to Low which will run the code without warnings. The options under the Trusted Publishers tab enable the user to trust content from certain publishers although this requires the content to be signed with a security certificate which you might never encounter with Access databases.

Figure S.2 - Macro security options

Page 4

Page 9: Microsoft Access for Beginners

Microsoft Access for Beginners

Access 2007

In Access 2007, Microsoft introduced the Trust Center which enabled the user to trust content in specific locations on the computer. This enables you to define places on your computer where you know that the content is safe rather than changing the security setting for the entire Access application. When you open the sample database in Access 2007, you might see the following message bar:

Figure S.3 - Access 2007 active content security warning

You can enable the content for the current session by clicking the Options button and selecting'Enable this Content'. One of the choices on the Options screen is a link to open the Trust Center which can also be opened from the Access program options screen available from the Office 2007 Button. The Trust Center dialog provides options to manage the list of trusted locations on the local system. Adding locations such as the Windows Desktop or My Documents folder will allow content in these locations to be run without restriction.

Figure S.4 - Access 2007 Trust Center

For more information, see the MSDN article "Security Considerations and Guidance for Access

Page 5

Page 10: Microsoft Access for Beginners

Microsoft Access for Beginners

2007", the link for which is available in the Suggested References list at the end of this book. You can also find the article by searching on the above title at msdn.microsoft.com.

Access 2010

Access 2010 takes the trust settings down to the document level. Clicking the 'Enable Content'button on the security warning will permanently enable that database at that location. If you copy the database to another location or rename the database, you will get the warning again. The Trust Center is still available from the Actions Options panel which is available on the Access 2010 File tab.

The Trust Center in Access 2010 also has more options including the option to disable document trusting and clear the list of previously trusted documents.

Interface GuideAs mentioned in the Introduction, this book accommodates users of multiple versions of Microsoft Access. With Access 2007, Microsoft introduced some major changes to the Office interface that required users to learn where everything was all over again. These changes were refined in Access 2010. I've included a short explanation here so you'll know what I'm referring to in upcoming chapters.

Figure IG.1 - Access 2002 interface

In Access 2003 and earlier, Access used a standard menu and toolbar interface. Figure IG.1

Page 6

Page 11: Microsoft Access for Beginners

Microsoft Access for Beginners

shows the demonstration program with a customized menu system in Access 2002.

Office 2007 introduced the Office Button and Ribbon. The Office Button is a pull-down menu that replaces the old File menu. You can use it for file and print management functions, to close the database and to access the program options. The Ribbon groups all of the program functions under tabs according to category. Figure IG.2 shows the Office Button and many of the examples in this book show a customized ribbon that I created for the full version of Job Search Plus.

Figure IG.2 - Access 2007 interface

Office 2010 did away with the Office Button and returned its functions to a File tab on the Office Ribbon. Customizing the Ribbon is also easier in 2010. In Access 2007, it was necessary to create a special table containing custom XML code, Office Access 2010 providesan interface for adding and removing controls from the ribbon.

While the Ribbon interface took some time to get used to, I feel that it was a good move for Office. With the increasing number of features available in the programs, the ribbon makes it easier for users to find the one they need. The return of the Office Button features into the main ribbon interface was also an improvement.

If you're generally familiar with the way things work in Windows and Office, then you shouldn't have much of a problem switching between versions of Access but in this book, I do try to make things as easy as possible for users of all versions. While many features maintain the same interface between the various versions, I will provide an explanation for how to accomplish something in each version as necessary.

Page 7

Page 12: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure IG.3 - Access 2010 interface

Page 8

Page 13: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter I - Creating the Database

A Different Set of Tools

For many people, Microsoft Access is probably the most enigmatic of all the Microsoft Office applications. It's only included in the Professional editions of the suite or as a standalone package which means that most home users won't have it installed. People will often hang out in Word, Excel and Outlook but never have reason to wander into the database portion of the suite. The interface itself is unfamiliar to the average user who is more accustomed to a spreadsheet or blank word processing document than the collection of objects that Access presents. Even in Access 2007 and later, the ability to create entire applications from templates departs from the document focus that many users expect.

Those who do explore the features in Microsoft Access, however, find that it is likely the most powerful of all the Office applications with its ability to store and organize huge amounts of information in related tables, then query and sort the information as needed and finally present the data in attractive, professional reports. Custom data entry forms make it easy to enter and review data and guard against data entry errors. All of this is available even before a user might start playing around with Visual Basic for Applications, the programming language that enables users to create virtually any type of interactive application and turns Microsoft Access into a full development environment.

What is Access?

As a Windows desktop database, Microsoft Access provides many of the features of a Relational Database Management System (RDBMS). In order to understand what that means, we have to take the term a bit at a time.

A database is any collection of information that can be organized by a standard set of fields. Your address book is one classic example. Each entry in the book represents a record with fields such as Name, Address, Phone Number, etc.. A dictionary could also be considered a database with its standard entries including the word, pronunciation and definition. Databases might include relatively few records or tens of thousands of records, depending on the need.

A database management system such as Access enables this data to be stored electronically according to a set of rules. The tables in Microsoft Access organize the data and provide features that are common to databases such as indexes to make it easier to search and sort

Page 9

Page 14: Microsoft Access for Beginners

Microsoft Access for Beginners

the data, primary keys that identify each record with a unique value and validation rules that help to ensure the data conforms to the necessary limitations. Access also provides a way to retrieve and manipulate the data through queries. Finally, a database management system enables the creation of new databases as needed and can be used to manage large collections of separate database applications.

Access is also a relational database system. There are different types of database systems that are structured differently in order to serve various purposes. In a relational database:

1. Data is organized into tables which are sometimes called relations by database experts.This is because each table has a subject (i.e. Companies) and every field in a given table is supposed to be directly related to the subject of the table.

2. Tables can be linked or related to each other. This is demonstrated in the sample database by a link between the Leads and Activities tables. Since there can be more than one activity for each job lead, the Activities details are placed in a separate table and the two tables are linked by an ID number assigned to the job lead. This eliminates the duplicate entry of information such as job title or description. This, in turn, reduces the size of the database and the possibility of data entry error and database corruption.

This is how Access differs from a program like Excel. While Excel organizes information and allows for calculations and analyses, Access takes it a step further and enables relationships between different categories of data and faster analysis of information.

Figure 1.1 - Relational databases enable you to link different categories of data as shown in thisdiagram of two related tables.

Database experts will point out that Access lacks a couple of the features that would fully qualify it as a relational database system, however it is still a good tool for small to medium sized database applications and provides an excellent training ground for database and

Page 10

Page 15: Microsoft Access for Beginners

Microsoft Access for Beginners

programming concepts.

File Formats

Microsoft Access uses a single file to store all of the objects used in a database application including tables, queries and reports. This differs from other desktop database systems which might store queries and other items in separate files. The use of one file makes the databases very portable.

Despite the use of one file to store everything, Access applications can make use of external files by linking to data in other Access databases. This ability is commonly used to separate the data tables from the interface portion of an Access application by storing the tables in one Access database file (referred to as the back end) and linking to them from another Access filewhich stores the forms, reports and other items (the front end). This has a number of advantages, such as enabling multiple users to access the data at the same time from differentlocations and making it easier to change reports and forms without disrupting access to the data. Access can also link to data in other file formats, including Excel and Microsoft SQL Server. Access references the links to external data sources just like any other table.

Figure 1.2 - Access is able to link to other data formats.

Figure 1.2 shows the table listing from an Access 2007 database that includes a couple of linked sources. The ResultLog item is a linked Access table while LeadsImport is a link to an Excel file. When linking to other formats like Excel, Access will look for data structures such as worksheets or tables that can be read like an Access table and provides a wizard that will guide you through the process of linking to the data.

Microsoft Access has many file extensions that can be used for different types of applications such as templates and add-ins but there are only a couple that you need to be immediately familiar with. In Access 2007 / 2010, the .ACCDB file extension indicates a typical database that you would create and work with. The .ACCDE file extension indicates an Access databasethat has been protected against changes to the objects within it. The data can still be changed

Page 11

Page 16: Microsoft Access for Beginners

Microsoft Access for Beginners

but no design changes can be made to the tables or other objects. The corresponding file extensions in Access 2003 and earlier were .MDB and .MDE. As with other Office applications,Access is able to open and save files created in other versions of the software although there are limitations in the creation of the protected databases (.MDE / .ACCDE).

Figure 1.3 - A few of the extensions and file formats used by Access.

Protected Access databases are also used to protect programming code and design details within the database from being viewed or modified. The demonstration database for this book is distributed as an unprotected MDB file created in Access 2002. It can also be opened and modified in any version of Access after that.

Creating a New Database

Once installed, Microsoft Access adds itself to the New Object menu in Windows. From the File menu in any folder, or by right-clicking on the Window Desktop, select 'New' and then ‘Microsoft Access Application'. This will create a blank database which you can then renameand open within Access. The other way is to use the New command from the Office button in Access 2007 or from the File menu in all other versions and then choose 'Blank Database'.

Access offers a number of pre-designed templates and wizards that can help you create entire applications just by answering a few questions. These are great examples of applications and worth studying if you're new to Access but, as I said in the Introduction, I would not recommend them for use with real data. As complex as Access applications and the requirements for them can be, it is in your best interests to learn what you need to know to design and support your own database.

When you first open a database in Access, you can press F11 to show the database window if it's not already visible. This window will display all of the objects in the database. Figure 1.4 shows the Access 2007 window with the menu that enables you to change the objects listed.

Page 12

Page 17: Microsoft Access for Beginners

Microsoft Access for Beginners

In Figure 1.5, you can see an example of the window from the sample database.

Figure 1.4 - Access 2007 database window settings

Protecting your Database Design

Earlier, I mentioned the .MDE and .ACCDE formats available in Microsoft Access. These are protected database formats in which all design features are disabled and all editable code has been removed. Sometimes, if you are distributing your database application to other people, you might want to use one of these formats to prevent unauthorized users from making design changes or prevent access to your code.

Creating a protected database is pretty simple in any version of Access.

• In Access 2010, select 'Save & Publish' from the File menu and select 'Make ACCDE' under the advanced options.

• In Access 2007, select 'Make ACCDE' under the Database Tools tab of the Office Ribbon.

• In Access 2003 and previous, select the 'Make MDE File' menu option under the Tools >> Database Utilities menu.

The Microsoft Access file that you are trying to convert must be saved in the same version of Access in which you are working before creating a protected file, i.e. if you are working in Access 2007, you must be working with an ACCDB file in order to make an ACCDE. You cannot make an ACCDE file from an MDB. If the Make ACCDE / MDE command is grayed out,it's probably because the file you're working with was saved under a different version of Access.

When you create an ACCDE or MDE, a new file will be created separately from your ACCDB

Page 13

Page 18: Microsoft Access for Beginners

Microsoft Access for Beginners

or MDB file. It's important to keep the original file in which you can make design changes because the protected database that you just created cannot be used to recover the original file.

Database Objects

Other Office applications deal primarily with documents such as letters and spreadsheets but Access takes a different approach; the database file can contain many objects of different types which work together to provide the functions you need in your database program.

Tables are the heart of the database, storing your data and organizing it for quick retrieval. Access data is, ideally, stored according to certain principles that organize the data by subject and eliminate duplication. I will provide more details on this in Chapter II. In Chapter III, you'll see how to design the tables and use table properties in order to get the maximum benefit out of Access as a database.

Queries provide a way to retrieve and manipulate data stored in the tables. Access uses Structured Query Language (SQL) to perform any type of operation that's needed on the data or even the structure of the tables themselves. Beyond reading and manipulating data, queriescan act as data sources similar to tables, performing intermediary processing of the data and passing results on to other queries for further processing. Chapter IV provides additional information on queries and a beginners' guide to SQL is presented in Chapter V.

Forms provide a fast and customizable way to manage data within your program. Entering data directly into tables can be slow and prone to errors. Forms offer a wealth of tools and controls that will speed up your data entry and help prevent user errors. Chapter VI details some of the possibilities that are available with forms and how they can be used to create a professional user interface.

Chapter VII will get you started with reports which are essential to any data management system. The report designer is one of the greatest strengths of Microsoft Access. Access is loaded with features to help you analyze your data and all of these features come together in an easy-to-use report designer that will help you communicate the data to others within your organization.

Learning to use macros and modules is the next step once you've learned the basics of Microsoft Access. Chapter VIII introduces macros which are the most basic of programming features in Access, enabling you to automate basic tasks by scripting sequences of steps for Access to follow. Modules are used to hold advanced custom functions that you can create using Visual Basic for Applications (VBA). You'll see more information on them in Chapter IX.

Page 14

Page 19: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 1.5 - The database window shows all of the objects in the database in one place.

Compact and Repair

Microsoft Access database files are designed to hold up to two gigabytes of information, including your tables, forms, reports and other objects. The problem is that once the file grows to accommodate new data or design changes, it doesn't automatically let go of that space when data or objects are removed from the database. This can cause the database to grow quite large, especially during the design process when a lot of objects are being changed.

The solution for this is to use the Compact and Repair function in Access.

• Prior to Access 2007, the Compact / Repair function is available from the Tools >> Database Utilities menu.

• In Access 2007 and later, you can find it by clicking on the Office button and selecting 'Compact and Repair' from the Manage menu.

• In Access 2010, the Compact and Repair button is moved to the Database Tools tab of the Access ribbon.

Page 15

Page 20: Microsoft Access for Beginners

Microsoft Access for Beginners

Access will exit the database and create an entirely new database file from the old one, releasing the extra space. This process will also attempt to repair certain types of corruption in the database file.

Compact and Repair also resets certain counters in the database. For example, in a future chapter, you'll learn about AutoNumber fields which automatically generate a new unique number for each record that's entered into a table. These are often used for ID fields and are usually sequential. Compact and Repair will reset this number so that the next number used is continuous from the last one. This can be useful when you are first designing a database and entering and deleting a lot of test records in tables. Before releasing the database to other users, you should run a Compact and Repair which will reset those AutoNumber counters.

Compact and Repair is not foolproof for eliminating all wasted space or fixing errors. The Access file format holds on to temporary data that is not released even when compacting and there are some problems it won't fix. This is one reason backups are important. Be sure to backup your database often and before making any major changes to the design.

Conclusion

Microsoft Access is a little bit of a paradox; marketed as part of the Microsoft Office suite and yet providing enough functionality and power to stand on its own. Its ability to analyze data from a host of other programs makes it a valuable part of the Office environment and accessible to the average user. Yet, there are also people who have started programming careers by using Access to master the database and programming concepts involved in creating a great database application.

Whatever your goal with Access, the following chapters will provide you with all you need to know to start building databases and add some very valuable skills to your resume.

Page 16

Page 21: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter II - Organizing the Data

A Structure for Your Data

In Chapter I, I explained how a relational database enables you to categorize data by subject within your database and then create relationships between different categories so the data can be viewed according to those relationships. In this chapter, I want to explain the system that's used to do this. In the next chapter, I'll show you how to actually create and fine-tune tables but first, I need to show you the proper way to design what's called the database schema (pronounced SKEE-mah) which is the collection of related tables and other objects that form the structure of the database.

Beginning in 1970, a computer scientist at IBM, Edgar F. Codd, developed a set of rules by which data could be organized in relational databases such as Microsoft Access (although neither Microsoft or Access would be around for a few years at that point). This system is called Database Normalization and has become the accepted standard for designing relationaldatabases. The purpose of normalization is to simplify the updating of data and avoid inconsistencies and duplication within the database. It also makes adding new types of data to the database structure easier because there is already a context to build on.

While there are several rules in database normalization, also referred to as Normal Forms, there are only three that you really need to be concerned with when working with Microsoft Access. If you implement these three in your database, you will have a very stable and well-organized system.

The basic rules of normalization that you need to know at this point can be summed up as follows:

1. Table fields should be designed to hold single values that represent basic units of information.

2. There should be no repeating fields or groups of fields in a table. (i.e. Item1, Item2, Item3, etc..).

3. All fields in any given table should relate directly to that table's entire primary key and non-key fields should not be dependent on each other.

This is a very basic summary and I will present a more detailed explanation later in the chapter. First, let's see the rules in action in the Job Search Plus demonstration database.

Page 17

Page 22: Microsoft Access for Beginners

Microsoft Access for Beginners

Tables and Relationships

After downloading the demonstration database, start by opening the database in Access. Press the F11 key to show the database objects window. The database window will show you all the tables and other objects in the database.

Figure 2.1 - In all versions of Access, the database window is accessed by pressing F11.

Although the F11 key works in all versions, Access 2007 introduced some radical changes to the Access interface. While many screens look the same, some are different enough to be worth mentioning and I will note the differences as necessary.

One of the goals of a user-friendly Access database is to minimize the amount of work required to enter and retrieve the information, thereby reducing workload and the possibility of error. This is where the ability to group data into separate tables comes in handy. These tablesorganize the data so that it's easier to find and, as you'll see, they help to eliminate the need toenter the same information over and over again. The tables you create and the relationships between them are the backbone of your database. Once you have the tables designed correctly, you're halfway there.

Job Search Plus was designed to assist individuals in managing the information involved in a job search so the Leads table is the central table in the database and it contains the essential information for each job opportunity. In accordance with database normalization, Leads only contains the information that specifically relates to the job lead itself such as the date recorded,job title and description.

If you view the design of the Leads table by right-clicking on the table in the database window and selecting 'Design View', you will see by the key symbol next to the field name that the LeadID field is identified as the table's Primary Key. This means that the field contains a value that is unique for each record in the table, enabling the database to identify that particular record. Access encourages you to create a primary key for every table that you design.

Page 18

Page 23: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 2.2 - The table design view provides complete access to settings for the table and theindividual fields.

In the second column of the design view, you'll see the data types assigned to each field. Assigning specific data types to fields enables the database to more efficiently store the data and enforce rules for entering the data as needed. A number of types are shown in the Leads table including the Date/Time type which stores dates and enables date based calculations, the Yes/No type which stores a simple 'Yes' or 'No' value appropriate to checkbox options and the Number type which allows for a wide range of numeric formats. The data type assigned to the LeadID field is called an AutoNumber. This is a unique number assigned by the database to every record that the user enters and cannot be edited by the user.

For example, if you were creating an employee database, you would not want to use this number as an employee number within the company records because there is no guarantee that it won't skip values if records are canceled as they're being entered. It will also assign the numbers in the order that the records are entered while employee numbers are often assigned in order of hire. The main, and often the only, purpose of an AutoNumber primary key field such as LeadID is to create an identifier that the database can use to refer to each record.

The Activities table in the sample database, which lists actions for each job lead such as applications, correspondence and follow-ups, also has a field titled LeadID but the data type is Number instead of AutoNumber. In the Activities table, this field is referred to as the Foreign Key because it's used to relate records in Activities to the job lead records in Leads. The value originates in Leads as an AutoNumber that identifies a specific job lead and each record in the Activities table that relates to that job lead will use the identifying number from Leads to refer tothe correct Leads record. In Figure 2.3, you can see a relationship drawn between the two tables in the Relationships diagram. This relationship enforces the link between the LeadID field in each table.

Page 19

Page 24: Microsoft Access for Beginners

Microsoft Access for Beginners

In a later chapter, you'll see how forms use this relationship to automatically insert the correct LeadID value in the Activities table to link the records there to the right records in the Leads table.

Figure 2.3 - Relationships between tables use corresponding fields such as record IDs to linkdata. In this example, the LeadID field links the Leads and Activities tables.

Using the LeadID value in the Activity table as a unique identifier, rather than something like the job title field, saves space and allows for additional report functions that you will see later. The nature of the Leads table also means that there is no single field or even combination of fields that will be unique for each record. By using the number, the database knows exactly which Leads record each Activity corresponds to.

Sometimes it might be tempting to use a naturally unique value such as a Social Security Number or credit card number as a primary key, depending on what type of database you're building. I cannot stress this enough - NEVER use confidential information as a table key. You cannot prevent users from viewing table keys if they wish, especially if they're referenced by every other table as in this database.

This arrangement between the Leads and Activities tables is an example of how a relational database works. In a flat spreadsheet, you might see all of the Leads fields laid out and then repeating groups like 'Activity1', 'Activity2', 'Activity3', etc.. There are problems with that approach. First, it limits the number of activities that can be entered to an arbitrary number. It's also very difficult to search on. If you wanted to see all of the activities that involved a resume being sent, for example, you would have to search each of the fields separately. The approachshown in Figure 2.3, on the other hand, changes the direction of the data. The Activities table can hold an unlimited number of activities for each lead and uses the LeadID as an identifier for which Leads record is being referred to. It's also easily searched with a simple query.

In the bottom half of the table's design screen, you'll see some extra settings for each field. When adding fields to a table, you should pay particular attention to settings such as 'Field Size', 'Input Mask', 'Default Value', the validation settings and 'Required'. Proper use of these

Page 20

Page 25: Microsoft Access for Beginners

Microsoft Access for Beginners

settings will provide the controls needed to help ensure that data is accurately entered. I provide more information on these properties in the next chapter and you can get more information on any of them by placing the cursor in one of the setting boxes and pressing F1.

Types of Relationships

If you select 'Relationships' from the Access menu, it will bring up the relationship diagram for the database like the one shown in Figure 2.4. In Access 2007 / 2010, select the 'Relationships' option from the Database Tools tab on the Office Ribbon. In Access 2003 and prior versions, it's available from the Tools menu.

Figure 2.4 - The relationship diagram for the Job Search Plus sample database.

Page 21

Page 26: Microsoft Access for Beginners

Microsoft Access for Beginners

This is an interactive tool that you can use to view and manage relationships between tables. The relationship diagram for Job Search Plus might look complicated until you remember some of the things I've mentioned so far and notice relationship lines between ID fields in one table and corresponding fields in another. The link between Leads and Activities is one of these.

Many of the relationships travel in the other direction. Reference tables such as Companies or Contacts use an AutoNumber as a primary field and the Leads table stores that value to refer to a specific item.

At first, this diagram might also seem to contradict what I said about making data entry easier. Another aspect of a relational database, however, is that it can contain data that is entered once and then referenced many times. The Companies and Sources tables in the database are good examples of this. The Companies table is a reference or lookup table for the information related to companies on various leads. By putting this information in a separate table from the job leads, the company information can be entered once and then referenced asneeded. This is a lot better than having to enter a company name over and over again, hoping that it's always spelled right and then trying to retrieve all information on all leads related to a specific company.

By looking at the relationships between these tables, you can see how these relationships are defined. Double-clicking on an existing relationship line on the diagram in the database will bring up the Edit Relationships screen shown in Figure 2.5 where you can view the settings. In

the relationship between Leads and Activities, the 1 and symbols above the line indicate a One-To-Many relationship between the tables. This means that for every job opening listed in Leads, there can be many activities recorded.

Figure 2.5 - The Edit Relationships dialog

Back in the relationships window, you'll also notice that the direction of the arrow points to Activities. If you click on the Join Type button on the Edit Relationships panel, you can see that

Page 22

Page 27: Microsoft Access for Beginners

Microsoft Access for Beginners

the relationship is set to show all records from Leads and then any records in Activities that match those records. This will pull records from Leads even if there are no records for that job lead in Activities. It is referred to as an Outer Join. The first option on the Join Properties panel would pull only the records where the value for this field is present in both tables and this is called an Inner Join. In this case, job leads with no activities would not be listed and this might or might not be what you want. You'll see the importance of using the proper join type when you start designing queries to work with your table data as shown in an upcoming chapter.

A one-to-many relationship might be the most common type used but there are other types. A one-to-one relationship is formed when each record from the parent table can have no more than one corresponding record in the child table. The job search database does not have an example of this but one example would be a Human Resources database where the employeeaddress and contact information is split off into a separate table from the main employees tableas shown in Figure 2.7. This might be done to isolate the contact information for security purposes or simply to reduce the size of the main table.

Figure 2.6 - The Join Properties dialog

In order for the database to recognize the one-to-one relationship in this example, the employee and contact information tables would need to link on an Employee ID field. This ID field would be the primary key and an AutoNumber in the Employees table. In the contact information table, the corresponding EmployeeID field would be a regular numeric data type but would be set to prevent duplicate values so that a specific employee ID could only be used once in the table. Fields outside the primary key can be set to be unique as you will see later. When a relationship was created between the two tables using the corresponding EmployeeID fields, Access would recognize that the field was unique in both tables and see it as a one-to-one relationship.

Sometimes, a third type of relationship, a many-to-many relationship, is needed. Again, it's not used in the job search database but an example would be a student database tracking class registrations. A hypothetical relationship diagram is shown in Figure 2.8. For each class, there will be many students and each student will take more than one class. This is a many-to-many relationship. These relationships are not directly definable in Access so a third intervening table that breaks the relationship down into two one-to-many relationships is needed. This table is also known as a cross-reference table. In this example, a class registration table includes fields for the Student ID and the Class ID as well as any other information pertinent to

Page 23

Page 28: Microsoft Access for Beginners

Microsoft Access for Beginners

that student's registration in the class. This table then links to both the student and class tableson those fields.

Figure 2.7 - Another example of a relationship between parent and child tables.

Figure 2.8 - A many-to-many relationship with an intervening table.

Page 24

Page 29: Microsoft Access for Beginners

Microsoft Access for Beginners

Referential Integrity

In the bottom half of the Edit Relationships box, you'll see a section dealing with something called Referential Integrity. This is a method for ensuring that if data from one table is supposed to match data in another table, then any changes are made on in both tables.

Figure 2.9 - Referential Integrity options

An example of this would be if one of the records in the Companies table was deleted. If there were job leads recorded for that company, this could cause a problem. Without referential integrity, you would be left with job leads but no company information. It would get even worse if a number of companies were deleted at once. With referential integrity activated, Access protects records and primary keys that are referenced by records in other tables. If you try to delete a record that is referenced by another table, you might get a message like the one in Figure 2.10. On the other side of the example, it would not be possible for someone to enter a non-existent company number in the Leads table because the database would not find a corresponding company in the Companies table.

Figure 2.10 - Referential integrity prevents the deletion of records that are referenced by othertables.

Of course, in some cases, you do need to be able to delete or change records, even if they arereferenced in other tables. The two options under referential integrity for 'cascade' updating and deleting of records address this. Using cascade update, if a record's primary key is changed, that value is also changed throughout the database in any records that reference it. Ifcascade delete is active, then instead of getting the message shown in Figure 2.10, you'll get amessage informing you that you are about to delete records in a related table and confirming that you wish to proceed. If you select 'Yes', then any records in other tables relating to that record would be deleted. In the case of the relationship between Leads and Activities, if a job lead record was deleted, a cascading delete would delete any activities associated with that lead.

The options for referential integrity are not automatically appropriate for every situation. Alwaystake the nature and needs of the data being stored into account when you set options for

Page 25

Page 30: Microsoft Access for Beginners

Microsoft Access for Beginners

tables and relationships.

Remaining Tables

In addition to the tables already mentioned, the job search database has others that are used for reference and one or two interesting features.

Figure 2.11 - Job Search Plus relationship diagram.

The Sources and Contacts tables act much like the Companies table, holding reference information as indicated. Sources stores a few details on lead sources such as online job boards and newspapers. It's linked directly to the Leads table with a one-to-many relationship so a Source reference can be stored with each lead. These tables are examples of how

Page 26

Page 31: Microsoft Access for Beginners

Microsoft Access for Beginners

information that doesn't directly relate to the Leads table primary key is moved to a separate table for lookup as needed.

BusinessTypes is a basic lookup table that supplies business categories to the Companies table. Again, each category might be used an indefinite number of times so it has a one-to-many relationship to Companies. This table doesn't eliminate any information from Companies as the Business Type description is still stored. Instead, the table provides a list of types for theuser to select from and limits the entry in the Companies table to those types, eliminating errors so that searches are more accurate.

The unique feature is the double listing of the Companies table under 'Companies' and 'Companies_1'. These are actually the same table, just with a separate reference name in the relationships diagram. The reason for this is that the Leads table includes two fields that can hold a company reference; CompanyID and AgencyID. This enables the user to record leads that are being pursued through a placement or recruiting agency. Since it would be exceedingly rare to have more than two companies that the job seeker would have to work with on any one job lead, I decided to include both fields in the Leads table rather than doing a separate table for the companies associated with a lead. By having both fields related to the Companies table, both of them can use the table as a lookup but it does require separate references in the Access Relationships window.

Also notice that the Contacts table is linked to both the Companies and the Leads table. The Leads table stores a primary contact for a job lead that might come from either the company orthe agency and the Companies table links to it so that all contacts can be assigned to a specific company. The Companies-Contacts relationship would be the most obvious relationship but being able to link a table to multiple other tables provides flexibility in the database.

Database Normalization Overview

Now that you've seen an example of the rules in action, here are the first three normalization rules with some clarification. Normalization rules are referred to as Normal Forms and references to them are often abbreviated with the rule number followed by ‘NF'.

First Normal Form (1NF): All fields contain just one value and there are no repeating groups within the table.

The first part of this rule is sometimes referred to as atomicity. Each field value within a table should be atomic meaning that, just like an atom, it can't be broken down into anything smaller and still be useful. An example of this would be a company address. When designing the table to hold company addresses, you could have a single field that held the city, state and zip code and your database might work okay until you decided that you wanted to search for companiesby city or sort on the state in a report. You wouldn't be able to because these values would be part of a larger value rather than having been stored separately. That's why you will usually

Page 27

Page 32: Microsoft Access for Beginners

Microsoft Access for Beginners

see separate fields for the three values.

Depending on the database and what it's being used for, there might be some gray areas. An example would be a person's name. In most databases, you would want to split it into at least two fields; first and last, so that you could sort or search on either name. In some special cases, however, if you know that you're never going to need to do that, you could decide to keep the entire name together in one field.

There is a certain thing as over-normalization, where the normal forms are carried too far and no longer provide a benefit. An example would be if you decided to break up the street addressinto different fields, i.e. the street number, street name, suite number, etc. There is usually no clear benefit to this, it would result in a lot of blank fields (What if there is no suite number?) and it would force you to refer to more fields in order to construct an address. The various fields would no longer be useful in and of themselves as a City or State field would. This is where a certain amount of judgment is required when normalizing data.

The second part of this normal form is that there are no repeating groups within a table. The Leads and Activities tables were used as an example earlier. In Excel or another denormalizedenvironment, the activity items might be recorded in multiple numbered columns or groups of columns but this causes problems such as limiting the number of items that can be added to one order. The proper way to do this in Access is to change the direction of the data by having an Activities table with a record for each activity and a LeadID number that references the order that item is part of.

Second Normal Form (2NF): The requirements of the First Normal Form have been satisfied and all fields within the table are solely dependent on the entirety of the table'sprimary key.

Notice that the normal forms are cumulative. This requirement cannot be satisfied unless the values in your tables are atomic and repeating groups have been eliminated as mentioned in the First Normal Form.

The Second Normal Form simply means that every table must have a specific subject and every field within the table must relate directly to that subject. When evaluating a table against the rules of database normalization, that subject is what determines the field or combination of fields that would serve to uniquely identify the record. This is the primary key. In the example database, I often use AutoNumbers as primary keys for the purpose of linking tables but the normalization rules were not written with those in mind.

For example, in the demonstration database most job leads will have a company associated with them and if the table wasn't using an AutoNumber as the primary key, the company wouldbe one of the fields that would be part of a unique identification for the job lead, probably in addition to the Job Title and the Date. These three fields would make up the basis of the job lead. While the company identifier is stored in the Leads table, there is no reason to store the company address or phone number in the same table because that information does not relatedirectly to the job lead itself but only to the company. It is supporting information but not

Page 28

Page 33: Microsoft Access for Beginners

Microsoft Access for Beginners

primary information when referring to the job lead. If you were applying to more than one job atthe same company, you would not want to have to store the same company address over and over again in different Lead records. This would be duplication and could lead to errors when the information wasn't copied correctly. Instead, a separate table is built for the company information and only the company ID number is stored in the Leads table. The Leads table then links to the Companies table to get the information as needed.

The primary goal of this normal form is to avoid duplication of data. If you find that you are storing the same information more than once in your database, you need to ask why. Information that is stored in multiple places takes up space and is harder to update consistently.

Third Normal Form (3NF): First and Second Normal Forms are met and all non-key fieldswithin a table are mutually independent of each other.

This means no calculated fields or any other instances where the changing of one field will require a change in another.

In the example of a customer order database, this would prohibit the practice of having a total field that multiplies the number of items ordered by the item price. This type of field is not needed at the table level because it's easy enough to include as part of a query or data entry form so that it's available when it's actually needed. If you include it in the table, that means: a.) if the fields it's dependent on are ever changed, the field must be updated even if you don't need the information at the time which can affect the performance of your database or b.) the field is not updated automatically in which case it is not reliable. Calculated fields also take up additional space within the database for values that can easily be calculated as needed in a query or on a form or report.

Having said this, Access 2010 introduces calculated fields within tables. Microsoft's reasoning is that this provides a central location for expressions that might otherwise be duplicated on different forms and reports. Another reason is to increase the compatibility of Access with Microsoft SharePoint, a system used to share files and web-based information over networks. While I understand the logic here, I still believe that it is inherently poor design for a relational database because of the reasons stated above, especially when there are alternatives such asqueries that only perform the calculation as needed. You'll learn about queries in an upcoming chapter. Nevertheless, Access will allow you to do a lot of things that fall outside best practicesin database design and it is ultimately your responsibility to learn as much as you can and weigh all the options when designing your database.

When learning the rules of database normalization, some students have found it helpful to remember this rule which comes from E.F. Codd's definition of the Third Normal Form.

Every field in the table must provide information about the key, the whole key and nothing but the key (so help me Codd).

You probably have a basic understanding of these rules at this point but don't be surprised if it

Page 29

Page 34: Microsoft Access for Beginners

Microsoft Access for Beginners

takes some practice on your part to learn how to apply them when designing your own databases.

Conclusion

Microsoft's support site offers a couple of very good articles which detail the rules of normalization and provide more examples. For more information, please refer to the Suggested Reading list at the end of the book.

As I listed the tables in this database, you might have found yourself thinking that it looks like alot of data entry. If the tables were actually intended for data entry, that would be true. This is why I almost never allow users to enter data directly into the tables; that's what forms are for! In an upcoming chapter, you'll see how properly designed forms use the relationships betweenthe tables to bring much of the data entry work together in one place. They can automatically supply many of the values required in the tables and include interesting features like drop-down lists and default values that eliminate a lot of typing and help to ensure correct data entry.

In Chapter III, I'll go into greater detail about how you can create tables like the ones you've seen here.

Page 30

Page 35: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter III - Building the Tables

Introduction

In Chapter II, I wrote about designing a database in terms of organizing the information into a set of tables so that the data will be most accessible. The next step is to actually build the tables. The table design environment has a number of features that contribute to a stable database and some of these features can be confusing to someone new to Microsoft Access or even databases in general. More information on all of the features in this article is available through the help system in Access which I encourage you to become familiar with. For now, I'dlike to point out some of the most important items.

Creating a Table

There's often more than one way to do something in Access and this is true of creating tables as well.

1. In Access 2007 / 2010, these options are shown on the Create tab of the Office Ribbon control.

2. In previous versions, select the Tables option in the Database Window and click the New button at the top of the window. This brings up the New Table dialog with options for creating the table.

For this article, I'm going to focus on creating a table through the Design View screen. Figure 3.1 shows the design view for Leads, the main table in the demonstration database. Each field in the table is represented by a row in the top half of the window with additional settings for the field in the bottom half. You can switch between these two sections by pressing F6. This screen enables you to completely customize any table in order to get the most advantage fromstoring your information in Access.

Field Names

Access is very flexible in what it will accept for field names and allows names up to 64 characters in length. I try to keep mine short but descriptive enough to avoid confusion. Field names can contain spaces but I don't use them because they lead to confusion and possible errors that are hard to track down. The names shown in Figure 3.1 use a naming convention

Page 31

Page 36: Microsoft Access for Beginners

Microsoft Access for Beginners

called CamelCase where multiple words are joined without spaces but with each initial capitalized. Some people also use underscores between words.

Figure 3.1 - Pressing F6 in table design view switches between the list of fields and the fieldsettings.

It's also important to avoid using reserved words such as function names in tables. 'Date' would be a very common choice for a field name but Date() is a function in Access that returns the current date and this can cause conflicts when referring to the field. Something like 'Name' is not a reserved word but is not very specific either.

Data Types

After you name a field, you specify the type of data that will be stored there under the Data Type column in Table Design view. If used correctly, data type assignments help Access to store the information more efficiently with less wasted space and in a way that will enable you to use the data as needed.

The following is a list of available data types and some pointers on their use. Again, for full information, refer to the Access help system. In my comments, I often reference the number of bytes used to store a data type. This should not be confused with the number of digits allowed in numeric fields. For example, Access can use one byte of space to store a number up to 255 and four bytes can store numbers up to 2,147,483,647!

Text

The Text data type stores general text and alphanumeric data including names and formatted numbers that aren't used in calculations (i.e. phone numbers, serial numbers). Each field can

Page 32

Page 37: Microsoft Access for Beginners

Microsoft Access for Beginners

hold up to 255 characters.

This type will not reserve extra space for a field if you specify a field size larger than the actual data, i.e. a field size of 35 characters when your data only takes up 10. Still, for the sake of accurate data entry, it's better to specify field sizes only as large as you need them. It's easier to increase a field's size after data has been entered than to decrease it.

Memo

This is another text field for longer entries, up to 65,535 characters (64 KB). While memo fieldscan hold more information than text fields, they also have limitations such as the lack of lookupfunctions and some of the formatting features available to text fields. Heavy use of memo fieldscan also make your tables less structured and they should only be used when necessary.

Number

This type is for numeric-only values that might require calculations to be performed on them. When you select the Number data type, you'll see a list of options under the Field Size instead of a simple number. These are subtypes that determine how the number will be stored and how much space each field will take in the database. It is determined by the maximum value that can be stored in the field and the number of decimal places that can be used. The Long Integer is the default and can store whole numbers (no fractions) from -2,147,483,648 to 2,147,483,647. Access uses four bytes to store a long integer. A normal integer (-32,768 to 32,767) only takes two bytes. The Single and Double types store floating point values depending on the level of precision that you need. Choosing the right type can also help to limitthe type of values entered to prevent mistakes.

Date / Time

This type stores date and time values from the year 100 through the year 9999. Access includes functions to add and subtract days, months and years within date fields. Date fields can also be formatted and sorted in ways that text fields cannot be. Each field uses eight bytesregardless of formatting.

Currency

The Currency type stores monetary values and formatting with up to 15 digits to the left of the decimal point and four digits on the right. It also eliminates rounding during calculations. Each value uses eight bytes.

AutoNumber

As I mentioned in Chapter II, this is a value that is generated by the database which cannot be updated by the user. It can be set to start at 1 and increment for each record or it can be set to generate a random unique value. This field can be stored as a random or incrementing long

Page 33

Page 38: Microsoft Access for Beginners

Microsoft Access for Beginners

integer which takes four bytes of space.

Yes / No (Boolean)

This is a field with only three possible values; 0, -1 and 1. It's often used behind checkboxes. It's the smallest of all fields as it only needs to store a simple True or False value. While -1 and1 both equal True, the extra possible value allows for checkboxes with three possible values which can allow for an indeterminate value.

OLE Object

The OLE Object is a generic field used to store objects such as pictures or other files within thedatabase. The data is not directly readable within the table but the object can be opened by its required application. The size of this field depends on the size of the object stored within it although there are special considerations when storing images because the field does not compress image data so the images will take up amounts of space far beyond their actual file size. The field's maximum size is one gigabyte.

Hyperlink

This field type stores a three-part text value that enables a hyperlink to be stored and activatedfrom the table or a form field. The hyperlink field is broken down into three parts; the text displayed in the field, the address / subaddress and the screen tip that is displayed when the user moves the mouse over the hyperlink. Each of these parts can hold 2048 bytes (2 KB) for a total of 6144 bytes.

Lookup Wizard

This is listed with the field types but is actually a wizard that configures the field to automatically retrieve data from a table or query or to supply a list of values provided at design time. The determination of the field type is made automatically after the steps of the wizard arecompleted.

Attachment

The Attachment type was introduced in Access 2007 and is an improvement over the OLE object field. An Attachment field can store multiple files in one record including images, Acrobat files and other Office files. Double-clicking on the field in either form or table view will bring up the Manage Attachments dialog where you can add, view, save and delete any of the attachments stored. This field type uses less disk space than an OLE Object field when storingimages.

Calculated Fields

Introduced in Access 2010, calculated fields enable you to store the results of calculations

Page 34

Page 39: Microsoft Access for Beginners

Microsoft Access for Beginners

between fields within the same table row. For example, you could have two fields specifying the number of items ordered and the price for that item and then a third, calculated field which multiplies the two field values to get the total for that row.

While this might seem like a handy feature, it presents a couple of problems. Most seriously, even though Access 2007 and 2010 use the same file format, calculated fields are not compatible with Access 2007. If you add calculated fields to a database with Access 2010 and even try to open the table in Access 2007, you'll get a message like the one in Figure 3.2. You'll also see a compatibility warning as soon as you open the database and Access 2007 detects the use of the calculated field.

Figure 3.2 - Although the file format is the same, Access 2010 has features that are incompatiblewith Access 2007.

Another problem is that calculated fields cannot be indexed which can slow the performance ofa database with large tables. The final, most basic problem I'll mention is that calculated fields are a basic violation of database normalization as detailed in the last chapter. They take up unnecessary space and can decrease the overall performance of your program.

Adding a Primary Key

One of the essential tasks of designing a table is choosing one or more fields to uniquely identify each record. This is referred to as the table's primary key. Without a table key, it's impossible to organize your data as shown in Chapter II. The primary key is important enough that if you don't set one, Access will prompt you when you try to save the table design. A table key can be a single field or a combination of fields (a composite key). In some cases, one field is not enough to uniquely identify a record, so additional fields are needed.

While a primary key can be used to ensure unique data, its main purpose is to identify specific records in the table and enable their retrieval. While designing the table structure for Job Search Plus, I chose to use an AutoNumber field as the primary key for the Leads table. A composite key including the Job Title, Record Date and Company ID certainly would have been unique and could have served as the primary key but could not have been used to link to the Activities table. For the sake of simplicity, I decided to let the database assign the new value for each record by using the AutoNumber. This number is unique for each record in Leads and can be easily shared by any other table that needs to reference this table.

Page 35

Page 40: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 3.3 - Most tables require a primary key that acts as an identifier for each row.

After you decide on the fields involved, setting a primary key is as simple as selecting the field(s) in Table Design view, right-clicking and selecting the option from the pop-up menu as shown in Figure 3.3. A small key icon will show up at the left of each field in the key.

Figure 3.4 - Indexes other than the primary key can be set to require unique values orcombinations of values.

After you set the primary key, the fields involved will show as indexed in the field properties.

Page 36

Page 41: Microsoft Access for Beginners

Microsoft Access for Beginners

The primary key is the main index for the table. If it's a single field key, then the index will not allow duplicates for that field. For a composite key, each field in the index will allow duplicates on its own but the combination of fields that make up the index will not allow duplicates.

The UniqueLead index demonstrates another way to ensure that data is not duplicated within atable. This index is separate from the primary key as shown in Figure 3.4. Single or multi-field indexes can be set as unique so that the database will not allow more than one record with thesame value or combination of values to be entered.

Field Properties

For each field in the table, there is a list of settings that you can use to customize how the database displays and processes the data.

Figure 3.5 - The field properties grid

This is shown in the bottom half of the design screen and the list changes depending on the data type of the field you're working with. The sample in Figure 3.5 is a Date / Time field which has most of the settings filled in.

Many of these options display a small button on the right side as shown in Figure 3.5 for the Format option. The drop down shown here will provide a list of options for the setting. Other settings, like the Input Mask property, display a Build button which has an ellipsis (...) for a symbol. Clicking on the build button will activate a wizard or dialog that will guide you through the settings. It's important to pay attention to these settings whenever you are designing a table. These give you full control over how data is entered into the table. The following notes give a brief explanation of the major properties. For more information on any of these settings, click inside the setting box and press F1.

Format

Page 37

Page 42: Microsoft Access for Beginners

Microsoft Access for Beginners

For number (including currency) and date types, this setting offers predefined formats for the data being entered. Among other possibilities, currency can be formatted with or without symbols and dates can be formatted to include weekdays. You can also define custom formatsif you want to add dashes or other symbols to your data. The advantage of using this setting is that Access will automatically reformat the data as it's entered.

Input Mask

This is a great setting for controlling data entry. Whenever a user moves to a field with an inputmask, Access places a template inside the field to guide the user in entering the data. Access can also use the input mask to create a password field where all characters entered are displayed as '*'. As with the Format setting, you can select from pre-defined masks based on the data type or you can create your own. Form fields will inherit masks from the table fields they are based on.

Caption

Any text you enter here will be shown in the table header in place of the field name or as a caption on forms. I prefer to use the Description property next to the field's Data Type selectionin the top half of the Design View screen if a field requires some explanation beyond the name.Data entered under the Description will show up in the status bar when the user views the fieldon a form.

Default Value

This can be helpful if a field is supposed to hold the current date or another value that can be predicted. Using this setting when possible speeds up data entry and reduces error. In additionto holding single values, it can also use calculations and formulas.

Validation

The validation settings are also useful for data entry control. In the example screen in Figure 3.5, this setting uses a formula to test that the date entered is less than 61 days in the future. Adate in the past would pass this test. A date three months from now would not. The validation text setting provides an error message that the user will see when the table refuses to accept avalue. This test is only performed when entering new data or editing existing data. It will not cause an error for data entered prior to the rule being setup unless that data is edited.

Required / Allow Zero Length

The database will not save a record that does not have entries for fields where Required is set to True. I use this sparingly during design as it can be difficult to test a database with a lot of required fields. Allow Zero Length is a setting for text fields that will determine if the user is allowed to enter zero length strings for text fields. This needs to be used carefully because in some cases it can be difficult to tell the difference between a field where there is no value (null)

Page 38

Page 43: Microsoft Access for Beginners

Microsoft Access for Beginners

and a field with a string that's zero characters long.

Indexed

An index is used by Access to speed up sorting and searching the data in a field. According to the Access specifications, you can have up to 32 indexes on a single table although the more indexes are present, the more work Access has to do to maintain these indexes. Indexes should not be used on fields such as Boolean (True / False) fields where there are only two possible values.

Indexes can also be used to prevent duplication of values. The index for a field is automaticallyset as unique when choosing the field as the table key. If it's a composite key combining two ormore fields, then each field in the key might allow duplications on its own but the index will not allow the fields to contain a duplicate combination of values. In Access 2007 / 2010, the collection of indexes on a table can be viewed and managed by clicking on the Indexes icon onthe Access Ribbon while in table design mode. In previous versions, you can select it from the View menu.

Figure 3.6 - Tables use indexes to help search for and sort data faster. The indexes dialogenables the creation and editing of indexes.

Unicode Compression

In Access, text characters are stored with a character set that uses two bytes for a character instead of one to allow for additional alphabets and symbols. Unicode compression is used to offset the difference in fields over a certain size. New users can safely ignore this field and leave it on the default setting

IME Mode / Sentence Mode

These are also settings that new users can pass by. They concern the use and display of

Page 39

Page 44: Microsoft Access for Beginners

Microsoft Access for Beginners

Asian character sets. For more information, refer to the help files.

Text Align

This setting was introduced with Access 2007 and determines how the information is aligned inthe field; left, right, center and full-justification.

Table Properties

In addition to individual field properties, an Access table has a panel of properties that apply to the entire table. You can view these by right-clicking anywhere in the table design screen and selecting Properties. The example in Figure 3.7 shows the panel in Access 2007 and the following is a list of some of the key properties.

Description

When Details view is selected in the main database window, this value will show up next to thetable name. It can be useful, especially in large databases.

Default View

Most beginning users will stick with Datasheet which shows a simple row and column format. The Pivot views listed here, though, provide a simple and flexible way to analyze the data in a table with grouping and totals by specific fields.

Figure 3.7 - Tables feature properties such as validation rules that apply to the entire table.

Page 40

Page 45: Microsoft Access for Beginners

Microsoft Access for Beginners

Record Validation

In addition to validating the entry in specific fields, you can use the expression builder to validate fields against each other and setup rules for the entire record.

Filter

By placing a filter on a table, you can restrict the number of records that you want to view at one time. This can be useful for very large tables or when accessing data from other databases.

Order By

The default order of records as displayed by the table can also be set for one or more fields.

Subdatasheet / Child and Master Fields

When viewing the data in a table, you can show subdatasheets for linked tables. In this example, when viewing the Leads table, a datasheet is set to display for every activity on each job lead. When you select the table or query to use, the Child and Master fields are automatically set by default. This can be changed if necessary.

Figure 3.8 - Datasheet View features subdatasheets based on table relationships.

The subdatasheet height setting sets the maximum height of the subdatasheet when expanded. A vertical scroll bar will be shown if the number of records exceeds this height.

The subdatasheet expanded setting, when set to 'Yes', automatically expands the subdatasheet for each record in the table view.

Orientation

The table can be set to display fields and related controls either left-to-right or right-to-left.

Page 41

Page 46: Microsoft Access for Beginners

Microsoft Access for Beginners

Relating Tables

Once you've created the table, the next step is to decide how it's going to relate to the other tables in the database. This can be done through the Relationships window which is displayed by clicking on the Relationships button under the Database Tools section of the Access 2007 / 2010 ribbon. In earlier versions, select Relationships from the Tools menu.

Figure 3.9 - The relationships window enables you to click and drag fields to create relationshipsbetween tables.

If you don't have any relationships defined yet, the Show Table dialog will appear as soon as you open the Relationships window. Double-clicking on the tables in this dialog will add them to the Relationships layout. If the dialog doesn't appear, right click on any empty space in the Relationships window and select Show Table from the pop up menu.

Page 42

Page 47: Microsoft Access for Beginners

Microsoft Access for Beginners

To set a relationship, click on the field in one table, such as the primary key, and drag that fieldto the corresponding field from another table. For example, the relationship between the Leadsand Activities tables would be created by clicking on the LeadID field in the Leads table (the Primary Key) and dragging it on top of the LeadID field in the Activities table.

If you want to try this, right-click on the relationship line between the two tables in the Relationships view, choose Delete from the pop-up menu and click Yes to confirm. Then click on the LeadID field in the Leads table and drag it on top of the LeadID field in the Activities table. The dialog in Figure 3.9 should appear.

Figure 3.10 - The Edit Relationships dialog enables you to set the relationship type betweentables.

Notice the LeadID field under both tables and that Access has already assigned a one-to-manyrelationship based on the fact that LeadID is the primary key in Leads and that it's not unique in Activities. Referential integrity is not set so this is a good time to choose the settings.

The Cascade Update and Cascade Delete options determine how the database will respond if the field value is changed in a row in one of the related tables. If referential integrity is activated without selecting either of these options, then the database will not allow deletions or updates on the 'one' side of the relationship. For example, if you tried to delete a record in Leads that had corresponding records in Activities but Cascade Delete wasn't chosen, you'd get a message like this:

Figure 3.11 - Referential integrity protects the relationships between tables.

Page 43

Page 48: Microsoft Access for Beginners

Microsoft Access for Beginners

On the other hand, if Cascade Delete is chosen, you'd get a confirmation message notifying you that corresponding records in the Activities existed and asking if you really wanted to delete the record. I did not design the database to allow lead records to be deleted so my choice for settings would be to activate referential integrity without any cascade options.

The Join Type button on the Edit Relationships dialog enables you to decide what kind of join will exist between the tables.

Figure 3.12 - The Join Properties dialog enables you to specify which table has the priority in therelationship.

The first option shown in Figure 3.12 is an Inner Join. Only records in Leads that have corresponding records in the Activities table will be shown in the default join between the tables. I don't really want this since some job leads might not have any activities on them. The second option is what's called a Left Outer Join which shows ALL records from Leads and thenany corresponding fields from Activities. This would be my choice because I want to give preference to the Leads table in any queries. The third option would create a Right Outer Join, giving preference to the child table (Activities) and only showing the records in Leads that match.

The names I'm using for the joins are the names used in SQL and you can read a more detailed explanation in the introduction to Structured Query Language in Chapter V.

Tables can have more than one relationship as shown by the relationships between Leads andCompanies and, in a large database, the relationships can get complicated. You can actually show and hide tables within the Relationships window without affecting the relationships between them and then restore all tables by right-clicking within the window and choosing 'Show All' from the pop-up menu.

Conclusion

In this chapter, I've explained the settings that you'll encounter in Access table design. Access is a powerful program and with that power comes a certain amount of complexity. There are some settings in the table design panel that you might not use for a long time, if at all, and still produce very professional databases. Still, the more features you are aware of, the more

Page 44

Page 49: Microsoft Access for Beginners

Microsoft Access for Beginners

options you will have available to you when building your solutions.

Getting familiar with the various features of table design and the settings shown here is actually one of the most straightforward aspects of learning to work with databases. At the same time, it includes some important concepts such as proper use of data types and data entry validation. I'd encourage you to take some time to experiment with these settings. The more you know, the better your databases will be.

Page 45

Page 50: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter IV - Writing the Queries

Introduction

A database storing every bit of knowledge you could ever need wouldn't be of much use without some way to retrieve the data. After I create the tables, my next step is usually to create the forms for the database but first I need to provide some information on queries. Manyof the queries that you use will actually be created automatically as you design forms and reports which use them to obtain the required data. If you do any significant amount of work with Access, you will need to know how to construct queries for those times when you need something specific.

Background

Microsoft Access uses Structured Query Language (SQL - often pronounced "sequel") in orderto manipulate the data in the database tables. It is not necessary to know this language in order to create queries and work with Access but going the extra mile and being familiar with it will make you more productive if you decide to continue working with Access and other databases long-term. In addition to viewing the data as shown in the example in this article, queries can also be used to add, delete and change data from various sources based on the criteria that you specify.

If you don't have the demo database open already, open it now. Press F11 to view the database window. Select 'Queries' under the Objects selector. Open the query titled 'LeadsList'by right-clicking on it in the window and selecting 'Design View'.

The Query by Example (QBE) window enables the user to quickly create the desired query by selecting the appropriate tables and fields and setting the right options to retrieve the data. When you use the QBE screen, Access writes the necessary SQL behind the scenes.

Figure 4.1 shows the screen you'll see when you open the query in design view. Figure 4.2 shows the raw SQL code behind the query. It looks complicated until you break it down by keywords shown in all caps such as SELECT, FROM and GROUP BY. Then notice that much of the rest is made up of table and field names with a few formulas here and there. At this point, it actually becomes very simple to learn. In a later chapter, I'll show you how to write SQL queries without using the QBE window.

Page 46

Page 51: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 4.1 - The Query By Example designer

The LeadsList query is a simple query based on the Leads and Companies tables that demonstrates the different functions of the QBE window. This type of query is known as a SELECT query as it doesn't actually affect the data in any way. It only selects it for viewing based on the user's specifications. By default, all new queries are Select queries until you specify otherwise.

Figure 4.2 - SQL View

Other query types include:

• APPEND - Queries can be used to append data to a table from another source such as other tables, queries, user input or real-time calculations.

• DELETE - You can delete groups of records from a table based on one or more criteria.

Page 47

Page 52: Microsoft Access for Beginners

Microsoft Access for Beginners

• MAKE TABLE - Queries can create new tables from the same sources used by Append queries.

• UPDATE - Values can be changed throughout a table using an UPDATE query. This might be handy if a certain mistake has been made consistently when entering numerous records or if a piece of data such as an area code changes.

All of these query types and more can be created using the Query menu in the query design view. In Access 2007 / 2010, look for the Query Design option under the Create menu. Check the help files for more information on each of them and take some time to play around with the different options.

The LeadsList Query

When you create a new query, you'll see that the program immediately asks you to add tables or other queries to the new query. The LeadsList query is adapted from the query behind the main Leads listing screen in the database and includes the Leads and Companies tables. In Figure 4.5, you can see how the one-to-many relationship that already existed between the tables is automatically included.

You can add and remove tables from a query and manage the relationships between them much as you would in the Relationships window as explained in Chapter II. To add a new table, right-click in the top half of the QBE window and select the 'Show Table' command. The query will automatically add any relationships that exist between that table and the others in the database. The relationships between tables can be changed in a query without affecting the rest of the database. This is handy when you want to create queries that perform analyses from a different perspective than normal. Double-clicking on a relationship line within a query shows a dialog like the one in Figure 4.3 that displays both the tables and fields involved and the type of join it represents.

Figure 4.3 - Tables can be joined in a query design just as they are in the relationships window.

Page 48

Page 53: Microsoft Access for Beginners

Microsoft Access for Beginners

For this query, the default relationship works fine as it will show all active job leads and the necessary company information for each one. If there is no company entered for a lead, blank fields will be shown. If I wanted to, I could double-click on the relationship line shown here and change the relationship for this query to get different results. It would not affect anything else inthe database.

You can add fields to your query by double-clicking on the table fields in the top half of the window shown in Figure 4.1. You can also select multiple fields by holding down the CTRL or SHIFT keys and then add them by dragging the selected fields to the grid in the bottom half of the window. Selecting the asterisk (*) at the top of the field list selects all fields in the table.

Navigating the Design Grid

The bottom half of the query window is known as the design grid. The first two rows in the grid show the relevant field and table names. If you place your cursor in any of these spaces, you'll notice that a selector button appears on the right side of the text. This tab enables you to quickly change the selected fields or table if necessary.

Figure 4.4 - Displaying the Totals row in query design view

The Total row shown in the example does not appear automatically when you create a new query. You activate it by clicking on the toolbar icon (in Access 2003 and earlier) or ribbon icon(in 2007 and later) or by right-clicking on the design grid and selecting 'Totals' from the context menu as shown in Figure 4.4. This row specifies aggregate functions for the columns in the query. These functions enable you to group the data in the query and return calculations basedon those groupings such as averages and row counts. Once you activate this row in the query settings, each field must have one of these functions specified. Group By is the default setting for each column in the query.

As an example of what you would do with aggregate functions, suppose you had a query that returned a simple list of job leads with company information for each lead. You could change

Page 49

Page 54: Microsoft Access for Beginners

Microsoft Access for Beginners

the function under the LeadID field to 'Count' and then include the City or ZIP fields as Group By fields. This would return a list of Cities or ZIP codes, depending on the field that you used, with the number of job leads for each item in the list. In a query that linked the Leads and Activities tables, you could create a query that used the Max function to return the latest activity date for each job lead. These are just a couple of things that you can do with all of the functions available and you should take time to experiment.

Figure 4.5 - The Totals, Sort and Criteria rows can be used within the Query Design Grid toanalyze the data within your tables.

The Sort row specifies the sort order by field. In this example, if you select more than one field to sort on, the query will give preference to the first selected field on the left and work its way tothe right of the query. In other words, if I sorted by job title and location, the records would be sorted by job title and then if there was more than one lead with the same title, it would sort within that title by location. You can change the order of the columns in the query window by selecting and dragging them around.

The next row in the query window, Show, specifies if a field should be shown or hidden in the query results. In some cases, you might use a field to specify criteria for a query but not actually want to show it in the results.

The Criteria rows in the design grid supply the criteria or desired values for each field in the query. In the LeadsList query, there is only one field that has criteria added and that is the Active field which is a Boolean (True/False) field. I've specified 'Yes' (True) to show only active leads. You can also use values and expressions to specify what rows should be returned. For example, you could enter an expression like > 1/1/2011 to only return leads that were entered after January 1, 2011 or Like A* in the City field to specify job leads where the city starts with

Page 50

Page 55: Microsoft Access for Beginners

Microsoft Access for Beginners

'A'. In both cases, Access will add delimiters around the sample values that you enter; the pound sign in the case of date values and double quotes for string values.

Figure 4.6 - By using the Criteria row in query design view, queries can accept parameters fromthe user.

The criteria fields are very flexible and can even contain equations and specialized functions that present choices based on user input. Using the 'Or' row and the rows below it, you can specify multiple alternate conditions for a field. Specifying conditions for multiple fields such as JobTitle and Location, on the same criteria row would act in a cumulative way to limit the records returned. For example, specifying criteria for the JobTitle and Location fields on the same criteria row means that the query will be limited to records where both of those criteria are met while if you specified the criteria on different rows, the query would return records where either condition was true.

Figure 4.6 shows another way to use the Criteria field. A bracketed value has been entered in the Criteria row for the Location field and the screenshot shows the result after I clicked on Datasheet View. The text in brackets becomes a user prompt that accepts a parameter for usein the query. The brackets actually indicate to Access that a field value is being specified as the criteria but Access doesn't recognize that field name so it requests the value of the field from the user. It will apply whatever value is entered in the input box as the criteria value.

Getting the Results

After creating the query, it's time to run it. There are two ways of seeing the results of a query. In the case of a SELECT query like this one, there is no difference between the two. It's important to know the difference when running other types of queries, though, and to be in the habit of using the right one because otherwise the consequences can be disastrous.

Page 51

Page 56: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 4.7 - There are two ways to view the results of a SELECT query.

Datasheet View, available through a pull-down option on the left of the toolbar or ribbon, will show you the records affected by your query without actually running it. This distinction becomes important when you are working with queries that are adding or changing data in a table. By using datasheet view, you can see the affected records without actually committing the changes.

The Run option, activated by the exclamation point highlighted in Figure 4.7, actually runs the queries and performs any actions specified. If data will be changed or deleted, Access will warn you about the changes and ask for verification unless this option has been turned off. Once verified, however, the changes are permanent.

To be safe, it's best to use Datasheet View when working with select queries like this one so as to develop the right habits.

Figure 4.8 - Datasheet View shows the records affected by the query without applying anychanges made.

Beyond Field Selection

Queries can do more than select data for display and I want to point out a couple of other things about the LeadsList query that demonstrate this.

Page 52

Page 57: Microsoft Access for Beginners

Microsoft Access for Beginners

The first example is the CompanyLocation field in the LeadsList query. This is an example of how expressions can be used to manipulate separate fields into one value. In the original query, the city and state are contained in separate fields. While this might be okay in some cases, I want the query to combine these two values into one that shows the company's location.

By right-clicking on the CompanyLocation field in the Field row and selecting 'Build' from the pop-up menu, you can display the Expression Builder. This tool is very useful for building expressions and adding them to query fields.

In Figure 4.9, you can see how the lower left-hand box in the Expression Builder displays all of the objects within the database by category along with some extra features such as functions that you can use in your expressions. The first item in the box is the LeadsList query that the Expression Builder was opened from. In the middle box, it displays all of the fields within the query.

Figure 4.9 - With the Expression Builder, you can design sophisticated expressions for use inqueries.

To build an expression, just double-click on the necessary objects in the lower boxes and add the correct operators using the buttons below the expression area at the top. You can also paste an expression in the box and modify it as needed. For this example, I've created a simple expression that will concatenate the city and state fields into one value with a comma between them.

This expression combines the three values into one using the concatenation character (&). I'veadded a comma and a single blank space between the city and state values. Any non-field textthat's added must be surrounded by quotation marks. Thus, 'Atlanta' and 'GA' would become

Page 53

Page 58: Microsoft Access for Beginners

Microsoft Access for Beginners

'Atlanta, GA'.

It's not necessary to include the table names since the field names are unique within the query.When using a field name that exists in more than one table and both of the tables are represented in the query, it's then necessary to enter it with the table name (i.e. 'Companies.State'). If there are any spaces in the field or table names, remember to use brackets around the name so Access will recognize it as one name (i.e. [Employees].[First Name]). The same holds true in the Expression Builder as shown in Figure 4.9. The brackets around the field names are the way Access indicates the name of an object such as a field, table or form name. The brackets are optional unless there is a space in the name.

After entering the expression and clicking the OK button, Access inserts the expression back inthe design grid in place of the field name that was there before. It also adds a name to the expression since the query field needs a single name for the field. This name can be changed to anything that complies with Access field name rules.

One question you might be asking is "Why go to the trouble of storing the name or the city and state information in two parts only to combine it again?" One reason is that you have greater flexibility in the way data is used. The CompanyLocation field in the query cannot be sorted by state, for example. Breaking the information down into the smallest useable parts makes the data more versatile. This is referred to as ‘atomicity' in database theory and discussed in therules of database normalization from Chapter II. There is some flexibility when it comes to something like the employee name and the decision depends on the needs of the organization.

Queries can also call functions in order to manipulate data while the query is running. Like Microsoft Excel, Access includes a long list of built-in functions that you can use to perform calculations. These functions and any custom functions that you design, can be called by queries in order to display the necessary results as part of the query. The LatestActivity field in the LeadsList record source is an example of this.

LatestActivity:DMax("[ActivityDate]","Activities","[LeadID] = "& [Leads]![LeadID] & " AND [Complete] <> 0")

This field actually calls two functions, one nested inside the other, and a table that's not officially included in the query. The DMax (domain maximum) function will retrieve the maximum value from a field within a specific domain such as a table. A simplified example of the one shown in the database would look like this:

DMax("[ActivityDate]", "Activities" , "[LeadID] = " & [Leads]![LeadID])

The DMax function is a kind of query in and of itself. It looks for the maximum value in a specific field based on the specified criteria. In this example, it's looking at the ActivityDate fieldfrom the Activities table. It then limits its search by the LeadID field using the LeadID value from the current query record.

Page 54

Page 59: Microsoft Access for Beginners

Microsoft Access for Beginners

The result is that for each lead shown in the query results, you will see the date of the latest activity recorded for that lead. The function used in the actual query takes it a step further and adds a second condition to the function; it only searches activities that are marked as complete. This means that you will see the date of the last completed activity on the lead.

The second function used is the Format function which will take the date generated by DMax and format it as directed. In this case, it uses the 'Short Date' format which would be MM/DD/YYYY.

Figure 4.10 - Expression results being returned as part of query results.

One thing to note here is that these calculations are being done separately for every record in the query. In this case, it doesn't cause a problem because there aren't that many records and for each record, the DMax function only looks at a few activity records at the most. If this queryreturned a few hundred records, however, or the calculations were individually looking at more data, the time that it took to run the query could become a problem.

There are two design considerations here; first that the number of records being accessed at one time should be limited where possible. The first limitation occurs naturally in the number ofactivities per lead as most leads will only have a few activities. The second limitation is in the use of filters on the query, in this case 'Active = True'. The query only looks at job leads that are still open. Data retrieval uses resources like memory and bandwidth, especially if you're accessing a database over a network or a server database like SQL Server. In a database withmultiple users, it can also cause records to be locked unnecessarily. Data inconsistencies or even corruption can occur if rows are changed but not correctly updated back to the database. Retrieving unnecessary data also takes time which can cause noticeable delays in your program. Your database might be rich in data but it should be thrifty in the way it accesses thatdata.

The second design consideration is where a calculation should be performed. In this example, I decided it was okay to place it in the query but if the calculation took longer to perform and there was another place to do it, for example on a form or report that pulled a single record at atime, I might put the calculation there instead. Of course, I would also check for ways to reducethe amount of time the function was taking. It's best to learn to think of these things now because if you find yourself working on more sophisticated systems, the efficiency of your program might affect more than the local user.

Page 55

Page 60: Microsoft Access for Beginners

Microsoft Access for Beginners

The Role of Queries

In this chapter, I've shown you a query as a standalone object within the Access database. This is not the only place you will find a query in Microsoft Access. Queries are the primary toolAccess uses to retrieve information for use within your applications. They can be very useful when stored as standalone objects but they are also used as the record source for forms and reports.

In Figure 4.11, you can see the properties for the main listing of the job search program. The first property is the Record Source which defines the data available to the form. The Record Source is in the form of an SQL query and if you were to click on the Build button to the right ofthe field, it would bring up the QBE window with a query very much like the LeadsList query you've been looking at in this chapter.

Figure 4.11 - Queries are used as the record source for forms and reports.

I could also use a standalone query object for this source. Queries are also used as the record source for reports and can be called from VBA code. Finally, a SELECT query can be includedin another query just as you would include a table. This makes the records returned by the firstquery available as a data source to the second query.

You'll learn more about all of these items in later chapters. Right now, it's just important to understand that queries are pretty much everywhere in Access. They act as both data retrievaland manipulation tools and as data sources.

Page 56

Page 61: Microsoft Access for Beginners

Microsoft Access for Beginners

Conclusion

As you continue to work with Microsoft Access and get into some of the more advanced functions, you'll see that the program often treats tables and queries very much the same. As adatabase management system, Access deals primarily with data, not the objects in which it is stored. Further, both tables and queries can exist as abstract collections of data in memory without being bound to the table and query objects that you see in the database window. This might not be something you need to be concerned with now but understanding this can help you avoid some confusion later on.

Page 57

Page 62: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter V - Understanding SQL

Selecting Data

In the chapter on queries, I briefly wrote about Structured Query Language (SQL) which Microsoft Access and other relational databases use to select and manipulate information. SQL (often pronounced "sequel") is a scripting language resembling English that is used to relay instructions to the database and specify exactly what is to be done with the data. Many Access users might think of a query as an object within the database window that can be run to retrieve data but the query is actually the SQL code within this object. The Query By Example (QBE) window that most Access users are familiar with is simply an interface that makes it easier to select tables and fields and specify what the query should do. As you use this interface, Access writes the SQL code, referred to as an SQL statement, in the background and saves it when you click the save button in the query designer.

In addition to these standalone queries, SQL statements can be used as the data source for forms, reports and controls within Microsoft Access. SQL statements can also be issued from macros and within VBA code in order to automate operations on data. If you move beyond Access to databases like Microsoft SQL Server, you will also see that SQL statements can be run from a command line to affect data being stored in a network database. The following are examples of queries that you could actually run on the Job Search Plus demonstration database and you might find them self-explanatory.

SELECT * FROM Leads WHERE Location = "Atlanta, GA";

UPDATE Companies SET City = "Tampa" WHERE CompanyID = 6;

DELETE FROM Activities WHERE LeadID = 2;

(The asterisk [*] is a wildcard symbol used to indicate all columns in record source. It is not required for DELETE queries in Microsoft Access.)

Many Access users will rely on the QBE interface to construct queries as needed. While this might be all that you need when designing applications, it's important to understand the basics of SQL if you actually want to understand how your database works. You will be much more efficient when it comes to retrieving and analyzing data if you can write at least basic queries rather than depending on whatever interface might be available at the time, especially if you use other database systems. Despite its appearance, SQL is a very simple language that you can learn the basics of with a day or two of practice so there's really no reason to avoid it.

Page 58

Page 63: Microsoft Access for Beginners

Microsoft Access for Beginners

Behind the Scenes

Figure 5.1 - The Query By Example (QBE) grid provides a easy way to create new queries.

You can view and edit the SQL statement directly by opening the QBE window and selecting 'SQL View' from the View menu or by right clicking within the tables area in the QBE window and selecting it from the pop-up menu.. Figures 5.1 and 5.2 show the LeadsList query which shows basic information on each lead and links to the Companies table for company details.

At first, the SQL view looks like a confusing mess until you focus on the keywords shown in all caps in Figure 5.2. Notice that all of these keywords are followed by table and field names. Each of these keywords corresponds in some way to a part of the Query Builder window.

Figure 5.2 - SQL View shows how the query is written in the background.

Page 59

Page 64: Microsoft Access for Beginners

Microsoft Access for Beginners

When processing the SQL statement, the program ignores extra white space and lines in the statement. I formatted the statement below as I usually do for readability but I could also put everything in one continuous line or every word on a separate line and Access would read it just as easily. I've also removed the table names from the code below to simplify things. Specifying the table names before the field names often isn't necessary in queries unless you have the same field name in more than one table.

SELECT JobTitle, EmploymentType, CompanyID, Description, ActiveFROM LeadsLEFT JOIN ActivitiesON Leads.LeadID = Activities.LeadIDWHERE Location = "Orlando, FL"GROUP BY JobTitle, EmploymentType, CompanyID, Description, ActiveHAVING Active <> 0ORDER BY EmploymentType;

Let's take a look at the individual parts:

SELECT FROM - First, the query specifies the fields to be displayed. It lists the fields that are to be shown in the order they are placed in the grid and separates them with commas. Notice that the Location field is not listed, even though you'll see it further down in the query. In the QBE window, the Show checkbox for the field would be cleared as it's only being used in the query to provide criteria to limit the records returned.

JOIN ... ON - SQL uses JOIN clauses to refer to the relationships between tables. These are much the same as the relationships that are defined between tables in the Relationships window. In this case, it means that all of the records from the table on the left side of the relationship (Leads) are available to the query while only the corresponding records from the right side of the relationship (Activities) are available. This join displays all employees, including those who have no records in Activities. This is also referred to as a Left Outer Join. An Inner Join would only show employees who had records in both tables. The ON keyword specifies the fields on which the tables are to be joined, in this case the LeadID field. The corresponding fields on which two tables are joined must be of the same data type in order to permit a join.

The use of the words LEFT and RIGHT do not refer to the placement of the tables in the QBE window but rather on their order in the relationship. In this case, the value of the LeadID field issupplied by Leads on the left side of the relationship because the LeadID field is the primary key for that table. The Activities table uses that value to link an address record to an employee record and is therefore on the right side of the relationship.

Thinking of LEFT and RIGHT for table relationships can be confusing but it might help if you compare it to reading a sentence from left to right, and think of the parent table (the table that supplies the value for the field that's being linked on) on the left. As you move to the right of therelationship, you see the child tables that use the field as a foreign key to link to the parent table. A LEFT JOIN would therefore be a join that starts from the left of the relationship (Leads

Page 60

Page 65: Microsoft Access for Beginners

Microsoft Access for Beginners

in the SQL example) and a RIGHT join would start from the right (Companies). Note the word OUTER is optional in both relationships. Both of these conditions place a priority on one of the tables, selecting all records from one and matching records from the other. An INNER JOIN only looks for matching records in both tables.

WHERE - This clause specifies the criteria that each row must meet in order to be included in the results. In this example, we're looking for records where the Location field equals a particular string. This clause can specify multiple conditions using the AND / OR keywords andparentheses to group conditions for the right result. Some of the possible WHERE clauses in this sample could be:

WHERE JobTitle = DriverWHERE Active <> 0 AND Location = Orlando, FLWHERE (Active <> 0 AND EmploymentType = Full-Time) OR EmploymentType = Freelance

GROUP BY - Group By is used to create groupings within the data based on specific fields. This query is grouping by the fields in the query that identify the job lead, they are listed here inthe order shown on the design grid. Grouping is the default treatment for fields in SQL queries and is only noticeable in the end results when aggregate functions like counts or averages are applied. For example, in the following query, the COUNT() function is used to get a count of leads in each group.

SELECT Count(LeadID) AS CountOfLeadID,RecordDate, EmploymentType, LocationFROM LeadsGROUP BY RecordDate, EmploymentType, Location;

The groupings in the query are applied in the order that they're shown in the statement so this query is going to group first by the date the lead was recorded. If that was the only grouping, you would get a list of recording dates and the number of leads for each date.

Figure 5.3 - A query of the Leads table showing number of leads by date.

Then the query breaks out the results by Employment Type and finally Location so the final query returns the job lead count for each combination of RecordDate, EmploymentType and Location in the table.

Page 61

Page 66: Microsoft Access for Beginners

Microsoft Access for Beginners

HAVING - HAVING is used to limit the records returned based on properties of groups defined by the GROUP BY clause and cannot be used unless GROUP BY is present. The difference between WHERE and HAVING is that WHERE is applied to individual records before the query performs any grouping. If you specify a particular city in the WHERE clause, only records with that city will be returned. HAVING is applied after the grouping is done. In Figure 5.4, you could use HAVING to return only the cities for which there was more than a specific number of leads found. This would have to be done after the SQL statement completed the grouping by city so it would be done through the HAVING clause. The HAVING keyword is more often used to select by the results of aggregate functions like COUNT or AVG.

Figure 5.4 - Adding fields to the query gives a more detailed view of the data.

ORDER BY - The final keyword lists any fields used to sort the query results. In the example query, the records are sorted by the Employment Type. Again, you can sort by multiple fields and the results will be sorted according to the order of the sorted fields in the SQL code.

Note that the semicolon at the end of the ORDER BY clause is not part of that clause but actually indicates the end of the SQL statement. This indicator is optional but if you include it and then continue the statement after it, you will not be able to run the query.

The example in Figure 5.5 also demonstrates the WHERE and HAVING keywords. This is a short query on a database I created to analyze data from my website logs. The query shows the number of page requests and it groups the data by the file name requested from the site (shown in the cs-uri-stem field). The Count() function on the first line counts the number of requests in each group. The WHERE clause uses the Like keyword to limit the query to certaintypes of content, in this case, it's using the asterisk (*) wildcard to select all files that end with the ZIP extension. Finally, the HAVING clause uses the Count() function again to limit the query results to groups with a count of over 100. In other words, I only want to see cases where a specific type of file (ZIP files) was requested more than 100 times.

Page 62

Page 67: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 5.5 - Another example of the WHERE and HAVING keywords in SQL.

SQL contains many other statements, commands, operators and functions but the ones listed above will be enough to keep you from feeling lost when you view the SQL for a query.

Modifying Data

Beyond selecting records, SQL is also used to change data when necessary. With some very simple statements, you can make changes to large numbers of records or very precise changes to a single record. Using some of the same clauses that you would use for SELECT statements, you can be very specific about what changes you make.

SQL statements that change data are often called action queries or data manipulation queries. The most important thing to remember with action queries is that they cannot be undone. Oncethe data is changed, the only way you're going back to the original data is if you have a backupof the database. For this reason, it's very important to double-check your queries before running them. The old saying 'Measure twice, cut once' applies. Of course, it's also good to backup the database every so often.

Here are some of the common action queries you can use in Access and other databases. Youcan test each one of the sample queries in the demo database.

UPDATE queries

With UPDATE queries, you can change a single record or large numbers of records with a single statement. The syntax is a little different than the SELECT statement but still pretty straightforward.

Page 63

Page 68: Microsoft Access for Beginners

Microsoft Access for Beginners

UPDATE LeadsSET Active = 0WHERE Location = "Atlanta, GA";

The first line specifies the table to be updated and the SET clause uses a simple expression toset the Active field to '0'. The WHERE clause is important here as it limits the records on whichthe change is made. Without this clause, the query would change the Active field for all leads to '0'. In a really large table, you might find yourself wondering why the query is taking so long and then realize with a sinking feeling that you'd forgotten the vital WHERE clause and that you're changing a lot more records than you meant to.

Microsoft Access offers Datasheet View within the Query Builder to show you the results of thequery before it's executed and it's a good idea to get in the habit of using this. Since other database systems like SQL Server don't offer Datasheet View, another way to avoid such mistakes is to write queries as SELECT queries first to see what records will be affected and then changing it to an action query. This is also a good way to get practice writing SQL statements. The example below shows how this would be done with a simple query.

SELECT *FROM LeadsWHERE Location = "Atlanta, GA";

Becomes

UPDATE LeadsSET Active = 0WHERE Location = "Atlanta, GA";

JOIN clauses can also be used in UPDATE statements when two or more tables are related and you need to make changes in one table based on an identifying record in another. Here's an example:

UPDATE LeadsINNER JOIN CompaniesON Companies.CompanyID = Leads.CompanyIDSET Leads.Active = 0WHERE Companies.State = "GA";

This is a variation on the earlier query which sets the Active field to 0 based on the location. Instead of using the Location field in Leads, it uses the State field in the Companies table. The two tables are linked on the CompanyID field so the query uses a join to ensure that only the Leads records that link to Companies in Georgia will be updated. An INNER JOIN is used to limit the records with the value in both tables.

Page 64

Page 69: Microsoft Access for Beginners

Microsoft Access for Beginners

DELETE queries

DELETE queries are used to delete records from specific tables and again, I will emphasize that these queries cannot be undone so it is important to carefully check the query before executing it.

The syntax for a DELETE query is actually very similar to a SELECT query so it's easy to use the method I mentioned earlier of creating the SELECT first.

SELECT *FROM ActivitiesWHERE LeadID = 3;

You can change this to a DELETE query by changing one word:

DELETE FROM ActivitiesWHERE LeadID = 3;

As with SELECT and UPDATE queries, you can join on other tables to determine which records will be selected for deletion.

INSERT INTO (Append) queries

With SQL, you can insert new records into tables, using either a combination of values assigned to the fields or records from another table. You can even copy records from a table back into that same table, changing selected values as needed.

INSERT INTO Companies (CompanyName, City, State)VALUES "ProSoft", "Ocala", "FL";

In the query above, the INSERT INTO clause names the table that will receive the records withthe second line specifying the field names. The VALUES clause specifies the values to be entered in the same order as the field names.

Here's another example where records are copied from one table into another.

INSERT INTO Leads (RecordDate, JobTitle,Description, EmploymentType, Active)SELECT Date(), Title, Details, EmploymentType, ActiveFROM tblLeadImport;

The above is an example where records from an import table are being imported into Leads. The names in the import table are slightly different but so long as the data types of the fields are compatible with the fields in the target table, it will work. The first field in the SELECT clause isn't even coming from the Import table; it's the Date() function which will provide the current date. Also notice that after the INSERT INTO clause, the rest of the query is an

Page 65

Page 70: Microsoft Access for Beginners

Microsoft Access for Beginners

ordinary SELECT statement. It could even use a WHERE clause to limit the records being transferred from tblLeadImport.

INSERT INTO Activities (Activities.LeadID, ActivityDate,ActivityType, ActivityDetails, Complete)SELECT 4, Date(), ActivityType, ActivityDetails, CompleteFROM ActivitiesLEFT JOIN LeadsON Activities.LeadID = Leads.LeadIDWHERE Leads.LeadID = 5

The above query would copy all the activities for one job lead back into the Activity table under another job lead number. It uses a join on Leads to help identify the records to be copied by the LeadID. The result is that the query finds records matching a LeadID value of '5' and copies them, replacing the LeadID with '4'.

The above query will run as shown but if you switch to design view and then back to SQL view,you might see extra text added after the specified values; 'AS Expr1' is added after '4', etc.. These are referred to as aliases and are used as shortcut references to elements within a SQLstatement. Access SQL assigns these aliases to values that are manually entered like the ones in the example. Aliases can also be assigned to tables as shortcut references for long table names.

The important thing to remember with INSERT queries that you must supply values for any required fields in the target table or the query will fail when you try to run it.

MAKE TABLE queries

Sometimes you might want to export data from one table to another. One way to do this is to use a Make Table query. By this time, you'll find the SQL statement pretty familiar.

SELECT LeadID, RecordDate, JobTitle,Description, EmploymentType, Location, Active,CompanyID, AgencyID, ContactID,SourceID, SelectedINTO LeadsCopyFROM LeadsWHERE RecordDate < DateAdd("d",-30,Now());

This query copies all records from Leads where the RecordDate is more than 30 days prior to the current date into a new table called LeadsCopy. The new table doesn't have to exist beforeyou run the query. The query will create it on its own. Access even assigns the correct data types. The only difference between this and a SELECT query is the INTO clause which specifies the destination table.

Page 66

Page 71: Microsoft Access for Beginners

Microsoft Access for Beginners

Conclusion

There are additional types of queries available in Access that enable you to retrieve and analyze data in different ways but the four mentioned here should give you an introduction thatyou can build on as you learn to write your own queries. Learning how to write SQL independently of an interface is an important step in realizing the power available to you when working with Access or any other database.

Page 67

Page 72: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter VI - Designing the Forms

Introduction

In Chapters II and III, I demonstrated how to build the foundation of your database application with properly designed and related tables. Then I showed you how queries can read and manipulate the data you've stored in your tables. Now you need a way for the average user to quickly access and edit the data when needed. As wonderful as a properly designed set of tables and queries is, the database window does not provide a great interface for someone who knows little about the structure of your database or even for you on a regular basis.

The word 'interface' is important because that is what you are designing when you create a data entry form. A well-designed application interface does the following:

• Provides easy access to the features of the program • Simplifies data entry and retrieval with fields that anticipate, where possible, the values

to be entered • Helps to ensure correct data entry and protects existing data by providing templates,

masks and validation rules that require items such as dates to be entered correctly • Anticipates user error where possible and prevents or corrects for it • Offers as much compatibility as possible with accepted design standards and user

expectations so as to minimize the learning curve required to use the program • Conforms to the user's natural workflow so that data can easily be entered and updated

in the relevant order

This represents the ideal that you can work toward as you gain experience with Access and other programming tools. When you design an interface with these goals in mind, your programs are more likely to be readily accepted by other people and you will have an easier time training people on how to use them.

I design my Access applications so that the average user will never have to directly open a table or even view the database window. All work should be completed through the forms and menus. This reduces errors and the chance of a necessary form or query being accidentally deleted or records being improperly deleted from a table. It's not necessary to completely prevent access to the database window except in the most secure applications as some users might be qualified to add their own queries and tools. You should, however, do everything you can to minimize the confusion for those who aren't.

Page 68

Page 73: Microsoft Access for Beginners

Microsoft Access for Beginners

A Word about VBA

For me, any discussion of forms includes references to Visual Basic for Applications (VBA), theprogramming language that Access uses to provide extra functionality behind forms and reports. In this chapter, I make references to the VBA code that I've attached to the form objects in the sample database. You don't need any actual VBA knowledge to benefit from this chapter beyond the understanding that code can be attached to objects to carry out tasks when a button is pressed or other events are triggered. I do recommend that you look at these examples as a first introduction to the use of VBA with Access and start learning the language as soon as possible. A complete introduction to the language is featured in Chapter IX.

Data Sources

Creating forms from scratch is about two things: learning how to use the different controls that are available and how to link the data to them. Every form has a Record Source property whichdetermines where the data comes from. This can be a table, a query or an SQL statement. Figure 6.1 shows part of the properties sheet for the main leads form from the demo database with the Record Source holding a SQL statement.

Figure 6.1 - Forms use the Record Source, usually a SQL statement, to view and edit data in thetables.

The record source of a form specifies where the data comes from. Clicking on the Build button on the right of the Record Source setting will bring up the query window to show you the query behind the form. The text for this query is stored completely within the form rather than as a

Page 69

Page 74: Microsoft Access for Beginners

Microsoft Access for Beginners

separate query in the database.

The record source can also hold the name of a table or a separate query that will function as the data source. If it does, then all of the records returned from that source will be available to the form. Using a SQL statement as shown in Figure 6.1 or a separate query is one way to limit the number of records shown. The form works with the record source to determine which record is currently displayed and to manage the transfer of data between that record and the controls on the form.

Another word for the collection of records made available to the form is a recordset. This recordset is sorted according to the specifications of the query or the order in which the records are held in the table.

Figure 6.2 - The query behind a form can be viewed and edited using the Query By Examplescreen.

The controls you place on the form such as text boxes, combo boxes, radio buttons, etc. access individual fields from the recordset. Each control has a Control Source property which determines which field it will work with. In Figure 6.3, the properties sheet for the JobTitle text box from one of the Job Search Plus forms is shown with the Control Source set to the JobTitlefield provided by the record source shown in Figure 6.2.

This control reads from the JobTitle field so that each record on the form displays the value from the next record in the recordset. Once you understand these two properties, the rest is about placement of controls and fine-tuning of their properties.

Page 70

Page 75: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 6.3 - A form control's Control Source determines where the data will come from.

Creating the Form

To create a new, blank form in Access 2003 and earlier, select the Insert option from the from the main Form menu or select 'New' in the Forms section of the database window. In Access 2007 / 2010, click the Form Design icon from the Create tab on the Access ribbon and then click on the Add Existing Fields icon on the Design tab.

Figure 6.4 - The new form dialog prior to Access 2007.

In Access 2003 and earlier, the New Form dialog shown in Figure 6.4 lets you select a table or query to use as the form's recordset source. In Access 2007 / 2010, you can select a table or query from the database window, select the Create tab on the Access ribbon and click on the Form icon as shown in Figure 6.5 and a form will be generated for that table or query. In order to see what you're actually doing in either of these actions, try this:

Page 71

Page 76: Microsoft Access for Beginners

Microsoft Access for Beginners

1. Select Design View from the New Form dialog (in Access 2003 and earlier) or click the Form Design icon on the Office ribbon in Access 2007 / 2010.

2. Once in design view, display the properties for the form and verify that the Record Source is defined. If it isn't, select a table or query or create a new query by clicking the Build button next to the Record Source property.

3. Try selecting the LeadsList query as the Record Source.

Figure 6.5 - The form creation controls in Access 2007

To view the list of fields available, select Field List from the View menu in Access 2003 and earlier or click the Add Existing Fields icon from the Design tab on the Access 2007 / 2010 Office ribbon. You'll then see the Field List dialog shown in Figure 6.6.

You can click and drag these fields onto the form to automatically add the necessary controls. You'll notice that the type of control added to the form depends on the fields. Fields with lookupfunctions behind them result in combo boxes being added while normal fields create text boxesor checkboxes. When you switch from Design to Form View, the form automatically loads the first record from the table it's using as a data source and displays the data from the fields that have been placed on the form.

At the bottom of the form is the record navigation toolbar which enables you to move through the available records. As with any list, the recordset has a beginning and an end. On this form, moving beyond the last record will create a new blank record and the function of the controls will change. Instead of reading and editing the data, anything typed into the controls will be written to the new record. Depending on the needs of your application, the form can be set to simply display read-only data, to disallow the creation of new records or to hide the navigation bar altogether and only show a single record.

Experimenting with the other form properties available in Design View will also help you become familiar with the many ways in which you can get the most out of your forms.

Page 72

Page 77: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 6.6 - Adding controls to the form is as simple as dragging the controls to the form designgrid from the field list.

Figure 6.7 - The Record Navigation bar displayed at the bottom of Access forms.

Types of Forms

Forms can be used in a number of different ways in Access which is why there are different layouts available. The form shown in the previous section was designed to display a single record at a time with the navigation bar at the bottom enabling the user to move between records. This might not be appropriate to your needs, however, and there are other ways to display your data.

In the form properties, you'll see the Default View setting which, by default, is set to 'Single Form'. You might decide instead to select the 'Continuous Forms' option which enables the user to scroll through multiple records using a scroll bar rather than the navigation control. Thismight be the choice if you were designing a form around a recordset with only a few fields or wanted to focus on scanning through large numbers of records rather than one record at a time. The main Job Leads listing in the sample program is an example of continuous forms. It provides the user with a way to quickly scan through all the available records and select one towork with.

Page 73

Page 78: Microsoft Access for Beginners

Microsoft Access for Beginners

Datasheet View is a format that looks like a table view but allows the fields to have form level controls. The design view for a datasheet form is the same as for single or continuous forms in that you place fields in the grid and set their properties. When you enter Form View, however, the form looks like a datasheet.

PivotTable and PivotChart forms enable quick analysis of numeric data such as sales figures or, in the case of Figure 6.8, my website statistics. Using a PivotTable, you can drop fields from a table or query into the analysis grid and instantly generate counts, averages and other summaries. Using the controls on the form, you can view as much or as little detail as you want for specific elements within the data. In this example, I'm able to see the average numberof requests for specific pages across a given month or quarter and quickly determine the popularity trends for different content.

The unique thing about the Pivot forms is that they focus on analysis rather than entry of data and the view that's shown in Figure 6.8 is the actual Form View where fields can be rearrangedwithin the analysis grid and settings can be adjusted to show the totals needed. Most form types would limit this type of work to the design view but Pivot forms have a dynamic design.

Figure 6.8 - Pivot tables offer a flexible way to analyze data.

When designing Job Search Plus, I designed most forms to display a single record at a time and provided a couple of forms such as the main job leads listing that would enable the user toselect a record for viewing. Even the leads listing is designed to pull only a few fields and is filtered by default. As I mentioned in the last chapter, I did this to minimize the amount of data being retrieved from the database and to protect the data from accidental edits to the wrong record.

Page 74

Page 79: Microsoft Access for Beginners

Microsoft Access for Beginners

Working with Properties

As you've seen by now, every object in Access has a list of properties that you can set to customize your application. The form designer is especially flexible in the ways you can adjust the look and feel of your program. If the properties screen is not already visible, pressing F4 or right-clicking anywhere on the form and selecting Properties from the menu will bring up the list.

Figure 6.9 - The form's property dialog provides a great deal of control over your form's operationand appearance.

One of the things to keep in mind about form properties is that a form has a number of sub-sections including the main detail area, a header and footer section. This is in addition to all the controls you place and a main list of properties that apply to the entire form as a whole.

In Figure 6.9, notice the combo box at the top of the properties sheet. This control contains a list of all of the form elements including the controls that you create. Here, it's set to the properties for the form itself. Each element has a different list of property settings available to it. As you select different controls or sections with this box, you will notice that they are selected within the form design window as well. This can be an easy way to find a specific control on an intricate form.

There are far too many properties available to detail here but you can get more information on any of them by placing the cursor in one of the properties fields and pressing F1 for help. The

Page 75

Page 80: Microsoft Access for Beginners

Microsoft Access for Beginners

more time you spend getting familiar with them, the more you will be able to access the power behind Access form design.

Form Design Toolbar

One of the standard toolbars that you'll use quite a bit when working with Access is the Form Design Toolbar, sometimes called the Toolbox. If this bar doesn't appear automatically when you enter form design mode, you can view it by selecting Toolbars on the View menu. In Access 2007 / 2010, an equivalent set of tools is available in design mode from the Design menu on the Access ribbon. This toolbar includes icons for all of the form controls that I mention in this article plus a few more. It also has a Control Wizards option which is activated by the magic wand icon. Figure 6.10 shows this toolbar in both Access 2002 where it is selected on the left end of the toolbar and Access 2007 where it appears on the right side.

Figure 6.10 - The form design toolbars from Access 2002 and 2007

For the beginner, command buttons and other form controls are one of the few exceptions that I make to what I said about not using the wizards. If you have the Control Wizards activated, a dialog box will appear as soon as you create a form control and guide you through setting up the control to perform any one of a limited number of actions. The wizard will write all the code necessary to carry out the action needed. For small controls such as buttons, it is fine to use these when first designing forms until you become comfortable designing macros and writing code. It is still important, however, to learn how to design without them for finer control.

Startup Options

Forms can serve other purposes besides data entry. The Welcome screen (frmSplash) is one example of this in Job Search Plus. It provides a title screen for the program that includes the version and copyright information. In the application startup options, you can specify a form to load as soon as the application starts. In Access 2003 and prior versions, you open this screenby selecting the Startup option from the Tools menu. In Access 2007, it's opened by clicking onthe Office button and selecting 'Access Options' at the bottom of the menu. Access 2010 features an Options button under the File tab of the Access ribbon. The Startup Options enableyou to define a welcome screen like the Job Search Plus splash screen or run code that is attached to a form to carry out almost any task at startup.

Page 76

Page 81: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 6.11 shows images of the startup settings screens for the sample application under Access 2002 and 2007 / 2010. These settings are unique to the application you're designing. I've set an application title that will display at the very top of the screen while the application is loaded. I've also set frmSplash as the form to be displayed at startup. The option directly belowthis, Display Database Window, specifies if the window will be shown or hidden. I've set it to behidden but you can see it whenever you need to by pressing F11.

Figure 6.11 - The startup options enable you to set such things as the application title and theform that will open on startup.

Sometimes you might want to override these settings and keep the startup from from loading if you're making changes to the database. If you hold down the SHIFT key as you're opening thedatabase, this will bypass all of these properties and give you immediate access to the database window for the application.

Page 77

Page 82: Microsoft Access for Beginners

Microsoft Access for Beginners

Subforms

When viewing the main job leads listing in Job Search Plus, if you double-click on any of the leads, the program brings up the Lead Central screen which shows all the data for that lead in one form. In addition to data from the main Leads table, there's company, contact and activity information for each lead.

The form itself is based on a single table as you'll see if you open the form in design view and find the Record Source property in the form's properties listing. It contains a SELECT statement that pulls exclusively from the Leads table. Previously, I mentioned the importance of limiting the fields in each table to those directly relevant to the table's subject. Now the program needs to bring that data back together in a coherent way. This was done to a certain degree by the LeadsList query which used the link between the Leads and Companies tables to retrieve company information for each lead. The Lead Central form does it in a different way.

With tables that maintain a one-to-one relationship with Leads, it would be simple to include them in the record source for Lead Central. Each lead would still generate one record althoughit would include the fields from the other tables. The Activities table, however, has a one-to-many relationship with Leads and I needed a way to display the Activities information as a part of each job lead record on the form.

Figure 6.12 - Subforms enable data from related tables to be brought together in one form.

A subform is a form that can reside within another form. This creates a parent / child type of relationship just like the tables the forms are based on. In this case, the subform object on frmLeadCentral holds a subform named subActivities which uses the Activities table as a record source and is related to the main form by the one-to-many relationship between the Leads and Activities tables. This relationship is defined when the subform is added to the mainform and is shown in the property sheet in Figure 6.13. You can see the relationship reflected in the Source Object and Link properties. Because of these settings, whenever you pull up a lead in the Lead Central form, the Activities subform will show the correct activities for that lead.

Page 78

Page 83: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 6.13 - Subforms use the relationship between tables to link the data on the form.

Subforms can be created independently of the main form and then added or created with the subform / subreport button on the toolbar. In either case, they are saved as separate objects inthe database. Using subforms, you can add, edit and delete multiple records in the related tables as needed.

There are a few ways to add a subform in Access. The primary method is to select the subformcontrol from the control toolbox while in form design view and click anywhere on the form to which it is to be added. If the Control Wizards option is activated, a series of dialog boxes will guide you through the selection of a subform and setting up the relationship.

Figure 6.14 - The subform wizard makes it easy to create a new subform.

Page 79

Page 84: Microsoft Access for Beginners

Microsoft Access for Beginners

You can also drag a subform from the database window to the main form while in design view and Access will automatically add it as a subform control. If you do this or if you insert a subform normally but without the Control Wizards activated, you will need to manually set the Master and Child Field settings as shown in the property sheet shown in Figure 6.13. Clicking on the build button next to one of these properties brings up the Subform Field Linker dialog. This dialog can recommend field relationships based on the recordset in each form.

A unique feature of the subform object on LeadCentral is that it actually uses a number of subforms to display all of the data available. If you click on the option buttons above the form, you can switch between the activities data and the company, contacts or related leads. Often aTab control would be used to do this but I decided it didn't fit with the appearance I wanted for the program so I decided to program my own system to change out the subform when the userclicks on one of these radio buttons. This is all done with VBA code which is not exactly one of the basics of Microsoft Access but all the code really does is change the Source Object and Link fields for the subform control on the Lead Central form. As you gain more experience with Access, it will help you to learn something about VBA as it makes it possible to dynamically change form settings based on user actions and apply these types of customizations possible. For more about Visual Basic for Applications, see Chapter IX.

Figure 6.15 - The subform field linking dialog

Additional Controls

The Job Lead Central form has a good sampling of some of the controls you can use to enter and manage data in Access. Using these very flexible controls, you can build an interface that provides the features and protections outlined in the introduction to this chapter. You'll probably want to have the form open in Design View as I go over some of the controls that this form uses. To view the properties on any control, right-click on it and select the Properties menu option.

Page 80

Page 85: Microsoft Access for Beginners

Microsoft Access for Beginners

Combo Boxes

A number of fields on the Job Lead Central form are represented by combo boxes which are the fields with the dropdown arrow on the right side which enable you to choose from a list of values. When typing values in these boxes, you'll notice that they also attempt to supply possible values based on what you're typing. This is called the Auto Expand feature. In addition to speeding up data entry, combo boxes can also help to ensure accuracy by supplying a set number of choices for the user to enter into the field.

To see the flexibility available through this control, look at the properties for one of the combo boxes. See Figure 6.16 for an example.

Figure 6.16 - Combo box controls also use queries as data sources.

If you look at the Row Source property for the Location field, you'll notice that it's actually a query. The control uses a query to pull up a list of the Locations that were previously entered inthe database so that when the user enters a location for a lead, he or she only has to start typing the location name or press F4 for the pull-down list. Also, you'll notice that the 'Limit to List' property for this control is set to No. This means that the user can enter new locations thatare not in the database and those locations will be added to the available choices.

The Limit to List property could also be set to Yes if the user was to be limited to a specific list of choices. An example of this would be the ActivityType field on the Activity subform. All of theproperties in this section affect the way this control accesses and displays information. By clicking once on a property and pressing F1, you can find additional information on its function and uses.

The ActivityType field also demonstrates another setting. The values from this field do not come from a table. Instead, it's a small list of values that are stored within the field setting itself.

Page 81

Page 86: Microsoft Access for Beginners

Microsoft Access for Beginners

The options are entered in the Row Source property as string values (non-numeric values enclosed in quotes) separated by semi-colons. The pull-down list on the control shows these values just like the other controls did and the user is limited to using one of the values supplied.

Figure 6.17 - Value lists can also be used as the data source for combo boxes.

This type of control can be created manually when designing the form and you can adjust the settings as needed. In the case of these fields, however, the settings were made automatically as soon as the fields were placed on the form. This is because the lookup functions described above were actually defined when creating the tables. If you open the Leads table in design view, you'll see that the Location field is designed to get its information in the same way as its control on this form. When I placed the control on the form, it inherited the properties of the table field that it was bound to. This inheritance only happens when the control is created. If you change the table field properties, the control does not change automatically.

Radio Buttons and Checkboxes

Sometimes, you might want to provide a small list of choices for a user to select from and then use the result to update a field. The radio button is one control that you can use for this. In the lower right-hand corner of the Job Lead Central form, you'll see the following control which enables the user to mark the lead as active or inactive by changing the value in the Active fieldof the Leads table.

Figure 6.18 - Radio buttons provide a good interface for Yes or No options.

This is actually a Boolean field which would normally generate a checkbox when placed on a form but I decided that radio buttons would make the choice clearer for the user so I used theminstead. In this case, the individual buttons return either a -1 or 0 depending on the selection and that value is used to update the Boolean field.

Page 82

Page 87: Microsoft Access for Beginners

Microsoft Access for Beginners

Radio buttons are contained within an Option Group control which groups the buttons together to deliver one value to a table field. To create the control, you would create the Option Group on the form first, set its Control Source property to the necessary field, drop the Radio Buttons inside the group and set the Option Value property of each Radio Button control to the value you want the button to return. When the user clicks on one of these buttons, it will return that value to the Option Group control which will update the field through its Control Source setting.

Again, the Active control shown in figure 6.18 would normally be represented by a checkbox. When a checkbox is checked, it equals a True value which can be represented by -1. When unchecked, it equals a False or 0 value. You can also use the Triple State property of the checkbox to have the control deliver a third value to the field if necessary which could be shown as 1.

Figure 6.19 - Some controls are more appropriate than others depending on the situation.

I generally favor using a combo box supplied by a value list as shown with the ActivityType field because it takes up less space on the form. Sometimes, however, an option group can bethe appropriate choice depending on the application. The example in Figure 6.19 shows how the appearance of an option group compares to the combo box control.

Command Buttons

Command buttons are one of the most useful and versatile tools in form design. The buttons atthe bottom of the Job Lead Central screen enable the user to navigate to different screens andperform necessary functions. The appearance options for command buttons are much more flexible in Access 2007 and 2010 than in previous versions.

Figure 6.20 - Command buttons provide a simple way to run commands or navigate betweenforms.

A command button provides a familiar device that the user will recognize as a way to start a task. When the user clicks on the button, it appears to act just like a real button, moving in and out. What the user is actually doing is activating the macro or section of VBA code that is attached to one of the button's event properties, usually the 'On Click' or 'On Dbl Click' event.

Page 83

Page 88: Microsoft Access for Beginners

Microsoft Access for Beginners

To see what I'm referring to, choose one of the buttons in design view and find the On Click event in the button's properties. The words '[Event Procedure]' indicate that VBA code has been written for that event. Then click on the Build button that appears next to the property. This will bring up the VBA design environment in a separate window and you can view some ofthe code that I've written for these buttons.

Figure 6.21 - Form events are used to run macros or VBA code when a specific action occurs.

The code in Figure 6.21 is an example from the button that returns the user to the main Leads List form. The first and last lines indicate the beginning and end as well as the name of the subroutine and its attachment to the command button's click event. The rest represents instructions to save the record shown in the Job Lead Central form and then close the form if the record has been successfully saved.

If you place a button control on the form and have the Control Wizards activated, you can use the wizard to select what action should take place when the user clicks the button. This could be anything from moving to another record to closing the form to closing Access itself. The command button wizard will create the button based on your instructions and actually write the VBA code in the background for you. I'd recommend experimenting with the button control wizard to get a sense of all the things you can do with this type of control.

Page 84

Page 89: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 6.22 - The command button wizard provides an easy way to create buttons for a variety oftasks.

Tab Controls

A tab control features tabbed pages, each with its own set of properties and controls. You can add and remove pages as needed from the control. In Figure 6.23, you can see how a tab control from another sample database organizes information on a form.

Controls can be dragged from the form to a tab control which can hold as many tabs as you need. They are very useful in cases like this one and there are a couple of extra features that I'll talk about later on.

Form Events

As I mentioned in the section on command buttons, forms and other objects have events that are triggered by user actions or other events. These include events such as On Current (the event that runs every time the user moves to a new record) and On Click (run when the user clicks a button). The events on the form's property list can hold VBA code or macro references that can be used to change other form properties or perform various actions when a specific event occurs. A number of events can and often do occur in rapid succession in what would appear to the user to be only one event. For example, when the demo program's splash screen closes, this triggers the form's On Close event which contains code that opens the job leads listing. When this form is opened, the following events occur between the time the command is issued to open the form and the time you see the form on the screen:

Page 85

Page 90: Microsoft Access for Beginners

Microsoft Access for Beginners

Open >> Load >> Resize >> Activate >> Current

You can see all of these events listed on the form's property sheet where you can get more information by clicking on any of them and pressing F1. For right now, just understand that these events are always going on in the background and Access makes them available to give you precise control over how your application operates. For this reason, Access programming is referred to as event-driven.

Figure 6.23 - The tab control provides a way to fit more controls on a form without making itcluttered.

Custom Menus and Tools

If you are using the sample database, you might notice that the tool and menu bars at the top of the screen look different than normal. This is because in addition to designing forms for the database, I also designed a custom menu and toolbar as part of the interface. If you right-click anywhere on these bars in Access 2003 or previous versions, the pop-up menu should containa Customize command with which you can pick and choose the buttons and menu options youwant to show to users. This can be very useful both for hiding potentially dangerous options from inexperienced users and providing custom functions that will automate various tasks in your application.

Access 2007 and 2010 still have a Quick Access toolbar which is displayed above the Office ribbon and can be customized to include the controls you need. When using the demonstrationdatabase within Access 2007 / 2010, you'll find the custom menu and tool bar shown under theAdd-Ins tab on the Office ribbon.

Custom utility bars are part of the application and are not dependent on the forms. You can specify different menu and tool bars for different forms and reports. In this way, you could

Page 86

Page 91: Microsoft Access for Beginners

Microsoft Access for Beginners

design separate custom bars based on the needs and functions of specific sections of your program. If you import a form from one database file to another, you will see an option to import whatever custom utility bars are referenced by it. If you don't want to specify a menu baron every form you create, you can also name one menu bar as the default in the application startup options and it will appear throughout the database, even when viewing the database window.

Figure 6.24 - Custom menu and toolbars are useful for refining your application's interface.

A third type of custom menu is a pop-up menu. This is the menu that appears when you right-click on a form or another object. Again, this menu can be customized to meet the specific needs of the application.

The Office 2007 / 2010 ribbon can also be customized to fit your application. In Access 2007, however, it is a complicated process that involves writing XML code in a hidden table and is beyond the scope of this book. If you want to tackle it, start with the following link:

http://www.databasedev.co.uk/access2007ribbon.html

Access 2010 simplifies the process by adding a dialog interface which you can access by right-clicking on the ribbon and selecting Customize Ribbon.

My personal use of custom utility bars is mostly limited to removing unneeded or confusing options but as you work with Access, you might find the ability to customize these menus to be

Page 87

Page 92: Microsoft Access for Beginners

Microsoft Access for Beginners

a powerful part of application design that you wouldn't want to be without. It is one more tool that you can use to make the application your own.

Tab Order

Figure 6.25 - Tab order determines the order in which controls on the form receive the focus.

One of the properties of your form that determines its behavior is the Tab Order. This one can be seen in Design View by right-clicking on the form and selecting it from the pop-up menu. This dialog shows the order in which the focus will move between your form controls when youpress the Tab key. The property sheet for each control contains the Tab Index and Tab Stop properties which determine if and when a control will receive the focus. In the Tab Order dialog, you can drag the fields within the list to change their tab order or you can click Auto Order which will reorder the fields according to the order in which they appear on the form, left to right and then top to bottom. The Tab Order settings are very important in terms of making the form's behavior conform to the order in which the user can most easily enter the data.

Storing Pictures and Attachments

Storing photos or other images in Access is a challenge because of the way the program stores the image information. Access has an OLE Object field type that will store any kind of file, including other Office documents, Acrobat files and images. For binary files like Word and Acrobat, this works great. For image files, however, Access stores the image in an uncompressed format. In other words, an image that takes up less than 50 KB in compressed

Page 88

Page 93: Microsoft Access for Beginners

Microsoft Access for Beginners

JPEG format on disk can take up well over a megabyte when inserted into the Access table. That's over a megabyte for every picture stored. The database file would get huge.

A common solution in Access 2003 and earlier is to store images on disk instead and store thepath information of the image file in the database. Figure 6.26 shows this solution implementedin an employee database.

The picture is actually an unbound OLE field and the text field above it is bound to a field in thetable that stores the path information. The Hide Employee Pictures button under the picture uses VBA code to switch between showing and hiding the photos. The On Current event for the form fires every time the user pulls up another record and includes code to read the location from the text field and display the picture in the box so long as the Hide button hasn't been invoked. The field displays the image without taking up room in the database.

Figure 6.26 - A database can also store pictures, however they do take up a lot of space.

Access 2007 introduces an Attachment field that can store different file types including images and the database settings can be adjusted to avoid the bloat that would previously occur from storing images. The field also allows multiple files per record and features a nice interface for browsing through the stored files which is a huge improvement over the OLE fields. Still, storing files in your database takes up extra space and if the database is corrupted in any way,you could lose the photos. Storing them in a dedicated directory that Access can link to is the better solution when possible.

Working Out the Bugs

It's a rare occasion when anything I'm designing works exactly right the first time. At the very least, some tweaks are needed here and there to get the right result. Sometimes the process can be much more involved and can take hours before a form or function works the way I needit to. During that time, I'll be making changes here and there, consulting technical forums and

Page 89

Page 94: Microsoft Access for Beginners

Microsoft Access for Beginners

help files and almost always learning something I didn't know before. Another rarity is a projectwhere I don't learn at least two or three new and fun things I can do with Access. Discovery is half the fun, after all.

The more time you spend testing and debugging a program, the better. Every hour that you spend testing means at least one less potentially embarrassing problem for the user to discover. Entering pages of test data and coming up with test scenarios can be tedious and sometimes Access can seem to have its own obstinate personality when that one function you know should work doesn't. Debugging is essential, however, if the interfaces you design are going to meet the user's needs.

Of course, beyond the process of debugging, there's the time that you spend looking for ways in which to improve the application. One saying that's stuck with me over the years is "That which is 'good enough' seldom is." Your willingness to look for improvements in your programs for the benefit of the users, even when you don't believe they're strictly necessary, makes the difference between designing a barely adequate program that eventually has to be replaced at great expense by a professional programmer and providing a great solution that is praised by the people who see and use it.

Conclusion

The introduction of forms and the event-driven interface in this chapter shows a different side of Access than you saw when setting up tables and queries. Where tables need to be setup according to the rules of database normalization for the application to work efficiently, forms and reports allow for much more flexibility and creativity on your part. Your next step should beto learn as much about form design and event handling as possible so you will have the foundation to build any application you need to. This knowledge will help you not only with Access but with other database systems and programming environments.

Page 90

Page 95: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter VII - Generating the Reports

Introduction

Most database applications of any size involve some kind of reporting system. A well-designedsystem compiles and summarizes information in a way that can be easily understood by those who need to make decisions based on it. Fortunately, one of the strengths of Microsoft Access is its built-in reporting tool. With Access, you can design a variety of report types, including charts and graphs, as easily as you would design a form.

From Forms to Reports

Designing reports is very similar to designing forms. Once you're familiar with one, you'll find many of the same features in the other. The only difference is that, in general, reports are intended for printing where forms are meant for screen display and user interaction. While reports use the same controls to display data such as text boxes, labels and subreports, the data is only intended for presentation and cannot be edited on the report.

Some other similarities:

• Reports are based on a query that pulls the data from the tables. The data can be drawn from multiple related tables.

• Once the source of the data is specified, controls are arranged and placed on the report design grid in the same way as they are on forms.

• The report uses the same controls and tools as forms do although some controls such as combo boxes might appear differently in an environment where the data cannot be edited.

• Reports have a set of properties and events that you can work with to control the behavior of the report.

Creating a Report

Creating a new report is very much the same as creating a new form; in Access 2007 / 2010, you can find the report controls under the Create section of the Office ribbon. In Access 2003 and earlier, select the Reports section from the database window and click 'New'.

Page 91

Page 96: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 7.1 - New reports are created in a similar way to new forms.

As mentioned above, reports share many features with forms. The report has a Record Sourceproperty that determines where the data comes from and each control on the report has a Control Source that specifies which field in the record source it interacts with. The main differences are a greater emphasis on header and footer sections and the formatting of pages for printing rather than display. New reports are automatically divided into three main sections that can contain data:

• Report Header / Footer - This section appears at the beginning and end of a report and can contain such things as the report title and the date it was run. On a multi-page report, the header only shows on the first page and the footer on the last.

• Page Header / Footer - This section is for information you want on every page such as page numbers or data headings.

• Detail - This section is for the actual report data and would contain all of the rows generated by the recordset behind the report.

Any of the header and footer sections can be shown or hidden based on your report needs by right-clicking on the report design and selecting or deselecting the option from the pop-up menu. You can also add custom header and footer sections to reports based on the way data is grouped in the record source. An example in the demo database is the Lead Detail report where the data is grouped on the LeadID value. This value is unique for each job lead so it provides a value for the report to reference. By adding a header section for this value to the report, I was able to generate a separate report section for each job lead as needed. I'll show more of the details on how this is done later in the chapter.

Page 92

Page 97: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 7.2 - The report design view interface with report and page header / footers visible

Report Margins

While in Design View, you can select the 'Page Setup' tab from the Access 2007 / 2010 Office ribbon or 'Page Setup' from the File menu in Access 2003 to see the page settings for the report as it will be printed. The first tab shows the margin settings for the report. Figure 7.4 shows some of the page settings for the Lead Detail report.

Figure 7.3 - Report design view for a finished report

Page 93

Page 98: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 7.4 - Report page setup options in Access 2007

I have all of the margins on this report set to 0.5 inches to provide plenty of space for the data. I've used the default settings with letter-sized paper (8.5" x 11") and set the orientation to Portrait. The Page Setup options also enable you to print from specific trays on your printer or to use a manual feed for such things as labels and envelopes. Also note that you can specify aspecific printer for the report from the Page Setup control panel in Access. An example would be if you had a wide report that could only be printed on a wide-carriage printer.

Another useful feature of the design environment is the ruler guide that shows the height and width of the report page. While a form that is too big for the screen will only require the user to move a scroll bar, a report that is too big for the paper it's being printed on will print the overflow on separate pages which will probably not be what you want.

Figure 7.5 - Report designer rulers can help place controls just right.

Figure 7.5 shows part of the design view for the Lead Detail report. Notice that the right edge of the report is set at 7.5" because the report is set with 0.5" margins on either side and it's printing on 8.5" paper. Setting it wider would result in a warning message when the report was opened in preview mode.

Sample Reports

To demonstrate some of the features available on Access reports, I've included the Lead Detail

Page 94

Page 99: Microsoft Access for Beginners

Microsoft Access for Beginners

report in the demonstration database. For the rest of this chapter, I'll offer some details on how I created it.

The Lead Detail report provides an overall picture of the information stored on each job lead. The query behind it is much like that of the Job Lead Central form. It contains linked tables to provide different types of data.

Custom Report Sections

In addition to the normal sections, this report also has a section titled 'LeadID Header'. This section represents a report grouping based on the LeadID field which uniquely identifies each job opportunity. To see the group settings, right-click on the group title bar and select 'Sorting and Grouping' from the pop-up menu. Access 2003 and earlier shows a separate dialog box while Access 2007 / 2010 displays the settings below the report design area. These controls are shown in Figure 7.6.

Figure 7.6 - Sorting and grouping options enable a report to be customized as needed. Dialogsfrom Access 2002 and 2007.

The settings specify that a header section for this group will be shown but no footer. The reportis grouped on each value which, in this case, means each job opportunity.

Custom headers and footers have their own sets of properties just as the other reports

Page 95

Page 100: Microsoft Access for Beginners

Microsoft Access for Beginners

sections do. If you right click on the LeadID header bar and choose 'Properties', the Properties sheet will appear.

Figure 7.7 - Report header and footer sections have their own set of properties.

Custom headers can also be created for other types of fields such as date ranges or currency values.

Automatic Report Fields

At the top of each report page, you can see a header that shows the date the report was printed. The bottom of each page shows the current page number. Since reports are often multiple page documents and are meant to be printed for reference and presentation, these are a couple of page elements that you can automatically insert to enhance the report.

Figure 7.8 - Dynamically generated text can add nice finishing touches to a report.

In Access 2003 and prior, choosing the options from the Insert menu in design view will bring up dialogs which include the necessary formatting options and this makes it pretty simple to

Page 96

Page 101: Microsoft Access for Beginners

Microsoft Access for Beginners

add these elements. In Access 2007 / 2010, these options are found in the Controls section of the Design tab on the ribbon. Behind the scenes, the dialogs simply create new text boxes on the report where the Control Source contains text and codes that Access translates into the current date and time or the correct page numbers.

Figure 7.9 is the property sheet from the page count on the profile report. Instead of referring to a table or query field, it uses the equals sign and then concatenates a text string using the [Page] and [Pages] values of the report which provide the current page and total number of pages respectively. Knowing this, you could customize the box as needed.

Figure 7.9 - The Control Source property for a report field is useful for generating dynamic text.

The date and time are the same except that Access uses the Date() and Time() functions to show the correct values.

Figure 7.10 - Functions can be combined with other text to return information on the report.

In this case, Access also uses the Format property to determine how to display the values. Again, knowing how this textbox is made, you can customize it to your own needs. You could even enter something like this for the Control Source:

= "Generated on " & Format(Date(),"Long Date") & " at " & Format(Time(),"Medium Time")

Page 97

Page 102: Microsoft Access for Beginners

Microsoft Access for Beginners

This would show up on the report like this:

"Generated on Sunday, February 03, 2012 at 10:46 AM"

Because I'm concatenating a string with both the date and time and extra words, I have to use the Format() function instead of relying on the Format property of the text box. The function accepts the Date() or Time() function as its first parameter and then I use a pre-defined format style for the second parameter, in this case "Long Date" which includes the weekday and the full spelling of the date and "Medium Time" which displays the time with the AM/PM indicator. For more information, search Access help for the Format() function as it applies to Date / Time formats.

Adding Subreports

The Detail section of the report is where you would put most of the data generated by the report query. In the detail section of the Lead report, I placed an activity subreport to show the activities for each lead. Subreports act a lot like subforms. They are based on a table that is related to a table in the main report query and linked to the main report on the corresponding fields.

Figure 7.11 - Subreports work much the same as subforms, linking data from related tables.

In this case, the subActivity report uses a simple query on Activities and links to the main report through the LeadID field. Because the detail section is contained within the LeadID grouping on the profile report, the subreport limits itself to the records pertaining to the lead shown on the current page.

The subreport object has a property that you need to be aware of. The 'Can Grow' property enables the subreport to expand vertically to accommodate extra data. In design view, you'll notice that the subreport is set to a minimum height but when you run the report for certain job leads, the content of the subreport takes up more room on the page. With the 'Can Grow' property set to 'Yes', the Activities subreport will expand as much as needed any other content below it would move as needed.

Page 98

Page 103: Microsoft Access for Beginners

Microsoft Access for Beginners

Printing Labels

Although it's not used in the demonstration database, there is one more report type that I wanted to mention as it's an exception to my warnings on using design wizards.

The Label Wizard does a great job of setting up a report to print labels on a range of predefined label templates including different Avery sizes. Microsoft Word and other software titles will also do this. The difference here is that you can fill the labels with data from your current database without having to export it.

To use this wizard in Access 2007 / 2010, select a table or query in the database window that contains the data you want to use, select the Create tab on the ribbon and select the Labels icon under the Reports section.

For this report, I'm using Avery 5160 labels to print mailing labels for the companies in the database. The report could be based on a query that selected the records to include. In this case, I'm taking it directly from the Companies table. Again, some of the tasks that the wizard does are ones that you could easily do yourself once you're familiar with report construction. The wizard shown in Figure 7.12 will lay out the fields from the query on a sample label.

Figure 7.12 - The Label Wizard is a simple way to create a variety of labels from your database.

Page 99

Page 104: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 7.13 - The Label Wizard includes a wide variety of label sizes.

The main benefit of using the wizard here is that it works with the page setup to set the width and height of the labels to the exact dimensions defined by the various label makers. This is something where you would otherwise spend a lot of time on trial and error.

Figure 7.14 - Creating labels is as easy as laying out fields on the label template.

Page 100

Page 105: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 7.15 - Design view makes it easy to fine tune the label design.

In the design view of the label report, you can see how the fields from the query are setup in the detail section and the report width is adjusted to the exact size of the label. The header sections are available but are not used as this report is just printing the labels. There are a couple of other screens in the Access 2007 / 2010 wizard that allow you to set the font size and color and choose a field to sort by. This is a good beginning example of how Access reports can be tailored to more than just straight reporting of data.

Managing the Interface

Users need some way of accessing new reports in the application, either from a button on one of the forms or from a menu. I try to avoid having users work with the database window as much as possible. Giving them interface elements to work with provides a smoother, more professional experience and protects the collection of objects that your application depends on. How you make a report available in the interface depends on how it will be used.

Figure 7.16 - Command buttons can be used to provide easy access to various parts of theprogram.

For convenience, the Lead Detail report is available via command buttons on both the Leads Search List and Job Lead Central. These two screens enable the user to select which lead the report will be run for. In the full version of Job Search Plus, it's also available from a program menu option which brings up a search options screen where the user can select the job leads to include in the report. If you examine the code behind these buttons, you'll see how VBA can be used to make the interface more responsive.

Page 101

Page 106: Microsoft Access for Beginners

Microsoft Access for Beginners

Conclusion

I've shown you the basics of reporting in Access but I hope you can see that there are a lot more possibilities available to explore. Having such a rich built-in design environment is one of the great strengths of Microsoft Access. Other development tools require you to either use a separate reporting system or to design your own. I've even seen Access used solely for its reporting tools by other programs.

Reporting might be the aspect of your application that adds the most value for the users who will ultimately decide if the application succeeds or fails as a production tool. It can also be the most demanding part of application design as it requires the most input from the people who will be relying on the reports and that input can sometimes be detailed and conflicting. The more familiar you are with the reporting tools and their abilities, the more likely you are to create a successful application that will impress the users and have them coming back for more.

Page 102

Page 107: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter VIII - Automating the Interface with Macros

Introduction

In earlier chapters, I mentioned that Microsoft Access is an event-driven environment, meaningthat forms and reports can respond to events such as a user clicking on a command button, a form opening or a control receiving the focus.

Access uses two kinds of programming in order to respond to these events; macros and VisualBasic for Applications (VBA). In this chapter, I'm going to give you an introduction to the simpler of the two; macros.

Access 2007 and Earlier

In Access, macros are an easy way to automate many types of operations such as the openingof forms and reports, record navigation and even the administration of custom menus. Macros enable you to specify a number of actions that should be taken in sequence and then to assignthese actions to form and report events. In Figure 8.1, you can see a simple macro in Access 2007 that opens the InitialEntry form from the sample database and then maximizes it on the screen.

Figure 8.1 - The Macro design environment from Access 2007 and earlier

Page 103

Page 108: Microsoft Access for Beginners

Microsoft Access for Beginners

You might notice that the macro designer looks a lot like the table designer. Macros are stored in groups as separate objects within the database and each macro object can store a single macro or multiple individual macros. These individual macros can be distinguished by names in the column at the very left of the designer. Each row in the top part of the designer represents a separate action within the macro and there's a predefined list of actions that you can select. In the bottom part of the designer, you'll see the parameters specific to the selectedmacro action. For the OpenForm action selected in the first row, these parameters include the name of the form, a form filter expression and options to determine how the form behaves on screen. Just like in the table designer, you can switch between these two sections by pressing F6.

The designer has five columns that can be used to define the macro actions, three of which can be shown or hidden from view.

Macro Name

This column defines the start of a new macro in the designer dialog. When Access is running the macro, it will start with that line and continue down the list until another macro name is specified.

Figure 8.2 - Submacros can be created by adding a name in the Macro Name column.

In Figure 8.2, there are actually two macros defined. If Access is instructed to run the InitEntry macro, it will start with the OpenForm action and continue with the Maximize action below it. Once it gets to the MsgBox macro name, it will detect a new macro and stop. Blank lines withinthe macro designer will not affect the execution of the macro commands.

Condition

This column can accept any expression that can evaluate to True or False. The condition is used to determine if the action on that row should be executed. The Expression Builder can beused by right-clicking in the condition column and selecting Build from the pop-up menu.

Page 104

Page 109: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 8.3 - The condition column allows for specific actions to be run only when necessary.

In Figure 8.3, a condition is placed on the MsgBox action so that it is only run if that condition is met. The expression shown counts the number of active leads in the Leads table, or leads where the Active field does not equal 0. If there are no active leads, the expression is True andthe message box is shown. If there are active leads in the table, the expression is False and the message box does not display.

Action / Arguments

The Action column specifies what you want that line of the macro to actually do. By using the dropdown list in this column, you can select from a wide range of actions that include everything from record and control navigation to the opening of specific forms and reports. If you select one of these actions, you'll see a description of the action in the bottom right-hand corner of the macro design screen next to whatever parameters exist for the action. Most of the time, you probably won't enter information directly in the Arguments column as this column is automatically completed when you set the parameters for the action in the bottom half of the design screen.

Comments

You can use this column to enter explanatory comments on your macros. This is a good idea when you're designing so that when you go back to make changes later, you can know what you originally had in mind.

Running Macros

Figure 8.4 - The macro control panel from Access 2007 includes buttons to run the macro, showand hide columns and mange rows.

There are a couple ways to run macros in Microsoft Access depending on how you're using the

Page 105

Page 110: Microsoft Access for Beginners

Microsoft Access for Beginners

macro. Within the macro designer, selecting a row and clicking on the Run button shown in Figure 8.4 will run that macro. Double-clicking a macro object in the Access database window or right-clicking on it and selecting Run as shown in Figure 8.5 will run the first named macro inthe macro object. This would be appropriate if you have a single, large macro that you're using for database maintenance or when testing a new macro. Next to the Run button in Figure 8.4, you'll notice the Single Step option. When this is activated, the macro will pause after every action and display a dialog box with the details of the step and any errors. This can be a usefultool for testing a new macro and finding the source of errors.

Figure 8.5 - Macros can be run either through the macro control panel or by right-clicking andselecting the Run option.

More commonly, macro names are referenced by the event properties of forms and reports. In Figure 8.6, you can see the event properties for a command button where the Click event calls the InitEntry macro in the FormEvents macro object. As soon as you save a macro, it will be made available in these dropdown boxes. This macro will open the form for entering a new job lead and selecting it for the On Click event will cause it to open when the button is clicked by the user.

Notice that the macro object itself is available along with the individually named macros within it. Again, calling the main macro object will run the first named macro within it. If there are no named macros within it, the macro commands will run sequentially.

Macros can also be embedded within forms and reports rather than being stored in the macro groups accessible from the database window. This might make it easier for you to manage your application as the macro code will be right there within the form or report and accessible from the event properties. To do this, select the event that will be calling the macro, click the Build button and select 'Macro Builder' from the choices presented.

Page 106

Page 111: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 8.6 - Once a macro is saved, it can be selected to respond to events on forms and reports.

Figure 8.7 - Macros can be embedded within forms to simplify editing.

The macro editing screen looks the same as the designer for the standalone macros shown earlier. After you save the macro, it will be available from the property sheet which will show the '[Embedded Macro]' notation for the events affected. You can use the Build button on the event property to edit the macro as needed.

Page 107

Page 112: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 8.8 - Macros can be embedded within forms and reports instead of being stored asstandalone macro objects.

The Autoexec Macro

In an earlier chapter, I wrote about the Startup option that enables you to specify a form that will be opened whenever the application starts up. Macros provide an even more flexible way to set actions at startup. By creating a macro and naming it "autoexec", you can specify a list of actions that will run as soon as you open the database. Using this method, you could do anything within the list of actions that macros can take, including running VBA code. The nameautoexec is a holdover from the days of DOS when PCs used a file called autoexec.bat which would run a group of commands every time the system started.

Sometimes, when opening a database to make design changes or examining an application someone else has written, you might want to avoid activating the Startup Options or running the autoexec macro. To do this, simply hold down the SHIFT key while the database opens. It's important to hold the SHIFT key down until you're certain that the database is finished opening. In a previous job, I was responsible for documenting a collection of Access databasesthat had been created by another developer. Some of these applications had been designed torun complex routines at startup, some of which made changes to company databases. It didn't take me long to get firmly in the habit of using the SHIFT key bypass as it's called whenever opening an Access database unless I was absolutely sure of what was going to be running at startup.

Access 2010

With the release of Access 2010, some major changes were made to the macro design interface. Macros can now perform more complex decisions based on conditions within the program. There were also changes in the look of the macro design environment.

One thing to remember is that for basic needs, macros still work essentially the same. In the left half of Figure 8.9, you can see the OpenForm action opening frmSplash, the title form of the database. Instead of laying out the actions in the old interface that was similar to the table design screen, the settings for the action are shown vertically. Below that action, you can see adropdown box that enables the selection of the next action for the macro.

Page 108

Page 113: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 8.9 - Macro editing environment from Access 2010

The pane on the right of Figure 8.9 is the Action Catalog. This is where you can select from thelist of actions available to the macro. At the top are the Program Flow actions and a couple of these are similar to functions in the old style macros. The Comment function does just what it says; it inserts a comment at a point within the macro. Instead of being tied to a specific action,however, these comments are meant to document the logic of the macro itself.

In Figure 8.10, you can see the comment that's been inserted at the top of the macro. Once you're finished editing a comment, it changes to the condensed format shown with the start and end points (/* */) shown. This is actually similar to the commenting style in other, more advanced, languages. By clicking on the comment, you can re-enter edit mode and make whatever changes you need to.

Another feature to notice here is on the OpenForm action. Notice the green arrow showing in the top right corner of the action's edit box. In Access 2010, macro actions can be reordered just by clicking on this up / down arrow. The X next to the arrow enables you to quickly removean action from the macro. Macro actions can also be dragged from one place to another in the macro.

Page 109

Page 114: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 8.10 - Access 2010 macros can include comments to describe the flow of the macro.

Going back to the Action Catalog, the submacro command under Program Flow is essentially the same as the internal macro names described earlier in the chapter. Commands added to a submacro will only be run if that submacro is specifically called within the program. If you run the parent macro, such as this autoexec macro, the submacros will not be run.

Figure 8.11 - Grouping in Access 2010 macros promotes organization and easier editing.

The Group action is strictly used for organizing the contents of macros and does not affect the execution of the macro. In a large macro, you might want to divide it into sections to help whendeciphering it later. Groups can be given helpful names that will make it easier to find specific submacros and actions. If you notice the minus sign next to the group name in Figure 8.11,

Page 110

Page 115: Microsoft Access for Beginners

Microsoft Access for Beginners

you'll see that they can also expanded and collapsed, allowing you to focus on the necessary part of the macro. Actions and submacros can also be collapsed or expanded as necessary. Again, this does not have any affect on the execution of the macro but is there for convenience.

The most powerful new feature in the Action Catalog is IF. This function enables you to add conditional statements to the macro which previously were only possible through VBA. The If ... Then ... Else decision structure allows for multiple conditions, each with a different response. The full syntax is something like this:

If <condition1> Then <action1>ElseIf <condition2> Then <action2>ElseIf <condition3> Then <action3>Else <action4>EndIf

In Figure 8.12, you can see the 'If ... Then' structure applied in decision about which report to open based on the current date.

The rest of the commands from the Action Catalog are similar to those in previous versions with, perhaps, a few new ones. The new macro designer does add the convenience of grouping them by category which might help you find what you're looking for faster. Regardlessof which version you're using, I'd recommend taking some time to experiment with different actions to get familiar with what you can do with macros in Microsoft Access.

Conclusion

Macros offer a fast and easy way to automate your application and make many tasks more convenient. Learning how to use them will help you become that much more familiar with what can be done with Access and you'll probably be surprised by the sophistication of some of the commands available. Macros are not the end of the road, however. Once you are comfortable with them, I highly recommend investigating Visual Basic for Applications (VBA) and learning how you can gain even finer control and perform more advanced tasks within your applications. As shown in Chapter IX, VBA adds looping functions to perform repetitive tasks based on conditions or collections of items. It also provides the ability to respond to errors within your application and log them as necessary.

Page 111

Page 116: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 8.12 - IF ... THEN ... ELSE statements enable complex decisions within Access 2010macros.

Page 112

Page 117: Microsoft Access for Beginners

Microsoft Access for Beginners

Chapter IX - Introducing Visual Basic for Applications

Introduction

Some people might spend years using Microsoft Access and never bother with one of its most powerful features; Visual Basic for Applications (VBA). Some will learn how to use macros for simple automation and stop there. It's only when you learn how to use VBA, however, that you will understand what Access is truly capable of.

What is Visual Basic for Applications?

Visual Basic for Applications is a version of the Visual Basic language that is included with Microsoft Office. When used with Office programs, VBA enables the user to design simple or complex routines that will run in the background and respond to events such as the opening of a form or the click of a command button.

Going back even further, Visual Basic for Applications is a version of the BASIC (Beginner's All-Purpose Symbolic Instruction Code) programming language. This language is called a high-level language because its commands and syntax are a few levels removed from the machine code that the computer actually processes. VBA uses English-like instructions which are then translated, or compiled, into instructions that the computer can use.

Reasons to learn VBA

There are two levels at which you can use Microsoft Access. The first is for simple database management where you create some tables to store your data or link to data from other sources and then create some queries and basic reports to analyze it. Maybe you'll have some simple data entry forms to make things a little easier. If this is all you want to do, then you'll probably get by without knowing VBA.

The next level is for building professional database applications. These are programs like the demonstration program for this book, Job Search Plus, that are centered around the ability to store important information but also include custom functions and an interface that makes it easy for anyone to use those functions. Such an interface includes user-friendly forms for

Page 113

Page 118: Microsoft Access for Beginners

Microsoft Access for Beginners

entering data and a menu system to navigate through the available forms and reports. To create something like this, you will need to be familiar with how VBA can tie your program together and provide functions that macros just aren't capable of.

Earlier in the book, I stated that I almost never allow users to work directly with the tables because it's safer for the data and easier for the user to go through data entry forms. When I design an application, the entire interface and all of its functions from the command buttons to the navigation and any analysis that the program performs in the background are enabled with VBA. All the user sees is a smooth running application.

Carrying out the instructions behind command buttons is one of the simplest things to do with the language. If you use the command button wizard to create buttons on your forms, it will write the VBA in the background. There are also VBA routines in the application that work independently of forms to oversee the application as a whole or to determine if a particular form is loaded. The Job Lead Central screen shown in Figure 9.1 has VBA code behind it that performs functions on specific job leads on request from the user.

All of these are still relatively simple routines. Some of the most advanced programs I've written manipulate entire database files and instances of Access itself. I wrote one routine that would enable an Access application to search for a newer version of itself. On finding the newer version, the program would shut down, perform the necessary file updates and then restart itself so the user could continue working.

Figure 9.1 - VBA can be used behind sophisticated user interfaces that make it easier for theuser to use and navigate through the application.

Page 114

Page 119: Microsoft Access for Beginners

Microsoft Access for Beginners

The way Access combines a relational database with a programming environment enables youto design data-driven applications without being dependent on pre-programmed abilities of the software. Although Access is included with Microsoft Office, in some ways it's set apart from the rest of the suite by the user's ability to create solutions that are almost indistinguishable from normal stand-alone programs. Access also provides a great training tool for both database and programming concepts.

Event-driven programming

As I mentioned in Chapter VIII, Access programs are referred to as event-driven because the forms and reports respond to events that are triggered, or fire, in response to actions by the user or another part of the program. This is true whether you use VBA or simple macros. This differs from other programming languages, including earlier versions of BASIC, where the codewas all contained in a single listing and was run in sequential order. In VBA, code is stored in methods and functions which are designed to run when specific events fire, such as when a form is opened, or when called by other code. This allows for a very flexible program operationthat can respond to the user's needs.

Figure 9.2 - VBA programming is driven by events which are triggered by user or programactions.

Another feature of event-driven programming is that multiple events may fire in sequence in response to a single action. On the main menu of the demo program, you'll see command buttons that activate different parts of the program. If you click on the button to bring up the Lead Entry form, it seems to open the form with a single action. Behind the scenes, however, it's firing a number of events:

Open >> Load >> Resize >> Activate >> Current

Each of these events refers to a different aspect of opening the form and displaying its data so that the user can interact with it. You can program any or all of these events so that the application will perform the necessary tasks exactly when needed. For example:

• The Open event can be canceled so that the form does not open if there is no data to

Page 115

Page 120: Microsoft Access for Beginners

Microsoft Access for Beginners

display.• The Resize event fires any time the size of the form is changed, including when it

opens, and can be programmed to prevent the resizing of the form or dynamically arrange controls to compensate for resizing.

• The Current event fires every time the user views a new record on the form and this canbe useful for adjusting properties of controls based on the data in the current record.

Figure 9.3 - VBA can be used to respond to events with custom actions and functions. Thisexample shows the code for the event from Figure 9.2.

If you look at the list of events under the form's Properties screen, you'll see quite a few that relate to actions from the mouse, the keyboard and the form itself. Although it may appear confusing at first, you'll find that this gives you very precise control over the operation of your program. An example of this property list and the code it uses is shown in Figures 9.2 and 9.3.

The English-like commands of VBA and the ability to carry out tasks by assigning small amounts of code to specific events actually makes the language easier to learn. The integration of VBA with the form and report controls in Access provides you with a graphical environment where you can focus on how the code works with the flow of your application rather than just picking your way through a long code listing.

Throughout this chapter, you will see code examples used to illustrate various functions. The main purpose of these examples is to demonstrate the function being explained and might not

Page 116

Page 121: Microsoft Access for Beginners

Microsoft Access for Beginners

represent the most efficient way to accomplish a given task. While learning to work with Visual Basic for Applications, I encourage you to explore the functions you find here, in the Access help files and other places and take plenty of time to experiment with different ways of doing things.

The VBA Environment

To non-programmers, the Visual Basic for Applications environment can be a little intimidating at first with its lack of directions and that big open area where the code resides. It's like being confronted with a blank sheet of paper and being told to just make something up. At first, it may be hard to see the connection between this and the work you've been doing in Access until you break it down into its different parts.

Figure 9.4 - The VBA development environment includes a variety of tools for working in thelanguage.

The VBA environment is referred to as an Integrated Development Environment (IDE) becauseit contains all of the tools that you need to write, compile and debug the code in one place. Other programming systems might require you to edit the code with one program and then compile it into an EXE file or other executable form with another command line program.

Page 117

Page 122: Microsoft Access for Beginners

Microsoft Access for Beginners

VBA does it all in one place.

Figure 9.5 - You can enter the VBA environment by using the Build button on the right side of theevent listing or by pressing Alt-F11.

There are a couple of ways to open the VBA environment. The simplest way is to press ALT-F11 which will bring up VBA from anywhere in Access. If a form event already has code assigned to it, you can also click on the Build button ( ) next to the event on the form Properties listing as shown in Figure 9.5. This will go straight to the section of code that deals with the event.

Project Explorer

In Figure 9.6, you'll see two smaller windows on the left side of the screenshot. One of these sections is labeled Project - with the name of the VBA project after it. Inside the window, you'll notice a directory listing which shows the names of some of the database objects. In this case, it's the project forms, a report and the two modules. The reason these are listed is because these objects have code associated with them that can be edited in the VBA environment.

Notice that this directory does not contain tables or queries. This is because those objects cannot have VBA code associated with them. Only forms and reports have events that can be programmed. Standalone modules, shown underneath the forms in the screenshot, are independent collections of methods and functions that you can create. The code in these modules can be called by forms and reports or by other modules. They're like reference libraries that can hold code that doesn't specifically apply to any of the other objects or that youwant to make available to the entire application.

Also notice that not all of the forms in the database are listed in this directory. That's because while all forms are able to contain VBA code, not all of them do. Each form and report has a property that you can set when you view the item in Design View. The 'Has Module' property determines whether the form has code behind it. For most of the forms and all of the reports in the demonstration database, this property is set to 'No' as those objects don't require code at this time and eliminating the modules behind them reduces the size of the database. If the HasModule property is already set to "Yes", you can set it to No but this will delete any code that exists in the module.

Page 118

Page 123: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 9.6 - The Project Explorer section of the VBA environment provides access to all codeswithin the project containing code.

Figure 9.7 - The Has Module property determines if an Access form or report has a VBA codemodule attached to it.

The code modules behind forms are similar to the standalone modules but they are inseparable from their forms and supply instructions for the form events rather than general functions.

Page 119

Page 124: Microsoft Access for Beginners

Microsoft Access for Beginners

As an exercise, try this:

1. Switch back to Access using the ALT-TAB keys and press F11 to bring up the database window.

2. Select the subContact form and open it in design view.3. Press F4 to bring up the properties dialog and select the 'All' tab. 4. Way down almost at the bottom of the properties, you'll see the Has Module property.

Double-click where it says 'No' to change it to 'Yes' or just type 'Yes' in the box.5. Close the report, clicking 'Yes' when you're asked to save it. 6. Now go back to the VBA environment and you'll see that the report has now been added

to the directory because it now has a module that can hold programming for its events. If you double-click on the object in the directory, it will bring up the blank module in the code window.

Properties Window

Figure 9.8 - The VBA Properties window enables quick access to the properties of the Accessobject for which the code is displayed.

The Properties window shows the properties associated with the object currently being edited. If you're viewing the module behind a form that is open in design view, you'll see a long list of properties in this window, much like the properties dialog in Access. If you use Alt-F11 to open the VBA environment and start editing the code for a form that is not currently open in Access, Access will automatically open that form in design view and the properties list will become available in VBA. This list includes the events for the forms and it's a handy way to reference and change the properties for a form or report while you make changes to the code. As you

Page 120

Page 125: Microsoft Access for Beginners

Microsoft Access for Beginners

learn VBA, you'll find that many of these properties can be set through code as the program is running (also called run time) as well as at design time. The properties window shows how the properties are set by default before the code affects them.

Code Window

There are three parts to the code window with the main one being the code editor itself. At the top of the editor are two dropdown boxes. The dropdown on the left lists all of the controls on the form or report that can be programmed such as command buttons and text fields. After selecting one of these objects, the dropdown on the right will list the events that can be programmed for that object. In Figure 9.9, the Controls dropdown is set to show the events for the form itself while the Events dropdown is set to the Load event for the form.

Figure 9.9 - The main code area of the VBA interface. The dropdowns at the top provide quickaccess to specific objects and events.

As an example, if you're using the demonstration database, bring up the code module for frmLeadCentral and select cmdAddLead from the controls dropdown. You'll see that the right-hand dropdown automatically changes to the Click event since this is the default event for a command button. If you open the events dropdown, you'll also notice it's the only event shown in bold since it's the only event with code attached to it. When you selected the cmdClose button from the controls dropdown, the cursor in the code editor window immediately moved tothe related section of code. This can be a quick way of navigating through a large module.

Page 121

Page 126: Microsoft Access for Beginners

Microsoft Access for Beginners

Additional Windows

Although they're not shown by default and you might not use them right away, there are a few extra windows that you can show when writing code. These windows are often used while testing the code or tracking down errors. You can select them for display from the View menu in VBA.

Figure 9.10 - Additional windows in the VBA interface enable tracking of specific variables andmonitoring of conditions within the code.

• Immediate Window - This window is useful for testing formulas and seeing values as they exist in the code. It can also be used by the program to display custom messages for the programmer related to activity by the program.

• Locals Window - The Locals window shows all the variables that have been declared in the part of the program that is running and their current values. This gives you a real-time view of the conditions in the program. If you're stepping through the code line by line, you can see when and how specific values change.

• Watches Window - Sometimes when you're testing a program, you want to know when a specific value changes without having to step through the code one line at a time. Thisis when you tell VBA to watch the value and report any changes. This window shows the watches that have been requested and their current status.

I'll include more details on the VBA environment later on. Meanwhile, you should take some time to explore the IDE and get comfortable with it. You'll be spending a lot of time there.

Compiling VBA Code

One of the functions of the Visual Basic for Applications IDE is to compile the code. This means that before the program runs, VBA examines all of the code for certain errors that couldcause it to crash while the program is running and translates the code into a form that is ready to be executed by the machine. You can run your Access code without compiling it but it will run slower because every time VBA encounters a new procedure, it has to check it for syntax problems, compile it then and there and then run it. Weeding out the syntax errors before it runs also avoids nasty surprises.

Page 122

Page 127: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 9.11 - To compile your VBA code before running it, you can select the Compile commandfrom the Debug menu in VBA.

The Compile command is located on the Debug menu in the Visual Basic for Applications IDE. If the code has not changed since it was last compiled, this option will be grayed out. A changeof one character of code will enable it again. If VBA finds any errors when you try to compile the code, it will take you directly to the spot that's causing the trouble so that you can fix it. Remembering to use this one simple menu command whenever you're making changes can save you a lot of grief later on.

Variables

Now that you know what Visual Basic for Applications (VBA) is and are familiar with the VBA environment, I want to start introducing you to the elements of the language. One of the basic elements in VBA is the variable. It serves as a placeholder and identifier for a specific value that allows the value to be changed when necessary and still retain its meaning and context.

Variables in Real Life

We actually use words in real life that could be considered variables. A good example would be the word "salary". If you ask one person what their salary is, they are likely to give you a different answer than if you ask someone else. A person's salary will also vary (hopefully increasing) from year to year. In this way, the term 'salary' refers to the same thing but a different value at different times or with different people. The value of the salary (i.e. $45,000) would have no meaning on its own but when the term "salary" is applied, it starts to make sense. In this way, the human expression "My salary is $45,000." could be expressed in VBA like this:

Dim Salary As CurrencySalary = 45000.00

If the person received a raise at the end of the year, it might be expressed like this:

Dim Salary as CurrencyDim Raise as Currency

Salary = $45,000Raise = Salary * 0.05Salary = Salary + Raise

Page 123

Page 128: Microsoft Access for Beginners

Microsoft Access for Beginners

In this case, another variable called Raise is declared using the 'Dim' keyword and set to 5% ofthe salary (the asterisk is used in VBA to multiply numbers). The resulting value is then added to the original salary to get the new value.

Using Variables in Code

An example of how VBA uses variables can be seen in this sample.

Public Sub FormOpen(strFormName As String)

'Declare variablesDim dbsCurrent As CurrentProjectDim frmCurrent As AccessObjectDim blnExist As BooleanblnExist = False

'Reference current project.Set dbsCurrent = Application.CurrentProject

'Check if requested form exists.For Each frmCurrent In dbsCurrent.AllFormsIf frmCurrent.Name = strFormName Then blnExist = TrueEnd IfNext

...

This code is a little more complex but demonstrates a few more ideas. It checks to see if a specific form exists by looping through all the forms in the Access database file and comparingthe name of each one to the value contained in the strFormName variable on the first line.

As you can see in the examples, the Dim keyword is used to declare a variable. This declaration documents the use of the variable for the code and assigns a specific data type to the variable (i.e. "as Boolean"). A good practice is to declare all variables at the top of a procedure in order to keep track of what has been declared. Variables take up memory and when changing code, it is a good idea to remove variable declarations that are no longer needed.

At the top of this sample, you can see three variables being declared using the Dim keyword. The first two, dbsCurrent and frmCurrent, are referred to as object variables because they referto objects that have properties and methods, just like forms and reports in Access. The third is a Boolean variable that refers to a single True or False value.

When a Boolean variable is declared, its initial value is False just as when an Integer is declared, it initializes to '0'. In the above example, I explicitly set blnExist to False for safety

Page 124

Page 129: Microsoft Access for Beginners

Microsoft Access for Beginners

and clarity. It's also a good habit to have as it's sometimes necessary when looping through the same operation more than once and reusing variables.

Variables are used in a couple of ways in this sample. The first line of the procedure, also called its declaration, accepts the strFormName parameter. This is a type of variable that holdsinformation being passed to the procedure by another section of code. The parameter name gives the value context within the code, identifying it as "the form name that was passed in". This particular variable doesn't change within the course of the procedure.

An example of a variable that does change throughout the procedure is frmCurrent. When the code is iterating through the available forms, it needs a variable to reference the form that it's working with at any given time. That's where the frmCurrent variable comes in handy. The For Each ... Next loop uses frmCurrent to hold each form for inspection until it's ready to move to the next one. Without a variable to hold the form reference, it would be more difficult to run through a list of objects like this. You'll learn more about For ... Next and other looping structures later in the chapter.

While frmCurrent is used to hold different items as the code runs, the blnExist variable holds a single value that might change while the code is running. In this case, it's holding a value indicating if the specified form has been found. This value remains False unless the specified form is found and then it becomes True. This indicator will be referenced later in the code to take further action depending on its value.

Declaring Variables

The Dim keyword (short for "dimension") is used to declare a variable in VBA as a specific type.

Dim CurrentForm as String

The above variable is declared as a string which holds alphanumeric data such as names, zip codes and other values that don't need math performed on them. The variable could be declared without specifying the type which would result in a Variant type that can hold any typeof value. This is to be avoided precisely because anything can be stored in it. Assigning a specific type to a variable guards against inappropriate values being stored in it which can and probably will cause errors later when the code references the variable and tries to use it in an operation.

For example, if you make a mistake as you're writing code and try to store the string value 'Boston' to a variable that is declared as an integer, VBA will catch this and alert you. Not so with a Variant type because it can store either one. It also makes the code unclear as in the above example where there's no way to know if the CurrentForm variable is supposed to refer to a form name or the form object itself.

More than one variable can be declared on a single line in VBA by placing a comma between

Page 125

Page 130: Microsoft Access for Beginners

Microsoft Access for Beginners

the declarations. The Dim keyword does not need to be repeated.

Dim FirstName as String, LastName as String

This example declares two string variables. Again, it's important to specify the type for each variable or you will end up declaring at least one of them as a Variant.

VBA does not absolutely require you to declare variables. You could just start using a variable in the code somewhere and VBA would treat it as a Variant. This is very bad programming practice as it does nothing to track or document the variables being used or define their data types. The fact that VBA allows it is one of the reasons the language is not regarded very highly by some professional programmers. VBA can be set to require all variables to be declared in the option settings or by placing the following statement at the top of a module:

Option Explicit

You'll see some data types in VBA that you'll recognize from table field types in Access but there are many more available. For more information on the data types that you can use with variables in VBA, search the Access help files for 'data type'.

Setting Variables

As shown throughout these examples, assigning a value to a variable is as simple as using theequals operator in a statement.

FirstName = "Andrew"

This works for value type variables such as String, Integer and Boolean variables that hold onevalue. The other type of variable is an object variable such as the dbsCurrent variable in the example above. Object variables contain items such as forms, reports and recordsets that can have multiple properties of their own. When assigning an object to an object variable, you needto use the Set command like this:

Set dbsCurrent = Application.CurrentProject

If you don't use the Set keyword with an object variable or you do use it with a non-object, you'll find out quickly enough when you get errors like these as you try to run the code.

The first error states that an object variable has not been set which means that it does not equal anything. An object variable that has not been assigned an object is referred to by VBA as being equal to Nothing. In this case, Nothing is a VBA concept that represents an empty state of an object variable. The second error results when the Set keyword is used on a value variable that cannot hold an object and simply states that an object variable is required. Non-object variables such as integers and strings which simply hold a value are sometimes referredto as primitive data types.

Page 126

Page 131: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 9.12 - When assigning values to variables in VBA, be sure to use the Set keyword forobjects variables. Not using it, or using it with non-object variables will result in errors.

In order to avoid memory problems and potential errors, it is important to explicitly destroy object variables when the code is finished with them, usually at the end of the procedure wherethey are used. This is done by setting the object variable to equal Nothing.

Set CustomerForm = Nothing

Naming Variables

There are very few actual rules for naming variables. Variables in VBA must start with an alphanumeric character (a-z, A-Z or 0-9) and cannot be longer than 255 characters. They also cannot contain spaces or any of the characters #, !, &, %, $ or @. These are type-declaration characters that can be used to mark a value as being of a specific data type and are reserved for use by VBA.

You must also remember to make your variable names unique within their scope. In other words, you wouldn't give two variables the same name within the same procedure or name a procedure variable the same as a module-level variable in the same module as the two would conflict. The main idea is to name it something that will be self-explanatory and not so long thatyou're likely to make a mistake when typing it. Variables in VBA are not case-sensitive which means that newForm, NewForm and NeWfOrM are all the same thing.

There are a couple of naming conventions that you can use as a guide in standardizing your

Page 127

Page 132: Microsoft Access for Beginners

Microsoft Access for Beginners

variable names. Hungarian Notation is an older style of variable naming that attaches a two or three letter prefix onto the beginning of the variable to indicate the data type, i.e. strName for a string variable or intAge for an integer. In newer programming technologies, this notation is discouraged but in VBA, it's still useful. You can find more information on this notation with a simple online search.

Another type of notation is called CamelCase. In this style, variables with more than one word have the first letter of each word capitalized. Although VBA is not case-sensitive when it comesto variables, it will remember the capitalization you use with a variable or procedure name. Examples of CamelCase would include:

AgeInYearsStreetAddressLastName

Another practice is to separate multiple words in a variable name with an underscore although this might be a little tedious when typing a lot of code.

Age_In_YearsStreet_AddressLast_Name

Constants

Sometimes when writing code, there is a specific value that you need to use more than once and you need to ensure that the correct value is used each time. This is when a constant should be declared. A constant is declared once in code using the Const keyword and then cannot be changed except by changing the declaration. Some examples might be:

Public Const VALUE_OF_PI As Double = 3.14Public Const SALES_TAX = As Double = .06Public Const DRINKING_AGE As Integer = 21

Notice that I've named the constants in all caps and used underscores to separate words. This is not required but it is one way to distinguish constants referenced in code from ordinary variables.

Also notice that the constants are all declared as Public. If I were coding these, I would probably place them in a standalone module named General or something similar and make them all public. This would mean that they would be available to the entire project. No matter where I referenced them in the code, VBA would automatically recognize them as the constants that had been declared and they would supply the correct value.

Using one of the above constants, you could have a function like this:

Page 128

Page 133: Microsoft Access for Beginners

Microsoft Access for Beginners

Public Const SALES_TAX = As Double = .06

Private Function TotalWithTax(Total as Double) As Double

Dim SalesTaxAmount as Double SalesTaxAmount = Total * SALES_TAX TotalWithTax = Total + SalesTaxAmount

End Function

In this example, the sale total is passed in and then multiplied by the SALES_TAX constant. The result is added to the original total to return the result.

In addition to defining standard constants as shown here, constants can be used to supply custom values such as company names or other values specific to your operation. Another advantage is that if those values ever do change, you only have to change them in one place rather than throughout the code.

Variable and Constant Scope

Variables and constants are private by default when declared with the Dim keyword. This means that the area in which they are recognized by the code is limited to the smallest area possible. Variables within procedures and functions cannot be public. If you declare a variable using the Private keyword at the top of a form module, it will not be seen outside that form's code. If you declare it at the top of a module, it's limited to the procedures within that module. You can also explicitly make a variable private by declaring it with the Private keyword:

Private TagNumber as String

At module level (at the top of the module, outside of any procedures), you can make a procedure or constant public by using the Public keyword:

Public MonthlySales as Double

This means that the variable and its value will be available from outside the module and, in thiscase, you would need to be careful not to name another variable MonthlySales so as not to conflict with this one.

Declaring and working with variables is one of the basic aspects of working in VBA and, in a short time, it will become second nature, especially as you see some of the errors that can be caused by improperly declaring or setting one or how easy they can accumulate within your code.

Page 129

Page 134: Microsoft Access for Beginners

Microsoft Access for Beginners

Procedures

VBA code is grouped into procedures that are used to perform one or more tasks or calculations, either in response to events or when called by other procedures. There are three types of procedures in VBA, each of which is used for a different purpose.

Subroutines

A subroutine (also called a method) is the most common procedure type. It's a group of statements intended to perform one or more tasks relating to the program's operation. Subroutines are used to handle events in Microsoft Access although they can be created independently of specific events and called as needed. Subroutines are declared with the Sub keyword.

In code samples like the one below, you'll sometimes see lines preceded by an apostrophe and usually in green text. These are code comments which are ignored by the compiler and help to clarify what's being done. Code commenting is a good practice and will be discussed more later.

Private Sub cmdCredits_Click() On Error GoTo errHandler 'Open splash screen. DoCmd.OpenForm "frmSplash", acNormalExit SuberrHandler: ErrorHandler Err.Number, Err.Description, _ "frmLeadsList.cmdCredits_Click"End Sub

This example from the demonstration database is a simple procedure used to open a form when the user clicks on the appropriate command button. On the first line, you can see the procedure declaration with the Sub keyword and then the name of the procedure. For events, the name is always the name of the form or report control with an underscore and then the name of the event (i.e. cmdCredits_Click). In VBA, this is the only way that the system has to associate a procedure to a specific event.

The last line of the procedure, "End Sub", terminates the procedure's operation. Also notice the"Exit Sub" command In the middle of the procedure. This is another way of exiting the procedure. In this case, it's used to leave the procedure before the code reaches a portion thatis only supposed to run if there's an error. It's good practice to have as few exit points as possible in a procedure and this procedure example is the ideal, with only one exit point other than the End statement and a clear path through the procedure to the exit. Having too many exit points makes a procedure difficult to follow when debugging or modifying the code and canlead to errors that are hard to find.

Page 130

Page 135: Microsoft Access for Beginners

Microsoft Access for Beginners

Going back to the first line, the parentheses at the end of the line indicate where the routine can accept input parameters for use in calculations. Here's another example from the section on variables where the name of a form is passed in.

Public Sub FormOpen(strFormName As String)

'Declare variables for use in procedure.Dim dbsCurrent As CurrentProjectDim frmCurrent As AccessObjectDim blnExist As BooleanblnExist = False

'Reference current project.Set dbsCurrent = Application.CurrentProject

'Check if requested form exists.For Each frmCurrent In dbsCurrent.AllFormsIf frmCurrent.Name = strFormName Then blnExist = TrueEnd IfNext

'If form exists, open it. Otherwise, notify'user.If blnExist ThenDoCmd.OpenForm strFormName, acNormalElseMsgBox "Sorry, that form does not exist.", _ vbOKOnly, "Form not found ..."End If

End Sub

This procedure is a little longer but still pretty straightforward. It accepts the name of a form as an input parameter and then matches that parameter against every form in the database in theFor ... Each statement. If it finds a match, it sets the blnExist variable to True. The If .. Then decision checks the blnExist value. If the variable equals True, the program opens the requested form. Otherwise, it notifies the user that the form doesn't exist.

You would decide on the name of the input parameter when writing the function and it can be anything but it should follow the rules for variable names and be something that indicates the purpose of the value as it will show up as a prompt when you call the function from elsewhere in the code.

One final note; in some of these code samples, you'll notice lines with and underscore ( _ ) at the end. In VBA, this is the line continuation character and is used when you want to divide lines into sections to make the code more readable. When you do this, it's best to indent the remainder of the line to show that it's part of the same line of code. VBA disregards indents on

Page 131

Page 136: Microsoft Access for Beginners

Microsoft Access for Beginners

code and most other whitespace but they make it easier for humans to read.

Functions

Functions are like subroutines except they are used to calculate and return a value. They can be placed either in form and report modules (also called class modules) or standalone modules.

Public Function formLoaded(ByVal strFormName As String) As Integer

'Returns a 0 if form is not open or a -1 if Open

If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> 0 Then If Forms(strFormName).CurrentView <> 0 Then formLoaded = -1 End If End If

End Function

Although some of the commands in the above example may look complicated, this is actually asimple function that shows the main features of a function in VBA. The function accepts the name of a form and determines if it is currently loaded.

The first line declares this as a function rather than a subroutine. It also accepts an input parameter for use by the function ('ByVal strFormName as String'). In this case, it means that the function will accept the name of the form in question. Finally, the first line states what type of value will be returned by the function ('As Integer'). This function is actually used to return a True / False value (the form is loaded or it isn't) so it could return a Boolean but an integer of -1 (True) or 0 (False) can be used in place of a Boolean value.

In the body of the function, you can see the decision process that it uses to come to the final result. The If...Then statements test two different conditions, referencing the form name that was supplied to the function. If both conditions pass, it returns the result by assigning the resultto the function name itself. Then when calling this function from any other procedure, you would simply type:

If formLoaded("<InsertFormName>") Then ...

or

If Not formLoaded("<InsertFormName>") Then ...

When a function is used this way in code, the function call represents the value or object it returns as a result and is treated that way by the code. This is why functions can also be referenced in Access queries and formulas. In this case, the function name followed by the

Page 132

Page 137: Microsoft Access for Beginners

Microsoft Access for Beginners

form name in parentheses automatically represents either a True or False value to the code. The Not keyword tests for a False value. It could also be written this way:

If formLoaded("<InsertFormName>") = False Then ...

Using the first method in the case of a True / False value makes for cleaner code.

Properties

The third type of procedure is the Property procedure which is only used in form or report modules.

The purpose of Property procedures is to create custom properties for forms or reports and to set and read those values as needed. These property settings can then be used to affect the program's operation. Properties make use of module-level variables, variables stored at the topof the module outside of any procedure, to store their values.

Private strReturn As String

Public Property Get ReturnForm() As String ReturnForm = strReturnEnd Property

Public Property Let ReturnForm(vdata As String) strReturn = vdataEnd Property

The example above is from the frmInitialEntry form in the demo database. This form can be called by more than one form and it's important to know which form did the calling so that the program can return to it afterward. The ReturnForm property is used to determine this.

In the first line, you see the strReturn variable declared. This is actually done at the top of the module. This variable is also referred to as a field and is being used by the Return property below it to store a string value.

After strReturn is declared in the example above, you can see a pair of declarations for the ReturnForm property. Unlike subroutines and functions, properties can have two declarations; the Let declaration sets the value of the module field while the Get declaration retrieves it. Notice that the Let declaration accepts an input parameter for which the type matches the type of the field and then uses it to set the value of strReturn. When the code sets this property, it might read as follows:

frmInitialEntry.ReturnForm = frmLeadCentral

There are a couple of reasons for having both a module-level field and a property to set and

Page 133

Page 138: Microsoft Access for Beginners

Microsoft Access for Beginners

read that field. The main reason is to limit access to the field value. You'll remember the Public and Private keywords in procedure and variable declarations. These keywords affect which code can access the item and this is referred to as scope. The Private keyword limits access tothe immediate area where the item is declared.

Since strReturn is declared as private in the module header, this means that only procedures within this module can access the variable's value. If it was declared inside a procedure, then itwould be limited to operations within that procedure. The ShowPicture property is declared as Public which means that procedures from other forms or modules can access the property. The property can then act as a gateway to the mblnShowPicture field, controlling conditions under which the value can be changed. Using the public property and private field combination, you could also test a value that the property receives before it's actually written tothe field. The public property can also be used to perform additional tasks each time a propertyis changed.

Properties don't need to have both declarations. A property that only has a Get declaration is called read-only, meaning that the property can only be read and not changed from outside themodule. The module in which it's declared can write directly to the private field since the module is within the scope of that field. Less commonly, you might have a write-only property that only has a Let statement. It could be written from outside but the module where it's declared would need to read the private field.

A third type of property declaration is the Set statement. This is the same as the Let statement in that it accepts a value on behalf of a field. The difference is that the Let statement is used forvalue fields (numbers, dates, strings, boolean, etc..) and Set is used for object fields (controls, forms and other database objects).

Intellisense

One of the features of VBA, along with other programming languages, is that the interface will detect a call to a function and assist you in entering it properly.

Figure 9.13 shows the formLoaded function from the above example being called from a subroutine. As soon as I entered the function name and typed the opening parenthesis (parentheses can be used with all function names, even if there are no variables passed), the compiler recognized the function name and prompted for the value to be passed in by showingthe function declaration and the current argument needed in bold letters. If there was more than one argument to be passed in, the values can be entered separated by commas and the prompt would change as I entered each one. This is a good reason to use self-explanatory function and argument names when declaring functions.

Page 134

Page 139: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 9.13 - Intellisense makes coding easier by prompting the programmer with the necessaryoptions for functions and object properties.

Optional and Default Parameters

In some cases, you might want to include a parameter in a function or subroutine declaration that has a default value. This means that a specific value will be supplied to the function even ifthe parameter is not specified in the call to the function.

Public Function AddTax(Price As Double, Optional taxRate As Double = 0.06) As Double

AddTax = Price + (Price * taxRate)

End Function

In this example, the first parameter, Price, is required but the second parameter does not needto be specified. If it isn't, the function will supply a default tax rate of 6%.

Figure 9.14 - Intellisense prompting for a parameter with a default value.

In Figure 9.14, you can see the function being called. The variable TotalSale is supplied for thefirst parameter and Intellisense shows that the second parameter has the default value of 0.06 or 6%. This default could be overridden by supplying another value:

TotalWithTax = AddTax(TotalSale, 0.08)

It could also be left as is:

Page 135

Page 140: Microsoft Access for Beginners

Microsoft Access for Beginners

TotalWithTax = AddTax(TotalSale)

There are a couple of rules for optional and default parameters:

1. An optional parameter can be declared without a default value but parameters with defaults must always use the Optional keyword.

2. If a parameter is declared as optional, all parameters that follow it must be optional as well. In other words, any optional parameters must be at the end of the declaration.

Parameter Arrays

In the section on variables, I talked about the dangers of using the Variant data type. I stated that since it will accept any value, it can lead to errors and should be avoided. An exception to this is the parameter array. Sometimes, you might want to pass a list of items to a function or procedure but you might not know in advance how many items that list will hold. In that case, you could use the ParamArray keyword in the procedure declaration. Parameter Arrays are required by VBA to be of the Variant type.

Public Function AverageItems(ParamArray NumericValues() As Variant)

Dim varItem As VariantDim dblItem As DoubleDim dblTotal As DoubleDim intCount As Integer

dblTotal = 0intCount = 0

'Iterate through parameter array. Add and count numeric values.For Each varItem In NumericValues()If IsNumeric(varItem) Then dblItem = CDbl(varItem) dblTotal = dblTotal + dblItem intCount = intCount + 1End IfNext

'If numeric values were found, average them for result.If dblTotal > 0 ThenAverageItems = dblTotal / intCountElseAverageItems = 0End If

End Function

The above example is a function that accepts a parameter array and averages any numeric

Page 136

Page 141: Microsoft Access for Beginners

Microsoft Access for Beginners

values it finds in that array. Notice the use of the ParamArray keyword in the procedure declaration. If a parameter array is used, it must be the last argument in the declaration to indicate that it is optional.

In the middle section of the function, you'll notice the For Each loop that iterates through each item in the array using the varItem variable as a placeholder. I'm using the IsNumeric function which is native to VBA to verify that each value is a number before using another VBA function, CDbl, to convert it to a Double value and then adding it to the sum of numeric values. I also keep a count of the numbers found. In the final section, if any numeric values have been found, I average them and return the result as the result of the function.

Although I avoid using Variants (or the generic Object type), this is an example of a place where they would need to be used and the precautions you would need to take when using them.

MsgBox

One of the internal VBA functions that you'll probably use most is MsgBox() and it's a good example of how functions can sometimes be used like subroutines and vice-versa.

The MsgBox function displays a message on the screen for the user to see and has five different arguments to determine its content, title, icon and even its associated help file but at its simplest, the code looks something like this:

MsgBox "This is a message."

Notice that there are no parentheses around the argument that specifies the content of the message. When you are calling a method with arguments, you don't actually need the parentheses unless VBA requires it for a specific method. You can just type the function name,hit the Space bar and Intellisense will help you fill in the arguments separated by commas. A longer version might look like this:

MsgBox "This is a message.", vbInformation, "Message "

This one specifies the message, an icon that indicates a purely informational message and a title for the message box. Still no parentheses and the method just displays the requested message box.

Sometimes, however, you might want to get input back from the user after you show the message box and that's when you have to use MsgBox as a function instead of a method because it actually does return a value whenever the user clicks on the button shown under the message. When you use MsgBox as a method, that value is tossed away but there's a wayyou can retrieve it for your own information.

Dim intResponse As VBMsgBoxResult

Page 137

Page 142: Microsoft Access for Beginners

Microsoft Access for Beginners

intResponse = MsgBox("Are you sure you want to exit Job Search Plus?", _vbYesNo, "Exit application? ...")

If intResponse = vbYes Then Application.QuitEnd If

In this example, MsgBox is used as a function and the integer it returns is assigned to the intReponse variable which is actually declared as a VBMsgBoxResult. This is a series of constant values that correspond to the buttons that might be shown in the message box which makes the result easier to reference in code. Because of this association, the code can test theintResponse variable against one of the easy to remember constants below. Because MsgBox is now being used as a function and is part of an expression, you must enclose the arguments in parentheses.

vbOK - 1vbCancel - 2vbAbort - 3vbRetry - 4vbIgnore - 5vbYes - 6vbNo - 7

You can find these and other constants by searching the Access help file for information on MsgBox constants. The constants presented through the MsgBox parameters act a lot like an enumeration which you'll learn more about in the next section.

When I started programming using an older version of the BASIC language, I learned to write programs as one long code listing that ran from start to finish. It was quite a different programming experience from the VBA style of separate procedures and functions. The advantage of VBA's style is that it encourages you to break the project down into pieces and analyze each part of the problem. This is an important skill when designing a solution to a real-life problem.

Arrays and Enumerations

Previously, I talked about using variables to store information. Another way to store values in VBA is the array. A single array can hold multiple values in a way that can be individually referenced through code. The advantage of using arrays is when you have many values in the same category, i.e. sales figures or sports scores. Instead of declaring multiple variables, you can declare a single array variable with enough places to hold all of the information. Functions can return arrays so a custom function could use an array to return multiple values or even a set of data from a table.

You declare an array just as you would a variable except that in parentheses after the variable

Page 138

Page 143: Microsoft Access for Beginners

Microsoft Access for Beginners

name, you specify the number of elements to allow.

Dim MonthlySales(11) as Integer

One of the ideas that you'll need to remember in VBA and other types of programming is that numbered items often start with zero. This is referred to as being zero-based. Arrays are an example of this; array elements are numbered for reference purposes and by default, the numbering beginning with zero. Therefore, the above declaration statement actually declares an array that can hold 12 separate integer values.

If you want the array's lower limit (also called the lower boundary) to start at a number other than 0, there are two ways to do this.

• Use the Option Base statement at the top of the module. This statement can declare thelower boundary for all arrays in the module as either 0 or 1.Option Base 1Option Base 0

• To set the lower boundary for a specific array, you can use the declaration itself to set it to any value. For example:Dim Months(1 to 12)Dim Century(1901 to 2000)

Setting or reading information from an array is also the same as working with a standard variable except that you reference a specific element by number as shown in these examples which assume the array starts at 1.

MonthlySales(4) = 12000

JanuarySales = MonthlySales(1)

Figure 9.15 shows how Intellisense recognizes MonthlySales as an array variable when the first parenthesis is typed and requests an element number.

Figure 9.15 - Intellisense recognizing an array variable and prompting for the item index number.

You can use a variable to indicate the element being referenced as in this example which assumes that the MonthlySales array has already been declared and each element has a

Page 139

Page 144: Microsoft Access for Beginners

Microsoft Access for Beginners

value:

Dim ArrayPlace as IntegerDim MaxSales as Integer

MaxSales = 0

For ArrayPlace = 1 to 12If MonthlySales(ArrayPlace) > MaxSales Then MaxSales = MonthlySales(ArrayPlace)End IfNext ArrayPlace

MsgBox "The maximum monthly sales is: " & MaxSales & "."

The For ... Next loop in this code uses the ArrayPlace value to cycle through each element in the MonthlySales array. The code then reads the value of the array element where the elementnumber matches the value in the ArrayPlace variable. If it's greater than the value in MaxSales, then the MaxSales value is replaced. At the end, a message box announces the highest monthly sales.

Using the functions available through VBA, you could also write an expression like this one with the above array:

CurrentSales = MonthlySales(Month(Date))

The Month() function returns an integer between 1 and 12 representing the month part of the specified date so the above expression uses this function to fill in the month part of the current date in a reference to the MonthlySales array.

Multidimensional Arrays

In the examples above, I've shown you how to declare arrays with a single list of values but sometimes you need the data to go in more than one direction. For this, you need to declare an array with multiple dimensions. For example, if you wanted an array to hold the monthly sales for five different sales reps you could do it this way with Option Base 1 stated.

Dim MonthlySalesByRep(5,12)

Although the array is entirely in memory, it may be easiest to think of it in rows and columns. The above example would therefore be a grid with a row for each of the five sales reps (1 to 5) and a column for each month (1 to 12). If you wanted the above array to hold five years worth of data you could add a third dimension like this:

Dim MonthlySalesByRep(5,12,5)

Page 140

Page 145: Microsoft Access for Beginners

Microsoft Access for Beginners

In this case, the third dimension could be seen as a set of pages. So if you were referring to the sales for the third sales rep in the list during January of the second year represented, the reference could be:

Sales = MonthlySalesByRep(3,1,2)

The rules for changing the lower boundary on each dimension are the same as with single dimension. In VBA, you can declare an array with up to 60 dimensions although you'll probablystick to 2 or 3 most of the time to avoid confusion. If you do need to go beyond three dimensions, it may help to think of the array references in terms of coordinates rather than a physical representation of rows and columns.

Resizing Arrays

All of the examples so far have involved fixed arrays where the size is determined when the array is declared. With this type of array, the declaration requires that a hard number or a constant be used to specify the number of elements. You may have a situation where you wantto use a variable to specify the number of elements in an array. An example would be if you read all of the values from a table and wanted an array that would match the number of records.

To do this, you would declare a dynamic array and use the ReDim keyword to resize it as needed.

Dim TableValues() as StringDim RecordCount as Integer

RecordCount = DCount("[Business]", "BusinessTypes")

ReDim TableValues(RecordCount)

The code above declares TableValues() as a dynamic array simply by omitting the number of elements. It then uses the DCount() VBA function to count the number of records in the BusinessTypes table and resizes the TableValues array to match that number.

You can use the ReDim statement more than once on an array but be aware that ReDim will erase all of the information stored in the array unless you use the Preserve keyword with it.

ReDim Preserve TableValues(RecordCount)

If you shrink an array using the Preserve keyword, you will lose the data in the elements that are removed. You can also resize an array to add or remove dimensions.

Page 141

Page 146: Microsoft Access for Beginners

Microsoft Access for Beginners

Enumerations

Enumerations are groups of constants that you can define within VBA in order to make it easier to reference a list of values. Enumerations can only be declared at module level (not within procedures) and use the Enum ... End Enum syntax shown below.

Enum OfficesBostonDetroitTorontoPhoenixMiami[Los Angeles]End Enum

Note that the value for Los Angeles above is enclosed in brackets. This is necessary if there are any spaces in the enumeration names or VBA will not recognize any of the items from that item onward. Ideally, it's best not to include spaces in these names and I'll mention more aboutthat later.

The enumerations themselves are actually treated as custom data types within VBA so to reference the one above, you would declare a variable as shown in Figure 9.16:

Figure 9.16 - Intellisense also works with enumerations to supply possible values.

As you can see, when you assign a value to the variable you've declared as the enumeration type, Intellisense kicks in, recognizes the custom type and supplies a list of the possible values. This is very useful when you're dealing with a list of items that you need to reference frequently and want to make sure that it's always done correctly.

In the background, the enumeration values are stored as integer values despite being represented with the strings that you supply. By default, the list starts with 0 and increments by1 for every value you add but you could supply your own integer values so long as they were sequential.

Page 142

Page 147: Microsoft Access for Beginners

Microsoft Access for Beginners

Enum OfficesBoston = 100Detroit = 200Toronto = 300Phoenix = 400Miami = 500[Los Angeles] = 600End Enum

In the above example, you can see where the members of the Offices enumeration have been given custom values. These could represent location codes. In Figure 9.17, the code declares a variable of the Offices type, sets it to the [Los Angeles] enumeration member and then calls a message box to display the Integer value of that member which is 600.

Figure 9.17 - Custom integer values can be assigned to enumeration items and returned by usinga function to convert the item to an integer.

Although I've used ordinary names for this example, it's considered good practice to use a naming convention for enumeration members that makes them recognizable as such. An example would be something like this:

Enum OfficeseBoston = 100eDetroit = 200eToronto = 300ePhoenix = 400eMiami = 500eLosAngeles = 600End Enum

Remember that when referencing enumeration members, VBA's focus is on the integer value. The string value is merely used to provide a recognizable reference for each member so the above names would make it easy enough to work with this enumeration in code.

Page 143

Page 148: Microsoft Access for Beginners

Microsoft Access for Beginners

Enumeration types can be used in procedure arguments just like other data types. In Figure 9.18, you can see a function that is declared with the Offices type as an argument. Then a subroutine calls this function and Intellisense supplies the list of enumeration members to complete the function call.

Figure 9.18 - Enumerations can be used as arguments in functions just like any other variabletype.

As a final note, enumerations can contain both positive and negative values.

Enum ConnectStatus eError = -1 eClosed = 0 eOpen = 1End Enum

Enumerations are a very useful tool whether you need to reference a list of items as shown above or supply a short list of possible values for a custom form property as I do in the this example from another database with the FormModes enumeration.

Public Enum FormModes eAdd eEdit eReadEnd Enum

Private menmMode As FormModes

Public Property Let CurrentMode(vdata As FormModes)

Page 144

Page 149: Microsoft Access for Beginners

Microsoft Access for Beginners

menmMode = vdataEnd Property

Public Property Get CurrentMode() As FormModes CurrentMode = menmModeEnd Property

In this example, the FormModes enumeration contains only three members and I don't even worry about their integer values. VBA can take care of that in the background. The enumeration is used as the type for the Form property that the rest of the code uses to determine the editing mode of the form.

Operators

Whether you're programming a method or a function, there's an excellent chance you're going to be using formulas of some kind to get the results you need. In order to construct these formulas and perform the right calculations, you need to be familiar with the operators available in Visual Basic for Applications.

The operators in VBA are mostly the same as the ones that you used back in your school mathclass (+, -, =, etc..) with a few extra that are specific to the programming environment. Here's asmall example of how operators could be used in VBA. I've numbered the lines here for reference.

Public Function IsPrime(Candidate As Long) As Boolean

'Determine if the number passed in is a prime number.'Declare the variables.

1: Dim TestLimit As Long, TestValue As Long

'Assume it is prime until proven otherwise.

2: IsPrime = True

'If the number is higher than 3, test against every integer up to'the square root of the number.

3: If Candidate > 3 Then4: TestLimit = Int(Sqr(Candidate))5: For TestValue = 2 To TestLimit6: If Candidate Mod TestValue = 0 Then7: IsPrime = False8: Exit For9: End If10: Next13: Else

Page 145

Page 150: Microsoft Access for Beginners

Microsoft Access for Beginners

12: IsPrime = False13: End If

End Function

As the comments indicate, this function accepts a long integer (a data type capable of holding numbers between - 2,147,483,648 and 2,147,483,647) and determines if it's a prime number (a number only divisible by 1 and itself).

The function returns a Boolean value and on Line 2, you can see where the code uses the assignment operator (=) to set the return value to True. In VBA, like other forms of BASIC, the equals sign doubles as the operator used to assign a value to a variable and to test for equalitybetween two values.

On Line 3, the function uses the greater than operator (>) to find out if the number passed in is greater than 3. Then on Line 6, it uses the Mod (modulus) operator which returns the remainder when one number is divided into another. In this case, it's looking for a value of 0 indicating that there is no remainder. If the For Next loop is able to cleanly divide the candidate number by another number, a False result is returned.

The Access help files contain notes on all the different operators available and their behavior when used with different data types but here is a short listing of those you might use.

Operator Sign

Description Example

Arithmetic

+ Addition Price + Tax = Total

- Subtraction Price - Discount = Total

* (asterisk) Multiplication Price * .06 = Tax

/Division with floating point result

Hours / 24 = Days

\Division with integer result

Months \ 12 = YearValue

Mod Division remainder 26 Mod 12 = 2

^ Exponent 10 ^ 3 = 1000

Page 146

Page 151: Microsoft Access for Beginners

Microsoft Access for Beginners

Comparison

< Less than Month < Year

<= Less than or equal to364 Days <= Year365 Days <= Year

> Greater than Decade > Year

>= Greater than or equal to10 Years >= Decade20 Years >= Decade

<> Not equal to Decade <> Century

Concatenation

&Combine two string values

FullName = First & Last

+ Addition of two numbers Total = Price + Tax

Logical (comparison of conditions)

ANDBoth conditions are True.

Value = 14. Therefore:

Value < 25 AND Value > 10

EQVBoth conditions evaluateto the same result, either True or False.

(Year = Day * 7) EQV (Hour = Minute * 12)

(Both are False so the operator returns True)

NOT Condition does not evaluate to specified result.

IF NOT(24 > 100)

(This would evaluate to True since 24 is not

Page 147

Page 152: Microsoft Access for Beginners

Microsoft Access for Beginners

greater than 100.)

OREither of two conditions is True

IF Price > 10 OR Price < 5

(The values 11 and 4 would both pass the test but values 5 through 10 would not.)

XOROne, but not both, of theconditions is True.

IF Year = 2010 XOR Month = 2

(Will return False in February 2010 as both conditions would be True.Returns True during the rest of 2010 or during February of any other year.)

Using DoCmd

One of the unique features of VBA is the DoCmd object which you can use to run many actions such as opening and closing forms and reports, manipulating data and even running other code or applications.

DoCmd has a collection of methods that act like subroutines you can call to perform the various actions. Each of these methods has a definition that accepts one or more parameters to define the action you want to perform. When you call one of the methods, Intellisense will prompt you to enter the parameters, some of which are limited to a list of specific values.

You can perform many of these methods in VBA in other ways than using DoCmd and, in some cases as you write more advanced programs, DoCmd might not be the best way to go. Itis, however, a valuable shortcut, especially as you become more familiar with VBA and the things you can do with the language. Exploring the DoCmd methods is a great way to become more comfortable working with VBA.

Private Sub cmdCancel_Click()

On Error GoTo errHandler

Page 148

Page 153: Microsoft Access for Beginners

Microsoft Access for Beginners

'Cancel the record entry by clearing the values and close the form. Me.Undo DoCmd.Close acForm, Me.Name, acSavePrompterrHandler: ErrorHandler Err.Number, Err.Description, _ "frmActivity.cmdCancel_Click"End Sub

The above example shows a form event that is using DoCmd to carry out a form close action. The button, cmdCancel, is designed to close the job lead activity entry form of the application and cancel any entry that's in progress. The Close method of the DoCmd object is called to close the form. The Close method uses three arguments to:

1. Specify that it's closing a form 2. Specify the form name 3. Require that the program prompt the user to save any design changes that have been

made to the form before closing it.

Often, just like with other functions, the DoCmd methods include optional and default parameters. In the case of the Close method, the defaults would have enabled this command to be written in this case as:

DoCmd.Close

This would have assumed that the active window, or the form where the button was being clicked, was to be closed and that the program should prompt to save any changes. It's also possible to accept the defaults for some parameters and specify others like so:

DoCmd.Close , , acSaveYes

In this case, the command closes the current window and automatically saves any design changes without prompting. When accepting the default values in this way, the commas are only required if you want to specify the value for a parameter later in the declaration statement.For example:

DoCmd.Close , "Welcome"

The comma acts as a placeholder for the first argument and accepts the default for the object type being closed. The form name is then specified here but no further placeholders are needed at the end of the statement even though there are additional parameters that could be used.

In Figure 9.19, you can see another example of DoCmd being used to open a form in Access. Note that for a number of the parameters of the OpenForm method, Intellisense supplies a list of possible values to choose from.

Page 149

Page 154: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure 9.19 - Intellisense supplying possible values for the parameters in a DoCmd statement.

Also notice that after the FormName parameter in the first screenshot, the rest of the parameters are optional and have default values. The command could be left at:

DoCmd.OpenForm "mnuReference"

This would open the form with the default and most common options. Having the extra options,however, gives you more control if you need it.

Other Methods

There are a lot of methods available through DoCmd but here are a few that you might use more often.

Method Description

CloseClose a object such as a form or report.

DeleteObject Delete an Access object (table,

Page 150

Page 155: Microsoft Access for Beginners

Microsoft Access for Beginners

query, form, etc.).

MinimizeMinimize a form or report to a tab atthe bottom of the screen.

FindRecordSearch form records for a specific value.

OpenFormOpenReport

Opens a form or report in Access.

GoToControlMoves the focus to a specific control on the form.

QuitClose current database and exit Microsoft Access.

BeepPlay a beep sound through the speaker.

For a complete list, look up the DoCmd object in the Access help file. You can also get help ona specific method by positioning the cursor on the command in VBA code and pressing F1.

Decision Structures

Prior to the introduction of advanced macros in Access 2010, one of the advantages of using VBA rather than macros was the ability to control the order in which actions are performed andallow the code to make decisions based on the conditions it finds as it runs. This is partially done through the event-driven programming structure of VBA. Within procedures, it's done through the use of decision structures.

IF ... THEN ... ELSE

The most basic structure is the If ... Then ... Else statement. This statement controls the actions of the code depending on one or more conditions. Its basic syntax is:

Page 151

Page 156: Microsoft Access for Beginners

Microsoft Access for Beginners

If <boolean condition> Then <action>ElseIf <action>Else <action>End If

The Else and ElseIf statements are optional but the If ... Then and End If statements are required. Here's an example of If ... Then in action:

Public Function StrongPassword (Password as String) as Boolean

If Len(Password) > 7 Then StrongPassword = TrueElse StrongPassword = FalseEnd If

End Sub

The example above tests the length of the password entered, returns True if it's more than seven characters and False otherwise, thus making it an example of a boolean condition. Obviously, more than size matters when it comes to password strength but this is a start.

The If .. Then statement can also support multiple conditions:

If Len(Password) > 7 AND IsNumeric(Left(Password, 1)) Then StrongPassword = TrueElse StrongPassword = FalseEnd If

This is a variation on the password example where the length must be greater than seven characters and the first character must be a number. In this case, if both conditions are true, the function will return True. Otherwise it will return False. Aside from the logical AND operator used above, you could also use one of the other logical operators such as OR or XOR to govern the decision made by an If ... Then statement.

If I wanted to add a third test for the password, I could write this:

If Len(Password) > 7 AND IsNumeric(Left(Password, 1)) AND NOT IsNumeric(Password) Then ...

Writing it this way is considered bad practice, though, because it's unwieldy (a.k.a. ugly) code and causes VBA to do unnecessary calculations. If the first condition fails, the other two still have to be tested. A better way to write this is to nest the If ... Then statements like so:

Page 152

Page 157: Microsoft Access for Beginners

Microsoft Access for Beginners

If Len(Password) > 7 Then If IsNumeric(Left(Password, 1)) Then If Not IsNumeric(Password) Then StrongPassword = True End If End IfEnd If

The three conditions are now split into three decision statements and nested within each other.If the password fails the first test, the others don't even execute and StrongPassword is not setto True unless all three pass.

With nesting, it's still best not to get carried away with too many levels because it can be hard to read and support later but this does allow for more operations. It's also important not to get the levels of nesting tangled by accident. Close the most recently opened decision statement first.

As a final example, If ... Then can also test for multiple results from the same condition.

Public Function DayMessage(TestDate As Date) As String

If Weekday(TestDate) = vbSunday Then DayMessage = "It's a brand new week!" ElseIf Weekday(TestDate) = vbMonday Then DayMessage = "Back to work ..." ElseIf Weekday(TestDate) = vbFriday Then DayMessage = "T.G.I.F!!!" Else DayMessage = "Have a great day!"End If

End Function

In this example, the function accepts a date value that's passed in and uses the VBA Weekdayfunction to determine the day of the week that it represents and provides the appropriate message. The ElseIf statements tests the date against the VBA weekday constants one at a time until a match is found. If no match is found, the final Else statement acts as a catchall.

You can find more information on VBA functions like Weekday, Len and others used in these examples online in the Access help system.

Optimizing Code

When you're writing code, you can often find ways to make the code more efficient, just as youmight find better ways of saying something as you're writing a letter or e-mail. In programming, this is referred to as "optimizing" the code. After writing this example, I remembered there was

Page 153

Page 158: Microsoft Access for Beginners

Microsoft Access for Beginners

a better way to write it:

Public Function DayMessage(TestDate As Date) As String

Dim DayValue As Integer

DayValue = Weekday(TestDate)

If DayValue = vbSunday Then DayMessage = "It's a brand new week!"ElseIf DayValue = vbMonday Then DayMessage = "Back to work ..."ElseIf DayValue = vbFriday Then DayMessage = "T.G.I.F!!!"Else DayMessage = "Have a great day!"End If

End Function

In this variation, notice that the WeekDay function is only called once and the result is assigned to the Integer variable DayValue. Instead of running the Weekday function over and over again, the DayValue variable is tested against the weekday constants which, although they are named, correspond to the numbers 1 through 7. In this case, the change won't make any noticeable difference but if the Weekday function was a large function that took even a couple seconds to run or accessed data tables, the time and resource difference could be verynoticeable, especially if the function or method calling it ran repeatedly.

Another advantage would be if the result of the function being called could change from one moment to the next. In this case, you might want to capture the result at a given moment in time and then refer to that result instead of calling the function again. This is where programming goes beyond knowing the commands and syntax and involves design decisions and an understanding of how the system works. I'll talk about this more in the section on algorithms.

SELECT CASE

While the above example for the If ... Then statement is acceptable and works perfectly well, the ElseIf statement isn't always appropriate for testing all the possible values of a given condition. If there are more than three possible values to test against or you need to carry out the same action for a range of values, a Select Case statement might be the better choice. Here's the basic syntax:

Select Case <statement>Case <value> <action>Case <value>

Page 154

Page 159: Microsoft Access for Beginners

Microsoft Access for Beginners

<action> ..Case Else <action>End Select

Here's the previous If ... Then example rewritten in Case statements and expanded with more options.

Public Function DayMessage(TestDate As Date) As String

Select Case Weekday(TestDate)Case vbSunday DayMessage = "It's a brand new week!"Case vbMonday DayMessage = "Wake me when Monday's over."Case vbWednesday DayMessage = "Halfway there!"Case vbFriday DayMessage = "T.G.I.F.!!!!"Case vbSaturday DayMessage = "Sleep in today. It's Saturday!!"Case Else DayMessage = "Have a great day!"End Select

End Function

Notice how much cleaner the code looks. It's easier to read and understand. Another advantage is that it evaluates the expression once at the top of the Case statement rather thanmultiple times. This eliminates extra processing and the need for the proxy variable that I declared in the If...Then statement. There is still a catchall statement at the end where Case Else handles any result that doesn't match any of the other statements. It's best to get in the habit of using an Else statement since it's possible to leave conditions unhandled without one and this can lead to errors, the causes of which aren't immediately obvious.

As with the If...Then statement, only the first matching Case statement is used and the code then continues after the End Select statement. You can put any number of lines for execution after each Case statement. You could even have Case statements with no code to execute if you wanted to take no action for a particular result.

The Case statements also have flexibility in specifying groups or ranges of values. The following statements are all valid assuming that any variables used have been declared.

Case 100 to 199

Case 5, 10, 15, 20, 25 To 30

Page 155

Page 160: Microsoft Access for Beginners

Microsoft Access for Beginners

Case Is < 21, Is > 45

Case "Red", "Yellow", "Blue"

Case #1/1/2010# To #1/31/2010#

Note the use of the Is keyword with the greater/less than operators and the # around the date values. The # is a type declaration character which signals to the code that the value should betreated as a date rather than a division formula. It's used just as the quotation mark is used for strings.

Program Loops

Sometimes, when writing a procedure, you might want to perform a certain operation repeatedly, such as if you had a group of records or other objects on which you wanted to carry out the same tasks or if you wanted to give the user a set number of chances to enter thecorrect password. Languages like Visual Basic for Applications include keywords that enable an operation to run in a loop for a given number of times. In this section, I'll explain two of these structures in VBA.

FOR ... NEXT

You would use the For Next loop if you knew how many times you wanted an operation to run or if it could be determined through a formula. In VBA, it uses a counter variable to track which iteration of the loop is currently running. Here's the basic syntax and an example:

For <Counter> = <Start Value> to <End Value><actions>Next <Counter>

Dim Properties(1 To 10, 1 To 5) as VariantDim Counter as Integer

For Counter = 1 to 10 Properties(Counter,1) = Counter Next Counter

The above example creates a Properties array with 10 rows and 5 columns. It then uses the For ... Next loop to count from 1 to 10. For each loop, it populates the matching position in the array's first column with the current value of the Counter variable, effectively numbering the rows in the array. In this way the Counter variable can be used for other things in addition to regulating the loop.

It is not absolutely necessary to specify the Counter variable in the Next statement at the end

Page 156

Page 161: Microsoft Access for Beginners

Microsoft Access for Beginners

of the loop but it does make the code easier to read. For ... Next loops can also be nested just like If ... Then statements and if you were to do this, you would want to specify which loop you were closing.

The loop can count forwards and backwards as needed, i.e.

For Counter = 10 to 1

As I said earlier, you can also use a variable or formula to specify the start and end values for the counter variable. The above example also could have been written this way:

For Counter = 1 to UBound(Properties, 1)

This would start at 1 and set the end value to the upper boundary of the Properties array's first dimension.

For...Next loops can also count forwards and backwards by values other than 1 by using the Step keyword on the first line:

For Counter = 0 to 500 Step 5For Year = 2000 to 1900 Step -10

If needed, you can also exit from the loop before the counter reaches its end value as shown inthe following function that accepts a full path reference and returns the file name.

Public Function GetFileName(PathReference As String) As String

'Declare and set variablesDim PathLength As IntegerDim Counter As IntegerDim NameOfFile As String, FileChar As String

NameOfFile = ""PathLength = Len(PathReference)

'Parse PathReference and return file name at the end.

For Counter = PathLength To 1 Step -1FileChar = Mid(PathReference, Counter, 1)If FileChar <> "\" Then NameOfFile = FileChar & NameOfFileElse Exit ForEnd IfNext Counter

GetFileName = NameOfFile

Page 157

Page 162: Microsoft Access for Beginners

Microsoft Access for Beginners

End Function

This function uses the loop to count its way backward through the PathReference string passed into the function, using the length of the string in characters as the starting value of the For loop. It looks at each character and so long as that character is not "\", the function adds the character to the beginning of the NameOfFile string that it's building. If the character does equal "\", the code exits the loop. Either way, after the end of the loop, the code returns the NameOfFile variable as the result.

There are often many ways to do something in VBA and you can often find ways to optimize the code. As it stands, the code above uses more variables and steps than necessary so let's try something different.

Dim PathLength As IntegerDim Counter As IntegerDim NameOfFile As String

PathLength = Len(PathReference)

For Counter = PathLength To 1 Step -1If Mid(PathReference, Counter, 1) = "\" Then NameOfFile = Right(PathReference, (PathLength - Counter)) Exit ForEnd IfNext Counter

GetFileName = NameOfFile

This change eliminates one of the variables and the string concatenation steps. The Mid() function which inspects a character at a specified location in the string now uses a positive testrather than a negative test to check for the "\" character. If it finds it, everything after that point is treated as the file name by the Right() function and the loop exits. Otherwise, it keeps going.

FOR EACH ... NEXT

The For Each loop is useful when you want to iterate through a collection of objects or an arraywithout regard to the number. The statement is limited to items that can be treated as a collection such as forms and array elements and you will probably not use it much until you aremore familiar with the concepts of object-oriented programming. Here's a simple example that demonstrates the syntax with an array:

Dim BusinessTypes(25) as StringDim Business as String

For Each Business in BusinessTypes <statements>Exit For

Page 158

Page 163: Microsoft Access for Beginners

Microsoft Access for Beginners

<statements>Next Business

The above is a stripped down example of the statement which is very similar to the For...Next loop of the previous section. You can also use the Exit For statement to get out of a For Each statement if a condition is met.

Another use for the For...Each statement is with objects in a collection. The below example references the controls collection on a form which includes text boxes, command buttons, check boxes and all the other elements of the form that are used to work with data.

Dim ctrl As ControlDim btnCommand As CommandButton

For Each ctrl In Me.ControlsIf ctrl.ControlType = acCommandButton Then Set btnCommand = ctrl btnCommand.Enabled = FalseEnd IfNext ctrl

This example iterates through all the controls on the form, selects those that are command buttons and disables them one by one. This might be useful if you wanted to lock down a form under certain conditions.

For another example of the For ... Each loop, refer back to the section on procedures which includes example code of For ... Each being used to iterate through all the available forms in an Access application.

Do Loops

While the loops explained in the last section were based on numbered iterations or collections of items, the Do Loop repeats a section of code based on whether a condition is True or False.This removes the necessity for declaring counter or object variables but it also introduces a certain amount of risk. When creating a conditional loop, you must be certain that the conditionyou specify in the loop will actually enable the loop to exit at some point. Otherwise, you will have an endless loop that causes the program to become unresponsive or crash.

There are two types of Do loops; Do While and Do Until. The first would repeat an action while a certain condition is met and the second until a condition is reached.

To try the following example, type the method and function shown below into a new module in VBA, position the cursor within the TestPrime method, press CTRL-G to show the Immediate window (or select Immediate Window from the View menu) and press F5 to run the code.

Public Sub TestPrime()

Page 159

Page 164: Microsoft Access for Beginners

Microsoft Access for Beginners

Dim TestValue as Long

TestValue = 1

'Test every value up to 10000 to'determine if it's a prime number.Do While TestValue <= 10000If IsPrime(TestValue) Then Debug.Print TestValueEndIfTestValue = TestValue + 1Loop

End Sub

Public Function IsPrime(Candidate As Long) As Boolean

'Determine if the number passed in is a prime number.

Dim TestLimit As Long, TestValue As Long

'Assume it is prime until proven otherwise.

IsPrime = True

'If the number is higher than 3, test against every integer up to'the square root of the number.

If Candidate > 3 ThenTestLimit = Int(Sqr(Candidate))For TestValue = 2 To TestLimitIf Candidate Mod TestValue = 0 Then IsPrime = FalseExit ForEnd IfNextElseIsPrime = FalseEnd If

End Function

After you run the program a couple times, I would recommend that you use this code to get familiar with the Access help system. Click on a keyword such as Int, Sqr or Mod and press F1. If the help files are properly installed on your machine, you should see more information onthese functions.

In the TestPrime() method, the code uses a Do While loop in order to test all values up to 10,000 to find prime numbers. If the IsPrime function returns a True result, the code prints the

Page 160

Page 165: Microsoft Access for Beginners

Microsoft Access for Beginners

value in the Immediate window in the VBA environment which is used to display information while debugging the code. (If you don't see this window, press CTRL-G to show it or select it from the View menu in VBA.) This window is scrollable so you'll be able to see the entire list of prime numbers that result.

After the If ... Then statement, the code increments the number to be tested and loops back to run the code again with the new value. Updating the condition being tested or using one that changes automatically is also an important part of using Do loops as testing the same condition over and over again would result in an endless loop and a hung program. To show the flexibility of the Do loop, the statement in the TestPrime() method could be written multiple ways:

DoTestValue = TestValue + 1Loop While TestValue <= 10000

In this variation, the looping decision is placed at the end of the loop, after the incrementing of the variable. The decision of whether to test the condition at the beginning or end of the loop depends on the actions being performed in the loop and how the condition might change between the Do and the Loop.

Do Until TestValue >= 10000TestValue = TestValue + 1Loop

DoTestValue = TestValue + 1Loop Until TestValue >= 10000

In the Do Until / Loop Until variations, the code tests the changing condition until it reaches a certain state. Again, it's important to test for a condition that actually can occur or else you'll have an endless loop. Where I'm incrementing by 1 in these examples, I'm comfortable that the value will actually hit the exact value of 10000 but for the sake of form and good habits, I'vechanged the formula to greater than or equal to 10000

Public Sub Pause(Seconds as Integer)

Dim CurrentTime As Date

CurrentTime = Now() Debug.Print CurrentTime

Do Until Now >= DateAdd("s", Seconds, CurrentTime) DoEvents Loop

Debug.Print Now()

Page 161

Page 166: Microsoft Access for Beginners

Microsoft Access for Beginners

End Sub

The example above is just what the name implies; a method that pauses the execution of codefor the requested number of seconds. It could be inserted before carrying out an action. It usesthe Now() function from VBA to assign the current date and time to a date variable and then uses Do Until to loop until the Now function returns a value greater than or equal to the specified number of seconds after the time that was stored. The method uses Debug.Print to show the start and end times. The DoEvents command allows any background tasks such as screen refreshes to complete while this loop is running. Without it, the loop would bog down your system.

You can also use the Exit Do command to exit a Do loop before it finds the specified condition.

Do Until <condition>If <condition> Then Exit DoEnd IfLoop

While ... Wend

A simpler form of While loop is While ... Wend which loops until a condition is found. This is an older syntax that has even more potential for endless loops and is not as flexible as Do loops.

Public Sub Pause(SpecTime as Date)

While Now() < SpecTime DoEventsWend

Error Handling

Sometimes, errors happen in programs and the advantage with VBA is that you have some very flexible options for responding to them and making sure that they don't disrupt the user's work any more than they have to. With proper error handling, the program can recover and move on from an error or at least keep the program from crashing, notify the user in a clear manner and provide enough information so that you can know what went wrong.

Error handling in any language is divided into catching the errors and determining how to respond to them. You've already seen the basic syntax for catching an error in VBA in some of my previous examples and it's simple enough that there's little reason not to use it.

Page 162

Page 167: Microsoft Access for Beginners

Microsoft Access for Beginners

On Error and the Err Object

In an earlier section, I wrote about object variables which store items that can have their own properties and methods. One of the native objects in VBA is the Err object which stores information on any errors that occur at runtime. This object enables you to see what happened and deal with it appropriately.

Private Sub cmdView_Click()

On Error GoTo errHandler'Open Lead Detail report.If Not IsNull(Me!LeadID) ThenLeadDetail (Me!LeadID)End If

Exit Sub

errHandler:'Ignore report cancellation error.If Err.Number <> 2501 Then MsgBox "The program has encountered an error. " _ & "Please contact support. " _ vbCrLf & "frmLeadsList.cmdView_Click" _& Err.Number & " - " _ & Err.Description, vbExclamation, _"Error - " & "Error"End IfEnd Sub

In the code example above, you can see an example of the Err object being referenced by a Click event from one of the buttons on the main job lead listing from the Job Search Plus demonstration database. At the top of the event code, notice the On Error GoTo statement which directs the method that, in case of error, it should jump to another part of the method. Halfway down the method, you see 'errHandler:'. The colon marks errHandler as a line label which you can use to redirect the program flow to a specific place in the method. In this case, itredirects the label that marks the beginning of the error handling routine.

Incidentally, while Goto is one of the oldest keywords in any version of the BASIC language, in VBA and other advanced versions of BASIC it has fallen far out of favor because overuse of the word can result in what's called spaghetti code. This is code where the flow of execution has been redirected so much that it's error prone and difficult for a programmer to follow and istherefore hard to support. With the ability to create short methods and functions that respond to specific events, it's also no longer needed as much. For these reasons, the On Error statement is one of the only times that you'll see GoTo used by professional programmers.

Note the Exit Sub statement just before the errHandler line label. This command stops the code execution before it reaches the error handler. This way, the error handler is only run if

Page 163

Page 168: Microsoft Access for Beginners

Microsoft Access for Beginners

there is an actual error and execution is redirected there by the On Error statement. Without the Exit Sub statement, the code would continue on and cause problems.

The error handler shows two properties of the Err object that you'll use most; Number and Description. VBA has a collection of numbered errors that can be returned under various circumstances and knowing which one has occurred can go a long way toward solving the problem. In Figure 9.20, you can see an example of an unhandled error that occurred when anobject variable was referenced without being assigned an object first. This type of dialog wouldend the program's operation and result in an unhappy user.

Figure 9.20 - VBA uses a collection of numbered error descriptions to communicate an error tothe user.

In the following code sample, you can see where these numbers are used to distinguish between various errors in order to take the correct action.

errHandler: 'Ignore report cancellation error. If Err.Number <> 2501 Then MsgBox "The program has encountered an error. " _ Please contact support. " & vbCrLf _ & "frmLeadsList.cmdView_Click" _ & Err.Number & " - " & Err.Description, _ vbExclamation, "Error - " & "Error"End If

The MsgBox function above might look complicated but it's actually just another VBA function with parameters that Intellisense will prompt you for. It even returns a numeric value that corresponds to an enumeration you can use in your code.

In most error handlers, I don't actually test for specific errors but this particular code uses the IF statement to test for error number 2501 which occurs when a form or report fails to open. Because there's no ELSE statement here, this code effectively ignores the error. For all other errors, it generates a message box like the one in Figure 9.21 which gives the programmer a lot more information to work with and directs them to support.

Page 164

Page 169: Microsoft Access for Beginners

Microsoft Access for Beginners

There are hundreds of possible error codes in VBA and they tend to change somewhat from one version of Access to the next so if you're looking for the definition of a particular code, it's best to search MSDN or Google for Access VBA error code and include the number of the error.

Figure 9.21 - By using an error handling routine, the program can generate an error message thatis a bit more user-friendly and doesn't crash the application.

As I said earlier, trapping the error is only half the battle. The next step is to decide what to do about it. The example in Figure 9.21 is the result of a programming error that's probably going to stop the program from doing what the user wants it to until the programmer can fix it so the notification is about all that can be done. The problem is that if it's just showing up on the user's screen, you as the programmer might not get to see it before the user clicks it away. Another option is to save it somewhere. In the Job Search Plus program, I opted for a text file that would reside in the same directory as the database itself. I could save it to an Access tablebut what if the error denies access to the database tables? A text file is the simplest, most readable solution in this case.

The result is the ErrorHandler subroutine in the mdlFunctions module of the sample database. This routine is declared as Public so the entire database has access to it. It accepts the error number, description and the name of the function or subroutine that threw the error.

Dim strError As StringDim strErrorLog As String strErrorLog = CurrentProject.Path & "\JobSearchErrorLog.txt" strError = strError & CStr(errNum) strError = strError & " - " & errDesc strError = strError & vbCrLf & vbCrLf strError = strError & "To report errors" strError = strError & vbCrLf & vbCrLf Open strErrorLog For Append As #1 Print #1, CStr(Now) & ": " & errLocation & " threw error " _ & Str(errNum) & " - '" & errDesc & "'"Close #1

The above code is the heart of the subroutine and it constructs a message that can be written

Page 165

Page 170: Microsoft Access for Beginners

Microsoft Access for Beginners

to the end of the error text file, the Open function opens the text file in Append mode as shown,prints the message to it and then closes the file. You can find out more about the Open, Print and Close file functions in the Access help files.

Once the error is written, you have a record of what happened that you can look up in the same directory as the database. Again, since the procedure is public, it can be called from any error handling code within the database. Using the previous example, the call would look something like this:

errHandler:'Ignore report cancellation error. If Err.Number <> 2501 Then ErrorHandler Err.Number, Err.Description, "frmLeadsList.cmdView_Click"End If

The call can pass the Err object properties directly to the ErrorHandler subroutine along with the name of the event that's throwing the error. This call can simply be copied to every event and function where error handling is performed. This effectively creates a central error handling routine.

Error Handling On the Spot

The approach I've shown above is to have all the error handling at the bottom of the subroutine. Another method is to use the following line at the top of the procedure instead:

On Error Resume Next

This means that, in case of an error, VBA will continue execution of the code on the line following the one that resulted in the error. This approach would be most appropriate in code that is accessing resources outside the program or where you're otherwise reasonably sure of where an error is likely to occur. One advantage is that it specifically targets the line of code that poses a risk. An example would be if you were importing an Excel spreadsheet into an Access table. Since this involves an outside file that is independent of the database, there is always the chance that the spreadsheet is inaccessible at the time the import is attempted so it's best to plan for this possibility.

Public Sub OpenExcelSheet()On Error Resume Next

DoCmd.TransferSpreadsheet acImport, _ acSpreadsheetTypeExcel12, _ "Customers", "C:\Data\Customers.xls", True

If Err.Number > 0 Then MsgBox "There was an error " _ opening the Excel spreadsheet.", _

Page 166

Page 171: Microsoft Access for Beginners

Microsoft Access for Beginners

vbOKOnly, "Error ..." Err.Clear End If

End Sub

In this example, the TransferSpreadsheet function attempts to import an Excel file. Immediately afterward, the code checks for an error. The Err object's number property is 0 if there is no error. If it's greater than 0, that means there is an error. The Resume Next command will prevent the code from crashing and a simple message box is shown. As before, you could use the properties of the Err object to populate a more detailed message if needed. Also note the Err.Clear command which clears the last error out of the error object including the error code and description. After this, you could go on with other operations.

You could actually mix the 'On Error GoTo' and 'Resume Next' approaches in the same procedure as one will override the other. If you start with the GoTo statement and then get to asection of code that might cause a specific error you want to check for, you could start the section with an 'On Error Resume Next', insert the error check as shown above and then repeat the 'On Error GoTo ' line to re-activate the original error handler. I wouldn't actually recommend this, however. It's a good idea to write a separate method or function for a dependency operation that could throw its own error.

The Excel file named in the function above is an example of what's called a dependency. That's an outside resource such as a data file or a software component that is outside of your program's control and yet supplies necessary data or functions for your program's operation. Dependencies are sometimes necessary but they should always be used with caution and you should assume that they are likely to fail at some point. In order to prepare for this, you start bydeciding whether you really need this outside resource or if there is another way to get the information or functionality. If you do decide to use them, it's always wise to write in the appropriate error handling so that when the dependencies do fail, your program is ready to handle it.

When deciding on how to handle errors in your code, there are two basic things you need to accomplish; making sure the right people know what error occurred and enabling the program to recover, if possible, so that the user can at least continue working in another area of the program. With Access, this might be as simple as doing nothing after displaying and recording the error since the error hasn't caused the user to leave the form they're on. Having said that, always try to be aware of how any data the user is working with might be affected by whatever subroutine to which you're adding error handling. You should also avoid doing anything in the error handler that might itself cause an error. Notice that the central ErrorHandler method shown earlier has its own error handler that displays a message box to the user in case it can't write the original error to the text file.

Finally, don't let error handlers deal with things that you can prevent. It is always better to write error free code and reserve the error handling for things that you cannot prevent or anticipate.

Page 167

Page 172: Microsoft Access for Beginners

Microsoft Access for Beginners

Algorithms

It's good to know the commands that you can use in Visual Basic for Applications and after you've worked with the language for awhile, you'll have a decent number of them memorized to the point where you won't have to rely on Intellisense. Keywords can be looked up in the help file or online, however, and after the basics that I've mentioned here, you pretty much learn them as you need them. As with most other things, it's about practice.

The other half of programming is knowing how to approach a problem and break it down into steps that can be coded with the right commands. That series of steps is called an algorithm. It's the instructions that a method, a function or a combination of procedures will use in order toaccomplish a task. You could compare it to a home repair project. The keywords and commands are the tools you will use and the algorithm is the instructions for installing a lock orreplacing a light fixture.

The tricky thing about algorithms is that, as I've mentioned before, there often is no one corrector obvious set of instructions. Very often, it's up to the programmer to analyze the problem andfind a good way to solve it in code. This applies on a small scale for individual tasks that involve one or two methods as well as on a large scale for entire projects where the developer must determine the best way he or she can to store data or translate a company's workflow into a series of entry forms and reports. This is why I consider programming to be an engineering discipline. Theoretical projects that you take on to see if something can be done orjust to try out a new function are fun but the real challenges and substance come when have toapply your wealth of technical knowledge and experience to design a practical solution to meetsomeone's needs - often by a deadline.

I'm avoiding referring to 'the best' or 'the most efficient' solution because you probably won't find such a thing at first or even for awhile after you've been programming. Even after you haveyears of experience at this, there's always someone with more experience or a fresh perspective who can come along and say "Why don't we do it this way?" and when you honestly look at their solution, you realize they're right. Programmers are also just as likely to second-guess each other as anybody else and there are as many egos among programmers as in any other field even though there's just as little room for them.

After you know the basics of VBA syntax; keywords, commands, structures, etc., and understand some of the best practices such as commenting and error handling, the rest comeswith the patience to approach a problem logically, the willingness to make a few mistakes and the understanding that things seldom work right the first time.

As for determining the algorithms for your code, it's an individual practice that can't be taught beyond looking at many examples of what works and what doesn't and lots of practice. In programming, as in many other fields such as writing, photography and music, it's important to sample the work of others to see how they do things.

I've shared a number of examples throughout this chapter which I would encourage you to

Page 168

Page 173: Microsoft Access for Beginners

Microsoft Access for Beginners

analyze to see how I did things. Certainly, don't take this as the last word, though. The more sources you find for programming advice, the more you'll learn. Reading someone else's code can be an intimidating thing and I know at one time it was the last thing I wanted to do until I took a job where I had to do it all the time. Eventually I learned to do just what is done when solving a problem; break it down into pieces and take it a piece at a time.

In an earlier section, I included an example function that parsed the filename from a path reference supplied to it and I thought this would be a good example with which to show the basic steps of developing an algorithm.

1. Determine the need.

You have to understand what the need is before you can code for it. Sometimes, that means getting through layers of distractions and asking a lot of questions in order to help the users define it. In the filename function, it's simple -

In Windows and DOS, path references include folders and subfolders as well as the filename. For this exercise, we only want the filename and need a way to separate it from the rest of the string.

2. What are the rules?

As a programmer, you will often deal with business rules. These are rules that define how the business must operate or the structure that the data must follow in order to satisfy the customer's needs. Issues addressed by business rules include:

• How often or how many times product can be ordered by a specific business customer • Under what conditions a discount can be applied • How long data must be retained • What type of notifications must be sent to a customer • What type of payments can be accepted and what data is required for payment

The business rules for a project can affect all aspects of the application, from what tools are used to design it and the type of security that's applied down to the design of specific methods and functions.

Determining the filename in the above example is a smaller task so the rules are simple.

1. Everything to the right of the last backslash in the path reference is to be treated as the filename.

2. The code must make this filename available for use by other code.Notice there's no mention here of how the code is supposed to do that or how it is to make the

Page 169

Page 174: Microsoft Access for Beginners

Microsoft Access for Beginners

value available. Business rules are supposed to specify what is to be done, not how to do it. The second rule actually teeters on the edge of this limitation but from the perspective of this project, I'm allowing it. This is an important issue and the line between those two things can getfuzzy sometimes but remembering this can save a lot of confusion between the programmer and the business.

3. Determine the steps.

Now we're getting to the fun part. For different projects, you might ask some of these questions:

• Where is the data coming from and in what format? • Do I need to store or transmit the data? How? • What type of user entry might be needed to satisfy the rules and what type of controls

would work best? • What queries will I need to create to get the information I need? • What tasks can be broken out into their own functions and should those functions be

available to other projects?

These are just a few of the questions you will learn to ask as you work on projects and, when programming professionally, you could even have the task of writing the answers in the form ofa technical specification for review prior to coding.

In this case, we're just parsing a string so here are the basic rules:

High-level (summary):

Create a function that will accept the path reference as a string parameter, extract the filenamefrom it and return the filename as a string.

Low-level (algorithm):

Determine the length of the string.

Use the length as the limit in a For ... Next loop with which to examine each character starting at the end of the string.

When a folder indicator ("\") is found, return the portion of the string after that point as the filename.

This is actually an extremely low-level algorithm for a single function that you would not normally see in a technical spec for an application. An application technical spec might simply say to write a function to parse the filename from the path string if it mentioned it at all. The level of detail in a technical spec will depend on the preferences of the programming team that

Page 170

Page 175: Microsoft Access for Beginners

Microsoft Access for Beginners

you're on and the nature of the application. More commonly, a spec will talk about things like how the tables are to be designed and normalized, what standalone queries might be created, what forms and reports will be designed and what outside dependencies will be referenced.

4. Write the code and test.

Public Function GetFileName(PathReference As String) As String

'Declare and set variablesDim PathLength As IntegerDim Counter As IntegerDim NameOfFile As String, FileChar As String

NameOfFile = ""PathLength = Len(PathReference)

'Parse PathReference and return file name at the end.

For Counter = PathLength To 1 Step -1FileChar = Mid(PathReference, Counter, 1)If FileChar <> "\" Then NameOfFile = FileChar & NameOfFileElse Exit ForEnd IfNext Counter

GetFileName = NameOfFile

End Function

Even after years of programming, I do not write code from top to bottom. In this example, I remember starting with the most obvious feature, the For loop and then remembering "Oh yeah, I'll need a counter variable for that." and going back up a few lines to declare the variableand while I was there I might have thought to declare an integer variable to hold the path length. After I'd set down the first draft of the function, I remembered to insert a line setting a string variable to a blank string for safety before anything else was done to it. Then there were error corrections, ad hoc changes, etc...

After I finished writing and testing the code and found it to work, I decided to change a few things to make it more efficient.

Public Function GetFileName(PathReference As String) As String

'Declare and set variablesDim PathLength As IntegerDim Counter As IntegerDim NameOfFile As String

Page 171

Page 176: Microsoft Access for Beginners

Microsoft Access for Beginners

PathLength = Len(PathReference)

'Parse PathReference and return file name at the end.For Counter = PathLength To 1 Step -1If Mid(PathReference, Counter, 1) = "\" Then 'Take everything to the right of the character 'as the filename. NameOfFile = Right(PathReference, (PathLength - Counter)) Exit ForEnd IfNext Counter

GetFileName = NameOfFile

End Function

You can see more about this function in the section on For ... Next loops. After I wrote the first draft, tested it and found it to work, I looked at the code and thought "I really made that a lot harder than it needed to be." and went back to simplify it. There's no shame in admitting that your code can be optimized further. This goes back to what I said about solutions rarely being right the first time.

If you'd like an exercise that will demonstrate how many ways there are to do one thing in VBA,you could redesign this function yourself. There's another way to find the last backslash in the string using VBAs InStr() function which you can find more information on in the Access help files. Have fun!

5. Test some more.

Seriously - throw everything you can at your code and try every way you can imagine to break it. I know it's tedious and it looks like it works so why tempt fate, right? Trust me; finding a bug in your code and fixing it before it goes to the customer is a lot less embarrassing than letting the customer find the bug. VBA also offers some good tools for testing code so there's really no good reason not to do it.

There have also been times when I've spent hours, or even a day or three, trying to find the right approach to a problem. Sometimes, it happens because you don't understand something as well as you think you do or because you've gotten so wrapped up in the problem that you can't see straight anymore and need to walk away from it for a bit. Sometimes, showing it to another programmer and asking for advice helps because programming, like other fields whereknowledge is the main tool, is best when done through collaboration with others.

Page 172

Page 177: Microsoft Access for Beginners

Microsoft Access for Beginners

Appendix I - "Where do I go from here?"I wouldn't have been inspired to write the series this book was based on if I hadn't talked to people who were just starting out with Microsoft Access and wanting to learn more. Since writing it, I've received many e-mails from beginners who have discovered just how useful Access can be. Some want to become experts and design professional applications that will help them to earn a bit more acknowledgment and respect at work. Maybe they just want to program for the fun of it or make their own work a little easier.

Whatever benefit you get from your database work, it's important to realize that the ability to design normalized tables and a user-friendly interface is only the beginning of application design and programming. Microsoft Access, despite being the leader in desktop database software and a great training tool, is only one of many applications that you need to be familiar with if you truly want to become a database administrator or programmer of one type or another. There are people who assume these titles when they only know Access but they're at a loss when the serious problems arise that require a perspective that only experience can bring.

So I decided to add a few notes here on some of the things you need to learn if you really wantto become an expert with Access and perhaps move beyond it to other technologies.

• Pay special attention to concepts that work with systems other than Access such as database normalization and data security. While Access is only a starting point, it does serve as a great introduction to database concepts in general and you can transfer a lot of the knowledge you gain from it to other software.

• Learn to work with Visual Basic for Applications (VBA) as soon as you can. Once you have a solid grasp on VBA, it can be a gateway to more advanced environments like the.NET languages and web design.

• Learn how to write SQL code so you're not dependent on the query builder in Access. There are also types of queries such as UNION queries that must be written manually. This is related to the advice I give elsewhere against using wizards. The query builder ishelpful but you won't truly understand queries until you know how to write them yourself.SQL is another technology that is used by many other systems besides Microsoft Access. Understanding it will give you a foothold when you want to move on to other systems.

• After you become an expert with Access, look into more advanced databases like Microsoft SQL Server. This is Microsoft's network database system that offers tighter security and better handling of large database systems. You can download a free version of the product from Microsoft along with free versions of VB.NET and other programming tools.

Page 173

Page 178: Microsoft Access for Beginners

Microsoft Access for Beginners

• Remember that no matter how much you know, there is always more to learn. The technology is always changing and if you want to stay current, you have to keep up with it. If you want to provide the best solutions to your employer, your clients or whatever problems you encounter yourself, you need to have a wide base of knowledge in order to make the best recommendations. There is no one tool that is appropriate in every situation.

• Remember that there will always be people who know more than you. Seek these people out and learn from them whether it's through participation in Internet forums, local user groups or even a team project that stretches your abilities. Being the most computer-literate person in the office can be fun but it can also lead to complacency. As long as you're willing to learn, you never have to be afraid to admit what you don't know.

• In their book, The Pragmatic Programmer, Andrew Hunt and David Thomas use the investment portfolio as a metaphor for a person's collection of knowledge and experience. The development of your 'knowledge portfolio' is essential to your success as a programmer or DBA. Adding to your portfolio often requires little more than an investment of your time. The state of your portfolio will affect such things as your salary, the respect your get at work and even where you are able to live.

• In your spare time, don't forget to learn what you can about networking and hardware. It's another part of the perspective that you need to be a true expert.

A final piece of advice: every day that you put off learning increases the chance that the knowledge won't be there when you need it. That time might come when you have to admit to not knowing something that you realize you should have learned a year ago or when you don't meet the requirements for that great job you really want and you know you could have if you'd been more attentive. This is a lesson I've learned the hard way more than once.

Once you get a good perspective on database operations and administration and have a decent knowledge of programming concepts, you'll have a foundation for building a rewarding I.T. career.

Have fun learning!

For more information:

Getting Started in Software Development - AndrewComeau.comhttp://www.andrewcomeau.com/Indexes/getting-started-software-development.aspxA series of articles with technical and professional advice for pursuing a career in computer programming or software development.

Page 174

Page 179: Microsoft Access for Beginners

Microsoft Access for Beginners

Appendix II - Using Lookup FieldsMicrosoft Access uses lookup fields to provide a selection of possible values for data entry. This selection can be obtained from another table or from a list of values manually entered intothe field settings. Depending on the type of data, the field can be limited to that selection of values or it can learn from the values that the user enters and build the list as new data is entered. This not only speeds up data entry but helps reduce errors and is part of a user-friendly interface.

A good example from the sample database is the CompanyID field in the Leads table. The table stores a number for the company which references one of the records in the Companies table. As shown in Figures A2.1 and A2.2, the Leads table uses a lookup field to display the actual company name from the Companies table although it only stores the ID number.

Figure A2.1 - Lookup fields are used to pull values from another source.

Without the lookup, the numeric CompanyID value would appear like it does in Figure A2.1 which is less than intuitive when viewing the data. Because of the lookup function added to theCompanyID field for this example, the table displays the appropriate title even though only its number is stored.

Page 175

Page 180: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure A2.2 - One benefit of lookup fields that a full name can be displayed in the field while onlystoring an ID number.

The settings for lookup fields are found in the Lookup tab under the individual field settings of the table design screen. These settings allow for a lot of flexibility in the way the data is displayed in the table view. These lookup settings are also inherited by form fields created from the table field.

Figure A2.3 - The lookup settings for a combo box

Display Control

The Display Control setting for a lookup field has three options; Text Box, Combo Box and List Box. Setting it to Text Box removes any lookup function from the field. In a table view, there isn't much difference between a combo and list box. On a form, however, the combo box provides a drop down list which takes up less room than a list box as shown in the comparison from Figure A2.4.

Page 176

Page 181: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure A2.4 - Depending on the number of lookup values, either a combo box or list view mightbe appropriate.

Row Source Type

The Row Source Type setting determines what type of lookup will be performed.

A Table / Query lookup is exactly that, with the data coming from either a table or query in the database or an SQL query added to the control itself. This is a good option for the example shown above where the data is coming from the Companies table. A field can also reference itself when doing a lookup. This might be done if you have a field where you want the lookup toremember values that the user has already entered. Every time a new value is entered into thetable, it's added to the lookup because the field is looking up its own values.

A Value List lookup is appropriate when there are only a few items that you want the lookup to present and it's not likely that the list will change. The ActivityType field in Activities is a good example of this. There is a small number of activity descriptions that can be used. Presenting them in a lookup simplifies data entry and ensures that the descriptions are entered the same way every time without misspellings.

The Field List lookup is a way in which you can list the field names from a specific table in the lookup. This might be used in constructing advanced search forms.

Row Source

This setting specifies the actual source of the lookup data by referencing a table or query, creating a new query or manually entering values. The CompanyID field in the Leads table hasa very simple query behind it that pulls the CompanyID, Company Name and Location from theCompanies table. The link between the tables does the rest and the company name and location is shown in the lookup.

A value list is used in the ActivityType field from the Activities table. The values are entered manually with a semi-colon between each one in the Row Source setting and this allows Access to recognize the separate values.

Page 177

Page 182: Microsoft Access for Beginners

Microsoft Access for Beginners

A Field List lookup will accept the name of any table or query in the database.

Bound Column / Column Count

As you can see by the Company lookup, the Row Source can have more than one column so it's necessary to specify which of the columns supplies the value that's actually saved to the field performing the lookup. In this case, it's the first column since it's the Company ID that's being saved. The company name is only displayed and the location is only shown in the drop down to help the user select a company if there's more than one company with the same name.

The Column Count setting enables Access to correctly read the Row Source and is especially important when using a Value List lookup. Remember that in this lookup, you supply the valuesmanually, placing semi-colons between them. Since there's nothing in the value list to indicate columns, specifying the column count tells Access how many columns of data this actually represents. For example, if you had a field named Location and needed to show company locations and IDs in the dropdown, you would enter something like this under Row Source:

"100";"Seattle";"200";"Denver";"300";"Boston";"400";"Chicago"

You would want this in two columns so entering 2 under the column count tells the database toshow two columns, using the available values to fill in the columns from left to right and adding rows as needed. You would then see something like the list in Figure A2.5.

Figure A2.5 - A lookup field can accommodate more than one column of information.

Depending on which column you chose as the bound column, the table would then save either the location ID on the left (Column 1) or the city name on the right (Column 2) when a user chose a value from the lookup.

Column Heads

This option specifies if a header row should be shown in the lookup. Depending on the source type you specify, this could be field names or, in the example in Figure A2.6, the first row of theValue List would be used as headers. In this case, you would want the Row Source to read something like the example in Figure A2.6.

"Location ID";"City";"100";"Seattle";"200";"Denver";"300";"Boston";"400";"Chicago"

Page 178

Page 183: Microsoft Access for Beginners

Microsoft Access for Beginners

Figure A2.6 - Column headers in the lookup field clarify the display.

By specifying that the list contains column headers and setting the column count to 2, Access reads the list and uses the first two values as the column headers and distributes the rest of the values between the two columns.

Column Widths / List Width / List Rows

The width of the columns in the drop down or list box and the total width of the list itself can be changed with these settings to accommodate headers and content. The Location ID column shown in Figure A2.6 is set at 0.75".

The List Rows setting specifies the number of rows that will be displayed in the drop-down list when it is expanded. This can be useful in adjusting the amount of space taken up by the lookup on a form or in a table view.

Limit to List

This setting determines if the user can enter new values or is limited to the choices offered by the lookup. In the example above, you probably would not want the user adding new locations and you would want to make sure the available locations were entered correctly for reporting purposes so you would probably set this to No. On the other hand, if you're entering a large number of addresses, you might put a lookup on the City field and allow the user to enter new cities as needed. This way, the user would be presented with a list of cities already used whichwould speed up data entry and cut down on error but would still be able to add new ones as needed.

Form Lookups

Combo and list boxes can be added to forms independently of the tables although if they are added to the table when it is designed, form fields based on the table fields will inherit the lookup settings and this saves time when designing. Still, if you decide when designing the form that a combo box is just what you need, the designer makes it easy to change between a text box and combo box just by right-clicking on the control and selecting Change To from the menu. In some cases, on a read-only form, you might want to have a text box rather than a lookup field that would imply that the field could be changed. The properties that the form combo and list boxes use are also identical to the ones described here.

Page 179

Page 184: Microsoft Access for Beginners

Microsoft Access for Beginners

Appendix III - GlossaryAggregate - A group of totaling functions within Access queries including COUNT, SUM and AVG that enable the user to analyze chunks of data.

Algorithm - The series of steps that a computer program uses in order to accomplish a given task. These steps are determined before writing the actual code. They can be expressed as a set of directions, sometimes in the code comments, for accomplishing the task and are decided upon before coding begins.

Alias - In a Microsoft Access query, a short name or abbreviation applied to a table name that makes the query language easier to read.

Alphanumeric - Data that can contain both letters and numeric digits such as license numbers, names, and serial numbers. The term is often used to distinguish these types of values from numeric values such as sales figures on which math operations might be performed.

Application - In Microsoft Access, a database designed to provide a specific solution which includes a combination of objects such as queries, forms, reports and functions.

Array - In Visual Basic for Applications, a variable that is able to hold multiple values so that they can be individually referenced as needed. The array is declared with one or more dimensions of various sizes as needed.

Atomicity - The conditions under which data has been broken down into separate values to the point where it cannot be broken down any further and still remain useful. This is done for the purpose of optimizing the design of tables within a relational database and enables the data to be searched on and sorted as needed. For example, a person's full name would be broken down into first, last and middle name so that a list of names could be sorted by any oneof these elements while an address would be broken down into address lines, city, state and zip. Atomicity is a requirement for the First Normal Form in Database Normalization.

Attachment - A feature introduced in Access 2007 where external files such as Word and Acrobat files can be stored in a field within the database.

Autoexec - A Microsoft Access macro that automatically starts as soon as the database is opened in Access. Simply naming the macro autoexec signals to Access that this is the macro to be run at startup.

Page 180

Page 185: Microsoft Access for Beginners

Microsoft Access for Beginners

Auto Expand - A feature in Microsoft Access and other software which automatically completes entry of information into a field based on previous entries or other criteria.

AutoNumber - A database field type which automatically generates a random or sequential unique value for a field when a new record is entered.

Boolean - As a data field type, this indicates a value that can be either True or False. These two conditions can be represented in the field either by those words or through values such as 0 and 1 or Y and N.

CamelCase - A naming convention for variables in VBA in which multiple words are strung together to form a recognizable name and the initial letter of each word is capitalized.

Class Module - In VBA, a code module that is attached to a form or report and supplies programming functions for that object.

Column - In a database table, this is a collection of cells that represents one element of data across all the rows such as a name or a city value. See Field.

Command Button - A control available on Access forms which mimics a real-life button. Whenthe user clicks on the command button with the mouse, a macro or VBA event is fired.

Compiler - A computer program that translates high-level programming instructions into a formusable by the computer and performs a limited amount of error checking on the code.

Composite Key - A primary index in a table that consists of more than one field so that no tworecords within the table can have the same combination of values in these fields. An example would be a table of contacts where the composite key combined the name and phone number fields. More than one record may exist with the same name or the same phone number but notthe same combination of both.

Concatenate - To combine multiple text values that are either specified or generated by functions into a single string using the "&" character, i.e. with the Date() function representing the current date, "Printed on: " & Date() would result in "Printed on April 30, 2008". This would be used to provide values for labels and text boxes, especially on reports.

Constant - In Visual Basic for Applications, this is a type of variable that is defined once duringthe program's operation and cannot be changed. An example would be a local sales tax or a mathematical constant such as the value of Pi.

Control - Part of a program interface that provides functionality to the user and can be designed to respond to events and user actions. Examples include command buttons and toolbars.

Database - In general terms, a database is any collection of formatted data such as an

Page 181

Page 186: Microsoft Access for Beginners

Microsoft Access for Beginners

address book or any other list of items that share a set of common characteristics. In a relational database, data is grouped into tables by subject or object type with columns that contain the specific attributes (i.e. name, address, city) and rows for each item stored. Database applications designed in Microsoft Access include objects such as queries for retrieving specific data, forms for entering and displaying data and reports for compiling the data into a presentable format.

Database Normalization - The process of organizing data into tables or other groupings by subject so as to eliminate redundancy and ensure the integrity of the data. See Normal Forms.

Data Type - A format used by a database to store different kinds of data. Data types are defined by the properties and limits of the data being stored. Examples include the Text or String data type which stores alphanumeric data such as city and state names and the Integer type which stores whole numbers within a given range. Data types also differ in the functions that can be performed on them and the amount of space that is used to store them. A number such as 33325 could be stored as a numeric type (integer, single, double, etc.) so that mathematical functions could be performed on it. It could also be stored as text or string data ifpart of an address or other text field.

Datasheet - A display of rows and columns that represent the data held in a data table or generated by a query.

DBA - Database Administrator; a person who designs and maintains database systems, usually for an organization and often as part of a larger I.T. department.

Declaration - In VBA, a line of code that indicates a new variable, constant or procedure to thecompiler.

Dependency - A resource that exists outside the control of an application and on which the application is dependent for data or functionality. An example would be a data file from which the program must obtain necessary data.

Developer - A person who develops software or database products. Aside from coding and final construction of the product, this can include a range of tasks covering the development life-cycle including gathering of business requirements, specification writing, testing and deployment.

Dialog - In Access and VBA, a dialog is a screen form used to present and gather information. It can include various types of controls that respond to specific events.

DoCmd - A VBA object that contains numerous methods which act as shortcuts, enabling the user to perform various tasks with a single command.

Enumeration - In VBA, this is a list of items such as office locations or product categories that is maintained as a collection of constants by the application. This list can be declared as a

Page 182

Page 187: Microsoft Access for Beginners

Microsoft Access for Beginners

variable type in VBA and the individual items can then be referenced through Intellisense. Each item in the collection is assigned either a default or specific value so that items are storedas numeric values while maintaining the name assigned to them for reference.

Event - In programming, an event is a condition which the program can respond to such as theclick of a command button or the change in a specific value. Events can be generated either byuser action or by a change in program conditions. Multiple events might occur or "fire" in rapid succession as part of a larger task such as the display of a form.

Event-Driven Programming - A programming model in which instructions are issued to the computer in response to actions by the user such as the click of a command button or the opening of a form. Programming instructions are broken up into procedures that run when the events fire. Event-driven programming is distinct from other forms of programming where the entire program is contained in a single listing and run sequentially.

Field - In database terms, a table element that holds a specific piece of data. A field can be represented by a column within a table or a box on a form where the user can enter or view thedata.

Field Validation - The process of applying certain rules to data within a field. This might be a requirement on the number of characters that can be entered for a password, or the assurancethat a date entered falls within a certain range.

Filter - A set of rules that are applied when selecting information from a database. The filter limits the amount of information returned thereby enabling the user to see only the relevant data.

Foreign Key - A column in a database table that is used to match records with data in another table. One example would be a Customer ID field used as the primary key in the main Customer table and then as a foreign key in a table which lists the customer orders. The foreign key identifies which orders belong to a specific customer by using the appropriate customer ID value for each order.

Formula - A set of mathematical instructions used to achieve a result. In Microsoft Access, thisformula can include variables and constants pulled from the database.

Footer - A repeating section in a form or report that is displayed at the bottom of each page or of the document itself. It can contain titles and controls such as page numbers and date displays.

Form - An object within a Microsoft Access application which is used to display and enter information. Forms may include multiple controls such as text fields and even other forms that are used to group and enter data. The forms can also contain a large amount of programming that is used to provide various functions to the user or to manage the operation of the interface.

Page 183

Page 188: Microsoft Access for Beginners

Microsoft Access for Beginners

Function - See Procedure

Grouping - Within a query, data can be grouped on one or more fields in order to provide results on groups of records. An example would be a grouping by city or department used to report information or subtotals of different values based on these groupings of data. Groups are also used in forms and reports to create custom headers and footers based on specific fields.

HTML - HTML (HyperText Markup Language) is a text markup language used to create web pages that can be displayed on the Internet and read by web browsers. It uses plain text whichis marked up with standard formatting codes that can be translated to format and arrange the text on the screen. It is the primary language used for the construction of websites.

Header - A repeating section in a form or report that is displayed at the top of each page or of the document itself. It can contain titles and controls such as page numbers and date displays.

Index - A structure in a database table that assists in the sorting and retrieval of data from the table. Indexes may be placed on single fields or combinations of fields and may apply restrictions such as the requirement of a unique value.

Inheritance - In Microsoft Access, the ability of a form field to inherit certain properties from the table field that it references. This often includes functions such as a data lookup on the field, providing pre-selected values for entry.

Integrated Development Environment (IDE) - A program that contains a combination of toolsfor writing, debugging and compiling code.

Intellisense - A function of the Visual Basic for Applications IDE that assists in the completion of commands as they are being typed and prompts for the necessary parameters for referenced functions.

Immediate Window - A window within the Visual Basic for Applications IDE that is used for testing formulas and displaying messages from the code in real time.

Integer - In Access, this is a data type that stores a whole number, a number with no fraction or decimal places to the right of the zero. There are two types of integers in Access; regular Integers store values from -32,768 to 32,767 while Long Integers store values from -2,147,483,648 to 2,147,483,647. The difference is in the number of bytes used to store the value.

Interface - A collection of controls that enable the user of a program to use its various functions. This can be in the form of commands entered on a command line or graphical controls on a form.

Join - The link between two related tables. A join specifies how the data is related and which

Page 184

Page 189: Microsoft Access for Beginners

Microsoft Access for Beginners

table is to take precedence in the relationship. The joins between tables affect the way that data is retrieved by queries and other elements in the database.

Lookup Field - A field that references a list of values from which the user can select the correct choice. This list may be a short list of values programmed into the field or a dynamic listdrawn from a database table.

Macro - A set of commands intended to run in order to carry out a specific task.

Margin - The areas at the top, bottom and sides of the report where data is not printed. In Microsoft Access, The margins are set for a report in the Page Setup dialog.

Menu - A list of options from which a user selects the necessary function.

Method - See Procedure.

Microsoft Access - A relational database management system (RDBMS) designed for use onpersonal computers. The software provides a system for designing database applications for use by a small number of users. These applications can include data entry forms, queries and reports in order to provide for all phases of data collection and analysis.

Module - A grouping of procedures and other code in Microsoft Access. It may be attached to a form or report or be a standalone object within the database.

Normal Forms - A set of rules for organizing data which ensures that it meets specific requirements of database normalization. The normal forms are applied in order with each building upon the last in order to eliminate various types of redundancy from the data. Normal forms are referred to by the order in which they are applied (i.e. First Normal Form or 1NF). There are three basic forms which are most commonly applied with additional forms for specific situations.

Object (VBA) - In VBA, an item which can have its own properties and methods and can be referenced and manipulated in code. Forms, reports and the controls that they contain are all considered objects. Custom objects can also be created in order to represent business related entities such as customer orders or inventory items as well as items that the program must interact with such as printers, files and database connections.

Operator - A symbol used to indicate a specific mathematical or logical operation in a formula. In VBA, operators include standard math symbols such as + and - as well as logical and comparison operators.

Parameter - A value accepted by a procedure or function for use in its calculations. In VBA, parameters are included in the procedure declaration and are also called input variables.

Primary Key - The main index on a data table which contains a unique value to identify the

Page 185

Page 190: Microsoft Access for Beginners

Microsoft Access for Beginners

item stored in each row of the table.

Procedure - A unit of VBA code that can be called to perform a given function or return a result. There are three types of procedures in VBA. Methods (subroutines) are the primary typeof procedure and are used to perform general operations and respond to events. Functions areused to calculate and return values. Property procedures are used to store and return custom property values on forms, reports and other values.

Programming Language - An artificial language used to issue instructions to a computer. Some languages are designed for specific purposes such as business or scientific programming while others are general purpose. Higher-level languages such as VBA and C# contain commands that resemble human language and use compilers or interpreters to translate the instructions into commands usable by the computer. While the syntax varies, languages often have features such as decision loops, variables and error handling structures in common.

Project Explorer - The section of the Visual Basic for Applications IDE that displays objects containing editable code.

Property Procedure - In VBA, this is a type of procedure that controls access to a custom property on a form or report. The property procedure can include functions to read and write to the property. One of these functions can also be omitted to make the property read-only or write-only.

Query - A set of instructions which retrieves data from a database table. In Microsoft Access queries are designed using Structured Query Language (SQL).

Record - A collection of fields or values which combine to describe a single item. In Microsoft Access, a record is represented by a single row within a table.

Recordset - A collection of data records. This term most often refers to records that have beenretrieved using a query or stored procedure and may have been pulled from a combination of tables.

Record Validation - The process of applying certain rules to the data within an entire row. These rules often involve the way in which different fields relate to each other. An example would be an employee table where the employee's start date could not occur before the hire date.

Recursive Programming - A programming technique in which a method or subroutine calls itself in order to perform repeating operations on objects such as subdirectories that are arranged in a hierarchy and therefore cannot be listed in a linear fashion.

Referential Integrity - The process by which relationships between tables are enforced. Most commonly, this ensures that a record cannot exist in one table without a related record in

Page 186

Page 191: Microsoft Access for Beginners

Microsoft Access for Beginners

another table. For example, an order cannot exist in the Orders table without a corresponding customer record in the Customers table which is required to supply a CustomerID value for theorder. It also ensures that data cannot be altered in a way that would defeat the established relationships. Again, a record in the Customer table could not be deleted without considering all of the records in other tables that referenced its CustomerID value. Access allows for cascading updates and deletions of related records in tables to maintain referential integrity.

Relational Database - A database in which data is arranged into tables by subject or object represented which are then related or joined by common fields. A common example is a customer orders database in which one table contains information specific to the customer such as contact information and another table contains the orders. A Customer ID would be used to link these tables. This allows for organized and flexible entry and storage of the data without the limitations of a flat file.

Relational Database Management System (RDBMS) - Software that enables the creation and management of relational database systems. This software can be desktop or network based and may allow for databases of varying sizes. An RDBMS must enforce the necessary rules to keep the database in conformance with the relational database model designed by E.F. Codd.

Relationship - Relationships specify how one set of data corresponds to another and are expressed in terms of the number of members on each side of a relationship. For example, therelationship between a Customer table and an Orders table would be a one-to-many relationship with many orders for each customer. Relationships are defined within the database in order to enable querying of data between tables for reporting and display on forms.

Report - A database object that compiles database information in a format suited for printing and analysis. The report design contains fields that pull data directly from the database and can manipulate or perform calculations on that data as needed.

Row - In a database table or query, this is a collection of cells across multiple columns that represent one data record.

Runtime - Refers to actions and decisions that happen during the operation of the program as opposed to design time or during the compilation of the program. More specifically, it might refer to an error that is not caught until the program runs that specific code. The Microsoft Access Runtime also refers to the software which enables an Access database to be opened and used on a specific machine. Starting with Access 2007, this software is available as a free download from Microsoft with the limitation that design changes to the database are disabled.

Schema - The schema describes the way the data will be organized and represented. This might be as general as an outline of objects represented by the database (i.e. employee, customer, order, product) and the way in which they relate or as specific as the collection of tables representing each object and the relationships drawn between them.

Page 187

Page 192: Microsoft Access for Beginners

Microsoft Access for Beginners

Scope - In VBA, the scope is the area of the code from which a specific variable or procedure can be accessed. This might be limited to the specific procedure in which a variable is declared or might encompass the entire application.

SQL - Structured Query Language - A scripting language that is used with relational databasesto provide an interface for the retrieval and storage of information in the tables. The language provides keywords such as SELECT, INSERT and ORDER BY to specify actions to be performed on specified fields and tables.

Subform / Subreport - In Microsoft Access, a form or report that is contained within another form or report, usually displaying a related set of data. For example, an employee form might contain a subform that would display a list of skills and certifications held by the employee which would be stored in a separate table. The subform or subreport is related to the parent object by a query that joins their respective tables.

Subroutine - See Procedure.

Tab Order - The order in which the TAB key will move the focus between various fields on a form in Microsoft Access. This order can be set by the designer of the form to assist in proper data entry.

Table - A database object that holds data in the form of rows and columns. This can be a stored object within the database file or an abstract recordset that is held in memory during an operation.

Template - An object which defines a pattern according to which data will be entered. This canbe a collection of symbols that specifies what type of characters will be allowed in each position within a field.

Toolbar - A program bar which includes a collection of buttons that can be clicked to perform various functions. In Microsoft Access, pre-defined and custom toolbars can be used with forms as part of the user interface.

Unicode - An expanded character set used by Microsoft Office and other programs to represent a wide range of characters from different languages including Arabic, Hebrew, Chinese, Japanese and others.

Value List - A list of values made available to a control for selection by the user. In Microsoft Access, this typically refers to a short list of values that are entered into the property sheet of adrop-down style form control.

Variable - A placeholder and identifier for a specific value or item within VBA code which allows that item to be changed when necessary and still retain its meaning and context.

Variant - A variable or object in VBA that is declared without a specific type and can then be

Page 188

Page 193: Microsoft Access for Beginners

Microsoft Access for Beginners

converted to the correct type as needed.

Visual Basic for Applications (VBA) - A version of Microsoft Visual Basic that is used with the Microsoft Office Applications, most notably Access. VBA is used in conjunction with forms, reports and other controls to perform functions beyond what is possible through standard macros. The language offers many of the features of Visual Basic including error handling, conditional operations and debugging tools.

Wizard - A section of a program which uses a series of dialog boxes to guide the user through the choices involved in the creation of a project. In Microsoft Access, wizards can be used for everything from creating simple controls such as command buttons to entire database applications.

Zero-based - In VBA and other programming languages numbered lists such as arrays and numbered collection items often start at 0 by default instead of 1.

Page 189

Page 194: Microsoft Access for Beginners

Microsoft Access for Beginners

Suggested Reading and References

Books

Microsoft Access 2010 Step by Step (Step By Step (Microsoft)) - Joan Lambert III, Joyce Cox (Microsoft Press)Published July 20, 2010, 448 pages (Kindle version available)

Access 2010: The Missing Manual - Matthew McDonald (Pogue Press)Published: June 29, 2010, 832 pages

Access 2007: The Missing Manual - Matthew McDonald (Pogue Press)Published: January 5, 2007, 752 pages (Kindle version available)

Microsoft Office Access 2007: The Complete Reference (Complete Reference Series) (McGraw-Hill Osborne Media)Published: January 26, 2007, 1024 pages (Kindle version available)

Links

Description of the Database Normalization Basicshttp://support.microsoft.com/kb/283878From Microsoft's support site. This is another resource for the basics of database normalization with links to additional materials.

Microsoft Access Blog: Access 2010: Design More Maintainable Apps with Calculated Columnshttp://blogs.msdn.com/b/access/archive/2010/01/22/access-2010-design-more-maintainable-apps-with-calculated-columns.aspxMicrosoft's explanation of the decision to introduce calculated fields into Microsoft Access tables.

Microsoft Access Tips for Casual Users: Calculated Fieldshttp://allenbrowne.com/casu-14.htmlAn opposing view on calculated fields from Allen Browne's Database and Training website.

Customize the Ribbon in Microsoft Access 2007

Page 190

Page 195: Microsoft Access for Beginners

Microsoft Access for Beginners

http://www.databasedev.co.uk/access2007ribbon.htmlA starting point for learning how to create a customized Office ribbon for your Access 2007 application.

Security Considerations and Guidance for Access 2007http://msdn.microsoft.com/en-us/library/bb421308.aspx

Introduction to Macroshttp://office.microsoft.com/en-us/access-help/introduction-to-macros-HA001214202.aspxMore information on creating and using macros in Access 2007

Get Started with Access Programminghttp://office.microsoft.com/en-us/access-help/get-started-with-access-programming-HA001214213.aspxAn introduction to Microsoft Access programming with a comparison of macros and Visual Basic for Applications (VBA)

Meet the Access 2010 Macro Designerhttp://blogs.office.com/b/microsoft-access/archive/2009/07/28/meet-the-access-2010-macro-designer.aspxAn introduction to the changes in the Microsoft Access 2010 macro designer. Includes a demonstration video.

Working with Macros and Expressions in Access 2010http://msdn.microsoft.com/en-us/library/gg435977.aspx

Page 191

Page 196: Microsoft Access for Beginners

About the Author

Andrew Comeau is a Microsoft-certified programmer based in Ocala, Florida. He has been working with Microsoft Access since 1997 and provides independent consulting with that and other technologies. He has also authored the book Your First Guide to Database Design, a beginner's guide to database design principles. More information is available on his websites at Drewslair.com and AndrewComeau.com.