This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
For my family, Cheryl, Amy, Aaron, and Arica, for your love and support. You are the reason I have written this book and I couldn’t have done it without you.
What do you think of this book? We want to hear from you! Microsoft is interested in hearing your feedback so we can continually improve our books and learning resources for you. To participate in a brief online survey, please visit:
What do you think of this book? We want to hear from you! Microsoft is interested in hearing your feedback so we can continually improve our books and learning resources for you. To participate in a brief online survey, please visit:
microsoft.com/learning/booksurvey
Acknowledgments Nearly every member of the Microsoft Access development team provided invaluable technical support as I worked through the finer details in Microsoft Access 2010. The program managers, developers, and test engineers on the team helped with suggestions, tips and tricks, and reviewing my material. Special thanks to program manager Ric Lewis, who helped write the Business Connectivity Services chapter. You folks make an author’s job so much easier. But any errors or omissions in this book are ultimately mine. A book this large and complex requires a top-notch team to get what I put into Microsoft Word documents onto the printed pages you are now holding. I had some of the best in the business at both Microsoft Press and O’Reilly Media to get the job done. Many thanks to Kenyon Brown at O’Reilly Media for serving as Acquisitions and Development Editor and to Juliana Aldous as Acquisitions Editor for Microsoft Press. Special thanks also to Linda Allen and Rachel Monaghan for handling copy and production editing and to Andrew Couch and Jim Bailie for technical reviewing. I couldn’t have done it without you! And last, but certainly not least, I thank my wife and soulmate, Cheryl. She not only patiently stood by me as I cranked through 1,800 pages of manuscript, but also helped behind the scenes reviewing and editing what I did. —Jeff Conrad Redmond, Washington July 2010
xxv
About the CD The companion CD that ships with this book contains many resources to help you get the most out of your Inside Out book.
What’s on the CD Your Inside Out CD includes the following: ●●
Sample client and web database applications. Includes query, form, and report examples.
●●
Four bonus chapters. Here you’ll find coverage of Visual Basic fundamentals, adding the finishing touches, and distributing your application.
●●
Six technical articles. This section includes an overview of SQL, exporting data, a function reference, color names and codes, and macro actions.
●●
Complete eBook. In this section, you’ll find the entire electronic version of this title.
Sample Applications Throughout this book, you’ll see examples from four sample Access applications included on the sample CD:
●●
Back Office Software System Restaurant Management Application (BOSS.accdb). This application is a hybrid Access application designed for use in both client and web. It demonstrates how a restaurant might manage food orders, maintain employee records, and create weekly work schedules. This application can be published to a server running SharePoint 2010 and Access Services and then used within a web browser. You’ll also find BOSSDataCopy.accdb and BOSSDataCopy2.accdb files that contain many of the query, form, and report examples.
●●
Conrad Systems Contacts (Contacts.accdb and ContactsData.accdb). This application is both a contacts management and order entry database—two samples for the price of one! This sample database demonstrates how to build a client/server application using only desktop tools as well as how to “upsize” an application to create an Access project and related SQL Server tables, views, stored procedures, and functions. You’ll also find a ContactsDataCopy.accdb file that contains additional query, form, and report examples.
xxvii
xxviii About the CD
●●
Housing Reservations (Housing.accdb). This application demonstrates how a company housing department might track and manage reservations in company-owned housing facilities for out-of-town employees and guests. You’ll also find HousingDataCopy.accdb and HousingDataCopy2.accdb files that contain many of the query, form, and report examples.
●●
Wedding List (WeddingMC.accdb and WeddingList.accdb). This application is an example of a simple database that you might build for your personal use. It has a single main table where you can track the names and addresses of invitees, whether they’ve said that they will attend, the description of any gift they sent, and whether a thankyou note has been sent. Although you might be tempted to store such a simple list in an Excel spreadsheet or a Word document, this application demonstrates how storing the information in Access makes it easy to search and sort the data and produce reports. The WeddingMC database is automated entirely using macros, and the WeddingList database is the same application automated with Visual Basic.
You can find these databases on the companion CD provided with this book. Please note that the person names, company names, email addresses, and web addresses in these databases are fictitious. Although we pre-loaded all databases with sample data, the Housing Reservations and Conrad Systems Contacts databases also include a special form (zfrmLoadData) that has code to load random data into the sample tables based on parameters that you supply. The examples in this book assume you have installed the 32-bit version of Microsoft Office 2010, not just the 32-bit version of Access 2010. The sample databases included with the companion CD have not been modified to work with the 64-bit version of Access 2010. Several examples also assume that you have installed all optional features of Access through the Office 2010 setup program. If you have not installed these additional features, your screen might not match the illustrations in this book or you might not be able to run the samples from the companion CD. A list of the additional features you will need to run all the samples in this book is included in the Appendix.
System Requirements Following are the minimum system requirements neccessary to run the CD: ●●
A Pentium 500 megahertz (MHz) or faster processor (Pentium III is recommended as a minimum), and 1 gigahertz (GHz) is required for Microsoft Outlook with Business Contact Manager.
●●
Microsoft Windows XP with Service Pack (SP) 3 (32-bit), Windows Vista with SP1 (32bit or 64-bit), Windows Server 2003 R2 (32-bit or 64-bit) with MSXML 6.0 installed,
About the CD xxix
Windows Server 2008 (32-bit or 64-bit), or Windows 7 (32-bit or 64-bit). Terminal Server and Windows on Windows (WOW), which allows installing 32-bit versions of Office 2010 on 64-bit operating systems, are supported. ●●
At least 256 megabytes (MB) of random access memory (RAM); 512 MB is recommended.
●●
A hard drive with at least 527 MB of free space for a minimum installation when your network administrator has set up an install package for you on a server. When you perform a local installation, you need up to 3.5 gigabytes (GB) on your primary hard drive for the installation files and programs. At the end of the Office system install, you have the option to leave some of the installation files on your hard drive, which requires up to an additional 240 MB of free space.
●●
A CD-ROM or DVD-ROM drive. (A DVD-ROM is recommended.) If you are installing over a network, no disc drive is required.
●●
A mouse or other pointing device.
●●
A 1024 × 768 or greater monitor display.
Other options required to use all features include the following: ●●
A multimedia computer for sound and other multimedia effects.
●●
Dial-up or broadband Internet access.
●●
Certain inking features require running Windows XP Table PC edition or later. Speech recognition functionality requires a close-talk microphone and an audio output device. Information Rights Management features require access to a Windows Server 2003 with SP1 or later running Windows Rights Management Services.
●●
Connectivity to Microsoft Exchange 2000 Server or later is required for certain advanced functionality in Outlook 2010. Instant Search requires Windows Desktop Search 3.0. Dynamic Calendars require server connectivity.
●●
Microsoft Internet Explorer 6 or later, 32-bit browser only. Internet functionality requires Internet access (fees might apply).
●●
Connection to an Internet service provider or a local copy of Microsoft Internet Information Services (IIS) installed.
●●
512 MB of RAM or higher recommended for Outlook Instant Search. Grammar and contextual spelling in Microsoft Word 2010 is not turned on unless the computer has 1 GB memory.
xxx
About the CD
Note An internet connection is necessary to access the hyperlinks on the companion CD. Connect time charges may apply.
Support Information Every effort has been made to ensure the accuracy of the contents of the book and of this CD. As corrections or changes are collected, they will be added to a Microsoft Knowledge Base article. Microsoft Press provides support for books and companion CDs at the following website: www.microsoft.com/learning/support/books/. If you have comments, questions, or ideas regarding the book or this CD, or questions that are not answered by visiting the site above, please send them via e-mail to mspinput@ microsoft.com. You can also click the Feedback or CD Support links on the Welcome page. Please note that Microsoft software product support is not offered through the above addresses. If your question is about the software, and not about the content of this book, please visit the Microsoft Help and Support page or the Microsoft Knowledge Base at http://support. microsoft.com.
Conventions and Features Used in This Book This book uses special text and design conventions to make it easier for you to find the information you need.
Text Conventions Convention
Meaning
Abbreviated menu For your convenience, this book uses abbreviated menu commands. commands For example, “Click Tools, Track Changes, Highlight Changes” means that you should click the Tools menu, point to Track Changes, and click the Highlight Changes command. Boldface type
Boldface type is used to indicate text that you enter or type.
Initial Capital Letters
The first letters of the names of menus, dialog boxes, dialog box elements, and commands are capitalized. Example: the Save As dialog box.
Italicized type
Italicized type is used to indicate new terms.
Plus sign (+) in text Keyboard shortcuts are indicated by a plus sign (+) separating two key names. For example, Ctrl+Alt+Delete means that you press the Ctrl, Alt, and Delete keys at the same time.
Design Conventions
INSIDE OUT
his Statement Illustrates an Example of an “Inside Out” T Heading
These are the book’s signature tips. In these tips, you’ll get the straight scoop on what’s going on with the software—inside information about why a feature works the way it does. You’ll also find handy workarounds to deal with software problems.
Sidebars Sidebars provide helpful hints, timesaving tricks, or alternative procedures related to the task being discussed.
xxxi
xxxii Conventions and Features Used in This Book
Troubleshooting This statement illustrates an example of a “Troubleshooting” problem statement. Look for these sidebars to find solutions to common problems you might encounter. Troubleshooting sidebars appear next to related information in the chapters. You can also use the Troubleshooting Topics index at the back of the book to look up problems by topic.
Cross-references point you to other locations in the book that offer additional information about the topic being discussed.
Note Notes offer additional information related to the task being discussed.
!
Caution
Cautions identify potential problems that you should look out for when you’re completing a task or problems that you must address before you can complete a task.
When an example has a related file that is included on the companion CD, this icon appears in the margin. You can use these files to follow along with the book’s examples.
Syntax Conventions The following conventions are used in the syntax descriptions for Visual Basic statements in Chapter 24, “Understanding Visual Basic Fundamentals,” Chapter 25, “Automating Your Application with Visual Basic,” SQL statements in Article 2, “Understanding SQL,” and any other chapter where you find syntax defined. These conventions do not apply to code examples listed within the text; all code examples appear exactly as you’ll find them in the sample databases. You must enter all other symbols, such as parentheses and colons, exactly as they appear in the syntax line. Much of the syntax shown in the Visual Basic chapter has been broken into multiple lines. You can format your code all on one line, or you can write a single line of code on multiple lines using the Visual Basic line continuation character (_).
Conventions and Features Used in This Book xxxiii
Convention
Meaning
Bold
Bold type indicates keywords and reserved words that you must enter exactly as shown. Microsoft Visual Basic understands keywords entered in uppercase, lowercase, and mixed case type. Access stores SQL keywords in queries in all uppercase, but you can enter the keywords in any case.
Italic
Italicized words represent variables that you supply.
Angle brackets < > Angle brackets enclose syntactic elements that you must supply. The words inside the angle brackets describe the element but do not show the actual syntax of the element. Do not enter the angle brackets. Brackets [ ]
Brackets enclose optional items. If more than one item is listed, the items are separated by a pipe character (|). Choose one or none of the elements. Do not enter the brackets or the pipe; they’re not part of the element. Note that Visual Basic and SQL in many cases require that you enclose names in brackets. When brackets are required as part of the syntax of variables that you must supply in these examples, the brackets are italicized, as in [MyTable].[MyField].
Braces { }
Braces enclose one or more options. If more than one option is listed, the items are separated by a pipe character (|). Choose one item from the list. Do not enter the braces or the pipe.
Ellipsis …
Ellipses indicate that you can repeat an item one or more times. When a comma is shown with an ellipsis (,…), enter a comma between items.
Underscore _
You can use a blank space followed by an underscore to continue a line of Visual Basic code to the next line for readability. You cannot place an underscore in the middle of a string literal. You do not need an underscore for continued lines in SQL, but you cannot break a literal across lines.
Introduction Microsoft Access 2010 is just one part of Microsoft’s overall data management product strategy. Like all good relational databases, it allows you to link related information easily— for example, customer and order data that you enter. But Access 2010 also complements other database products because it has several powerful connectivity features. As its name implies, Access can work directly with data from other sources, including many popular PC database programs (such as dBASE), with many SQL (Structured Query Language) databases on the desktop, on servers, on minicomputers, or on mainframes, and with data stored on Internet or intranet web servers. Access also fully supports Microsoft’s ActiveX technology, so an Access application can be either a client or a server for all the other 2010 Microsoft Office system applications, including Word, Excel, PowerPoint, Outlook, Publisher, and OneNote. Access provides a very sophisticated application development system for the Microsoft Windows operating system. This helps you build applications quickly, whatever the data source. In fact, you can build simple applications by defining forms and reports based on your data and linking them with a few macros or Microsoft Visual Basic statements; there’s no need to write complex code in the classic programming sense. Because Access uses Visual Basic, you can use the same set of skills with other applications in the Microsoft Office system or with Visual Basic. For small businesses (and for consultants creating applications for small businesses), the Access desktop development features are all that’s required to store and manage the data used to run the business. Access coupled with Microsoft SQL Server—on the desktop or on a server—is an ideal way for many medium-size companies to build new applications for Windows quickly and inexpensively. To enhance workgroup productivity, you can use Access 2010 to create an Access Services web application running on a server with SharePoint 2010. Users of your application can view, edit, and delete data from your application directly in their web browser. For large corporations with a big investment in mainframe relational database applications as well as a proliferation of desktop applications that rely on personal computer databases, Access provides the tools to easily link mainframe and personal computer data in a single Windows-based application. Access 2010 includes features to allow you to export or import data in XML format (the lingua franca of data stored on the web).
xxxv
xxxvi Introduction
Getting Familiar with Access 2010 If you have never used a database program—including Access—you’ll find Access 2010 very approachable. Using the results of extensive productivity lab tests, Microsoft has revamped the user interface in all the Microsoft Office programs. The Backstage view and ribbon technology makes it much easier for novice users to get acquainted with Access and easily discover its most useful features. To get a new user jump-started, Microsoft has provided over a dozen local client and web database templates that load onto your hard disk when you install Access. In addition, you’ll find many additional database templates available for easy download from the Microsoft Office website directly from within Access. Microsoft plans to continue to add templates after Access 2010 is released to further enhance your productivity. But if you have used any version of Access prior to 2007, you’re in for a big surprise. Menus and toolbars are gone—all replaced by the Backstage view and ribbon. The Database window has been replaced by the Navigation pane. When you first start using Access 2010, you’ll probably notice a decrease in productivity, but it won’t take you long to get comfortable with the new interface. You’ll probably soon discover features that you didn’t know were there. Nearly all the old familiar objects are around—tables, queries, forms, reports, macros, and modules, and you’ll find that the standard design and data views you’ve come to know and love are still around. You’ll also quickly learn that the Layout and Report views and macro Logic Designer rapidly increase your productivity.
About This Book If you’re developing a database application with the tools in Access 2010, this book gives you a thorough understanding of “programming without pain.” It provides a solid foundation for designing databases, forms, and reports and getting them all to work together. You’ll learn that you can quickly create complex applications by linking design elements with macros or Visual Basic. This book will also show you how to take advantage of some of the more advanced features of Access 2010. You’ll learn how to build an Access web database that you can then publish to a server running SharePoint 2010 and Access Services. You’ll also learn about new data macros that allow you to attach business logic to your tables and how to work with the revamped Logic Designer to design macros. If you’re new to developing applications, particularly database applications, this probably should not be the first book you read about Access. We recommend that you first take a look at Microsoft Access 2010 Plain & Simple or Microsoft Access 2010 Step By Step. Microsoft Access 2010 Inside Out is divided into nine major parts:
Introduction xxxvii
●●
●●
●●
Part 1 provides an overview of Access 2010 and provides you with a detailed look at the user interface, including the new Backstage view. ●●
Chapter 1 explains the major features that a database should provide, explores those features in Access, and discusses some of the main reasons why you should consider using database software.
●●
Chapter 2 thoroughly explores the user interface introduced in the Office 2010 release. The chapter also explains content security, working with the Backstage view, ribbon, and the Navigation pane, and setting options that customize how you work with Access 2010.
●●
Chapter 3 describes the architecture of Access 2010, gives you an overview of the major objects in an Access database by taking you on a tour through two of the sample databases, and explains the many ways you can use Access to create an application.
Part 2 shows you how to create your desktop or web database and tables. ●●
Chapter 4 teaches you how to design client databases and tables.
●●
Chapter 5 shows you the ins and outs of modifying tables even after you’ve already begun to load data and build other parts of your application.
●●
Chapter 6 focuses on designing tables for use in a web database.
●●
Chapter 7 discusses the new feature of table data macros and how to work with the new Logic Designer to create your macro logic.
●●
Chapter 8 explains how to link to or import data from other sources.
Part 3 focuses on how to build queries to analyze and update data in your tables. ●●
Chapter 9 shows you how to build simple queries and how to work with data in Datasheet view.
●●
Chapter 10 discusses how to design client and web queries to work with data from multiple tables, summarize information, build queries that require you to work in SQL view, and work with the PivotTable and PivotChart views of queries.
●●
Chapter 11 focuses on modifying sets of data with queries—updating data, inserting new data, deleting sets of data, or creating a new table from a selection of data from existing tables.
xxxviii
Introduction
●●
●●
●●
●●
●●
Part 4 discusses how to build and work with forms in client and web applications. ●●
Chapter 12 introduces you to forms—what they look like and how they work.
●●
Chapters 13, 14, and 15 teach you all about form design in client and web applications, from simple forms you build with a wizard to complex, advanced forms that use embedded forms and navigation and web browser controls. You’ll also learn how to use Layout view to design web forms that you can open in a web browser using Access Services.
Part 5 explains how to work with reports in client and web applications. ●●
Chapter 16 leads you on a guided tour of reports and explains their major features.
●●
Chapters 17 and 18 teach you how to design, build, and implement both simple and complex reports in your client or web application.
Part 6 shows you how to make your client and web applications “come alive” using macros. ●●
Chapter 19 discusses the concept of event processing in Access, provides a comprehensive list of events, and explains the sequence in which critical events occur.
●●
Chapter 20 covers macro design for client applications in depth and explains how to use error trapping and embedded macro features.
●●
Chapter 21 focuses on how to create web macros, work with web forms and control events, and perform actions in a web browser.
Part 7 is all about using Access tools and working with the web. ●●
Chapter 22 teaches you how to publish your web database to an Access Services site and use your application in a browser. It discusses making changes to a web application, synchronizing your changes with the server, working in offline mode, and instantiating a web template.
●●
Chapter 23 covers features in Access that handle XML and how to use Business Connectivity Services.
The Appendix explains how to install the Office 2010 release, including which options you should choose for Access 2010 to be able to open all the samples in this book.
Introduction xxxix
●●
●●
●●
Part 8, on the companion CD, shows you how to use the programming facilities in Microsoft Visual Basic to integrate your database objects and automate your application. ●●
Chapter 24 is a comprehensive reference to the Visual Basic language and object models implemented in Access. It presents two complex coding examples with a line-by-line discussion of the code. The final section shows you how to work with the new 64-bit Access Visual Basic.
●●
Chapter 25 thoroughly discusses some of the most common tasks that you might want to automate with Visual Basic. Each section describes a problem, shows you specific form or report design techniques you must use to solve the problem, walks you through the code from one or more of the sample databases that implements the solution, and discusses calling named data macros.
Part 9, on the companion CD, covers tasks you might want to perform after completing your application. ●●
Chapter 26 teaches you how to automate custom ribbons, create a custom Backstage view, and how to set Startup properties.
●●
Chapter 27 teaches you tasks for setting up your application so that you can distribute it to others. It also shows you how to create your own custom Data Type Parts, Application Parts, and application templates.
The CD provides an additional six Articles that contain important reference information: ●●
Article 1 explains a simple technique that you can use to design a good relational database application with little effort. Even if you’re already familiar with Access or creating database applications in general, getting the table design right is so important that this article is a “must read” for everyone.
●●
Article 2 is a complete reference to SQL as implemented in desktop databases. It also contains notes about differences between SQL supported natively by Access and SQL implemented in SQL Server.
●●
Article 3 discusses how to export data and Access objects to various types of other data formats from your Access application.
●●
Article 4 lists the functions most commonly used in an Access application categorized by function type. You’ll also find a list of functions that you can use with web databases.
●●
Article 5 lists the color names and codes you can use in Access.
●●
Article 6 lists the macro actions for both client and web applications you can use in Access.
Extending the Power of Access to the Web. . . . . . . . . . . . 17
Access as an Application Development System. . . . . . . . . 13
I
f you’re a serious user of a personal computer, you’ve probably been using word processing or spreadsheet applications to help you solve problems. You might have started a long time ago with character-based products running under MS-DOS but subsequently upgraded to software that runs under the Microsoft Windows operating system. You might also own some database software, either as part of an integrated package such as Microsoft Works or as a separate program. Database programs have been available for personal computers for a long time. Unfortunately, many of these programs have been either simple data storage managers that aren’t suitable for building applications, or complex application development systems that are difficult to learn and use. Even many computer-literate people have avoided the more complex database systems unless they have been handed a complete, custom-built database application. The introduction of Microsoft Access nearly two decades ago represented a significant turnaround in ease of use. Many people are drawn to it to create both simple databases and sophisticated database applications. Now that Access is in its ninth release and has become an even more robust product in the seventh edition, designed for 32-bit versions of Windows and the first edition designed for 64-bit versions of Windows, perhaps it’s time to take another look at how you work with your personal computer to get the job done. If you’ve previously shied away from database software because you felt you needed programming skills or because it would take you too much time to become a proficient user, you’ll be pleasantly surprised at how easy it is to work with all the new features rolled into Microsoft Access 2010. Access 2010 comes loaded with many existing database templates to solve business and personal needs. These templates are fully functioning applications that can be used as is, without having to make any modifications. For users who do want to modify the templates or even start from scratch, this latest version of Access comes with new application and data type parts, improved form and report What You See Is What You Get (WYSIWYG) authoring tools, data macros to control your business logic, new database level themes, and expanded
3
4
Chapter 1 What Is Access?
Chapter 1
conditional formatting options. You also can now publish your application to a Microsoft SharePoint Server 2010 site using Access Services and view your forms and reports in a web browser. But how do you decide whether you’re ready to move up to a database system such as Access? To help you decide, let’s take a look at the advantages of using database application development software.
What Is a Database? In the simplest sense, a database is a collection of records and files that are organized for a particular purpose. On your computer system, you might keep the names and addresses of all your friends or customers. Perhaps you collect all the letters you write and organize them by recipient. You might have another set of files in which you keep all your financial data—accounts payable and accounts receivable, or your checkbook entries and balances. The word processor documents that you organize by topic are, in the broadest sense, one type of database. The spreadsheet files that you organize according to their uses are another type of database. Shortcuts to all your programs on your Windows Start menu are a kind of database. Internet shortcuts organized in your Favorites folder are a database. If you’re very organized, you can probably manage several hundred spreadsheets or shortcuts by using folders and subfolders. When you do this, you’re the database manager. But what do you do when the problems you’re trying to solve get too big? How can you collect information about all customers and their orders easily when the data might be stored in several document and spreadsheet files? How can you maintain links between the files when you enter new information? How do you ensure that data is being entered correctly? What if you need to share your information with many people but don’t want two people to try updating the same data at the same time? How do you keep duplicate copies of data from proliferating when people can’t share the same data at the same time? Faced with these challenges, you need a database management system (DBMS).
Relational Databases Nearly all modern database management systems store and handle information using the relational database management model. In a relational database management system, sometimes called an RDBMS, the system manages all data in tables. Tables store information about a single subject (such as customers or products) and have columns (or fields) that contain the different kinds of information about the subject (for example, customers’ addresses or phone numbers) and rows (or records) that describe all the attributes of a single instance of the subject (for example, data on a specific customer or product). Even
What Is a Database?
5
The term relational stems from the fact that each table in the database contains information related to a single subject and only that subject. If you study the relational database management model, you’ll find the term relation applied to a set of rows (a table) about a single subject. Also, you can manipulate data about two classes of information (such as customers and orders) as a single entity based on related data values. For example, it would be redundant to store customer name and address information with every order that the customer places. In an RDMS, the information about orders contains a field that stores data, such as a customer number, which can be used to connect each order with the appropriate customer information. You can also join information on related values from multiple tables or queries. For example, you can join company information with contact information to find out the contacts for a particular company. You can join employee information with department information to find out the department in which an employee works.
Some Relational Database Terminology ●●
Relation Information about a single subject such as customers, orders, employees, products, or companies. A relation is usually stored as a table in a relational database management system.
●●
Attribute A specific piece of information about a subject, such as the address for a customer or the dollar amount of an order. An attribute is normally stored as a data column, or field, in a table.
●●
Instance A particular member of a relation—an individual customer or product. An instance is usually stored in a table as a record, or row.
●●
Relationship The way information in one relation is related to information in another relation. For example, customers have a one-to-many relationship with orders because one customer can place many orders, but any order belongs to only one customer. Companies might have a many-to-many relationship with contacts because there might be multiple contacts for a company, and a contact might be associated with more than one company.
●●
Join The process of linking tables or queries on tables via their related data values. For example, customers might be joined to orders by matching customer ID in a customers’ table and an orders table.
Chapter 1
when you query the database (fetch information from one or more tables), the result is always something that looks like another table.
6
Chapter 1 What Is Access?
Database Capabilities Chapter 1
An RDBMS gives you complete control over how you define your data, work with it, and share it with others. The system also provides sophisticated features that make it easy to catalog and manage large amounts of data in many tables. An RDBMS has three main types of capabilities: data definition, data manipulation, and data control. ●●
Data definition You can define what data is stored in your database, the type of data (for example, numbers or characters), and how the data is related. In some cases, you can also define how the data should be formatted and how it should be validated.
●●
Data manipulation You can work with the data in many ways. You can select which data fields you want, filter the data, and sort it. You can join data with related information and summarize (total) the data. You can select a set of information and ask the RDBMS to update it, delete it, copy it to another table, or create a new table containing the data.
●●
Data control You can take advantage of features that help ensure that the right type of data goes into the correct places. In many cases, you can also define how data can be shared and updated by multiple users using the database.
All this functionality is contained in the powerful features of Access. Let’s take a look at how Access implements these capabilities and compare them to what you can do with spreadsheet or word processing programs.
Access as an RDBMS An Access desktop database (.accdb or .mdb) is a fully functional RDBMS. It provides all the data definition, data manipulation, and data control features you need to manage large volumes of data. You can use an Access desktop database (.accdb or .mdb) either as a stand-alone RDBMS on a single workstation or in a shared client/server mode across a network. A desktop database can also act as the data source for data displayed on web pages on your company intranet. When you build an application with an Access desktop database, Access is the RDBMS. You can also use Access to build applications in a project file (.adp) connected to Microsoft SQL Server, and you can share the server data with other applications or with users on the web. When you create an Access project file (.adp), SQL Server (or the Microsoft SQL Server Desktop Engine—MSDE) is the RDBMS.
Access as an RDBMS
7
Access 2000, Access 2002 (XP), and Access 2003 databases use the .mdb file format, but beginning with Access 2007, Microsoft introduced a new file format with an .accdb extension. To maintain maximum backward compatibility, Access 2010 can still open, run, and save .mdb databases created in the Access 2000 or Access 2002–2003 .mdb format, but to take advantage of all the new features in Access 2010, you need to use the .accdb file format. If you have to create an Access application that will be run by users with previous versions of Access, you should use the Access 2000 or Access 2002–2003 .mdb file format. You’ll need to take extra precautions, however, to only use features in Access 2010 that are supported in earlier versions of Access.
Data Definition and Storage As you work with a document or a spreadsheet, you generally have complete freedom to define the contents of the document or each cell in the spreadsheet. Within a given page in a document, you might include paragraphs of text, a table, a chart, or multiple columns of data displayed with multiple fonts. Within a given column on a spreadsheet, you might have text data at the top to define a column header for printing or display, and you might have various numeric formats within the same column, depending on the function of the row. You need this flexibility because your word processing document must be able to convey your message within the context of a printed page, and your spreadsheet must store the data you’re analyzing as well as provide for calculation and presentation of the results. This flexibility is great for solving relatively small, well-defined business problems. But a document becomes unwieldy when it extends beyond a few dozen pages, and a spreadsheet becomes difficult to manage as the amount of data grows. If you design a document or spreadsheet to be used by others, it’s difficult (if not impossible) to control how they will use the data or enter new data. For example, on a spreadsheet, even though one cell might need a date and another a currency value to make sense, a user might easily enter character data in error. Some spreadsheet programs allow you to define a “database” area within a spreadsheet to help you manage the information you need to produce the desired result. However, you are still constrained by the basic storage limitations of the spreadsheet program, and you still don’t have much control over what’s entered in the rows and columns of the database area. Also, if you need to handle more than number and character data, you might find that your spreadsheet program doesn’t understand such data types as pictures or sounds.
Chapter 1
Note
8
Chapter 1 What Is Access?
Chapter 1
An RDBMS allows you to define the kind of data you have and how the data should be stored. You can also usually define rules that the RDBMS can use to ensure the integrity of your data. In its simplest form, a validation rule might ensure that the user can’t accidentally store alphabetic characters in a field that should contain a number. Other rules might define valid values or ranges of values for your data. In the most sophisticated systems, you can define the relationship between collections of data (usually tables or files) and ask the RDBMS to ensure that your data remains consistent. For example, you can have the system automatically check to ensure that every order entered is for a valid customer. With an Access desktop database (.accdb or .mdb), you have complete flexibility to define your data (as text, numbers, dates, times, currency, Internet hyperlinks, pictures, sounds, documents, and spreadsheets), to define how Access stores your data (string length, number precision, and date/time precision), and to define what the data looks like when you display or print it. You can define simple or complex validation rules to ensure that only accurate values exist in your database. You can request that Access check for valid relationships between files or tables in your database. When you connect an Access project (.adp) to an SQL Server database, SQL Server provides all these capabilities. Access 2010 includes an Attachment data type that can store images and other file types within the record. The Attachment data type can handle multiple attachment files per record via the use of a concept called Complex Data. In previous versions of Access using the .mdb file format, storing images and files through OLE Object data types caused significant bloat of the database file, but in version 2010, Access compresses these files to minimize the size overhead. Examples of files that could be attached to a record using the Attachment data type could be a cover letter created in Microsoft Word for each business contact, a bitmap picture of the contact person, or various sales worksheets created in Microsoft Excel. Figure 1-1 shows an example of a form using the Attachment data type to display a contact picture in the Contacts Map.accdb sample web database. (You can find the Contacts Map.accdb database loaded with sample data on the companion CD.)
Access as an RDBMS
9
Chapter 1
Figure 1-1 The Attachment data type displays a picture in a form.
Access can also understand and use a wide variety of other data formats, including many other database file structures. You can export data to and import data from word processing files or spreadsheets. You can access dBASE III, dBASE IV, Microsoft FoxPro, and other database files directly. You can also import data from these files into an Access table. In addition, Access can work with most popular databases that support the Open Database Connectivity (ODBC) standard, including SQL Server, Oracle, and DB2. Access 2010 has added enhanced functionality to work with SharePoint Server 2010.
Data Manipulation Working with data in an RDBMS is very different from working with data in a word processing or spreadsheet program. In a word processing document, you can include tabular data and perform a limited set of functions on the data in the document. You can also search for text strings in the original document and, with ActiveX controls, include tables,
10
Chapter 1 What Is Access?
Chapter 1
charts, or pictures from other applications. In a spreadsheet, some cells contain functions that determine the result you want, and in other cells, you enter the data that provides the source information for the functions. The data in a given spreadsheet serves one particular purpose, and it’s cumbersome to use the same data to solve a different problem. You can link to data in another spreadsheet to solve a new problem, or you can use limited search capabilities to copy a selected subset of the data in one spreadsheet to use in problem solving in another spreadsheet. An RDBMS provides you with many ways to work with your data. You can, for example, search a single table for information or request a complex search across several related tables. You can update a single field or many records with a single command. You can write programs that use RDBMS commands to fetch data you want to display and allow the user to update. Access uses the powerful SQL database language to process data in your tables. (SQL is an acronym for Structured Query Language.) Using SQL, you can define the set of information that you need to solve a particular problem, including data from perhaps many tables. But Access simplifies data manipulation tasks. You don’t even have to understand SQL to get Access to work for you. Access uses the relationship definitions you provide to automatically link the tables you need. You can concentrate on how to solve information problems without having to worry about building a complex navigation system that links all the data structures in your database. Access also has an extremely simple yet powerful graphical query definition facility that you can use to specify the data you need to solve a problem. Using pointing and clicking, dragging, and a few keystrokes, you can build a complex query in a matter of seconds. Figure 1-2 shows a complex query used in the Conrad Systems Contacts application. You can find this query in the Contacts.accdb sample database on the companion CD included with this book. Access displays field lists from selected tables in the upper part of the window; the lines between field lists indicate the automatic links that Access will use to solve the query.
Access as an RDBMS
11
Chapter 1
Figure 1-2 This query will retrieve information about products owned by contacts in the Conrad Systems Contacts sample application.
To create the query, you add the tables containing the data you need to the top of the query design grid, select the fields you want from each table, and drag them to the design grid in the lower part of the window. Choose a few options, type in any criteria, and you’re ready to have Access select the information you want. You don’t need to be an expert to correctly construct the SQL syntax you need to solve your problem, but you can learn a lot about SQL in the article “Understanding SQL,” found on the companion CD. For certain advanced types of queries, you’ll need to learn the basics of SQL. Figure 1-3 shows the result of asking the query to return its data.
12
Chapter 1 What Is Access?
Chapter 1 Figure 1-3 The query returns a list of contacts and the products they own.
Data Control Spreadsheets and word processing documents are great for solving single-user problems, but they are difficult to use when more than one person needs to share the data. Although spreadsheets are useful for providing templates for simple data entry, they don’t do the job well if you need to perform complex data validation. For example, a spreadsheet works well as a template for an invoice for a small business with a single proprietor. But if the business expands and several salespeople are entering orders, the company needs a database. Likewise, a spreadsheet can assist employees with expense reports in a large business, but the data eventually must be captured and placed in a database for corporate accounting. When you need to share your information with others, true RDMSs give you the flexibility to allow multiple users to read or update your data. An RDBMS that is designed to allow data sharing also provides features to ensure that no two people can change the same data at the same time. The best systems also allow you to group changes (a series of changes is sometimes called a transaction) so that either all the changes or none of the changes appear in your data. For example, while confirming a new order for a customer, you probably want to know that both the inventory for ordered products is updated and the order confirmation is saved or, if you encounter an error, that none of the changes are saved. You probably also want to be sure that no one else can view any part of the order until you have entered all of it.
Access as an Application Development System
13
Because you can share your Access data with other users, you might need to set some restrictions on what various users are allowed to see or update. Access 2010 has greatly improved the ability to share data with secured SharePoint lists to ensure data security. With SharePoint-to-Access integration, users can take advantage of improved workflow support, offline SharePoint lists, and a Recycle Bin to undo changes. Access 2010 also has strong data encryption with tougher encryption algorithms. Access automatically provides locking mechanisms to ensure that no two people can update an object at the same time, and Access also understands and honors the locking mechanisms of other database structures (such as FoxPro and SQL databases) that you attach to your database.
Access as an Application Development System Being able to define exactly what data you need, how it should be stored, and how you want to access it solves the data management part of the problem. However, you also need a simple way to automate all the common tasks you want to perform. For example, each time you need to enter a new order, you don’t want to have to run a query to search the Customers table, execute a command to open the Orders table, and then create a new record before you can enter the data for the order. After you’ve entered the data for the new order, you don’t want to have to worry about scanning the table that contains all your products to verify the order’s sizes, colors, and prices. Advanced word processing software lets you define templates and macros to automate document creation, but it’s not designed to handle complex transaction processing. In a spreadsheet, you enter formulas that define what automatic calculations you want performed. If you’re an advanced spreadsheet user, you might also create macros or Microsoft Visual Basic procedures to help automate entering and validating data. If you’re working with a lot of data, you’ve probably figured out how to use one spreadsheet as a “database” container and use references to selected portions of this data in your calculations. Although you can build a fairly complex application using spreadsheets, you really don’t have the debugging and application management tools you need to construct a robust data management application easily. Even something as simple as a wedding guest invitation and gift list is much easier to handle in a database. (See the Wedding List sample database on the companion CD included with this book.) Database systems are specifically designed for application development. They give you the data management and control tools that you need and also provide facilities to catalog the various parts of your application and manage their interrelationships. You also get a full programming language and debugging tools with a database system. When you want to build a more complex database application, you need a powerful RDMS and an application development system to help you automate your tasks. Virtually all database systems include application development facilities to allow programmers or users of
Chapter 1
14
Chapter 1 What Is Access?
Chapter 1
the system to define the procedures needed to automate the creation and manipulation of data. Unfortunately, many database application development systems require that you know a programming language, such as C or Xbase, to define procedures. Although these languages are very rich and powerful, you must have experience working with them before you can use them properly. To really take advantage of some database systems, you must learn programming, hire a programmer, or buy a ready-made database application (which might not exactly suit your needs) from a software development company. Fortunately, Access makes it easy to design and construct database applications without requiring that you know a programming language. Although you begin in Access by defining the relational tables and the fields in those tables that will contain your data, you will quickly branch out to defining actions on the data via forms, reports, macros, and Visual Basic. You can use forms and reports to define how you want to display the data and what additional calculations you want to perform—very much like spreadsheets. In this case, the format and calculation instructions (in the forms and reports) are separate from the data (in the tables), so you have complete flexibility to use your data in different ways without affecting the data. You simply define another form or report using the same data. When you want to automate actions in a simple application, Access provides a macro definition facility to make it easy to respond to events (such as clicking a button to open a related report) or to link forms and reports. Access 2010 makes using macros even easier by letting you embed macro definitions in your forms and reports. When you want to build something a little more complex (like the Housing Reservations database included with this book), you can quickly learn how to create simple Visual Basic event procedures for your forms and reports. If you want to create more sophisticated applications, such as contact tracking, order processing, and reminder systems (see the Conrad Systems Contacts sample database), you can employ more advanced techniques using Visual Basic and module objects. Access provides advanced database application development facilities to process not only data in its own database structures but also information stored in many other popular database formats. Perhaps Access’s greatest strength is its ability to handle data from spreadsheets, text files, dBASE files, FoxPro databases, and any SQL database that supports the ODBC standard. This means you can use Access to create a Windows-based application that can process data from a network server running SQL Server or from a mainframe SQL database.
Deciding to Move to Database Software
15
For advanced developers, Access provides the ability to create an Access application in a project file (.adp) that links directly to SQL Server (version 7.0 and later). You store your tables and queries (as views, functions, or stored procedures) directly in SQL Server and create forms for data entry and reports for data output in Access.
Deciding to Move to Database Software When you use a word processing document or a spreadsheet to solve a problem, you define both the data and the calculations or functions you need at the same time. For simple problems with a limited set of data, this is an ideal solution. But when you start collecting lots of data, it becomes difficult to manage in many separate document or spreadsheet files. Adding one more transaction (another contact or a new investment in your portfolio) might push you over the limit of manageability. If you need to change a formula or the way certain data is formatted, you might find that you have to make the same change in many places. When you want to define new calculations on existing data, you might have to copy and modify an existing document or create complex links to the files that contain the data. If you make a copy, how do you keep the data in the two copies synchronized? Before you can use a database program such as Access to solve problems that require a lot of data or that have complex and changing requirements, you must change the way you think about solving problems with word processing or spreadsheet applications. In Access, you store a single copy of the data in the tables you design. Perhaps one of the hardest concepts to grasp is that you store only your basic data in database tables. You can use the query facility to examine and extract the data in many ways. This allows you to keep only one copy of the basic data, yet use it over and over to solve different problems. In a sales database, you might create one form to display vendors and the products they supply. You can create another form to enter orders for these products. You can use a report defined on the same data to graph the sales of products by vendor during specified time periods. You don’t need a separate copy of the data to do this, and you can change either the forms or the report independently, without destroying the structure of your database. You can also add new product or sales information easily without having to worry about the impact on any of your forms or reports. You can do this because the data (tables) and the routines you define to operate on the data (queries, forms, reports, macros, or modules) are completely independent of each other. Any change you make to the data via one form is immediately reflected by Access in any other form or query that uses the same data.
Chapter 1
16
Chapter 1 What Is Access?
Reasons to Switch to a Database Chapter 1
Reason 1: You have too many separate files or too much data in individual files. This makes it difficult to manage the data. Also, the data might exceed the limits of the software or the capacity of the system memory. Reason 2: You have multiple uses for the data—detailing transactions (invoices, for example), and analyzing summaries (such as quarterly sales summaries) and “what if” scenarios. Therefore, you need to be able to look at the data in many different ways, but you find it difficult to create multiple “views” of the data. Reason 3: You need to share data. For example, numerous people are entering and updating data and analyzing it. Only one person at a time can update a word processing document, and although an Excel 2003 and later spreadsheet can be shared among several people, there is no mechanism to prevent two users from updating the same row simultaneously on their local copies of the spreadsheet, requiring the changes to be reconciled later. In contrast, Access locks the row of a table being edited by one person so that no conflicting changes can be made by another user, while still permitting many other users to access or update the remaining rows of the database table. In this way, each person is working from the same data and always sees the latest saved updates made by any other user. Reason 4: You must control the data because different users access the data, because the data is used to run your business, and because the data is related (such as data for customers and orders). This means you must control data values, and you must ensure data consistency.
If you’re wondering how you’ll make the transition from word processing documents and spreadsheets to Access, you’ll be pleased to find features in Access to help you out. You can use the import facilities to copy the data from your existing text or spreadsheet files. You’ll find that Access supports most of the same functions you have used in your spreadsheets, so defining calculations in a form or a report will seem very familiar. Within the Help facility, you can find “how do I” topics that walk you through key tasks you need to learn to begin working with a database, and “tell me about” and reference topics that enhance your knowledge. In addition, Access provides powerful wizard facilities to give you a jump start on moving your spreadsheet data to an Access database, such as the Import Spreadsheet Wizard and the Table Analyzer Wizard to help you design database tables to store your old spreadsheet data.
Extending the Power of Access to the Web
INSIDE OUT
17
esign Considerations When Converting from a Spreadsheet D to a Database
You can obtain free assistance from us and many other Microsoft Most Valuable Professionals (MVPs) in the Access newsgroups. Some of the most difficult problems arise in databases that have been created by copying spreadsheet data directly into an Access table. The typical advice in this situation is to design the database tables first, then import and split up the spreadsheet data. You can access the newsgroups using Windows Mail, or you can go to http://support. microsoft.com/communities/newsgroups/default.aspx, and in the Community Newsgroups column on the left, expand the Office category and then the Access category to see the available newsgroups. Click one of the links to go to that newsgroup within your web browser, where you can post questions and read answers to questions posted by others.
Extending the Power of Access to the Web The World Wide Web, built from simple low-cost servers and universal clients, has revolutionized computing. Not so long ago, the very concept of a common global information network was unthinkable. Today, the concept of living without the web is just as unthinkable. Database applications were among the last to appear on the web, but today, they are arguably the fastest growing type of web application. The prospect of distributing data to or collecting it from literally a world of clients, working on disparate computers and operating systems, and not requiring software distribution other than the ubiquitous browser, is simply too compelling to resist for long. As Microsoft looked at the long-term direction of Access, it was clear that the Access development team needed a way to make it easier for Access developers to move their applications to the web—a cloud. In the new global economy we are in, Access developers need an easier way to share their databases and still maintain a single point of maintenance. In fact, if you look at the types of questions Access developers post into newsgroups and support forums, one of the most common questions in the last few years has been: “How do I move my database to the web so that users who do not have Access can use my application?”
Chapter 1
18
Chapter 1 What Is Access?
Chapter 1
Access 2007 laid the foundation of using SharePoint lists as a data platform for Access databases; however, there were still many limitations of using SharePoint lists to store your data. Access developers wanted better data integrity—relationships, validation rules, and the ability to enforce required uniqueness for fields. Developers also wanted better performance when running against large data sets in SharePoint and the ability to design forms and reports that run in a web browser. Access 2010 includes an exciting new feature set to make it easy to provide access to your data and objects over your company’s local intranet or on the web using SharePoint Server 2010, Enterprise Edition. You can publish your database to a server running SharePoint Server 2010 and Access Services to make a fully functional web application. Access Services is a set of features and services running on top of the SharePoint Server platform. After you publish your database to a server running SharePoint Server and Access Services, your forms and reports can be viewed in a web browser. You can edit and view data from your web browser, in addition to editing your data from within Access 2010. Creating an Access Services web application with your data and objects stored in a SharePoint site allows you to tap into the security, backup, and collaboration capabilities built into the SharePoint Server platform. In Figure 1-4, you can see an example of an Access Services web application, created entirely within Access 2010, published to a server running SharePoint Server, and running in a web browser. The data for the application lives in SharePoint lists, macros which control the logic of the application are converted to SharePoint workflows, and Access forms and reports are converted to objects that can be viewed in a web browser.
Extending the Power of Access to the Web
19
Chapter 1
Figure 1-4 Access Services, running on a server running SharePoint Server, allows you to publish your web database and view it in a web browser.
Take a long look at the kind of work you’re doing today. The sidebar, “Reasons to Switch to a Database,” on page 16, summarizes some of the key reasons why you might need to move to Access. Is the number of files starting to overwhelm you? Do you find yourself creating copies of old files when you need to answer new questions? Do others need to share the data and update it using only a web browser? Do you find yourself exceeding the limits of your current software or the memory on your system? If the answer to any of these is yes, you should be solving your problems with an RDMS like Access. In Chapter 2, “Exploring the Access 2010 Interface,” you’ll learn about all the new user interface changes in Access 2010. You’ll also open some of the built-in Access web template databases and explore the new Microsoft Office Backstage view for Access 2010. Finally, you’ll learn about using the Navigation pane to interact with all your various database objects.
c hapte r n C 2o
Chapter Title Exploring the Access 2010 Interface
Opening Access for the First Time. . . . . . . . . . . . . . . . . . . . 21
efore you explore the many features of Microsoft Access 2010, it’s worth spending a little time looking it over and “kicking the tires.” Like a new model of a favorite car, this latest version of Access has changes to the body (user interface) as well as new functionality under the hood. In this chapter and the next, we’ll explore the changes to the user interface, show you how to navigate through Microsoft’s new replacement for the File menu called the Microsoft Office Backstage view, and discuss the various components of an Access database and how they interact.
Opening Access for the First Time The first time you open Access 2010, you are presented with the Privacy Options dialog box shown in Figure 2-1. This dialog box lists three radio buttons, which are not selected by default. Note that you must have an active connection to the Internet to use the first two options. The Use Recommended Settings radio button, when selected, turns on several features of your Microsoft Office 2010 installation. Your computer will periodically check Microsoft’s website for any product and security updates to your Office, Windows, or other Microsoft software. If any updates are detected, your computer will install these updates automatically for you. Selecting this radio button also allows Access to search Office.com’s vast resources for content relevant to your search. Access downloads this information to your local computer for faster searching when you search for items in the Help section. Selecting this option means you will have the latest Help information at your disposal. When you choose Use Recommend Settings, Office downloads a special diagnostic tool that interfaces with the Office 2010 system. You can use this tool to help identify problems with your Office installation. Although not required to run the Office 2010 release or Access 2010, this tool might assist you with locating the cause of any unforeseen system crashes. Selecting Use Recommend Settings also allows you to sign up for Microsoft’s Customer Experience Improvement Program. This utility tracks various statistics while you use Access 2010 and the Office 2010 release and sends that information to Microsoft. By tracking how
21
22
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
customers are using their products, Microsoft can improve its Office line of products for future releases. Note that this option does not send any personal information to Microsoft. Click the Read Our Privacy Statement link in the lower-left corner to read Microsoft’s privacy statement.
Figure 2-1 You can choose Privacy Options when you first start Access 2010.
The second radio button in the Privacy Options dialog box, Install Updates Only, performs a subset of the features for Use Recommend Settings. When you select this option, your computer will check Microsoft’s website only periodically for any product and security updates to your Office, Windows, or other Microsoft software and install them. The last radio button, Don’t Make Changes, makes no changes to your Office 2010 installation. Selecting this option could leave your computer at risk, however, because your computer will not download and install product or security updates. After you make your selection in the Privacy dialog box, click OK to start using Access 2010.
Note The dialog box shown in Figure 2-1 is what we saw when opening Access for the first time using Windows 7. You might see a slightly different sequence of prompts if you install Office on Windows Vista.
Getting Started with Access 2010
23
After selecting your options in the Privacy Options dialog box, you can always alter these settings later. For more information on changing these settings, see “Modifying Global Settings via the Access Options Dialog Box,” on page 112.
!
CAUTION
If you are in a corporate network environment, you should check with your Information Technology (IT) department to determine whether your company has established guidelines before making selections in the Privacy Options dialog box.
Getting Started with Access 2010 If you are a seasoned developer with the 2007 version of Access, the user interface of Access 2010 should be familiar to what you’ve been working with. If however, you have been working only in Access versions before 2007, be prepared for quite a shock when you first open Access 2010. Microsoft revamped the entire look and feel of the user interface in Access 2007 and made additional changes in Access 2010 and the other products in the Office 2010 release. To some degree, users of versions before Access 2007 will have a challenging task adjusting to all the changes the development team has incorporated into Access 2007 and Access 2010. If you are one of these users, you might even experience a short-term decrease in productivity as you become accustomed to where commands and tools are located on the new user interface elements called the Backstage view and the ribbon. (See “Exploring the Microsoft Office Backstage View,” on page 27, for details about the Backstage view, and “Understanding the Office Fluent Ribbon,” on page 57, for details about the ribbon.) For first-time users of Access, Microsoft continues to spend a great deal of development effort trying to make the “Access experience” easier and more intuitive in this version. With a new Getting Started screen, a host of ready-to-use client and web database applications available, and a context-driven, rich graphical ribbon and Backstage view, users will have an easier and quicker time creating professional-looking database applications.
Chapter 2
24
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
On first starting Access, you see a new Getting Started screen on the New tab of the Backstage view, as shown in Figure 2-2. We will discuss all the elements of this New tab and the Backstage view in great detail in “Exploring the Microsoft Office Backstage View,” on page 27.
Figure 2-2 When you first open Access 2010, you can see the new Backstage view.
Getting Started with Access 2010
25
To showcase the user interface, let’s take one of the template databases out for a test drive. Using the TasksSample.accdb database on the companion CD, based on the Microsoft Tasks template, we will highlight some specific areas of Access 2010. First, follow the instructions at the beginning of this book for installing the sample files on your hard drive. Click the Open button on the left side of the Backstage view to see the Open dialog box shown in Figure 2-3.
Figure 2-3 You can use the Open dialog box to find and open any existing database file.
In the Open dialog box, select the TasksSample.accdb file from the folder in which you installed the sample databases, and then click OK. You can also double-click the file name to open the database. (If you haven’t set options in Windows Explorer to show file name extensions for registered applications, you won’t see the .accdb extension for your database files.) The Tasks sample application will start, and you’ll see the startup form for the Tasks Sample database along with all the various database objects listed on the left side, as shown in Figure 2-4.
Chapter 2
Opening an Existing Database
26
Chapter 2 Exploring the Access 2010 Interface
Backstage View Quick Access Toolbar
Ribbon
Chapter 2 Navigation Pane
Task List Form
Figure 2-4 When you open the Tasks Sample database, you can see the user interface for Access 2010.
Note If you installed the sample files for this book in the default location from the companion CD, you can find the files in the Microsoft Press\Access 2010 Inside Out folder on your C drive.
Getting Started with Access 2010
27
We will discuss each of the Access 2010 user interface elements in greater detail in the following sections, but for now, here is a brief overview of the different elements. The upperleft corner of the screen contains a tab called File. This tab, called the Backstage view, replaces the Microsoft Office Button from Access 2007. Above this tab are a few smaller buttons on what is called the Quick Access Toolbar. This toolbar holds frequently used commands within Access 2010. Beneath the Quick Access Toolbar is a series of four tabs (Home, Create, External Data, and Database Tools) that contain many commands, options, and drop-down list boxes. These tabs are on what Microsoft refers to as the Office Fluent Ribbon and it replaces menu bars and toolbars from versions of Access before 2007. You will interact heavily with the ribbon when developing and using Access 2010 databases because most of the commands you need are contained on it. Beneath the ribbon is a small message that says “Security Warning.” This Message Bar informs you if Access has disabled potentially harmful content in this database. See “Understanding Content Security,” on page 47, to learn what this message means and what you can do to avoid it. On the left side of the screen is the Navigation pane, which replaces the Database window from versions of Access before 2007. In the Navigation pane, you can find all the various database objects for this database (tables, queries, forms, and so on). To the right of the Navigation pane is where your database objects open. In Figure 2-4, you see that the Task List form is open. All possible views of your database objects appear in this area. Just beneath the Navigation pane and main object window is the status bar. The status bar displays text descriptions from field controls, various keyboard settings (Caps Lock, Num Lock, and Scroll Lock), and object view buttons.
Exploring the Microsoft Office Backstage View The new Microsoft Office Backstage View in Access 2010 replaces the Microsoft Office Button from Access 2007, and you can display its collection of commands by clicking the File tab from within any database. Figure 2-5 shows you the available commands on the Info tab of the Backstage view.
Chapter 2
28
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-5 You can view many commands by clicking the File tab to open the Backstage view.
The Backstage view contains information and commands that apply to an entire database, as well as commands that were on the Microsoft Office Button in Access 2007. If you used versions of Access before 2007, the Backstage view contains commands that were on the File menu. At the upper-left section of the Backstage View, you’ll see five commands that show at all times—Save, Save Object As, Save Database As, Open, and Close Database. Using these commands, you can do any of the following: ●●
Save Save design changes for the database object that is open and has the focus in the Navigation pane.
●●
Save Object As Save a copy of the current open object that has the focus or the object that has the focus in the Navigation pane.
●●
Save Database As Save a copy of the current database. Note that if you click this command, Access closes the database that you have open so that it can create the copy.
Getting Started with Access 2010
●●
Open Open any existing database file on your computer or network.
●●
Close Database Close the currently open database and return to the New tab in the Backstage view.
29
Listed below the first five commands on the Backstage view, Access, by default, displays the file names of the last four databases you recently opened. To open any of these databases quickly, click the file name in the list. The six main tabs of the Backstage view—Info, Recent, New, Print, Save & Publish, and Help—are beneath the list of recently opened databases. Commands and information displayed on these tabs can change depending upon the current state of your database or if you are using a client versus a web database.
Info Tab Let’s first explore the Info tab previously shown in Figure 2-5. The Info tab displays the name of your database and the full path to its location. Beneath the file path, you’ll see an Enable Content button and security information about your database. You’ll learn more about these settings in “Understanding Content Security,” on page 47. The button below it, Compact & Repair Database, compacts and repairs your database file. The last button on the Info tab, Encrypt With Password, creates an encrypted version of your database with a password. On the far right of the Info tab, you’ll see a thumbnail preview of your database in its current state. Beneath the preview picture, is the View And Edit Database Properties link. Click this link to open the Database Properties dialog box to review and change properties specific to this database.
Recent Tab The Recent tab, shown in Figure 2-6, displays a list of the databases you previously opened. If the number of databases you open exceeds the space to display them, Access provides a scroll bar for you to scroll up and down to see the complete list. At the bottom of the Recent tab, you’ll see a check box called Quickly Access This Number of Recent Databases, which is selected by default. Clear this check box if you do not want to show a list of recent databases you have opened above the Info tab on the Backstage view. You can also customize the number of databases you want to display above the Info tab by changing the default value of four databases in the text box at the bottom of the screen.
Chapter 2
30
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-6 The Recent tab of the Backstage view displays a list of recent database files you opened.
To the right of each database file name, you’ll see a pushpin button. Click this button to pin that specific database file to the displayed list of recent databases. Right-click any of the recent databases displayed, and Access provides a shortcut menu with four options, as shown in Figure 2-7. Select Open from the list, and Access opens the highlighted database. When you select the Pin To List option, Access pins that specific database file to the displayed list of recent databases. When you select the third option, Remove From List, Access removes that database file from the list of recent databases. Note that when you remove the database file from the list, you’re not deleting the database from your computer; you are only removing it from this list on the Backstage view. When you select the last option
Getting Started with Access 2010
31
on the list, Clear Unpinned Items, Access prompts you for confirmation that you want to remove all unpinned items from the list. Click Yes in the confirmation dialog box, and Access removes all database files from the list of recent database files that you have not pinned. You can use this option to quickly clear database files that you might have deleted and no longer wish to use from your list of recent databases.
Figure 2-7 Right-click a database file to see additional options you can use to manage your list of recent databases.
New Tab The New tab, shown in Figure 2-8, is the first tab shown in the Backstage view when you open Access. The Office.com Templates area in the center of the screen displays different template categories grouped by subject. Click one of these categories to change the display in the center of the screen to a list of templates that you can download from the Office. com website. Note that you must be connected to the Internet to see and download any templates in each of these categories. These templates were created by the Access development team and developers in the Access community. The templates represent some of the more common uses for a database and are therefore presented to you first. Microsoft is continually adding and modifying the selections available in the Office.com categories, so the list you see might be different from that shown in Figure 2-8. Be sure to check these groups from time to time to see if a new template exists for your specific needs. You can also search for a template on the Office.com website by typing your search criteria in the Search Office.com for Templates text box.
Chapter 2
32
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-8 You can create a database from a template, create a new blank or web database, or search for a database file to open on the New tab of the Backstage view in Access 2010.
Just above Office.com Templates in the middle of the screen are five buttons under Available Templates. The first button on the left is labeled Blank Database. You use this button to start the process of creating a new empty client database with no objects. See Chapter 4, “Designing Client Tables,” for details on how to create a new blank client database. The next button to the right, Blank Web Database, starts the process of creating a new empty web database with no objects. See Chapter 6, “Designing Web Tables,” for details on how to create a new blank web database. When you click Recent Templates, Access displays a list of database templates that you recently created from this New tab. To view the list of database templates available on your local drive that were installed with Access, click Sample Templates. Five of the sample templates listed under Sample Templates are web-compatible templates—Assets, Charitable Contributions, Contacts, Issues, and Projects. The last button under Available Templates, My Templates, lists any database templates that you created and saved locally to your computer. See Chapter 26, “The Finishing Touches,” on the companion CD, for details on how to create your own database template. Just beneath the Available Templates text at the top of the screen you’ll see three navigation buttons. The Back, Forward, and Home buttons function like web browser buttons. As you navigate between the various template screens, you can click Back to move you back
Getting Started with Access 2010
33
one screen in the history of screens you’ve opened. Click Forward to move you forward one screen in the history of screens you’ve opened. Click Home to take you back to the main page of the New tab on the Backstage view. The task pane on the right of the New tab displays a graphic of the database template you select from the list of templates. For new blank databases you create, Access leaves this graphic empty. You can type the name of a new database file in the File Name text box beneath this graphic and browse to a location to save the database using the Browse button.
Print Tab The Print tab, shown in Figure 2-9, displays three commands—Quick Print, Print, and Print Preview. Click Quick Print to send the selected database object to the printer immediately. Be careful here, because the object that has the focus might not be the one currently on the screen. If the focus is on an object in the Navigation pane, that object is printed instead of the object currently open. When you click Print, Access opens the Print dialog box to print whatever object currently has the focus. Here again, be careful about which object has the focus. Click Print Preview to preview the printed appearance of what you are about to print on your monitor.
Figure 2-9 The Print tab of the Backstage view displays commands to print objects in your database.
Chapter 2
34
Chapter 2 Exploring the Access 2010 Interface
Save & Publish Tab Chapter 2
The Save & Publish tab, shown in Figure 2-10, displays commands to save your database and objects in other formats and to publish your application to Access Services. In the center of the Save & Publish tab, you’ll see two categories—File Types and Publish—and three commands—Save Database As, Save Object As, and Publish To Access Services. If you click one of these commands, additional commands appear in a submenu to the right. Click Save Database As and you’ll see two categories for this option—Database File Types and Advanced. Under Database File Types, you can choose to save a copy of your entire database in 2007/2010 (.accdb), 2002/2003 (.mdb), or 2000 (.mdb) Access format. Note that if you choose to save the entire database, Access closes the database you have open so that it can create the copy. You can use the last option under Database File Types, Template (.accdt), to save your database as an Access database template. To start these commands, you can either double-click the command you want or highlight the command and then click the Save As button at the bottom of the screen. Under the Advanced category, the first option, Package And Sign, packages your database as a Cabinet file (CAB) and digitally signs it. Double-click the Make ACCDE command to make an execute-only version (.mde or .accde) of your database. When you double-click the Back-up Database command, Access creates a complete backup of your database file with the current date in the file name. You can choose the last command under the Advanced category, SharePoint, to publish your database to a document manager server.
Getting Started with Access 2010
35
Chapter 2
Figure 2-10 The Save & Publish tab contains commands to save your objects and database in different formats and to publish your application to Access Services.
Click Save Object As under File Types on the Save & Publish tab, and Access displays a different set of commands on the right, as seen in Figure 2-11. When you double-click Save Object As on the right side, the default is to save a copy of the current open object that has the focus or the object that has the focus in the Navigation pane. Double-click PDF Or XPS to publish a copy of the current open object as a Portable Document Format (PDF) or XML Paper Specification (XPS) file. The last command for Save Object As, Save As Client Object, saves a copy of the current open web object to a client object format. See Chapter 6 for details on how to create a web database and work with web objects.
36
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-11 You can use the Save Object As command to save a copy of your database objects into different formats.
Click Publish To Access Services under the Publish category on the Save & Publish tab, and Access displays commands and information on the right concerning the new Access Services feature in Access 2010, as seen in Figure 2-12.
Figure 2-12 You can publish your database to Access Services from the Save & Publish tab of the Backstage view.
Getting Started with Access 2010
37
Under Access Services Overview, you’ll see information and bullet points on when using Access Services might benefit you. You’ll also find a link you can click to watch a prepared video demo of Access Services on the Office.com website. Click Run Compatibility Checker to scan your database and identify any issues or settings that are not supported for Access Services. (See Chapter 6 for details on how to create a web database and working with the Web Compatibility Checker.) If any issues are found during the web compatibility scan, Access enables the Web Compatibility Issues button. Click that button to open a table that lists all the issues found. If you are currently using a web database, the Publish To Access Services button is enabled. Clicking this button starts the process of publishing your web database to a Microsoft SharePoint site to become an Access Services application. To the right of the Publish To Access Services button, you’ll see two text boxes—Server URL and Site Name. Enter the full Uniform Resource Locator (URL) to the SharePoint server that you want to publish to in the Server URL text box and the name of the site you want to create in the Site Name text box. You’ll learn more about all the Access Services features later in this book, beginning in Chapter 6.
Help Tab The Help tab of the Backstage view, shown in Figure 2-13, displays commands and links to helpful information concerning Access 2010 and the Office 2010 software. Under the Support category in the center of the screen, you’ll see three commands—Microsoft Office Help, Getting Started, and Contact Us. Click Microsoft Office Help to open the Access Help system where you can search Access topics for assistance building your database. Click Getting Started to open a link on Office.com where you can see a list of new features and resources pertaining to Access 2010. Click Contact Us to go to a website where you can find links to support options, go to online support communities, or submit suggestions to improve the product or report a problem.
Chapter 2
38
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-13 The Help tab on the Backstage view displays links to resources, help, and support for Access 2010.
Under the Tools For Working With Office category in the center of the screen, you’ll see two commands—Options and Check For Updates. Click Options to open the Access Options dialog box, where you can choose different settings and preferences for your Access installation. Click Check For Updates to go to a website where you can run a program that verifies that you have the latest updates for your Office system. On the right side of the Help tab, you’ll see information about your Access 2010 and Office 2010 installed programs. Click the Change Product Key link to open the Microsoft Office setup dialog box to change your product key for your installation. Click the Additional Version and Copyright Information link to open the Access About dialog box to view the copyright information of your Access and Office installations. Click the last link on this tab, Microsoft Software License Terms, to view and print the licensing terms for your Office installation.
Getting Started with Access 2010
39
●●
Options Opens the Access Options dialog box, where you can choose and define many different settings and preferences for Access. See “Modifying Global Settings via the Access Options Dialog Box,” on page 112, for a discussion of these options.
●●
Exit Closes the currently open database file as well as completely exits Access.
Inside Out
Closing the Backstage view
You can close the Backstage view quickly by pressing the Esc key. When you do this, Access returns focus to where you were before opening the Backstage view.
Taking Advantage of the Quick Access Toolbar Above the Backstage view is the Quick Access Toolbar. This special toolbar gives you “quick access” to some of the more common commands you will use in Access 2010, and you can customize this toolbar to include additional commands. Here are the default commands available on the Quick Access Toolbar: ●●
Save Saves any changes to the currently selected database object
●●
Undo Undoes the last change you made to an object or a record
●●
Redo Cancels the last Undo change you made to an object or a record
At the right end of the Quick Access Toolbar is a small arrow. Click that arrow, and you’ll see the Customize Quick Access Toolbar menu, as shown in Figure 2-14.
Chapter 2
Beneath the Help tab, you can also find these two commands at the bottom of the Backstage view:
40
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Save Undo Redo Customize Quick Access Toolbar
Figure 2-14 The default Quick Access Toolbar contains the Save, Undo, and Redo commands for the current object, and the command to customize the toolbar.
The upper section of the menu displays common commands that you might want to add to the Quick Access Toolbar. Note that the three default commands—Save, Undo, and Redo— have check marks next to them. You can click any of these to clear the check mark and remove the command from the Quick Access Toolbar. You can click any of the other nine commands (New, Open, E-Mail, Quick Print, Print Preview, Spelling, Mode, Refresh All, and Sync All) to add them to the right end of the Quick Access Toolbar. Near the bottom of this menu is More Commands, which allows you to fully customize what commands are available and how those commands appear on the Quick Access Toolbar. The Show Below The Ribbon option on the menu allows you to move the Quick Access Toolbar above or below the ribbon, depending on your preference. To customize the Quick Access Toolbar, click the arrow on the right end and click More Commands near the bottom of the list. The Access Options dialog box appears, with the Quick Access Toolbar category selected, as shown in Figure 2-15.
Getting Started with Access 2010
41
Chapter 2
Figure 2-15 You can add or remove commands on the Quick Access Toolbar and change their sequence using the Customize category in the Access Options dialog box.
On the left, you can see a list of built-in Access commands that you can select to add to the Quick Access Toolbar. By default, the list shows commands from the Popular Commands category—commands that are used very frequently. You can change the list of commands by selecting a different category from the Choose Commands From list. The All Commands option displays the entire list of Access commands available in alphabetical order. Just below the list of available commands is a check box that you can select to show the Quick Access Toolbar below the ribbon. Clear the check box to show the Quick Access Toolbar above the ribbon. The list on the right side of the screen by default displays what options are available on every Quick Access Toolbar for all your database files. If you add, remove, or modify the commands shown in the list on the right when you have chosen For All Documents (Default) in the Customize Quick Access Toolbar list, the changes are reflected in every database you open with Access 2010. To customize the Quick Access Toolbar for only the specific database you currently have open, click the arrow in the drop-down list and select the database file path for your current database from the list, as shown in Figure 2-16.
42
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Figure 2-16 You can add or remove commands on the Quick Access Toolbar for the current database by selecting your database from the Customize Quick Access Toolbar list.
When you select the current database, the command list below it is now empty, awaiting the changes you request. Find a command in the list on the left, and then either doubleclick it or click the Add button in the middle of the screen to add this command to your custom Quick Access Toolbar, as shown in Figure 2-17. If you make a mistake and select the wrong command, select the command in the list on the right and click Remove to eliminate it from your custom list.
Figure 2-17 Add a command to the Quick Access Toolbar by selecting it in the list on the left and then clicking Add.
In addition to the built-in commands, you can select any macros you have defined in this current database. To do this, select Macros in the Choose Commands From list on the left.
Getting Started with Access 2010
43
A list of all your saved macro objects appears, and you can add these macros directly to your custom Quick Access Toolbar, as shown in Figure 2-18. We added one macro called mcrSample to this Tasks Sample database to illustrate the next steps.
!
CAUTION Do not add a macro to your Quick Access Toolbar when you have selected the option to customize the Quick Access Toolbar for all documents. Access displays an error if you try to click your custom macro command in a database that does not contain the macro you selected.
Figure 2-18 Add a saved macro object to the Quick Access Toolbar by selecting it in the list on the left and then clicking Add.
You can also assign custom button images to the macro objects you select. To do so, select one of your macros in the list on the right, and then click the Modify button to open the Modify Button dialog box shown in Figure 2-19. From here, you can choose one of the predefined button images available and also change the display name for this option on your custom Quick Access Toolbar.
Chapter 2
44
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-19 You can change the button face and the display name in the Modify Button dialog box.
After you have all the commands and macros that you want on your custom Quick Access Toolbar, you might decide that you do not like the order in which they appear. Access 2010 allows you to modify this order easily using the Move Up and Move Down arrow buttons at the far right of the dialog box. (You can rest your mouse pointer on either button to see the button name.) Select a command you want to move in the list on the right and click the up arrow to move it up in the list, as shown in Figure 2-20. Each successive click moves that command up one more place in the custom list. Likewise, the down arrow shifts the selected command down in the list. In Figure 2-20, you can see that we have moved the macro titled Greeting above the Options command.
Getting Started with Access 2010
45
Chapter 2
Figure 2-20 You can change the order of the commands on your Quick Access Toolbar by clicking the Move Up and Move Down arrow buttons.
From top to bottom in the list on the right, the commands appear from left to right on the Quick Access Toolbar after the commands assigned to all databases. When you are completely satisfied with your revisions, click OK to save your changes. Observe that your custom Quick Access Toolbar now appears on the screen above or below the ribbon, depending on the choice you have selected. Figure 2-21 shows our completed changes to the Quick Access Toolbar for this specific database.
Note You might have noticed the option in the list on the left. Adding to your custom Quick Access Toolbar places a small space below the command currently selected in the list on the right. You can add as many separators as you want to your custom Quick Access Toolbar to separate groups of commands visually.
46
Chapter 2 Exploring the Access 2010 Interface
Greeting Options
Chapter 2
Figure 2-21 Our two additional commands now appear on the Quick Access Toolbar for this database.
To remove an item from your custom Quick Access Toolbar, reopen the Access Options dialog box with the Quick Access Toolbar category selected again by clicking the arrow on the Quick Access Toolbar and then clicking More Commands. To remove an item, select it in the list on the right and click Remove, and Access removes it from your list of commands. If you inadvertently remove a command that you wanted to keep, you can click the Cancel button in the lower-right corner to discard all changes. You can also find the command in the list on the left and add it back. Keep in mind that you can remove commands for all databases, or for only the current database. If you want to restore the Quick Access Toolbar for all databases to the default set of commands, select For All Documents (Default) in the Customize Quick Access Toolbar list, click the Reset button in the lower-right corner of the screen, and then click Reset Only Quick Access Toolbar from the drop-down list. To remove all custom commands for the current database, select the database path in the Customize Quick Access Toolbar list, click Reset, and then click Reset Only Quick Access Toolbar. Before removing any commands on the Quick Access Toolbar, Access displays the warning message shown in Figure 2-22. If you click Yes to this Reset Customizations message, Access resets the Quick Access Toolbar for this current database back to the defaults.
Figure 2-22 Access asks you to confirm resetting the Quick Access Toolbar back to the default commands.
Understanding Content Security
INSIDE OUT
47
dding a Command to the Quick Access Toolbar with Two A Mouse Clicks
If you notice that you are using a command on the ribbon quite often, Access 2010 provides a very quick and easy way to add this command to the Quick Access Toolbar. To add a command on the ribbon to the Quick Access Toolbar, right-click the command and click Add To Quick Access Toolbar. This adds the command to the Quick Access Toolbar for all databases. Alternatively, you can remove an item from your custom Quick Access Toolbar quickly by right-clicking the command and clicking Remove From Quick Access Toolbar.
If you modify the Quick Access Toolbar for all databases, you can export your customizations to a file that can be imported to another computer running Access 2010. Click the Import/Export button at the lower-right corner of the screen and then click Export All Customizations, as shown in Figure 2-23. You can choose a location to save this customization file for use on other computers. To import the Quick Access Toolbar customizations onto another computer, open Access 2010 on the second computer, reopen the Access Options dialog box with the Quick Access Toolbar category selected, click the Import/Export button at the bottom of the screen, and then click Import Customization File. Your custom Quick Access Toolbar options for all databases created on the first computer now appear in the Access program installed on the second computer.
Figure 2-23 You can export and import your custom Quick Access Toolbar commands to other computers.
Understanding Content Security In response to growing threats from viruses and worms, Microsoft launched a security initiative in early 2002, called Trustworthy Computing, to focus on making all its products safer to use. In an email sent to employees, Bill Gates summed up the seriousness of the initiative:
Chapter 2
48
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
“In the past, we’ve made our software and services more compelling for users by adding new features and functionality, and by making our platform richly extensible. We’ve done a terrific job at that, but all those great features won’t matter unless customers trust our software. So now, when we face a choice between adding features and resolving security issues, we need to choose security. Our products should emphasize security right out of the box, and we must constantly refine and improve that security as threats evolve.” Prior to Access 2003, it was quite possible for a malicious person to send you a database file that contained code that could damage your system. As soon as you opened the database, the harmful code would run—perhaps even without your knowledge. Alternatively, the programmer could embed dangerous code in a query, form, or report, and your computer would be damaged as soon as you opened that object. In version 11 (Access 2003), you were presented with a series of confusing dialog boxes when you opened an unsigned database file if you had left your macro security level set to Medium or High. After wading through the various dialog boxes, you could still be left with a database you were unable to open. Access 2007 improved upon the security model by adding a component to the Access interface called the Trust Center. This security interface is far less confusing and intrusive than the Access 2003 macro security feature. With a security level set to High in Access 2003, you would not be able to open any database files because all Access databases could have some type of macros, Visual Basic for Applications (VBA) code, or calls to unsafe functions embedded in their structure. Access 2010 further improves upon the Access 2007 security model by adding Trusted Documents. Any database with queries is considered unsafe by Access 2010 because those queries could contain expressions calling unsafe functions. In Access 2010, each database file opens without presenting you with a series of dialog boxes as in Access 2003. Depending on where your file is located on the local computer drive or network share, Access silently disables any malicious macros or VBA code without any intrusive dialog box messages.
Note The sample databases included on the companion CD are not digitally signed, because they will become unsigned as soon as you change any of the queries or sample code. We designed all the sample applications to open successfully, but each displays a warning dialog box if the database is not trusted. If you have installed the database in an untrusted location, the application displays instructions in the warning dialog box that you can follow to enable the full application. See “Enabling Content by Defining Trusted Locations,” on page 55, for information about defining trusted locations.
Understanding Content Security
49
When you open an existing database or template, you might see a Security Warning message displayed in the Message Bar, just below the Quick Access Toolbar and ribbon, as shown in Figure 2-24. This message notifies you that Access has disabled certain features of the application because the file is not digitally signed, the file is not a trusted document, or the file is located in a folder that has not been designated as trusted.
Message Bar Figure 2-24 The Message Bar alerts you if Access has disabled certain content.
To ensure that any restricted code and macros function in this database, you must manually tell Access to enable this content by clicking the Enable Content button on the Message Bar. After you click this button, Access closes the database and then reopens the file to enable all content. Access does not display the Message Bar after it reopens the file, and all functions, code, and macros are now allowed to run in this specific database. Access also adds this database to its list of trusted documents. If your database is not currently trusted, Access displays the Security Warning information on the Info tab of the Backstage view, as shown in Figure 2-25. Note that if you have enabled the content of the database you are viewing or if the file is located in a folder that has been designated as trusted, Access does not display the Security Warning information on the Info tab of the Backstage view.
Chapter 2
Enabling a Database That Is Not Trusted
50
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-25 If your database is not trusted, Access displays the Security Warning on the Backstage view.
When you click the Enable Content button under Security Warning, Access displays two options—Enable All Content and Advanced Options, as shown in Figure 2-26. When you click Enable All Content, Access adds this database to its list of trusted database files. Each time you open this database from this point on, Access does not disable the content for that database. Note that if you move this database to a different file location on your computer, Access disables the content again when you open the database.
Figure 2-26 Click Enable Content to enable all the content of your database or open advanced security options.
Click Advanced Options under Enable Content, and Access opens a dialog box, called Microsoft Office Security Options, as shown in Figure 2-27. This dialog box warns you that this file’s content cannot be verified because a digital certificate was not found.
Understanding Content Security
51
Chapter 2
Figure 2-27 You can enable blocked content from the Microsoft Office Security Options dialog box.
You can choose to have Access 2010 continue to block any harmful content by leaving the default option set to Help Protect Me From Unknown Content (Recommended). By having Access block any harmful content, you can be assured that no malicious code or macros can execute from this database. However, you also have to realize that because Access blocks all Microsoft Visual Basic code and any macros containing a potentially harmful command, it is quite possible that this application will not run correctly if you continue to let Access disable potentially harmful functions and code. To have Access discontinue blocking potentially harmful content, you must select the option Enable Content For This Session. After you select that option and click OK, Access closes the database and then reopens the file to enable all content. Access does not display the Message Bar after it reopens the file, and all functions, code, and macros are now allowed to run in this specific database.
Note When you enable content after opening an untrusted database, the database becomes trusted only for the current session. If you close the database and then attempt to reopen it, Access displays the warnings again on the Message Bar.
52
Chapter 2 Exploring the Access 2010 Interface
Understanding the Trust Center Chapter 2
You might have noticed a link to the Trust Center in the lower-left corner of the Microsoft Office Security Options dialog box. You can also open the Trust Center from the Info tab of the Backstage view by clicking the Trust Center Settings link beneath Security Warning, as discussed earlier. We will discuss the Access Options dialog box later in this chapter; see “Modifying Global Settings via the Access Options Dialog Box,” on page 112. Click Open The Trust Center in the Microsoft Office Security Options dialog box to view the advanced security settings. If the Security Warning on the Info tab of the Backstage view is not currently available, click the File tab and then click Options on the Backstage view. In the Access Options dialog box, click the Trust Center category on the left and then click Trust Center Settings. In the Trust Center dialog box, shown in Figure 2-28, you see nine categories of security settings.
Figure 2-28 The Trust Center dialog box displays various categories, from which you can select trust and privacy options.
Briefly, the categories are as follows: ●●
Trusted Publishers Use to view and remove publishers that you have designated as being trustworthy. When applications are digitally signed by one of these trusted publishers, Access does not disable any content within the database and the Message Bar does not display any warning. By default, digitally signed applications from Microsoft are trusted. You might see one or more additional trusted publishers if you have ever tried to download and run a signed application and have indicated to Windows that you trust the publisher and want to save the publisher’s certificate. See
Understanding Content Security
53
●●
Trusted Locations Use to designate specific folders and subfolders as trusted locations. Access considers any database files within this folder as trustworthy, and all content in these folders is enabled. In the Trusted Locations dialog box, each designated trusted folder is listed with the file path, an optional description, and the date the entry was last modified. See “Enabling Content by Defining Trusted Locations,” on page 55, for details about using the options in this category.
●●
Trusted Documents Use to allow databases on a network share to be trusted, disable the Trusted Documents feature, or clear all trusted databases. By default, Access allows you to trust database files on a network share. Clearing this check box disables your ability to trust individual database files on network shares. If you select the option to disable trusted documents, Access disables all content in databases that you previously designated as trusted. If you click Clear, Access removes all database files from its internal list of trusted documents.
●●
Add-Ins Use to set specific restrictions on Access add-in files by selecting or clearing the three check boxes in this category. An add-in is a separate program or file that extends the capabilities of Access. You can create these separate files or programs by using VBA or another programming language such as C#. You can require that addin files be signed by a trusted publisher before Access will load and run them. If you select the option to require that add-ins be signed, you can disable notifications for add-ins that are unsigned. For added security, you can disable all application add-in functionality.
●●
ActiveX Settings Use to configure how Access handles ActiveX controls in databases. Five options are available with this feature, only one of the first four options can be active at any time. Table 2-1 discusses the purpose of each option.
Table 2-1 ActiveX Settings
Option
Purpose
Disable All Controls Without Notification.
Access disables all harmful ActiveX controls but does not notify you through the Message Bar.
Prompt Me Before Enabling Unsafe For Initialization (UFI) Controls With Additional Restrictions And Safe For Initialization (SFI) Controls With Minimal Restrictions.
If a VBA project is present, Access disables all ActiveX controls and displays the Message Bar. If no VBA project is present, Access enables SFI and disables UFI ActiveX controls. In this case, Access displays the Message Bar. If you enable the content for a UFI ActiveX control, they will be initialized, but with restrictions.
Chapter 2
Chapter 27, “Distributing Your Desktop Application,” on the companion CD, for information about digitally signing your own applications.
54
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Option
Purpose
Prompt Me Before Enabling All Controls With Minimal Restrictions.
This is the default option for new installations of Access. If a VBA project is present, Access disables all ActiveX controls and displays the Message Bar. If no VBA project is present, Access enables SFI and disables UFI ActiveX controls. In this case, Access displays the Message Bar. If you enable the content for a UFI ActiveX control, they will be initialized, but with restrictions.
Access enables any and all potentially harmful ActiveX controls Enable All Controls with minimal restrictions without prompting you. Setting this Without Restrictions And Without Prompt- option could leave your computer at risk. ing (not recommended; potentially dangerous controls can run) Safe Mode (helps limit the control’s access to your computer) ●●
This option, selected by default, enables SFI ActiveX controls in safe mode.
Macro Settings Use to configure how Access handles macros in databases that are not in a trusted location. Four options are available with this feature, only one of which can be active at any given time. Table 2-2 discusses the purpose of each option.
Table 2-2 Macro Settings
Option
Purpose
Disable All Macros Without Notification
Access disables all harmful content but does not notify you through the Message Bar.
Disable All Macros With Access disables all harmful content but notifies you through the Notification Message Bar that it has disabled the content. This is the default option for new installations of Access. This is equivalent to the Medium macro security level option available in Access 2003. Disable All Macros Except Digitally Signed Macros
Access allows only digitally signed macros (code in digitally signed databases). All other potentially harmful content is disabled. This is equivalent to the High macro security level option available in Access 2003.
Enable All Macros (not recommended, potentially dangerous code can run)
Access enables any and all potentially harmful content. In addition, Access does not notify you through the Message Bar. This is equivalent to the Low macro security option available in Access 2003.
●●
DEP Settings Use to enable or disable Data Execution Prevention (DEP) mode for your Access installation. This option, selected by default, helps prevent poorly written code from running on your computer. If, for example, an add-in that was not designed to run in a DEP setup tries to execute on your computer, Access might crash to prevent the add-in from damaging your computer. You can view the Add-ins category of the Trust Center to see if DEP is preventing any add-ins from running on your computer.
Understanding Content Security
55
●●
Message Bar Use to configure Access either to show the Message Bar when content has been disabled or not to display the bar at all.
●●
Privacy Options Use to enable or disable actions within Access regarding computing privacy, troubleshooting system problems, and scanning suspicious website links. The first check box under Privacy Options tells Access to scan Microsoft’s Office.com help site when you are connected to the Internet. If you clear this check box, Access scans only your local hard drive when you conduct a search in Help. Selecting the second check box instructs Access to download and activate a special file from Microsoft’s site that helps you troubleshoot Access and Office program installation and program errors. The third check box allows you to sign up for the Customer Experience Improvement Program. Microsoft uses this program to track statistics of the features you use most frequently and gather information about your Office system configuration. These statistics help determine changes in future program releases. The fourth check box, Automatically Detect Installed Office Applications To Improve Office.com Search Results, helps to narrow your search results on Office.com to programs you currently have installed. The fifth check box under Privacy Options allows Access to scan Office documents automatically for possible links to and from suspicious websites. This option is turned on by default to help safeguard your computer against documents containing harmful web links. The final check box, Allow The Research Pane To Check For And Install New Services, allows Access to automatically check for new updates to research services and install them.
Enabling Content by Defining Trusted Locations You can permanently enable the content in a database that is not trusted by defining a folder on your hard drive or network that is trusted and then placing the database in that folder. Alternatively, you can define the folder where the database is located as trusted. You define trusted locations in the Trust Center dialog box.
!
CAUTION If you are in a corporate network environment, you should check with your IT department to determine whether your company has established guidelines concerning enabling content on Access databases.
To define a trusted location, click the File tab on the Backstage view and then click Access Options. In the Access Options dialog box, click the Trust Center category and then click Trust Center Settings. Access displays the Trust Center dialog box. Click the Trusted Locations category to see its options, as shown in Figure 2-29.
Chapter 2
56
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-29 The Trusted Locations category in the Trust Center dialog box shows you locations that are currently trusted.
Click Add New Location. Access now displays the Microsoft Office Trusted Location dialog box, as shown in Figure 2-30.
Figure 2-30 Creating a new trusted location from the Microsoft Office Trusted Location dialog box.
Click Browse and locate the folder that you want to designate as trusted. You have the option of designating any subfolders in that directory as trusted without having to designate each individual folder within the hierarchy. Enter an optional description you want for this folder, and click OK to save your changes. The new location you just specified now appears in the list of trusted locations. Microsoft recommends you do not designate the root folder for your Windows installation (for example, C:\ on a standard installation) as a trusted location. You should instead designate only the individual folders you want trusted.
Understanding the Office Fluent Ribbon
57
If you later decide to remove this folder as a trusted location, select that location, as shown in Figure 2-29, and then click Remove. Any Access databases in that folder are now treated as unsafe. Figure 2-29 also shows two check boxes at the bottom of the dialog box. The first check box allows you to define network locations as trusted locations. Microsoft recommends you not select this check box because you cannot control what files others might place in a network location. The second check box disables all Trusted Location settings and allows content only from trusted publishers.
Note To ensure that all the sample databases from the companion CD operate correctly, add the folder where you installed the files (the default location is the Microsoft Press\ Access 2010 Inside Out folder on your C drive) to your Trusted Locations.
Understanding the Office Fluent Ribbon The Office Fluent Ribbon, shown in Figure 2-31, is a strip that contains all the functionality of the older menu bar options (File, Edit, View, and so on) and the various toolbars from versions of Access before Access 2007, condensed into one common area in the application window. Microsoft’s usability studies revealed that most users failed to discover many useful features that were previously buried several levels deep in the old menu structure. The ribbon is a context-rich environment displaying all the program functions and commands, with large icons for key functions and smaller icons for less-used functions. Access displays a host of different controls on the ribbon to help you build and edit your applications. Lists, command buttons, galleries, and Dialog Box Launchers are all on the ribbon and offer a rich user interface for Access 2010 and the other Office 2010 system products.
Figure 2-31 The ribbon interface replaces menu bars and toolbars from versions before Access 2007.
The ribbon in Access 2010 consists of four main tabs—Home, Create, External Data, and Database Tools—that group together common tasks and contain a major subset of the program functions in Access. These main tabs are visible at all times when you are working in Access 2010 because they contain the most common tools you need when working with any database object. Other tabs, called contextual tabs, appear and disappear to the right
Chapter 2
58
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
of the Database Tools tab when you are working with specific database objects and in various views. (In the following chapters, we will discuss in detail the various database objects and the contextual tabs that appear when working with each.)
Inside Out
Scrolling Through the Ribbon Tabs
If you click one of the ribbon tabs, you can then scroll through the other tabs using the scroll wheel on your mouse.
Each tab on the ribbon has commands that are further organized into groups. The name of each group is listed at the bottom, and each group has various commands logically grouped by subject matter. To enhance the user experience and make things easier to find, Microsoft has labeled every command in the various groups. If you rest your mouse pointer on a specific command, Access displays a ScreenTip that contains the name of the command and a short description that explains what you can do with the command. Any time a command includes a small arrow, you can click the arrow to display options available for the command.
Home Tab Let’s first explore the Home tab, shown in Figure 2-32.
Figure 2-32 The Home tab provides common commands for editing, filtering, and sorting data.
The Home tab has the following groups: ●●
Views Most objects in an Access database have two or more ways to view them. When you have one of these objects open and it has the focus, you can use the View command in this group to switch easily to another view.
●●
Clipboard You can use the commands in this group to manage data that you move to and from the Clipboard.
●●
Sort & Filter You can use these commands to sort and filter your data.
Understanding the Office Fluent Ribbon
59
●●
Records Use the commands in this group to work with records, including deleting records and saving changes.
●●
Find The commands in this group allow you to search and replace data, go to a specific record, or select one or all records.
●●
Window Use the commands in this group to resize windows or select one of several windows that you have open. Note that Access displays this group only when you have set your database to display Overlapping Windows rather than Tabbed Documents. For more details, see “Using the Single-Document vs. the Multiple-Document Interface” on page 107.
●●
Text Formatting You can change how Access displays text using the commands in this group. You can also design fields in your database to contain data formatted in Rich Text. (See Chapter 4 for more details about data types.) You can use the commands in this group to format text in a Rich Text field.
INSIDE OUT
dding a Group to the Quick Access Toolbar with Two A Mouse Clicks
If you notice that you are using commands found in a group on the ribbon quite often, Access 2010 provides a very quick and easy way to add the entire group to the Quick Access Toolbar. To add a group on the ribbon to the Quick Access Toolbar, right-click the group and click Add To Quick Access Toolbar. This adds the group, including all commands, to the Quick Access Toolbar for all databases. Alternatively, you can quickly remove a group from your custom Quick Access Toolbar by right-clicking on the group and clicking Remove From Quick Access Toolbar.
Create Tab The Create tab, shown in Figure 2-33, contains commands that let you create new database objects. Each group on this particular tab arranges its specific functions by database object type.
Figure 2-33 The Create tab provides commands for creating all the various types of database objects.
Chapter 2
60
Chapter 2 Exploring the Access 2010 Interface
The Create tab contains the following groups: Chapter 2
●●
Templates Use the commands in this group to create new templates parts such as fields, tables, forms, and other objects. You can learn more about template parts in Chapter 4.
●●
Tables Use the commands in this group to create new tables or link to a SharePoint Services list. You can learn more about SharePoint Services in Chapter 22, “Using Web Applications in a Browser.”
●●
Queries Use the commands in this group to create new queries. You can learn more about creating queries beginning in Chapter 9, “Creating and Working with Simple Queries.”
●●
Forms You can create new forms using the commands in this group, including PivotChart, PivotTable, and web forms. For more details about PivotCharts, see Chapter 15, “Advanced Form Design.” For more details about web forms, see Chapter 12, “Using Forms in an Access Application.”
●●
Reports The commands in this group allow you to create new reports using available wizards, start a new report design from scratch, or build web reports.
●●
Macros & Code Use the commands in this group to build macros or modules to automate your application.
External Data Tab The External Data tab, shown in Figure 2-34, provides commands to import from or link to data in external sources or export data to external sources, including other Access databases or SharePoint lists.
Figure 2-34 The External Data tab provides commands for working with external data sources.
Understanding the Office Fluent Ribbon
61
●●
Import & Link The commands in the Import group let you link to data or import data or objects from other sources such as other Access databases, Microsoft Excel spreadsheets, Windows SharePoint Services lists, and many other data sources such as Microsoft SQL Server and dBase.
●●
Export You can use these commands to export objects to another Access database or to export data to Excel, SharePoint, Microsoft Word, and more.
●●
Collect Data These two commands allow you to update data in your Access 2010 database from special email options using Microsoft Outlook 2010. See Chapter 8, “Importing and Linking Data,” for details about using these features.
●●
Web Linked Lists Commands in this group allow you to synchronize offline data with an active SharePoint site, cache list data, and relink SharePoint lists.
Database Tools Tab The last tab that is always available on the ribbon is the Database Tools tab, shown in Figure 2-35. The upper part of Figure 2-35 shows the Database Tools tab when using an Access 2010 database (.accdb) and the lower part shows the Database Tools tab when using Access 2000, 2002, or 2003 databases (.mdb).
Figure 2-35 The Database Tools tab gives you access to miscellaneous tools and wizards.
Chapter 2
This tab has the following groups:
62
Chapter 2 Exploring the Access 2010 Interface
The Database Tools tab on the ribbon includes the following groups: Chapter 2
●●
Tools This group has one command: Compact And Repair Database. Use this command to compact and repair your database file.
●●
Macro Commands in this group let you open the Visual Basic Editor or to run a macro.
●●
Relationships Commands in this group activate useful information windows. Use the Relationships command to view and edit your table relationships. (See Chapter 4 for details.) Click the Object Dependencies command to see which objects are dependent on the currently selected object.
●●
Analyze Use the commands in this group to print a report about your objects or run one of the two analysis wizards.
●●
Move Data The three wizards available in this group allow you to either move some of or all your tables to SQL Server, move all your tables to a separate Access database and create links to the moved tables in the current database, or move some or all of your tables to a SharePoint site.
●●
Add-Ins You can manage add-ins from this group or start the Add-In Manager to install new add-ins for your Access installation.
●●
Administer Access displays this group on the Database Tools tab only when you open an Access database file created in Access 2000, 2002, or 2003 (.mdb). The Replication Options let you manage the legacy replication features that are no longer supported in Access 2007 format database files. For more information on these features, see Running Microsoft Access 2000 (Microsoft Press, 1999) or Microsoft Office Access 2003 Inside Out (Microsoft Press, 2004). The Switchboard Manager command starts the Switchboard Manager to assist you with building a switchboard form for navigating through your application.
Inside Out
Collapsing the Entire Ribbon
If you need some additional workspace within the Access window, you can collapse the entire ribbon by double-clicking any of the tabs. All the groups disappear from the screen, but the tabs are still available. You can also use the keyboard shortcut Ctrl+F1 to collapse the ribbon or click the Minimize The Ribbon button next to the Help button in the upper-right corner of the application window. To see the ribbon again, simply click any tab to restore the ribbon to its full height, press Ctrl+F1 again, or click the Expand The Ribbon button.
Understanding the Office Fluent Ribbon
63
In Access 2010 and the other Office 2010 products, Microsoft introduces a new feature that allows you to customize the ribbon easily through an interface similar to customizing the Quick Access Toolbar. If you do not like the order of the groups on the four default ribbon tabs, for example, you can easily change the order to your liking. To customize the ribbon, click the File tab and then click the Options button on the Backstage view to open the Access Options dialog box. Now click the Customize Ribbon category on the left to begin customizing the ribbon, as shown in Figure 2-36.
Figure 2-36 You can add new tabs, groups, or commands to the ribbon and change their sequence using the Customize Ribbon category in the Access Options dialog box.
On the left, you can see a list of built-in Access commands that you can select to add to groups on the ribbon. By default, the list shows commands from the Popular Commands category— commands that are used very frequently. You can change the list of commands by selecting a different category from the Choose Commands From list. The All Commands option displays the entire list of Access commands available in alphabetical order.
Chapter 2
Customizing the Ribbon
64
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
INSIDE OUT
pening the Access Options Dialog Box Quickly to O Customize the Ribbon
Right-click any part of the ribbon and then click Customize The Ribbon to open the Access Options dialog box quickly with the Customize Ribbon category selected.
The list on the right side of the screen by default displays a list of the built-in Access ribbon tabs—Print Preview, Home, Create, External Data, Database Tools, Source Control, and AddIns. You can change the list of tabs by selecting a different category from the Customize The Ribbon list. The All Tabs option displays the entire list of Access ribbon tabs, and the Tool Tabs option displays only the list of Access contextual ribbon tabs. Next to the name of each tab in the list below Customize The Ribbon is a plus symbol. Click the plus symbol, and Access expands the list beneath the tab to show you all the groups and commands within that specific tab. Click the minus symbol, and Access collapses the list to show you only the name of the tab itself. Similarly, you’ll see a plus symbol next to each of the group names underneath the tab name. Click the plus symbol here, and Access expands the group to show you all the commands on that specific group. Click the minus symbol to collapse the group. Next to the plus and minus symbols for each tab, you’ll see a check box. Clear this check box to not display that tab on the ribbon. Note that clearing this check box does not delete the tab and all its contents; it merely tells Access not to show this tab on the ribbon. Select the check box, and Access displays that tab in the ribbon. You’ll notice that all the commands listed on the default tab groups are dimmed. You cannot rename or reorder the commands listed on the default tab groups; however, you can rename and reorder the group names on the default tabs, rename and reorder the names of the default tabs, add new custom groups to the default tabs, and add commands to these custom groups on the default tabs. You can also create your own custom tabs and add groups and commands to those tabs to customize the ribbon further. To create a new custom tab, click the New Tab button near the lower-right corner of the screen. Access adds a new tab to the list on the right called New Tab (Custom) and a new group beneath that tab called New Group (Custom), as shown in Figure 2-37. All custom tabs and custom groups have (Custom) after the name. However, Access does not show (Custom) on the ribbon.
Understanding the Office Fluent Ribbon
65
Chapter 2
Figure 2-37 Click New Tab to create a new custom tab on the ribbon.
To change the name of your custom tab, highlight it and then click Rename. Access opens the Rename dialog box, as shown in Figure 2-38. Type in a new name for your custom tab in the Display Name text box and then click OK. Access displays your new tab name in the tab list followed by (Custom). Remember that (Custom) appears only in the Customize Ribbon category of the Access Options dialog box.
Figure 2-38 You can change the display name of a custom tab on the Rename dialog box.
66
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
To change the name of your custom group, highlight it in the list of groups and then click Rename. Access opens the Rename dialog box for group names, as shown in Figure 2-39. On this dialog box, you can type in a new name for your custom group and you can choose an icon to represent the group. If you add this entire group to your Quick Access Toolbar, Access displays your custom icon for this group instead of a default green ball icon.
Figure 2-39 When you rename a group, you can also choose an icon from the Rename dialog box to display for your group.
To add a command to your custom group, find a command in the list on the left, and then either double-click it or click the Add button in the middle of the screen to add this command to your custom ribbon group, as shown in Figure 2-40. If you make a mistake and select the wrong command, select the command in the list on the right and click Remove to eliminate it from your custom group.
Understanding the Office Fluent Ribbon
67
Chapter 2
Figure 2-40 To add a command to your custom group, highlight a command on the left and then click Add.
After you have all the commands and macros you want on your custom group, you might decide that you do not like the order in which they appear. Access 2010 allows you to easily modify this order using the Move Up and Move Down arrow buttons at the far right of the dialog box. (You can rest your mouse pointer on either button to see the button name.) Select a command that you want to move in the list on the right and click the up arrow to move it up in the list. Each successive click moves that command up one more place in the group. Likewise, the down arrow shifts the selected command down in the group. Alternatively, you can right-click a command and then click Move Up or Move Down on the shortcut menu, as shown in Figure 2-41.
Figure 2-41 Right-click a command, and Access displays a shortcut menu that you can use to rename, remove, or move commands up and down the group list.
68
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
To add additional groups to your custom tab or to one of the built-in ribbon tabs, click the New Group button at the bottom of the screen, or right-click a tab and then click Add New Group. You can continue customizing the ribbon by adding more commands to these additional groups, renaming the groups and commands, and changing their display order. By default, Access displays labels next to your custom commands on the ribbon. If you don’t want to display these labels, right-click your custom group and click Hide Command Labels. To see how your custom ribbon looks, click OK at the bottom of the screen to save your work. In Figure 2-42, you can see the custom ribbon tab and group we created. The upper part of Figure 2-42 shows our custom ribbon tab and group with command labels showing, and the bottom part of Figure 2-42 shows our custom ribbon tab and group with command labels hidden.
Figure 2-42 You can choose to display or hide the labels for your commands in a custom group.
If you want to remove a custom group from your custom ribbon tab or from one of the default tabs, highlight the group in the list on the right side and then click the Remove button in the middle of the screen. Alternatively, you can right-click a custom group name and then click Remove from the shortcut menu. If you want to remove an entire custom tab from the ribbon, highlight the tab name in the list on the right side and then click Remove. Alternatively, right-click a custom tab name and then click Remove from the shortcut menu, as seen in Figure 2-43.
Figure 2-43 Right-click a custom tab and click Remove if you want to remove the entire tab from your ribbon.
Understanding the Office Fluent Ribbon
69
If you want to restore one of the built-in ribbon tabs to the default set of groups and commands, highlight the tab name in the list on the right, click the Reset button in the lower-right corner of the screen, and then click Reset Only Selected Ribbon Tab from the drop-down list. To remove all ribbon customizations, click Reset, and then click Reset All Customizations. Before removing all ribbon customizations, Access displays the warning message shown in Figure 2-44. If you click Yes to this Reset Customizations message, Access resets the ribbon, as well as the Quick Access Toolbar, back to the defaults.
Figure 2-44 Access asks you to confirm resetting the ribbon and Quick Access Toolbar back to the default commands.
You can export your ribbon customizations to a file that can be imported to another computer running Access 2010. Click the Import/Export button at the lower-right corner of the screen, and then click Export All Customizations, as shown in Figure 2-45. You can choose a location to save this customization file for use on other computers. To import the ribbon customizations onto another computer, open Access 2010 on the second computer, reopen the Access Options dialog box with the Customize Ribbon category selected, click the Import/Export button at the bottom of the screen, and then click Import Customization File. Your Access ribbon customizations that you created on the first computer now appear in the Access program installed on the second computer.
Figure 2-45 You can export and import your ribbon customizations to other computers.
Note When you choose to export ribbon customizations, Access also exports any Quick Access Toolbar customizations you created for all databases.
Chapter 2
70
Chapter 2 Exploring the Access 2010 Interface
Understanding the Navigation Pane Chapter 2
In versions of Access before Access 2007, you navigated among the various database objects through the Database window. Access grouped all database objects together by type and displayed various properties of each object alongside the object name depending on the view you chose. Beginning with Access 2007, Microsoft replaced the Database window with the Navigation pane, shown in Figure 2-46. Unlike the Object bar in the old Database window that you could position anywhere in the Access workspace, the Navigation pane is a window that is located permanently on the left side of the screen. Any open database objects appear to the right of the Navigation pane instead of covering it up. This means you still have easy access to the other objects in your database without having to shuffle open objects around the screen or continually minimize and restore object windows. In contrast to the Database window, the Navigation pane lets you view objects of different types at the same time. If the list of objects in a particular group is quite extensive, Access provides a scroll bar in each section so that you can access each object. To follow along in the rest of this section, open the Tasks Sample database (TasksSample.accdb) from the companion CD. Unless you have previously opened this database and changed the Navigation pane, you should see the Navigation pane on the left side of the screen, exactly like Figure 2-46.
Understanding the Navigation Pane
71
Chapter 2
Figure 2-46 The Navigation pane replaces the Database window from Access versions before Access 2007.
Inside Out
Jumping Quickly to a Specific Object in the Navigation Pane
Click an object in one of the groups in the Navigation pane to highlight it and then press a letter key to jump quickly to any objects that begin with that letter in that particular group.
Shutter Bar Open/Close Button
You can expand or contract the width of the Navigation pane easily by positioning your pointer over the right edge of the Navigation pane and then clicking and dragging the edge in either direction to the width you want. Keep in mind that the farther you expand the width, the less screen area you have available to work with your database objects because all objects open to the right of the Navigation pane. To maximize the amount of screen area available to work with open objects, you can collapse the Navigation pane completely to the far-left side of the application window by clicking the double-arrow button in the upper-right corner, called the Shutter Bar Open/Close button. When you do this, the Navigation pane appears as a thin bar on the left of your screen, as shown in Figure 2-47.
72
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
After you have “shuttered,” click the button again to reopen the Navigation pane to its previous width. Access 2010 remembers the last width that you set for the Navigation pane. The next time you open an Access database, the width of the Navigation pane will be the same as when you last had the database open. Pressing the F11 key alternately toggles the Navigation pane between its collapsed and expanded views.
Figure 2-47 You can collapse the Navigation pane to give yourself more room to work on open objects.
We will discuss the various database objects and their purposes within an Access database in Chapter 3, “Access 2010 Overview.”
Exploring Navigation Pane Object Views When you first open the TasksSample.accdb sample database, the Navigation pane shows you all the objects defined in the database grouped by object type and sorted by object name. You can verify this view by clicking the menu bar at the top of the Navigation pane, as shown in Figure 2-48, which opens the Navigation Pane menu. Under Navigate To Category, you should see Object Type selected, and under Filter By Group, you should see All
Understanding the Navigation Pane
73
Access Objects selected. This is the view we selected in the database before saving it on the companion CD. By default, all new blank databases created in the Access 2007/2010 format display the object list in the Navigation pane in this view.
Figure 2-48 You can change the display in the Navigation pane by selecting a different category or filter from the Navigation Pane menu.
This view closely matches the Database window in previous versions of Access, where you could select tabs to view each object category, and each object type was sorted by object name. The objects in each of the six object types—Tables, Queries, Forms, Reports, Macros, and Modules—are grouped together. When the list of objects is longer than can be displayed within the height of the Navigation pane, Access provides a scroll bar. You can customize the Navigation pane to display the object list in many different ways. Access 2010 provides a set of predefined categories for the Navigation pane that you can access with a few mouse clicks. You can see these available categories by clicking the top of the Navigation pane to open the menu, as shown in Figure 2-48. Notice that this Tasks Sample database lists six categories under Navigate To Category: Tasks Navigation, Custom, Object Type, Tables And Related Views, Created Date, and Modified Date. The first category in the list, Tasks Navigation, is a custom category specific to this database. We’ll show you how to create and modify custom categories later in this section. Access always provides the other five categories in all databases to allow you to view
Chapter 2
74
Chapter 2 Exploring the Access 2010 Interface
objects in various predefined ways. We will discuss the Custom and Tasks Navigation categories in “Working with Custom Categories and Groups,” on page 78. Chapter 2
Inside Out
Collapsing an Entire Group in the Navigation Pane
If you click the header of each object type where the double arrow is located, Access collapses that part of the Navigation pane. For example, if you want to hide the tables temporarily, you can collapse that section by clicking the double arrow next to the word Tables. To bring the table list back to full view, simply click the double arrow that is now pointing downward, and the tables section expands to reveal all the table objects.
The Navigation pane menu also provides commands under Filter By Group to allow you to filter the database object list. The filter commands available change depending on which Navigate To Category command you select. Notice in Figure 2-48, where Navigate To Category is set to Object Type, that the Filter By Group section in the lower half of the Navigation Pane menu lists each of the object types that currently exist in your database. When you have the menu categorized by object type, you can filter the list of objects further by selecting one of the object types to see only objects of that type. Click one of the object types (Forms, for instance), and Access hides all the other object types, as shown in Figure 2-49. This feature is very useful if you want to view and work with only a particular type of database object. Click the All Access Objects filter command to see all objects by object type again.
Figure 2-49 You can display only the Forms group of objects in the Object Type view by applying a filter in the Navigation Pane menu.
Understanding the Navigation Pane
75
By default, new blank databases created in the Access 2007/2010 format also include a Navigation Pane category called Tables And Related Views. You can switch the Tasks Sample database to this category by opening the Navigation Pane menu that contains categories and filters, and then clicking the Tables And Related Views command, as shown in Figure 2-50.
Figure 2-50 The Tables And Related Views category on the Navigation Pane menu offers a different way to view your database objects.
After you click Tables And Related Views, the Navigation pane should look similar to Figure 2-51. This particular view category groups the various database objects based on their relation to a common denominator—a table. As you can observe in Figure 2-51, each group of objects is the name of one of the tables. Within each group, you can see the table as the first item in the group followed by all objects that are dependent on the data from the table. Therefore, Access lists all database objects dependent on the Tasks data table together in the Tasks group, and similarly, it lists all objects dependent on the Contacts table in the Contacts group. At first glance, you might be a bit confused as to the purpose of each object, but notice that the various types of objects each have their own unique icon to help you differentiate them. The Tasks table, for example, is listed first with the icon for a table before the name and the word Table next to it. The remaining objects in the group are the various objects that are dependent on the Tasks table in alphabetical order by name, and each object has an icon before the name that identifies the type of object. You can find more details about the various object types and related icons in Chapter 3.
Chapter 2
76
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-51 The Tables And Related Views category in the Navigation pane groups objects under a table.
Some objects appear in a category called Unrelated Objects, such as the macro called mcrSample and the module called basSampleSub, in this Tasks Sample database. Macros and modules contain code that you can reference from any object in your database. They always appear in the Unrelated Objects category of Tables And Related Views because Access does not search through the macro arguments and module code to see if any table references exist.
Inside Out
When to Use the Tables And Related Views Category
This particular view category can be quite useful if you are making some changes to a table and want to see what objects might be affected by the change. You can check each query, form, and report that is related to this table one at a time in this view to ensure that no functionality of the database is broken after you make a change to the underlying table.
Understanding the Navigation Pane
77
Now that you have changed to Tables And Related Views, open the Navigation Pane menu again. Notice that the names of both data tables in this database are listed beneath Filter By Group, as shown in Figure 2-50. Click Tasks, and Access reduces the Navigation pane to show only the objects related to the Tasks table, as shown in Figure 2-52. By filtering the Navigation pane to one table, you have reduced the number of objects displayed and can focus your attention on only a small subset of database objects. You can open the Navigation Pane menu again and click All Tables to restore the complete list.
Figure 2-52 You can filter Tables And Related Views to show only the database objects dependent on one table.
Access provides two related types of object view categories on the Navigation Pane menu called Created Date and Modified Date, as shown in Figure 2-53. These categories list all the objects in descending order based on when you created or last modified the object. These views can be quite useful if you need to locate an object that you created or last modified on a specific date or within a range of dates. When you click either of these commands, the Filter By Group options on the Navigation Pane menu offers to filter by Today, Yesterday, one of the five days previous to that (listed by day name), Last Week, Two Weeks Ago, Three Weeks Ago, Last Month, Older, or All Dates.
Chapter 2
78
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-53 The Created Date and Modified Date categories display objects in the order you created or last modified them.
Note You will not see the same options listed in Figure 2-53 when you open your copy of Tasks Sample, because all the Modified dates will be older than three weeks. The only two options you will see are Older and All Dates.
Working with Custom Categories and Groups We have not yet discussed the remaining two object categories available in the Navigation Pane menu of the Tasks Sample database: Custom and Tasks Navigation, as shown in Figure 2-54. Whenever you create a new database, Access creates the Custom category that you can modify to suit your needs. Initially, the Custom category contains only one group, Unassigned Objects, containing all the objects defined in your database. As you’ll learn later, you can change the name of the Custom category, create one or more custom groups, and assign objects to those groups.
Understanding the Navigation Pane
79
When you create a new database using one of the many templates provided by Microsoft, nearly all these databases contain an additional predefined group designed to make it easier to run the sample application. We created the Tasks Sample database using the Tasks template, and the Tasks Navigation category is predefined in that template. As with any custom category, you can create new groups, modify or delete existing groups, assign additional objects to the groups within the custom category, or delete the category and all its groups altogether.
Figure 2-54 Both Custom and Tasks Navigation are custom categories available in the Tasks Sample database.
To see an example of a finished custom category in this database, open the Navigation Pane menu and select Tasks Navigation. The Navigation pane changes to display the object list shown in Figure 2-55. This custom category contains three custom groups called Tasks, Contacts, and Supporting Objects. There is actually a fourth group called Unassigned Objects, which you cannot see. In the following sections, you’ll learn how to hide one or more groups.
Chapter 2
80
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-55 The Tasks Navigation category displays a custom view of the various database objects.
In Figure 2-55, notice that each object icon has a small arrow in the lower-left corner. This arrow indicates that you are looking at a shortcut or pointer to the actual object. These shortcuts act similarly to shortcuts in Windows—if you open the shortcut, you’re opening the underlying object to which the shortcut points. When you view custom categories and groups in the Navigation pane, you are always looking at shortcuts to the objects. If you delete one of these shortcuts, you are deleting only the pointer to the object and not the object itself. We’ll discuss more about working with these object shortcuts in “Hiding and Renaming Object Shortcuts,” on page 93.
Exploring the Navigation Options Dialog Box Now that you have seen how a completed custom view category looks in the Navigation pane, you can create your own new category and groups within that category in this Tasks Sample database for the Tasks forms and reports and the Contacts forms and reports. If any database objects are currently open, close them so that they do not interfere with the following steps. First, let’s create a custom category and then some groups within that category to hold our designated database objects. To begin this process, right-click the menu bar at the top of the Navigation pane and click Navigation Options on the shortcut menu, as shown in Figure 2-56.
Understanding the Navigation Pane
81
Chapter 2
Figure 2-56 Right-click the top of the Navigation pane and click Navigation Options to open the Navigation Options dialog box.
Access opens the Navigation Options dialog box, as shown in Figure 2-57.
Figure 2-57 The Navigation Options dialog box lets you create and edit grouping and display options.
The Categories list under Grouping Options lists all the categories that have been defined in this database. In this list, you can see two built-in categories—Tables And Related Views and Object Type—that you cannot delete. The list also shows the Tasks Navigation category that was defined in the template and the Custom category that Access defines in all new databases. When you select a different category in the list on the left, the list on the right displays the groups for that category. For example, click the Tasks Navigation category on the left and notice that Access changes the list at the right to show the four groups defined in that category—Tasks, Contacts, Supporting Objects, and Unassigned Objects, as shown in Figure 2-58.
82
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-58 Four groups have been defined in the Tasks Navigation category.
Next to each of the four groups for Tasks Navigation is a check box. All but the last check box, next to Unassigned Objects, is selected. When you clear the check box next to any group on the right, Access does not display that group in the Navigation pane. As you might recall, when you looked at the Tasks Navigation category in the Navigation pane, you could see only Tasks, Contacts, and Supporting Objects. Because we cleared the check box next to Unassigned Objects in the Navigation Options dialog box, you are unable to view it in the Navigation pane.
Note The Tables And Related Views category by default includes one group for each table defined in the current database and one additional group called Unrelated Objects. The Object Type category includes one group for each of the six object types—tables, queries, forms, reports, macros, and modules.
In the lower-left corner of this dialog box, the Display Options section contains three check boxes—Show Hidden Objects, Show System Objects, and Show Search Bar. We’ll discuss these options in detail in “Hiding and Renaming Object Shortcuts,” on page 93, and “Searching for Database Objects,” on page 102. The last section in the lower right of the Navigation Options dialog box is called Open Objects With. When you select the SingleClick option, each object listed in the Navigation pane acts like a hyperlink, so you need only one click to open the object. Double-Click, the default option, opens objects in the Navigation pane with a double click.
Understanding the Navigation Pane
83
To create your new navigation category, you could click Add Item. Alternatively, because the unused Custom category already exists, you can use it to create your new category. Start by clicking Custom under Categories and then click Rename Item, as shown in Figure 2-59.
Figure 2-59 Click Rename Item when Custom is selected to rename that category.
After you click Rename Item, Access unlocks the Custom field in the Categories list so you can change the name. Delete the word Custom using the Backspace or Delete key and type Tasks Database Objects for your new name, as shown in Figure 2-60.
Figure 2-60 You can rename the Custom group by typing a new name in the field.
Chapter 2
Creating and Modifying a Custom Category
84
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Under Groups For “Custom,” for the Tasks Database Objects category, you can see Custom Group 1 and Unassigned Objects, as shown in Figure 2-60. The Custom Group 1 group is an empty placeholder that Access defines in the Custom category in all new Access 2010 database files. By default, no objects are placed in this group for new databases. The Unassigned Objects group is also a built-in Access group for the Custom category. Access places all objects that are not assigned to any other groups in the Unassigned Objects group for display in the Navigation pane.
Creating and Modifying Groups in a Custom Category Beneath the Groups list are three buttons: Add Group, Delete Group, and Rename Group. When you click Custom Group 1 in the list, you can see that all these buttons are available. The Add Group button creates another group under whichever group you have currently selected; the Delete Group button deletes the currently selected group; and the Rename Group button allows you to rename the current group. If you click the Unassigned Objects group, the Delete Group and Rename Group buttons appear dimmed. You cannot delete or rename this built-in group from any custom category. For the Tasks Database Objects category, you need to create four groups. You can rename the Custom Group 1 group to a name of your choice, but you also need to create three additional groups. Let’s start by renaming Custom Group 1 to Tasks Forms. Click Custom Group 1 to highlight it and then click Rename Group. Access unlocks the name of this group so you can change it. Delete the words Custom Group 1 and type Tasks Forms for your new name, as shown in Figure 2-61.
Figure 2-61 Click Rename Group when Custom Group 1 is highlighted to rename that group.
You cannot change the name of the Unassigned Objects group, so you’ll need to create additional groups. To create a new group, click Add Group. Access creates another group
Understanding the Navigation Pane
85
called Custom Group 1 below Tasks Forms and unlocks it for you to enter a name, as shown in Figure 2-62. Type Tasks Reports for your new name and press Enter. Chapter 2
Figure 2-62 When you click Add Group, Access creates another Custom Group 1 group.
Follow the preceding steps to create two additional new groups for the Tasks Database Objects category called Contact Forms and Contact Reports. In each case, start by clicking Add Group to have Access create another Custom Group 1. Type over that name and enter Contact Forms and Contact Reports for the two names. Your completed changes should now look like Figure 2-63, with your new custom category, four custom groups, and the Unassigned Objects group.
Figure 2-63 The completed Tasks Database Objects category now contains five groups.
Next to whichever custom group is selected on the right are a Move Up arrow and a Move Down arrow, which you can click to change the display order of the groups in this category.
86
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
When you select this category from the Navigation Pane menu, Access displays the groups in the Navigation pane based on the display order that you set in the Navigation Options dialog box. In Figure 2-63, you can see arrow buttons next to the Tasks Database Objects category and the Contact Reports group within that category. For now, keep the display order of the custom groups and categories as they are. Click OK to save your current changes.
INSIDE OUT
nderstanding Display Order Rules for Categories and U Groups
In the Categories list of the Navigation Options dialog box, you cannot change the display order of the Tables And Related Views and Object Type categories. All custom categories you create must appear below these two built-in categories. The Unassigned Objects group in all custom groups you create can be displayed only at the bottom of the list of groups. You cannot place any custom groups below this builtin group. Similarly, the Unrelated Objects group within the Tables And Related Views category always appears at the bottom of the list.
To see how your changes appear in the Navigation pane, click the top of the Navigation pane to open the menu and select your new Tasks Database Objects category, as shown in Figure 2-64.
Figure 2-64 After you select the new Tasks Database Objects category, the Navigation pane displays the custom groups you defined.
Understanding the Navigation Pane
87
The Navigation pane now displays each of your four custom group names along with the Unassigned Objects category, as shown in Figure 2-65. Note that Access placed all your objects into the Unassigned Objects group and listed no database objects in any of the four custom groups. (In Figure 2-65, we collapsed the ribbon to show you all the objects.)
Figure 2-65 Access initially places all objects into the Unassigned Objects group after you create a custom category.
Creating Object Shortcuts in Custom Groups Now that you have finished creating the category and group structure, it’s time to move the objects into the groups you set up. You can move the forms that display or edit Tasks into the new group called Tasks Forms. To accomplish this task, hold down the Ctrl key and single-click each of the three forms that focus on Tasks: Tasks Details, Task List, and Tasks Subform. This action causes Access to highlight all these objects. If you make a mistake by selecting an incorrect object, continue holding down the Ctrl key and single-click the incorrect object to unselect it. After you have selected all three form objects, right-click one of them and, on the shortcut menu that appears, click Add To Group and then Tasks Forms to move the three selected form objects to that group, as shown in Figure 2-66.
Chapter 2
88
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-66 You can move several objects to your custom group at the same time by selecting them and clicking Add To Group from the shortcut menu.
Access creates a shortcut to each of the three objects in the first group, as shown in Figure 2-67. Each of the icons now has a small arrow next to it to indicate that it is actually a shortcut to the respective database object and not the actual object itself, as we discussed earlier. If you delete a shortcut, you are deleting only the shortcut or pointer to the object, not the object itself.
Understanding the Navigation Pane
89
Chapter 2
Figure 2-67 After you move your objects to the first custom group, Access creates a shortcut to each object.
With the first set of objects assigned to a group, let’s continue moving the other forms and reports. Hold down the Ctrl key and single-click each of the following five reports: Active Tasks, All Tasks, Task Details, Tasks by Assigned To, and Tasks Due Today. After you have selected these reports, right-click and click Add To Group. Click the group called Tasks Reports, and again note how Access creates a shortcut to each of these reports in our custom group, as shown in Figure 2-68.
90
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-68 Group all your tasks reports together under Tasks Reports by selecting them and clicking Add To Group from the shortcut menu.
Inside Out
Dragging and Dropping Objects into Custom Groups
You can also select objects you want to add to a custom group and drag them into the group with your mouse. If you want a shortcut to appear in more than one group, add it to the first group, select it with your mouse, and while holding down the Ctrl key, drag it into the second group. Holding down the Ctrl key tells Access that you want to copy the shortcut, not move it. (Release the mouse button before releasing the Ctrl key to be sure the copy feature works correctly.)
Now repeat this process for the two contact forms called Contact Details and Contact List and move them to the group called Contact Forms. Similarly, move the two contact reports called Contact Address Book and Contact Phone Book to the group called Contact Reports. The Navigation pane should now look like Figure 2-69.
Understanding the Navigation Pane
91
Chapter 2
Figure 2-69 All the form and report objects now have shortcuts in custom groups in the Navigation pane.
Hiding Custom Groups in a Category With the previous steps completed, you should now see only six objects in the Unassigned Objects group—a collection of data tables, queries, one macro, and one module. For now, assume that we do not want to have the users of this database application view these objects. We can hide this entire Unassigned Objects group of objects from the users by going back to the Navigation Options dialog box. Right-click the top of the Navigation pane, and then click Navigation Options to open the Navigation Options dialog box again. In the Categories list, click the Tasks Database Objects category to display our custom groups. Clear the Unassigned Objects check box to tell Access to hide this particular group when showing our custom Tasks Database Objects view in the Navigation pane, as shown in Figure 2-70.
92
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-70 Clear the check box next to Unassigned Objects to hide this group in the Navigation pane.
Click OK in the Navigation Options dialog box, and Access completely removes this group from view in the Navigation pane. We are now left with a concise list of form and report objects separated into logical groups, as shown in Figure 2-71.
Figure 2-71 The completed changes to the Navigation pane now display only form and report object shortcuts in four custom groups.
Understanding the Navigation Pane
Hiding a Group Directly from the Navigation Pane
You can also hide an entire group from view in the Navigation pane by right-clicking that group and clicking Hide on the shortcut menu that appears.
Hiding and Renaming Object Shortcuts We can customize our list of objects further by hiding object shortcuts directly in the Navigation pane. For example, for illustration purposes right now, assume that you want to hide the data entry form called Tasks Subform from the current view. (You’ll learn in Part 3, “Building Queries,” that a subform is a form designed to be embedded in another form. A user normally won’t need to open subforms directly.) There are two methods for accomplishing this task, both of which you can access directly from the Navigation pane. For the first method, right-click the Tasks Subform in the Navigation pane and click Hide In This Group from the shortcut menu, as shown in Figure 2-72.
Figure 2-72 To hide an object in a specific group, right-click it and click Hide In This Group from the shortcut menu.
Chapter 2
Inside Out
93
94
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Access hides this object shortcut from view in the Navigation pane, but it does not in any way delete or alter the existing form itself. Alternatively, you can right-click that object in the Navigation pane and click View Properties from the shortcut menu, shown in Figure 2-72, to open the Properties dialog box for this object, shown in Figure 2-73.
Figure 2-73 You can hide a database object or an object shortcut from view in the Navigation pane by selecting the Hidden check box in the Properties dialog box.
The Properties dialog box displays the name of the object and whether this is a shortcut to an object. In the middle of the dialog box, you can see any description inherited from the original object (which you can’t modify), the date the object was created, date the object was last modified, and the owner of the object. The Attributes section has two check boxes called Hidden and Disable Design View Shortcuts. (We will discuss Disable Design View in Chapter 26.) In the Attributes section, select the Hidden check box and then click OK. In the Navigation pane, you will see the Tasks Subform disappear from view. Remember that you have hidden only the shortcut for this object and have not affected the actual form itself in any way. You now know how to hide objects or object shortcuts from view in the Navigation pane, but what if you want to rename the object shortcuts? Access 2010 allows you to easily rename the shortcuts to database objects without affecting the underlying names of the objects. To illustrate this procedure, let’s rename one of the report object shortcuts. Rightclick the Tasks Details report and click Rename Shortcut from the shortcut menu, as shown in Figure 2-74.
Understanding the Navigation Pane
95
Chapter 2
Figure 2-74 To rename an object shortcut in the Navigation pane, right-click it and click Rename Shortcut.
Access sets the focus on this report in the Navigation pane and unlocks the name of the shortcut. Enter a new name for this object by typing All Task Details Report and then pressing Enter, as shown in Figure 2-75. Access saves the new name of this report shortcut, but it does not change the name of the actual report object to which the shortcut points.
96
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-75 After you click Rename Shortcut, Access unlocks the object shortcut name so that you can change it.
The final custom Navigation pane with all your modifications should now look like Figure 2-76. Behind the scenes, all the database objects are still present and unchanged, but you customized the display view for users of your database. You are now showing only a list of form and report shortcuts, while other objects are hidden from view.
Figure 2-76 The customized Navigation Pane category and groups now display only form and report shortcuts.
Understanding the Navigation Pane
97
If you have followed along to this point, remember that you hid the form Tasks Subform from the current view in the Navigation pane. To unhide this form, right-click the top of the Navigation pane and click Navigation Options to open the Navigation Options dialog box. Select the Show Hidden Objects check box, as shown in Figure 2-77. Click OK to save this change and close the Navigation Options dialog box.
Figure 2-77 Selecting the Show Hidden Objects check box causes Access to display any hidden object shortcuts in the Navigation pane.
When you return to the Navigation pane, Access displays the shortcut to the form Tasks Subform in the Tasks Forms group, as shown in Figure 2-78. If you look closely in Figure 2-78, you can see that Access displays the object dimmed compared to the other object shortcuts. This dimmed state is a visual cue that Access uses to indicate object shortcuts that are hidden. In Figure 2-78, you can also see that Access now shows the hidden group Unassigned Objects and all the objects contained within it. All the objects in the Unassigned Objects group, along with the group name itself, also appear dimmed in the Navigation pane.
Chapter 2
Revealing Hidden Shortcuts
98
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-78 Access displays any hidden shortcuts, objects, or groups in the Navigation pane when you select the Show Hidden Objects check box.
To change the Hidden property of the form Tasks Subform, right-click that object in the Navigation pane and click View Properties to open the Properties dialog box for this object, as shown in Figure 2-79. In the Attributes section, clear the Hidden check box and then click OK. You can see that the Tasks Subform no longer appears dimmed in the Navigation pane.
Figure 2-79 You can unhide a database object or an object shortcut from view in the Navigation pane by clearing the Hidden check box in the Properties dialog box for the object or shortcut.
Understanding the Navigation Pane
99
Now that you have changed the form Tasks Subform to be visible in the Navigation pane, you need to tell Access to hide the Unassigned Objects group again. To do this, right-click the top of the Navigation pane and click Navigation Options. Clear the Show Hidden Objects check box, as shown in Figure 2-80. Click OK to save this change, and Access once again hides the Unassigned Objects group from view in the Navigation pane.
Figure 2-80 Clear the Show Hidden Objects check box to have Access hide any hidden object shortcuts, objects, or groups in the Navigation pane.
On the companion CD, you can find a database file called TasksSampleCustom.accdb, which has all the changes from the steps we completed in the preceding sections. If you would like to compare your Tasks Database Objects category and groups to our completed sample, open this file from the folder where you installed the sample files.
Sorting and Selecting Views in the Navigation Pane By default, Access sorts the objects in the Navigation pane by object type in ascending order. The Navigation pane allows for several other types of object sorting. Right-click the menu at the top of the Navigation pane and move the mouse pointer over Sort By, as shown in Figure 2-81.
Chapter 2
100
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-81 The Sort By submenu in the Navigation Pane menu allows for further Navigation pane sorting.
The Sort By submenu has options to sort the Navigation pane list by the name of the object, the object type, the created date, and the modified date. You can change the sort order from ascending to descending for any of these Sort By options by clicking Sort Ascending or Sort Descending at the top of the Sort By submenu. The last option on the Sort By submenu, Remove Automatic Sorts, lets you lay out your object list in any order you want within the Navigation pane. With this option selected, you can click and drag your objects within their respective groups into any order, and Access will not re-sort them in alphabetical, type, created date, or modified date order after you have repositioned your objects in the list. The View By submenu has three choices available—Details, Icon, and List—as shown in Figure 2-82. The Details view displays in the Navigation pane the name of each object, its type, and the creation and modified dates, as well as a large icon next to each name. The Icon view displays only the name of the object (or the shortcut name) next to a large icon of the object type. The List view similarly displays only the name of the object or shortcut, but the object icon is smaller than in the other two views.
Figure 2-82 The View By submenu lists commands to view the Navigation pane objects by Details, Icon, or List.
Understanding the Navigation Pane
Inside Out
101
Viewing Categories from the Navigation Pane Submenus
You can choose one of the view categories—either a custom category or one of the built-in categories—by right-clicking the Navigation Pane menu and selecting the Category submenu.
In Figure 2-83, you can see what the Navigation pane looks like with the view set to Details. Notice that more information is displayed about each object, but you see fewer objects. To see the remaining objects, you have to use the vertical scroll bar. If you changed your view to Details to test this, go back to the View By submenu and change the view back to List before continuing.
Figure 2-83 The Details view displays more information about each object in the Navigation pane than Icon or List view.
Manually Sorting Objects in the Navigation Pane So far, we have seen how Access can sort the list of objects and object shortcuts in the Navigation pane automatically for you. Access also allows you to sort the object lists manually
Chapter 2
102
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
so that you can further customize the display order. You must first tell Access to stop automatically sorting your objects. Right-click the top of the Navigation pane, click Sort By, and then click Remove Automatic Sorts, as shown in Figure 2-84.
Figure 2-84 Click the Remove Automatic Sorts command to sort your object list manually in the Navigation pane.
Now you can click and drag your objects and object shortcuts around into different positions in the Navigation pane. For example, click and drag the Task Details form shortcut in the Navigation pane until you have your cursor between the Task List and Tasks Subform forms. An I-beam pointer will appear while you drag to help you position the object, as shown in Figure 2-85. After you release the mouse, Access drops the form shortcut into the new position.
Figure 2-85 Click and drag your form shortcut into a new position within the Tasks Forms category.
To have Access automatically sort the object list again, select any of the four available sort options above Remove Automatic Sorts from the Display Options menu.
Searching for Database Objects In databases with a large number of objects, locating a specific object can be difficult, so Access 2010 includes the Search Bar feature to make this task easier. By default, this feature is turned on; however, if the feature is turned off for your Access installation, you must turn it on through the Navigation pane. You can enable this feature in one of two ways. For the first method, right-click the top of the Navigation pane and then click Search Bar, as shown in Figure 2-86.
Understanding the Navigation Pane
103
Chapter 2
Figure 2-86 Click the Search Bar command on the Display Options menu to display the Search Bar.
Alternatively, you can right-click the top of the Navigation pane and then click Navigation Options from the shortcut menu to open the Navigation Options dialog box, shown in Figure 2-87.
Figure 2-87 Select the Show Search Bar check box in the Navigation Options dialog box to display the Search Bar.
Select the Show Search Bar check box and then click OK. Access displays a Search Bar near the top of the Navigation pane, as shown in Figure 2-88.
Figure 2-88 The Search Bar in the Navigation pane helps you find specific database objects.
We think the Search Bar is misnamed. Rather than “search” for objects that match what you type in the search box, Access filters the list in the Navigation pane. As you begin to type letters, Access filters the list of objects to those that contain the sequence of characters you enter anywhere in the name. For example, if you want to find an object whose name
104
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
contains the word Today, type the word today in the Search Bar. As you enter each letter in the Search Bar, Access begins filtering the list of objects for any that contain the characters in your entered search string. With each successive letter you type, Access reduces the list of objects shown in the Navigation pane because there are fewer objects that match your search criteria. Notice that as soon as you have typed the letters to, Access has reduced the list to two objects—Tasks by Assigned To and Tasks Due Today. The names of both objects contain the letters to. After you finish typing the entire word today in the Search Bar, the Navigation pane should look like Figure 2-89. Access collapses any group headers if it does not find any objects (or object shortcuts if you’re using a custom category) that meet your search criterion. In this case, Access located one object, Tasks Due Today, with the word today in its name. To clear your search string if you need to perform another object search, either delete the existing text using the Backspace key or click the Clear Search String button on the right side of the Search Bar. Clearing the search box or clicking the Clear Search String button restores the Navigation pane to show all displayable objects.
Figure 2-89 The Search Bar collapses any groups if it does not find any objects in that group that meet your search criterion.
Inside Out
Moving Focus to the Search Bar with a Keyboard Shortcut
You can quickly move the focus to the Search Bar from anywhere within the application window by pressing Ctrl+Alt+F.
Note that Access searches for objects only in categories and groups that are currently displayed in the Navigation pane. If Access cannot find an object that you know exists in the database, it is possible that the view you have selected in the Navigation pane is interfering. For example, suppose you conduct the same search as described previously, but this time you have only one group showing. Clear the Search Bar of any text by using the Backspace key or clicking the Clear Search String button. Now click the menu bar at the top of the Navigation pane and select Tasks Forms in the Filter By Group section of the Navigation Pane menu, as shown in Figure 2-90. The only group now displayed in the Navigation pane is Tasks Forms, with three object shortcuts.
Understanding the Navigation Pane
105
Chapter 2
Figure 2-90 Select Tasks Forms from the Navigation Pane menu to show only that group in the Navigation pane.
Enter the word today again in the Search Bar, and notice that Access cannot locate any objects that meet your criterion. In Figure 2-91, you can see that Access shows an empty Navigation pane because none of the three form object shortcuts in the Tasks Forms groups has the word today in its name. This does not mean that no objects in the entire database have the word today in their name; it means only that Access could not locate any objects with that search criterion in the current view selected in the Navigation pane.
Figure 2-91 Access might not be able to find any objects that meet your criterion if your chosen display view is too restrictive.
If you know the exact name of the object you want to find and the type of object as well, you can save some additional searching through object types that you might not be interested in. For example, suppose you want to find a form that has the word list in its name. First, open the Navigation Pane menu and click Object Type. Open the menu again and click Forms under Filter By Group to restrict the list of objects to display only forms, as shown in Figure 2-92.
Inside Out
Using the Shortcut Menu to Display Only One Category
You can also right-click the Forms group header and click Show Only Forms so that only forms show in the Navigation pane.
106
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-92 You can limit your search to form objects by selecting the Object Type category and Forms group from the Navigation Pane menu.
Type the word list in the Search Bar, and Access searches through only data entry forms until it finds a match. In Figure 2-93, Access has found two forms that have the word list in their name—Contact List and Task List.
Figure 2-93 After restricting the Navigation pane to show only forms, text you enter in the Search Bar searches only in the Forms group.
Using the Single-Document vs. the Multiple-Document Interface
Inside Out
107
Maximizing Your Search to Include All Objects
If you need to search through all your database objects to find a specific named object, we recommend that you set the Navigation Menu category to one of the built-in categories such as Object Type or Tables And Related Views. Also check to see that all groups are visible in the Navigation pane for that category to ensure that Access does not miss any objects when it conducts the search.
Using the Single-Document vs. the Multiple-Document Interface In versions of Access before Access 2007, all objects opened in their own windows where you could edit, view, or print them. This type of interface, multiple-document interface (MDI for short), was the cornerstone for working with objects in Access. Office Access 2007 introduced a new interface model called single-document interface (SDI). In the SDI model, all objects open in a series of tabs along the top of the object window to the right of the Navigation pane. In the older MDI model, switching between open objects usually meant constantly minimizing, resizing, and maximizing the various objects to work with them. In Figure 2-94, you can see two forms, one table, and one report open using MDI format. To switch among these objects, you must move the objects around or minimize some of them, as shown near the bottom of the screen.
Chapter 2
108
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Close Maximize Minimize
Close Maximize Restore Figure 2-94 All open objects appear in their own separate windows when using the MDI.
In the SDI model, each open object appears on a tab to the right of the Navigation pane. In Figure 2-95, you can see the same four objects open as before, but here each open object has its name listed at the top of a tab next to an icon for that particular type of database object. Switching among open objects is as simple as clicking on a different tab. The end result of this interface is that you can easily see the names of all open objects and find the ones that you need to work with much faster.
Using the Single-Document vs. the Multiple-Document Interface
109
Chapter 2
Figure 2-95 All open objects appear on their own tabs when using the SDI.
Inside Out
Closing Objects with One Click
If you are using the SDI, you can close any window with a middle-click. Click the mouse wheel on the object tab at the top of the application window, even if the tab is not currently selected, and Access closes that object.
For new databases created in the Access 2007/2010 format, Access uses the SDI by default, but for older databases in the MDB/MDE type format, Access 2010 still opens those files in MDI mode. Access easily allows you to change the interface mode for any database through the Access Options dialog box. Click the File tab on the Backstage View, and then click Options.
110
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
The Access Options dialog box opens and displays many options for customizing the look and feel of Access 2010. You can find an explanation of more of the various options on these tabs in “Modifying Global Settings via the Access Options Dialog Box,” on page 112. Click the Current Database category in the left pane to display a list of settings to tailor this current database. In Figure 2-96, note the section called Document Window Options in the Current Database category of the Access Options dialog box.
Figure 2-96 The Document Window Options section in the Current Database category of the Access Options dialog box controls the interface mode.
To work in MDI mode, select Overlapping Windows. For the SDI interface, with each object on its own tab, select Tabbed Documents. Under these two options is a check box called Display Document Tabs. You can select this check box only in conjunction with the Tabbed Documents option. When you select the Display Document Tabs check box, each object has a tab across the top of the object window with the object’s name and an icon for the object type, as shown in Figure 2-95. If you clear Display Document Tabs, you do not see any tabs for open objects, nor do you see any Restore, Minimize, Maximize, or Close buttons for open objects. In Figure 2-97, we have two forms, one table, and one report open, but you can see only the report because no object tabs are visible. Notice that you do not see the Restore, Minimize, Maximize, or Close button along the top of the object window, which means it is
Using the Single-Document vs. the Multiple-Document Interface
111
After you make your selections in the Access Options dialog box, click OK to save your changes. Access applies these interface settings to this current database the next time you open the file. To see the interface change, you need to close and reopen the database.
Figure 2-97 With Tabbed Documents selected and the Display Document Tabs check box cleared, no tabs for open objects appear at the top of the object window.
INSIDE OUT
hy You Might Want to Use the Tabbed Documents Setting W with No Tabs Visible
If you’re creating an application for novice users, you might want to set up the application so that the user can work with only one object at a time. Presenting a single object minimizes the choices for the user. However, you will have to be sure to include a method to allow the user to navigate to other objects, perhaps with command buttons that execute VBA code or macros to open and set the focus to other objects. You must design such an application carefully so the user never gets “trapped” in one object, unable to get to others.
Chapter 2
more difficult to switch among various open objects. It is possible, but awkward, to switch from one object to another by pressing Ctrl+F6.
112
Chapter 2 Exploring the Access 2010 Interface
Chapter 2
Modifying Global Settings via the Access Options Dialog Box In addition to all the various commands and options available on the Backstage view, ribbon, and in the Navigation pane, Access 2010 has one central location for setting and modifying global options for all your Access database files or for only the database currently open. This location is the Access Options dialog box. To open the Access Options dialog box, click the File tab on the Backstage view and then click Options, as shown in Figure 2-98.
Figure 2-98 Click the File tab on the Backstage view and then click Options to open the Access Options dialog box.
The Access Options dialog box contains 11 categories in the left pane to organize the various options and settings. The first category, General, has settings that apply not only to Access 2010, but also any other Office 2010 system programs you might have installed.
Modifying Global Settings via the Access Options Dialog Box 113
From here, you can choose to enable Live Preview, display ScreenTips, select a color scheme for the application window, and enter a user name for use in all your Office 2010 system applications. In the Creating Databases section, you can choose a default file format for new databases that you create in Access 2010. By default, the file format is set to create all new databases in Access 2007 format. The Default Database Folder box displays the folder where Access will save all new database files unless you select a different folder when creating the database. Figure 2-99 shows the General category of the Access Options dialog box.
Figure 2-99 The General category has general settings for your Office system applications.
The Current Database category, shown in Figure 2-100, has many settings that apply only to the database currently open. This category groups the options into these areas: Application Options, Navigation, Ribbon And Toolbar Options, Name AutoCorrect Options, Filter Lookup Options, and Caching Web Service And SharePoint Tables.
Chapter 2
114
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-100 The Current Database category has general settings for the database currently open.
The Document Window Options section in this category was discussed previously in “Using the Single-Document vs. the Multiple-Document Interface,” on page 107. Use WindowsThemed Controls On Forms will be discussed in Chapter 13, “Building a Form,” and Chapter 14, “Customizing a Form.” The remaining options in the Current Database category will be discussed in Chapter 26, “The Finishing Touches.” The Datasheet category, shown in Figure 2-101, has settings that control the appearance of the datasheet views in your database. This category has options grouped in the following sections—Gridlines And Cell Effects and Default Font—which allow you to modify the look of your datasheets with different colors, gridlines, and cell effects. You can also select a default font and size under Default Font. You’ll learn more about applying these settings to datasheets in “Working in Query Datasheet View,” on page 589, and in Chapter 12, “Using Forms in an Access Application,” and Chapter 13, “Building a Form.”
Modifying Global Settings via the Access Options Dialog Box 115
Chapter 2
Figure 2-101 The Datasheet category has general settings to control the look of datasheets.
The Object Designers category, shown in Figure 2-102, includes settings for creating and modifying database objects in all databases. The Object Designers category is divided into four sections: Table Design View, Query Design, Form/Report Design View, and Error Checking In Form And Report Design View. The Table Design View section has settings for Default Field Type, Default Text Field Size, and Default Number Field Size. You’ll learn more about the impact of these settings in Chapter 4. The Query Design section lets you select a default font and size for working in the query design grid. You’ll learn more about the impact of these settings in Chapter 10, “Building Complex Queries.” The Form/Report Design View section has options that allow you to use the existing form and report templates or choose a custom template that you have created. You’ll learn more about these settings in Chapter 13. The Error Checking In Form And Report Design View section has several default options that Access looks for when checking for errors in your database file. You’ll learn more about these settings in Chapter 24, “Understanding Visual Basic Fundamentals,” on the companion CD.
116
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-102 The Object Designers category has settings for working with database objects.
The Proofing category, shown in Figure 2-103, includes options for controlling the spelling and AutoCorrect features. You can click AutoCorrect Options to customize how Access helps you with common typing mistakes. You can also click Custom Dictionaries to select a custom dictionary to use when working with Access 2010 and the other Office 2010 system applications. See Chapter 26 for more information on these options.
Modifying Global Settings via the Access Options Dialog Box 117
Chapter 2
Figure 2-103 The Proofing category has settings for checking spelling and AutoCorrect.
The Language category, shown in Figure 2-104, contains options for controlling the language settings for your Access 2010 and Office 2010 installed programs. Under Choose Editing Languages, you can select a default editing language for Access 2010. If you have installed additional language packs, you can choose to change your default language to a different language. Under Choose Display and Help Languages, you can change what display language and Help language to use when working with Access 2010. Note that you will need to close your current session of Access and reopen to see these changes. If you click the arrow next to View Display Languages Installed for each Microsoft Office Program, a list expands beneath the arrow that lists all of the Office applications that you have installed and their display languages.
118
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-104 The Language category has settings for changing your editing, display, and Help language for Access 2010 and other Office 2010 programs.
The Client Settings category, shown in Figure 2-105, contains a wide variety of settings for Access 2010. This category has options grouped in the following sections: Editing, Display, Printing, General, Advanced, and Default Theme. Each of the settings on this category applies to all client database files that you use in Access 2010. Many of these settings are discussed later in various parts of this book. See Chapter 8 and Chapter 9, “Creating and Working with Simple Queries,” for more information.
Modifying Global Settings via the Access Options Dialog Box 119
Chapter 2
Figure 2-105 The Client Settings category has options for controlling editing, display, and printing.
The Customize Ribbon category, shown in Figure 2-106, was discussed previously in “Customizing the Ribbon,” on page 63. This category is where you customize the ribbon. You can make modification to the built-in ribbon tabs or create your own custom ribbon tabs and groups.
120
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-106 The Customize Ribbon category allows you to customize the ribbon.
The Quick Access Toolbar category, shown in Figure 2-107, was discussed previously in “Taking Advantage of the Quick Access Toolbar,” on page 39. This category is where you customize the Quick Access Toolbar. You can make modifications to the Quick Access Toolbar for this specific database only or to the Quick Access Toolbar for all Access databases.
Modifying Global Settings via the Access Options Dialog Box 121
Chapter 2
Figure 2-107 The Quick Access Toolbar category allows you to customize the Quick Access Toolbar.
The Add-Ins category, shown in Figure 2-108, lists all the various Access add-ins that might be installed on your computer. You can manage COM add-ins and Access add-ins from this area, and each add-in has its various properties listed. COM add-ins extend the ability of Access and other Office system applications with custom commands and specialized features. You can even disable certain add-ins to keep them from loading and functioning.
122
Chapter 2 Exploring the Access 2010 Interface
Chapter 2 Figure 2-108 The Add-Ins category lists any installed Access add-ins and COM add-ins.
The Trust Center category, shown in Figure 2-109, is the last category in the Access Options dialog box. This category is where you access all Trust Center options for handling security. As we discussed earlier in “Understanding Content Security,” on page 47, you can open the Trust Center Settings dialog box, which controls all aspects of macro security. This category also has links to online privacy and security information.
Modifying Global Settings via the Access Options Dialog Box 123
Chapter 2
Figure 2-109 The Trust Center category has links to privacy and security information and the Trust Center Settings button, which allows you to view more options.
In the next chapter, you’ll learn about the internal architecture of an Access 2010 application. You’ll also open the Housing Reservations and Conrad Systems Contacts sample databases to explore some of the many features and functions of Access. Finally, you’ll discover some of the ways that you can use Access as an application solution.
ow that you are more comfortable with the user interface in Microsoft Access 2010, it’s time to dig deeper into exactly what makes up an Access database. This chapter helps you understand the relationships among the main components in Access and shows you how to move around within the database management system.
The Architecture of Access Access calls anything that can have a name an object. Within an Access database, the main objects are tables, queries, forms, reports, macros, and modules. If you have worked with other database systems on desktop computers, you might have seen the term database used to refer to only those files in which you store data. In Access, however, a desktop database (.accdb) also includes all the major objects related to the stored data, including objects you define to automate the use of your data. You can also create an Access application using a project file (.adp) that contains the objects that define your application linked to a Microsoft SQL Server database that stores the tables and queries. Here is a summary of the major objects in an Access database: ●●
Table An object that you define and use to store data. Each table contains information about a particular subject, such as customers or orders. Tables contain fields (or columns) that store different kinds of data, such as a name or an address, and records (or rows) that collect all the information about a particular instance of the subject, such as all the information about a department named Housing Administration. You can define a primary key (one or more fields that have a unique value for each record) and one or more indexes on each table to help retrieve your data more quickly.
125
126
Chapter 3 Access 2010 Overview
Query An object that provides a custom view of data from one or more tables. In Access, you can use the graphical query by example (QBE) facility or you can write SQL statements to create your queries. You can define queries to select, update, insert, or delete data. You can also define queries that create new tables from data in one or more existing tables. When your Access application is a project file connected to an SQL Server database, you can create special types of queries—functions and stored procedures—that can perform complex actions directly on the server.
●●
Form An object designed primarily for data input or display or for control of application execution. You use forms to customize the presentation of data that your application extracts from queries or tables. You can also print forms. You can design a form to run a macro or a Microsoft Visual Basic procedure in response to any of a number of events—for example, to run a procedure when the value of data changes.
●●
Report An object designed for formatting, calculating, printing, and summarizing selected data. You can view a report on your screen before you print it.
●●
Macro An object that is a structured definition of one or more actions that you want Access to perform in response to a defined event. For example, you might design a macro that opens a second form in response to the selection of an item on a main form. You can include simple conditions in macros to specify when one or more actions in the macro should be performed or skipped. You can use macros to open and execute queries, to open tables, or to print or view reports. You can also run other macros or Visual Basic procedures from within a macro.
●●
Module An object containing custom procedures that you code using Visual Basic. Modules provide a more discrete flow of actions and allow you to trap errors. Modules can be stand-alone objects containing functions that can be called from anywhere in your application, or they can be directly associated with a form or a report to respond to events on the associated form or report.
Chapter 3
●●
For a list of events on forms and reports, see Chapter 19, “Understanding Event Processing.”
The Architecture of Access
What Happened to Data Access Pages?
Access 2010 no longer supports designing or executing data access pages (DAPs). Usability studies conducted by Microsoft show that DAPs are not a widely used feature within Access, and Microsoft is focusing more of their efforts on publishing Access databases to Microsoft SharePoint Services as Access Services applications for sharing data in corporate environments. To maintain backward compatibility with previous versions, Access 2010 will continue to display DAPs in the Navigation pane for existing .mdb applications that contain DAPs, but you cannot create new data access pages, modify existing pages, or execute existing pages from within Access 2010.
Figure 3-1 shows a conceptual overview of how objects in Access are related. Tables store the data that you can extract with queries and display in reports or that you can display and update in forms. Notice that forms and reports can use data either directly from tables or from a filtered view of the data created by using queries. Queries can use Visual Basic functions to provide customized calculations on data in your database. Access also has many built-in functions that allow you to summarize and format your data in queries.
Figure 3-1 In an Access application, you can design queries to extract data from or update data in tables; you can build forms or reports on tables or queries, and you can write code in macros or modules to automate your application.
Chapter 3
Inside Out
127
128
Chapter 3 Access 2010 Overview
Chapter 3
Events on forms and reports can trigger either macros or Visual Basic procedures. An event is any change in the state of an Access object. For example, you can write macros or Visual Basic procedures to respond to opening a form, closing a form, entering a new row on a form, or changing data either in the current record or in an individual control (an object on a form or report that contains data). You can even design a macro or a Visual Basic procedure that responds to the user pressing individual keys on the keyboard when entering data. In Access 2010, you can now also trigger macros to run on table events such as before committing data or after entering new data. For more information about using data macros, see Chapter 7, “Creating Table Data Macros.” For more information about using Visual Basic within Access, see Chapter 24, “Understanding Visual Basic Fundamentals,” and Chapter 25, “Automating Your Application with Visual Basic,” on the companion CD.
Using macros and modules, you can change the flow of your application, build new tables, run queries, and open, filter, and change data in forms and reports. Using Visual Basic, you can manipulate data in your database row by row or column by column, handle exceptional conditions, and create, modify, and delete any Access object. Using module code, you can even call Windows application programming interface (API) routines to extend your application beyond the built-in capabilities of Access.
Exploring a Desktop Database—Housing Reservations Now that you know something about the major objects that make up an Access database, a good next step is to spend some time exploring the Housing Reservations database (Housing.accdb) on the companion CD that accompanies this book. First, follow the instructions at the beginning of this book for installing the sample files on your hard drive. When you start Access, it displays the New tab on the Microsoft Office Backstage view, as shown in Figure 3-2.
Exploring a Desktop Database—Housing Reservations
129
Chapter 3
Figure 3-2 Access 2010 displays the New tab on the Backstage view every time you start the program.
Click the Open button on the left side of the window to see the Open dialog box shown in Figure 3-3. In the Open dialog box, select the file Housing.accdb from the folder in which you installed the sample databases, and then click Open. You can also double-click the file name to open the database. (If you haven’t set options in Windows Explorer to show file name extensions for registered applications, you won’t see the .accdb extension for your database files.)
130
Chapter 3 Access 2010 Overview
Chapter 3 Figure 3-3 Use the Open dialog box to locate the database that you want to open.
When you open the Housing Reservations application, it displays a Not Trusted dialog box if you have not followed the instructions in Chapter 1, “What Is Access?” to define the location of the sample files as trusted. If this happens, click the Close button to close the dialog box. The application also briefly displays a copyright information notice and then displays a message box instructing you to open the frmSplash form. Click OK to dismiss this message box, and then Access puts the focus on the frmSplash form in the Navigation pane. (You can open the frmSplash form if you want to run the application, but for now, we’ll just explore the interface.) Your Access window should look similar to Figure 3-4.
Exploring a Desktop Database—Housing Reservations
131
Chapter 3
Figure 3-4 The Navigation pane displays the objects defined in the Housing Reservations sample database.
For an existing database, the Navigation pane is always the same width as it was when you last set it. The title bar of the window normally shows the name of the database that you have open. As you’ll learn in Chapter 26, “The Finishing Touches,” on the companion CD, you can set options in the database to change the title bar of the main Access window to show the name of your application instead of Access—we modified the sample database to display the title Housing Reservations on the title bar. As we discussed in the previous chapter, the ribbon has four main tabs that are displayed at all times. As you explore Access 2010, you’ll see that the ribbon provides several contextual tabs that appear and disappear as you work with specific database objects and areas of the program. These contextual tabs make available commands that are useful only within the context of the object that has the focus and that object’s current view. For example, it wouldn’t make sense to show you form design commands when you have a query open in Design view. We’ll explain the various contextual tabs in more detail as we explore the database objects and other areas of Access in the following chapters.
132
Chapter 3 Access 2010 Overview
Chapter 3
Inside Out
Viewing ScreenTips
You can rest your mouse pointer on any command or option on the various ribbon tabs for a second (without clicking the button), and Access displays a ScreenTip to help you discover the purpose of the button.
In the previous chapter, you learned that you can change how Access displays the list of objects in the database by using one of the built-in navigation categories (Object Type, Tables And Related Views, Created Date, and Modified Date) or by defining your own custom navigation category. You also learned that you can filter each navigation category to limit what group Access displays within each category so that you don’t have to wade through a long list to find what you want. In this chapter, we’ll be exploring each of the types of objects in the Housing Reservations database, so click the Navigation Pane menu at the top of the Navigation pane and click Object Type under Navigate To Category. Open the menu again and be sure that you have clicked All Access Objects under Filter By Group, as shown in Figure 3-5. Your Navigation pane should now look similar to Figure 3-4. You can collapse an entire group of objects by clicking the group’s header bar. If you open the Navigation Pane menu, you can see the names of some custom groups we have defined under Navigate To Category to help organize your work. You’ll learn how to work with groups later in this chapter.
Figure 3-5 Select Object Type under Navigate To Category, and then select All Access Objects under Filter By Group to see all objects organized in groups by object type.
Exploring a Desktop Database—Housing Reservations
133
Click the menu bar at the top of the Navigation pane and select Object Type under Navigate To Category. Open the menu again and select Tables under Filter By Group to display a list of tables available in the Housing Reservations database, as shown in Figure 3-6.
Figure 3-6 After filtering the Object Type category in the Navigation pane, you can see only the tables in the Housing Reservations database.
You can open a table in Datasheet view to see the data in the table by double-clicking the table name in the Navigation pane; or you can open the table in Design view by highlighting the table name, holding down the Ctrl key, and then pressing the Enter key. If you right-click a table name, Access displays a shortcut menu, as shown in Figure 3-7, that lets you perform a number of handy operations on the item you selected. Click one of the commands on the shortcut menu, or click anywhere else in the Access window to dismiss the menu.
Inside Out
Turning on Single-Click
If you want to make it easier to open objects from the Navigation pane, you can rightclick the menu bar at the top of the Navigation pane and select Navigation Options on the shortcut menu. In the lower-right corner of the Navigation Options dialog box, select Single-Click under Open Objects With and click OK. The examples in this chapter assume you are using the default Double-Click setting.
Chapter 3
Tables
134
Chapter 3 Access 2010 Overview
Chapter 3 Figure 3-7 You can access many commands from the shortcut menu for a table in the Navigation pane.
Table Window in Design View When you want to change the definition of a table (the structure or design of a table, as opposed to the data in a table), you generally must open the table in Design view. As you’ll learn in Chapter 6, “Designing Web Tables,” you can also make definition changes in Datasheet view while you are designing the table. For now, we will concentrate on changing the table definition in Design View. With the Housing Reservations database open, right-click the tblEmployees table and select Design View from the shortcut menu; this opens the tblEmployees table in Design view, as shown in Figure 3-8. (Collapse the Navigation pane to be able to see the entire width of the design area.) You’ll learn about creating table definitions in Chapter 4, “Designing Client Tables.”
Exploring a Desktop Database—Housing Reservations
135
Chapter 3
Each row defines a field in the table
List of properties for current field
Settings for each property
Figure 3-8 Open a table in Design view to change its structure.
In Design view, each row in the top portion of the Table window defines a different field in the table. You can use the mouse to select any field that you want to modify. You can also use the Tab key to move from left to right across the screen, column to column, or Shift+Tab to move from right to left. Use the Up and Down Arrow keys to move from row to row in the field list. As you select a different row in the field list in the top portion of the window, you can see the property settings for the selected field in the bottom portion of the window. Press F6 to move between the field list and the field property settings portions of the Table window in Design view. Unlike versions of Access before Access 2007, pressing F6 again does not immediately move the focus back to the field list. If you press F6 repeatedly, the focus goes to the Navigation pane, to the ribbon, and then finally back to the field list. Access has many convenient features. Wherever you can choose from a limited list of valid values, Access provides a list box to assist you in selecting the proper value. For example, when you tab to the Data Type column in the field list, a small arrow appears at the right of the column. Click the arrow or press Alt+Down Arrow to see the list of valid data types, as shown in Figure 3-9.
136
Chapter 3 Access 2010 Overview
Chapter 3 Figure 3-9 The Data Type list box shows you the available data types.
You can open as many as 254 tables (fewer if you are limited by your computer’s memory). If you have selected Overlapping Windows in the Access Options dialog box, you can minimize any of the windows to an icon along the bottom of the Access workspace window by clicking the Minimize button in the upper-right corner of the window. You can also maximize the window to fill the Access workspace to the right of the Navigation pane by clicking the Maximize/Restore button in that same corner. If you don’t see a window you want, you can select it from the list of active windows in the Switch Windows command in the Window group on the Home tab on the ribbon to bring the window to the front. Click the Close command from the Control Box in the upper-left corner, or click the window’s Close button in the upper-right corner to close any window.
Troubleshooting Why can’t I see the Maximize/Minimize buttons on my table? If you are using the Tabbed Documents interface (the setting used in the Housing Reservations sample database), each open object has its own tab to the right of the Navigation pane. This option is the default for new databases you create in Access 2010. However, when you open older database files created in earlier versions of Access before Access 2007, the Document Window Options setting in the Access Options dialog box defaults to Overlapping Windows. With the Tabbed Documents setting, there is no need to constantly minimize and maximize object windows to switch views because each open object has an individual tab at the top of the Access workspace (the area below the ribbon and to the right of the Navigation pane). Clicking on these object tabs enables you to switch easily among any open objects, so Access 2010 does not provide the Maximize/Minimize buttons. To set your database to Overlapping Windows or Tabbed Documents, see “Using the Single-Document vs. the Multiple-Document Interface,” on page 107.
Exploring a Desktop Database—Housing Reservations
137
To view, change, insert, or delete data in a table, you can use the table’s Datasheet view. A datasheet is a simple way to look at your data in rows and columns without any special formatting. You can open a table’s Datasheet view by double-clicking the name of the table you want in the Navigation pane or by right-clicking on the table name and selecting Open from the shortcut menu. When you open a table in Design view, such as the tblEmployees table shown in Figure 3-8, you can switch to the Datasheet view of this table, shown in Figure 3-10, by clicking the arrow in the Views group on the ribbon and clicking Datasheet View from the list of available views. Likewise, when you’re in Datasheet view, you can return to Design view by clicking the arrow in the Views group and clicking Design View from the available options. You can also switch views for the table by clicking the various view buttons on the status bar located in the lower-right corner of the Access window. You’ll read more about working with data in Datasheet view in Chapter 9, “Creating and Working with Simple Queries.” Views group
View buttons Figure 3-10 Use the Views button on the ribbon or the individual view buttons on the status bar to switch from Design view to Datasheet view.
Chapter 3
Table Window in Datasheet View
138
Chapter 3 Access 2010 Overview
Chapter 3
As in Design view, you can move from field to field in the Table window in Datasheet view by pressing Tab, and you can move up and down through the records using the arrow keys. You can also use the scroll bars along the bottom and on the right side of the window to move around in the table. To the left of the horizontal scroll bar, Access shows you the current record number and the total number of records in the currently selected set of data. You can select the record number with your mouse (or by pressing Alt+Shift+F5), type a new number, and then press Enter to go to that record. You can use the arrows on either side of this record number box to move up or down one record or to move to the first or last record in the table. You can start entering data in a new record by clicking the New (Blank) Record button on the right.
Troubleshooting Why does my table have extra rows in the lower half of the screen like a spreadsheet? You might notice in Figure 3-10 that there are extra rows beneath our existing records, and this grid very much resembles a spreadsheet. This is a departure from versions of Access before Access 2007, which displayed only one row for each record in that table, plus one for a new record. For tables in Datasheet view in Access 2010, the remainder of the space in the application window is filled with dummy rows that you cannot click into. In essence, these extra rows are simply placeholders for possible future records. It might be confusing to think of this grid as a spreadsheet because of its appearance, but you must remember that Access is not a spreadsheet. What you see is only a visual aid and does not denote actual records in the tables.
Queries You probably noticed that the Datasheet view of the tblEmployees table gave you all the fields and all the records in the table. But what if you want to see only the employee names and addresses? Or maybe you would like to see in one view information about employees and all their confirmed room reservations. To fill these needs, you can create a query. To do this, open the Navigation Pane menu, click Object Type under Navigate To Category if it isn’t already selected, and then click Queries under Filter By Group to display a list of queries available in the Housing Reservations database, as shown in Figure 3-11.
Exploring a Desktop Database—Housing Reservations
139
Chapter 3
Figure 3-11 When you filter object types by queries in the Navigation pane, Access displays a list of only the queries in the Housing Reservations database.
You can open a query in Datasheet view by double-clicking the query name, or you can open it in Design view by clicking the query to select it, and then pressing Ctrl+Enter. You can also right-click a query and click the Open or Design View command from the shortcut menu.
Query Window in Design View When you want to change the definition of a query (the structure or design, as opposed to the data represented in the query), you must open the query in Design view. Take a look at one of the more complex queries in the Housing Reservations query list by scrolling to the query named qryFacilityReservations. Select the query and then press Ctrl+Enter to display the query in Design view, as shown in Figure 3-12. Collapse the Navigation pane to see more of the width of the query design.
140
Chapter 3 Access 2010 Overview
Link between tables
Chapter 3 Tables used in this query
Fields used in this query
Figure 3-12 The qryFacilityReservations query in Design view shows data from three tables being linked.
In the upper part of a Query window in Design view, you see the field lists of the tables or other queries that this query uses. The lines connecting the field lists show how Access links the tables to solve your query. If you define relationships between two tables in your database design, Access draws these lines automatically when you include both tables in a query design. See Chapter 4 for details. You can also define relationships when you build the query by dragging a field from one field list to another field list. In the lower part of the Query window, you see the design grid. The design grid shows fields that Access uses in this query, the tables or queries from which the fields come (when you select Table Names in the Show/Hide group on the ribbon’s Design tab), any sorting criteria, whether fields show up in the result, and any selection criteria for the fields. You can use the horizontal scroll bar to bring other fields in this query into view. As in the Design view of tables, you can use F6 to move between the upper and lower portions of the Query window, but the F6 key also cycles through the Query window, the Navigation pane, and the ribbon.
Exploring a Desktop Database—Housing Reservations
141
You can learn how to build this type of complex multiple-table query in Chapter 10, “Building Complex Queries.” You can find this query used in the Housing Reservations database as the source of data for the fsubFacilityReservations form.
Query Window in Datasheet View On the Design or Home tab on the ribbon, click View to run the query and see the query results in Datasheet view, as shown in Figure 3-13. You can also right-click the query tab and click Datasheet View from the shortcut menu. The Query window in Datasheet view is similar to a Table window in Datasheet view. Even though the fields in the query datasheet shown in Figure 3-13 are from three different tables, you can work with the fields as if they were in a single table. If you’re designing an Access application for other users, you can use queries to hide much of the complexity of the database and make the application simpler to use. Depending on how you designed the query, you might also be able to update some of the data in the underlying tables simply by typing new values in the Query window as you would in a Table window in Datasheet view.
Figure 3-13 The Datasheet view of the qryFacilityReservations query shows you fields from three related tables.
Chapter 3
142
Chapter 3 Access 2010 Overview
Forms Chapter 3
Datasheets are useful for viewing and changing data in your database, but they’re not particularly attractive or simple to use. If you want to format your data in a special way or automate how your data is used and updated, you need to use a form. Forms provide a number of important capabilities: ●●
You can control and enhance the way your data looks on the screen. For example, you can add color and shading or add number formats. You can add controls such as list boxes and check boxes. You can display ActiveX objects such as pictures and graphs directly on the form. And you can calculate and display values based on data in a table or a query.
●●
You can perform extensive editing of data using macros or Visual Basic procedures.
●●
You can link multiple forms or reports by using macros or Visual Basic procedures that are run from buttons on a form.
Click the menu bar at the top of the Navigation pane, click Object Type under Navigate To Category, and then click Forms under Filter By Group to display a list of forms available in the Housing Reservations database, as shown in Figure 3-14.
Figure 3-14 When you filter Object Type by Forms, Access displays a list of only the forms in the Housing Reservations database.
Exploring a Desktop Database—Housing Reservations
143
You can open a form in Form view by double-clicking the form name in the Navigation pane. You can also open the form in Design view by clicking the form to highlight it, and then pressing Ctrl+Enter. Finally, you can right-click a form name and click a command from the shortcut menu. To create a new form, use the commands in the Forms group of the Create tab on the ribbon.
Form Window in Design View When you want to change the definition of a form (the structure or design, as opposed to the data represented in the form), you generally must open the form in Design view. As you’ll learn in Chapter 14, “Customizing a Form,” you can also set a form property to allow you to make changes in Layout view while you are designing the form. Take a look at the frmEmployeesPlain form in the Housing Reservations database. To open the form, scroll through the list of forms in the Navigation pane to find the frmEmployeesPlain form, click the form to select it, then press Ctrl+Enter. This form, shown in Figure 3-15, is designed to display all data from the tblEmployees table. Don’t worry if what you see on your screen doesn’t exactly match Figure 3-15. In this figure, we opened the field list on the right so that you can see some of the main features of the Form window in Design view.
Figure 3-15 When you open the frmEmployeesPlain form in Design view, you can modify its design.
Chapter 3
144
Chapter 3 Access 2010 Overview
Chapter 3
The large window in the center is the form design window where you create the design of the form. When you first open this form in Design view, you should see the Form Design Tools collection of three contextual tabs, Design, Arrange, and Format, on the ribbon just to the right of Database Tools. These tabs are the action centers of form design—you’ll use the tools here to add and arrange the design elements of your form. On the right side of the window shown in Figure 3-15, you can see a field list for this form, called the Data Source Task Pane. This form gets its information from a query called qryEmployees that selects all the fields in the tblEmployees table and then sorts the rows by last name and first name. If you don’t see the field list, click the Add Existing Fields command in the Tools group of the Design contextual tab. You can resize this window by clicking on the far-left edge of the box and dragging it to a new width toward the left side of the screen. When your mouse pointer is positioned over the title bar, it changes to cross arrows. Click the title bar and drag it to the left and down to undock the window from the right side and position it where you like. When you undock the Field List window, it becomes a window that floats on top of the design area. When you read about form design in Chapter 13, “Building a Form,” you’ll see that you can drag a field from the field list to place a control on the form that displays the contents of the field. After you place all the controls on a form, you might want to customize some of them. You do this by opening the property sheet displayed in Figure 3-16. To see the property sheet, click the Property Sheet button in the Tools group of the Design tab. In Figure 3-16, we collapsed the Navigation pane to show more of the property sheet. The property sheet always shows the property values for the control selected in the form design. (The property sheet can also display the properties for the form or any section on the form.) Click the tabs at the top of the property sheet to display all properties or to display only properties for formats, data, or events. In the example shown in Figure 3-16, we clicked the text box named EmployeeNumber, near the top of the form, to select it. If you click this text box and then scroll down the list of properties for it, you can see the wide range of properties you can set to customize this control. As you learn to build applications using Access, you’ll soon discover that you can customize the way your application works by simply setting form and control properties—you don’t have to write any code.
Exploring a Desktop Database—Housing Reservations
145
Chapter 3
Figure 3-16 The property sheet lets you set individual properties for a form, form sections, or form controls.
If you scroll to the bottom of the property list or click the Event tab, you’ll see a number of properties that you can set to define the macros or Visual Basic procedures that Access runs whenever the associated event occurs on this control. For example, you can use the Before Update event property to define a macro or procedure that performs additional validation before Access saves any changes typed in this control. You can use the On Click or On Dbl Click event properties to perform actions when the user clicks the control. If you need to, you can even look at every individual character the user types in a control with the On Key event properties. As you’ll discover later, Access provides a rich set of events that you can detect for the form and for each control on the form.
146
Chapter 3 Access 2010 Overview
Form Window in Layout View Chapter 3
In Access 2007, Microsoft introduced a new view for forms called Layout view. If you have the frmEmployeesPlain form from the previous section open in Design view, you can switch to Layout view by right-clicking the frmEmployeesPlain tab and clicking Layout View from the shortcut menu. You should now see the form in Layout view, as shown in Figure 3-17. This unique view for forms gives the developer a fast and easy way to create and modify form designs.
Figure 3-17 Layout view lets you see your data and also modify the design of the form.
Unlike Design view, Layout view enables you to work with the various control elements and form sections using existing live data. If, for example, you need to resize a text box to fit the available data, you do not have to switch back and forth continually between Form view and Design view to see if your size change works effectively—you actually see data in the text box while resizing the control. This What You See Is What You Get (WYSIWYG) formauthoring view provides the best of both worlds by combining the ability to change the structure of the data entry form at the same time you’re accessing actual data.
Exploring a Desktop Database—Housing Reservations
147
If you have grouped a set of controls in Layout view, you can move the controls around the form design grid together to maintain their proximity and orientation to one another. In this sample form, we grouped all the controls in the first column in a stacked layout. In Figure 3-18, you can see that we’re dragging the Email Name field down below the Office Location field. A horizontal bar designates where Access will place the control after you release the mouse button. Because these controls are grouped, Access places the Email Name field below the Office Location field and aligns it perfectly.
Figure 3-18 You can move a control within a group in Layout view, and Access keeps all the controls perfectly aligned.
Form Window in Form View To view, change, insert, or delete data via a form, you can use Form view. Depending on how you’ve designed the form, you can work with your data in an attractive and clear context, have the form validate the information you enter, or use the form to trigger other forms or reports based on actions you take while viewing the form. You can open a form in Form view by right-clicking the form’s name in the Navigation pane and clicking Open from the shortcut menu. If you still have the frmEmployeesPlain form from the previous section open in Layout view, you can go directly to Form view by clicking the arrow in the Views group and then clicking Form View. Figure 3-19 shows a complex form that brings together data from three tables and loads the related employee picture from a file on your hard drive into a screen that’s easy to use and understand. This form includes all the fields from the tblEmployees table. You can tab or use the arrow keys to move through the fields. You can click the Personal Info tab to see additional information about the current employee. You can experiment with filtering by selection to see how easy it is to select only the records you want to see. For example, you
Chapter 3
148
Chapter 3 Access 2010 Overview
Chapter 3
can click in the Department field, select the department name, click the Selection button in the Sort & Filter group on the Home tab, and then click Equals “Selected Department” (where “Selected Department” is the department name you highlighted) to display records only for the current department.
Figure 3-19 The frmEmployeesPlain form in Form view lets you view and edit employee data.
There are four other ways to look at a form: Datasheet view, PivotTable view, PivotChart view, and Print Preview. You can select the Datasheet view by clicking the arrow in the Views group and clicking Datasheet View to see all the fields in the form arranged in a datasheet, similar to a datasheet for a table or a query. When a form has been designed to display data in a PivotTable (similar to a spreadsheet) or graphed in a PivotChart, you can also select these views with the View button. You can click the File tab on the Backstage view, click Print, and then click Print Preview to see what the form will look like on a printed page. You’ll read more about Print Preview in the next section.
Exploring a Desktop Database—Housing Reservations
149
If your primary need is to print data, you should use a report. Click the menu bar at the top of the Navigation pane to open the Navigation Pane menu and click Object Type under Navigate To Category. Then open the menu again and click the Reports option under Filter By Group to display a list of reports available in the Housing Reservations database, as shown in Figure 3-20.
Figure 3-20 You can filter the Navigation pane to show only a list of the reports in your database.
Although you can print information in a datasheet or a form, neither of these formats provides the flexibility that reports do when you need to produce complex printed output (such as invoices or summaries) that might include many calculations and subtotals. Formatting in datasheets is limited to sizing the rows and columns, specifying fonts, and setting the colors and gridline effects. You can do a lot of formatting in a form, but because forms are designed primarily for viewing and entering data on the screen, they are not suited for extensive calculations, grouping of data, or multiple totals and subtotals in print.
Report Window in Design View When you want to change the definition of a report, you generally must open the report in Design view. As you’ll learn in Chapter 17, “Constructing a Report,” you can also make changes in Layout view while you are designing the report. In the report list for Housing Reservations, click the rptEmployeesPlain report to highlight it, and then press Ctrl+Enter to see the design for the report, as shown in Figure 3-21. Don’t worry if what you see on your screen doesn’t exactly match Figure 3-21. We clicked the Add Existing Fields command on the Design tab under Report Design Tools to display the Field List window.
Chapter 3
Reports
150
Chapter 3 Access 2010 Overview
Chapter 3
View button
Report Design Tools contextual tabs Design, Arrange, Format, and Page Setup
Navigation Pane
Report design grid
Add to Existing Fields button
Field List window
Figure 3-21 Open the rptEmployeesPlain report in Design view to modify its design.
The large window in the center is where you create the design of the report. This report is designed to display all the information about employees by department. Notice that Design view for reports is similar to Design view for forms. (For comparison, see Figure 3-15 on page 143.) Reports provide additional flexibility, allowing you to group items and to total them (either across or down). You can also define header and footer information for the entire report, for each page, and for each subgroup on the report. When you first open this report in Design view, you should see four new contextual tabs appear on the ribbon just to the right of Database Tools under Report Design Tools: Design, Arrange, Format, and Page Setup. These contextual tabs are the action centers of report design—you’ll use the tools here to add the design elements you want. On the right side of the window shown in Figure 3-21, you can see the field list for this report. This list shows all the fields returned by the record source for the report, the saved query qryRptEmployees. If you don’t see the field list, click the Add Existing Fields command from the Tools group on the Design contextual tab. You can resize this window by clicking the far-left edge and dragging it toward the left side of the screen to a new width. When your mouse pointer is positioned over the title bar, it changes to cross arrows.
Exploring a Desktop Database—Housing Reservations
151
Click the title bar and drag it to the left and down to undock the window from the right side and position it where you like. When you undock the Field List window, it becomes a window that floats on top of the design area. When you read about report design in Chapter 17, you’ll see that you can drag a field from the field list to place a control on the report that displays the contents of the field. After you place all the controls on a report, you might want to customize some of them. Do this by opening the property sheet, which you can see on the right side of the screen in Figure 3-22. To see the property sheet, click the Property Sheet command in the Tools group of the Design tab. In Figure 3-22, we collapsed the Navigation pane so you can see more of the property sheet.
Figure 3-22 The property sheet lets you set individual properties for a report, report sections, or controls on the report.
The property sheet always shows the property settings for the control selected in the Report window. (The Property Sheet pane can also display the properties for the entire report or any section on the report.) In the example shown in Figure 3-22, we clicked the text box named EmployeeNumber to select it. If you click this text box, you can see that Access displays the EmployeeNumber field from the tblEmployees table as the control source (input data) for this control. You can also specify complex formulas that calculate additional data for report controls.
Chapter 3
152
Chapter 3 Access 2010 Overview
Chapter 3
Reports can be even more complex than forms, but building a simple report is really quite easy. Access provides report wizards that you can use to automatically generate a number of standard report layouts based on the table or query you choose. You’ll find it simple to customize a report to suit your needs after the Report Wizard has done most of the hard work. You’ll learn how to customize a report in Chapter 17 and Chapter 18, “Advanced Report Design.”
Report Window in Print Preview To see what the finished report looks like, click the arrow in the Views group and then click Print Preview when you’re in the Report window in Design view. You can also right-click the report name in the Navigation pane and then click Print Preview from the shortcut menu. Figure 3-23 shows a report in Print Preview.
Print Preview Zoom button
Two Pages button More Pages button
Zoom control Figure 3-23 When you open a report in Print Preview, Access shows you how the report will look when you print it.
Exploring a Desktop Database—Housing Reservations
153
Access initially shows you the upper-left corner of the report. To see the report centered in full-page view in Print Preview, click the Zoom control in the lower-right corner of the status bar, where it says 100%. Clicking that button automatically adjusts the zoom level percent so that you can see a full page of the report. To see two pages side by side, click the Two Pages button in the Zoom group of the Print Preview contextual tab. This gives you a reduced picture of two pages, as shown in Figure 3-24, and an overall idea of how Access arranges major areas of data on the report. Unless you have a large monitor, however, you won’t be able to read the data. Click More Pages and then click an option (Four Pages, Eight Pages, or Twelve Pages) to see more than two pages. When you move the mouse pointer over the window in Print Preview, the pointer changes to a magnifying glass icon. To zoom in, click over an area that you want to see more closely. You can then use the scroll bars to move around in the magnified report. Use the Zoom control on the status bar to magnify or shrink your view. Access also provides several output options such as Word or Excel in the Data group of the Print Preview tab.
Figure 3-24 Click Two Pages to see two pages side-by-side in Print Preview.
Chapter 3
154
Chapter 3 Access 2010 Overview
Report Window in Layout View Chapter 3
In Access 2007, Microsoft introduced a new view for reports called Layout view. This unique view for reports gives the developer a fast and easy way to create and modify report designs. Unlike Design view, Layout view enables you to work with the various control elements and report sections using existing live data. Similar to Layout view for forms, this WYSIWYG report-authoring view provides the best of both worlds by giving you the ability to change the structure of the report as you’re accessing the data. To open the rptEmployeesPlain in Layout view, find the report in the Navigation pane, right-click the report name, and click Layout View from the shortcut menu. Figure 3-25 shows the report in Layout view. In Figure 3-25, we collapsed the Navigation pane so you can see more of the report design grid.
Figure 3-25 Similar to Layout view for forms, Layout view in reports lets you adjust design elements while looking at the data from your database.
Just like Layout view for forms, if you have grouped a set of controls, you can move them around the report grid together to maintain their orientation to one another. In Figure 3-26, you can see that we’re dragging the Birth Date field above the Email field. A horizontal bar designates where Access will place the control after you release the mouse button. Because these controls are grouped, Access places the Birth Date field above the Email field. The two controls align perfectly.
Exploring a Desktop Database—Housing Reservations
155
Chapter 3
Figure 3-26 Access makes it easy to move controls around within a group in Layout view in a report.
Report Window in Report View Beginning in Access 2007, Microsoft introduced another new view for reports, called Report view. This is an interactive view for reports that can respond to control events, much like data entry forms. If you have the rptEmployeesPlain report from the previous section open in Layout view, you can switch to Report view by right-clicking the Employees tab and clicking Report View from the shortcut menu. You should now see the report in Report view, as shown in Figure 3-27.
Figure 3-27 When a report is in Report view, you can program controls to respond to mouse clicks to open a related form.
156
Chapter 3 Access 2010 Overview
Chapter 3
Versions of Access before 2007 treat reports on screen as static. After you open a report on the screen, you can only view the report or print it. Report view in Access 2010 gives you the ability to interact with the report through filters to show specific records and then print only this smaller group of records. You can include command buttons on your reports with Access 2010 and program the buttons to respond to a mouse click in Report view. In Report view, you can designate controls that respond to events as hyperlinks to provide a visual cue that an event occurs when clicking that control. In Figure 3-27, for example, observe that the Employee Number field looks like a hyperlink with a blue line underneath the data. (In Figure 3-27, we have scrolled down the records to show Jeff’s information.) Clicking the Employee Number field opens the frmEmployeesPlain form to display all information for that specific employee so that you can make any necessary changes. After closing the form and returning to the report, click the Refresh All command in the Records group of the Home tab on the ribbon to see any changes you made to the data using the form reflected in the report. In Figure 3-27, you can see that the frmEmployeesPlain form opens on a new tab because we are using a tabbed interface. Close the Form window and the Report window to return to the Navigation pane.
Macros You can make working with your data within forms and reports much easier by triggering a macro action. Access 2010 provides more than 80 actions that you can include in a macro. They perform tasks such as opening tables and forms, running queries, running other macros, selecting options from menus, and sizing open windows. You can also group multiple actions in a macro and specify conditions that determine when each set of actions will or will not be executed by Access. Open the Navigation Pane menu and make sure that Object Type is selected under Navigate To Category. Then open the menu again and click Macros under Filter By Group to display a list of macros available in the Housing Reservations database, as shown in Figure 3-28. You can run a macro by right-clicking the macro name in the Navigation pane and clicking Run on the shortcut menu. To open a macro in Design view, right-click the macro name and click Design View from the shortcut menu. To create a brand new macro, click the Macro button in the Macros & Code group of the Create tab on the ribbon.
Figure 3-28 You can filter the Navigation pane to show the Macros list in the Housing Reservations database.
Exploring a Desktop Database—Housing Reservations
157
Macros are a great way to learn about the basics of responding to events and automating actions in an Access database. As you’ll learn later in Chapter 7, if you want to respond to table events such as after inserting new records or before committing new records, you’ll need to create macros for this purpose. If you are creating an Access Services application that you intend to publish to the web using Microsoft SharePoint Server, you can only use macros to automate your application. It is a good idea, then, to become familiar with how to create and use macros. For complex client applications that you intend to distribute to others, you’ll probably find that you need to use Visual Basic to handle events and automate actions. Nearly all the sample databases use Visual Basic exclusively. You can take a look at the design of a macro example in the Housing Reservations database by selecting the SampleMacro macro in the Navigation pane, and then pressing Ctrl+Enter. Access opens the Macro window (also called the Logic Designer) in Design view, as shown in Figure 3-29.
Figure 3-29 Open the SampleMacro macro object in the Housing Reservations database in Design view to examine and modify its definition.
In Access 2010, Microsoft has completely redesigned the macro design surface. In previous versions of Access, the macro design surface resembled more of a table datasheet. Each line or row in the macro window represented an action for the macro to execute. The columns in the older macro window designated the name, conditions, macro actions, and
Chapter 3
158
Chapter 3 Access 2010 Overview
Chapter 3
comments about that specific action to execute. In Access 2010, the macro designer surface resembles more of a Visual Basic Editor. As you can see in Figure 3-29, Access indents the lines of the macro for easier readability of the program logic. You’ll also notice that the new macro designer supports using If/Else/Else If/End If constructs. In previous versions of Access, you needed to use a continuation indicator (...) on subsequent lines to specify additional commands that should execute when a condition was true. With the new design surface in Access 2010, however, it is much easier for you to see what actions will execute and under what conditions. The Action Catalog on the right side of the macro designer lists all the macro actions grouped by subject. You can add macro actions directly within the design surface or drag actions from the Action Catalog. You’ll learn more about all the new changes in the macro designer in Chapter 7, “Creating Table Data Macros.” If you want to see what the SampleMacro macro does, click the Run button in the Tools group of the Design contextual tab to execute it. You should see a greeting message appropriate to the time of day appear on your screen. To learn more about events and the macro design facility, see Chapter 7, “Creating Table Data Macros,” Chapter 20, “Automating a Client Application with Macros,” and Chapter 21, “Automating a Web Application with Macros.” You can find one sample application on the companion CD that is automated entirely using macros—WeddingListMC.accdb. Close the Macro window now to return to the Navigation pane.
Modules You might find that you keep coding the same complex formula over and over in some of your forms or reports. Although you can build a complete Access application using only forms, reports, and macros, some actions might be difficult or impossible to define in a macro. If that is the case, you can create a Visual Basic procedure that performs a series of calculations and then use that procedure in a form or report. If your application is so complex that it needs to deal with errors (such as two users trying to update the same record at the same time), you must use Visual Basic. Because Visual Basic is a complete programming language with complex logic and the ability to link to other applications and files, you can solve unusual or difficult programming problems by using Visual Basic procedures. Version 2 of Access introduced the ability to code Basic routines in special modules attached directly to the forms and reports that they support. You can create these procedures from Design view or Layout view for forms or reports by requesting the Code Builder in any event property. You can edit this code behind forms and reports by clicking View Code from the Tools group on the Design contextual tab when you have a form or report open in Design view. See Chapters 24 and 25 for details. In fact, after you learn a little bit about Visual Basic, you might find that coding small event procedures for your forms and
Exploring a Desktop Database—Housing Reservations
159
reports is much more efficient and convenient than trying to keep track of many macro objects. You’ll also soon learn that you can’t fully respond to some sophisticated events, such as KeyPress, in macros because macros can’t access special additional parameters (such as the value of the key pressed) that are generated by the event. You can fully handle these events only in Visual Basic. Open the Navigation Pane menu and click Object Type under Navigate To Category. Open the menu again and click Modules under Filter By Group to display a list of modules available in the Housing Reservations database, as shown in Figure 3-30. The Housing Reservations database has several module objects that contain procedures that can be called from any query, form, report, or other procedure in the database. For example, the modMedian module contains a function to calculate the median value of a column in any table or query. The modUtility module contains several functions that you might find useful in your applications.
Figure 3-30 You can filter the Navigation pane to display only the Visual Basic modules in the Housing Reservations database.
From the Navigation pane, you can create a new module by clicking the Module button in the Macros & Code group of the Create tab on the ribbon, or you can open the design of an existing module by double-clicking the name of the module in the Navigation pane. In addition, you can right-click the module name in the Navigation pane and click Design View from the shortcut menu. In a module, you can define procedures that you can call from a macro, a form, or a report. You can also use some procedures (called functions) in expressions in queries and in validation rules that you create for a table or a form. You’ll learn about how to create procedures in Chapter 24. Right-click the modUtility module in the Navigation pane, and then click Design View to open the Visual Basic Editor window containing the Visual Basic code in the module. Use the Procedure list box (in the upper-right section of the Code window) to look
Chapter 3
160
Chapter 3 Access 2010 Overview
Chapter 3
at the procedure names available in the sample. One of the functions in this module, IsFormLoaded, checks all forms open in the current Access session to see whether the form name, passed as a parameter, is one of the open forms. This function is useful in macros or in other modules to direct the flow of an application based on which forms the user has open. You can see this function in Figure 3-31.
Figure 3-31 The Visual Basic Editor window displays the IsFormLoaded function in the modUtility module.
Note that the Visual Basic Editor runs in an entirely different application window from Access, and it still uses the classic menus and toolbars found in earlier versions of Access. Click the View Microsoft Office Access button on the far-left side of the toolbar to return to the Access window easily. This completes the tour of the objects in the Housing Reservations sample database. Close the Visual Basic Editor window (if you still have it open), return to the Access window, and close the database.
The Many Faces of Access
161
What Happened to Project Files (ADP)? Access 2000 introduced an advanced facility that allows you to create a project file (with an .adp extension) that contains only your forms, reports, macros, and modules. When you create a new project file, you can specify an SQL Server database to support the project. SQL Server stores the tables and queries you use in the application that you design in the project. You can connect your project file to a database in SQL Server version 7.0 or later, on a server or on your desktop. You can download a special edition of SQL Server 2008, SQL Server Express Edition, which you can install to run on your desktop computer from the following location on Microsoft’s website: http://www.microsoft.com/sqlserver/2008/en/us/ express.aspx Access Data Projects (ADPs) still exist in Access 2010; however, Microsoft did not add a lot of new functionality to them for the 2010 release besides adding support for connection to SQL Server 2008 and support for a few more data types. For the Access 2010 product cycle, most of the Access team’s development resources were focused in other areas, most notably the new Access Services functionality. In deciding what features to cover for this edition of the “Inside Out” series, there simply was not enough space to include a full discussion of ADPs along with all the new features included in Access 2010. For more information on ADPs, see Microsoft Office Access 2007 Inside Out (Microsoft Press, 2007).
The Many Faces of Access Access is not only a powerful, flexible, and easy-to-use database management system, but it is also a complete database application development facility. You can use Access to create and run, under the Microsoft Windows operating system, an application tailored to your data management needs. Access lets you limit, select, and total your data by using queries. You can create forms for viewing and changing your data. You can also use Access to create simple or complex reports. Forms and reports inherit the properties of the underlying table or query, so in most cases, you need to define such properties as formats and validation rules only once. Figure 3-32 gives you an overview of all the ways you can use Access to implement an application.
162
Chapter 3 Access 2010 Overview
Chapter 3 Figure 3-32 Although Access is primarily a desktop database system, you can use Access to build client/server applications.
The four panes in the figure illustrate ways you can implement an Access application, as follows: ●●
Using the desktop database facility or an Access project file linked to a local copy of MSDE, you can create a stand-alone application used by a single person.
●●
You can place a data-only desktop database on a file server or in a database in SQL Server and link the tables over a network into multiple desktop databases so that several users can share the same application.
●●
You can design your database in SQL Server and connect to the server over a network from multiple Access project files running on different computers.
●●
Finally, you can create an Access Services application using SharePoint Server that connects to data that you designed using Access.
To borrow a cliché, the possibilities are endless. . . .
The Many Faces of Access
163
In this chapter, you’ve had a chance to look at the major objects in the Housing Reservations sample database. You’ve also been introduced to the architecture of Access and the wide range of ways that you can use Access. You should be feeling comfortable that you can learn to use Access at the level appropriate to solve your database application needs. Perhaps the most important aspect of building an application is designing the database that will support your application. Chapter 4 describes how you should design your database application and its data structures. Building a solid foundation makes creating the forms and reports for your application easy.
efining tables in a Microsoft Access 2010 desktop database (.accdb file) is incredibly easy. This chapter shows you how it’s done. You’ll learn how to:
●●
Create a new database application using a database template
●●
Create a new empty database for your own custom application
●●
Create a simple table by entering data directly in the table
●●
Get a jump start on defining custom tables by using Application Parts
●●
Create new fields by using Data Type Parts
●●
Define your own tables from scratch by using Design view
●●
Select the best data type for each field
●●
Define the primary key for your table
●●
Set validation rules for your fields and tables
●●
Tell Access 2010 what relationships to maintain between your tables
●●
Optimize data retrieval by adding indexes
●●
Set options that affect how you work in Design view
●●
Print a table definition
167
168
Chapter 4 Designing Client Tables
Note Chapter 4
All the screen images in this chapter were taken on a Windows 7 with the Access color scheme set to Silver.
Inside Out
Take Time to Learn About Table Design
You could begin building a database in Access 2010 much as you might begin creating a simple single-sheet solution in a spreadsheet application such as Microsoft Excel—by simply organizing your data into rows and columns and then inserting formulas where you need calculations. If you’ve ever worked extensively with a database or a spreadsheet application, you already know that this unplanned approach works in only the most trivial situations. Solving real problems takes some planning; otherwise, you end up building your application over and over again. One of the beauties of a relational database system such as Access is that it’s much easier to make midcourse corrections. However, it’s well worth spending time up front designing the tasks you want to perform, the data structures you need to support those tasks, and the flow of tasks within your database application. To teach you all you might need to know about table design would require another entire book. The good news is Access 2010 provides many examples of good table design in the templates available with the product and online. If you want to learn at least the fundamentals of table and application design, be sure to read Article 1, “Designing Your Database Application,” which you can find on the companion CD.
Creating a New Database When you first start Access 2010, you see the New tab on the Microsoft Office Backstage view, as shown in Figure 4-1. We explored the New tab in detail in Chapter 2. If you’ve previously opened other databases, you also see a most recently used list of up to four database selections by default under Close Database on the left.
Creating a New Database
169
Chapter 4
Figure 4-1 When you first start Access 2010, you see the New tab on the Backstage view.
Using a Database Template to Create a Database Just for fun, let’s explore the built-in database templates first. If you’re a beginner, you can use the templates included with Access 2010 to create one of several common applications without needing to know anything about designing database software. You might find that one of these applications meets most of your needs right away. As you learn more about Access 2010, you can build on and customize the basic application design and add new features. Even if you’re an experienced developer, you might find that the application templates save you lots of time in setting up the basic tables, queries, forms, and reports for your application. If the application you need to build is covered by one of the templates, the wizard that builds an application with one of the templates can take care of many of the simpler design tasks. On the New tab of the Backstage view, you can access the built-in local templates by clicking Sample Templates under Available Templates in the center of the screen. You can also choose to download a template from Microsoft’s website by clicking one of the options under Office.com Templates. When you click one of the options under Sample Templates or Office.com Templates, the center section of the New tab changes to show a graphic
170
Chapter 4 Designing Client Tables
representing each of the database templates available in that category. Click the Non-Profit category under Office.com to see the list of nonprofit template options, as shown in Figure 4-2. Chapter 4 Figure 4-2 You can access templates from Office.com by selecting one of the categories to see a list of database templates for that category.
When you click one of the template graphics in the center of the New tab, Access 2010 displays additional information about the purpose of the database in the right task pane. Click the Home button near the top of the screen to return to the main Home page of the New tab. Click Sample Templates to see a list of templates installed locally on your computer. Click the Tasks template in the middle of the screen to see detailed information about the Tasks database template, as shown in Figure 4-3. You can work with all templates from the New tab in the same way. This example will show you the steps that are needed to build a Tasks database.
Creating a New Database
171
Chapter 4
Figure 4-3 When you choose one of the database templates in the center of the screen, Access shows you a larger graphic in the right task pane.
Access 2010 displays a larger graphic in the right task pane when you click a specific database template. Note that when you have selected an online template, Access 2010 also shows you the template size and the rating given this template by other users. Access 2010 suggests a name for your new database in the File Name text box and a location to save the file beneath the File Name text box. You can modify the name of this database by typing in the File Name text box. If you want to change the suggested save location, click Browse to open the File New Database dialog box, as shown in Figure 4-4.
172
Chapter 4 Designing Client Tables
Chapter 4 Figure 4-4 Use the File New Database dialog box to select a folder for saving the new local database template.
You can select the drive and folder you want by clicking the links on the left and browsing to your destination folder. After you select the specific folder to which you want to save this new database, click OK to return to the New tab on the Backstage view. Your new folder location is shown beneath the File Name text box. If you decide at this point not to create the database, click the Home button near the top of the screen to return to the main Home page of the New tab to stop the process. Click Download when working with an online template or Create when working with a local template, and Access 2010 begins the process of creating this new database template. The first time you choose to download an online template, Access 2010 might display the Microsoft Office Genuine Advantage confirmation dialog box, as shown in Figure 4-5. Each time you download a template, Access 2010 confirms that you have a valid and registered copy of the Microsoft Office 2010 system. If you do not want to see this dialog box again, select the Do Not Show This Message Again check box. Click Continue to proceed with the download and creation of your sample database.
Creating a New Database
173
Chapter 4
Figure 4-5 When you ask to download a template, Access verifies that you have a genuine copy of the Office 2010 release.
A progress bar appears on the screen asking you to wait while Access 2010 creates the template. After a few seconds of preparation, Access opens the new Tasks database and displays the Task List form, as shown in Figure 4-6. Close this new database for now by clicking the File tab on the Backstage view and then clicking Close Database to return to the New tab. Note that when you browse or download Access templates from Office.com, you might see additional folders on the New tab of the Backstage view under Office.com Templates.
Figure 4-6 After you create the Tasks database from a template, Access opens the database and displays the Task List form.
174
Chapter 4 Designing Client Tables
Creating a New Empty Database Chapter 4
To begin creating a new empty database when you start Access 2010, go to the Available Templates section in the middle of the New tab (as shown in Figure 4-1) and click Blank Database. The right side of the New tab changes to display the Blank Database task pane, as shown in Figure 4-7.
Figure 4-7 From the New tab on the Backstage view, click Blank Database in the center to open the Blank Database task pane on the right.
You can click Browse to open the File New Database dialog box, shown in Figure 4-4, to select the drive and folder that you want. In this example, we selected the Documents folder in Windows 7 for the current user. Next, type the name of your new database in the File Name text box—Access 2010 appends an .accdb extension to the file name for you. Access 2010 uses a file with an .accdb extension to store all your database objects, including tables, queries, forms, reports, macros, and modules. For this example, let’s create a database with a table containing names and addresses—something you might use to track invitees to a wedding. Type Kathy’s Wedding List in the File Name box and click Create to create your database.
Creating a New Database
175
Access 2010 takes a few moments to create the system tables in which to store all the information about the tables, queries, forms, reports, macros, and modules that you might create. Access then displays the Navigation pane for your new database and opens a new blank table in Datasheet view, as shown in Figure 4-8.
Figure 4-8 When you create a new blank database, Access 2010 opens a new table in Datasheet view for you.
When you open a database (unless the database includes special startup settings), Access 2010 selects the object you last chose in the Navigation pane for that database. For example, if you worked on a table the last time you opened this database, Access highlights that object (a table) in the Navigation pane. Access also remembers the view and filters you applied to the Navigation pane. For example, if Tables And Related Views was the last selected view applied to the Navigation pane, Access will remember this the next time you open the database.
Chapter 4
176
Chapter 4 Designing Client Tables
Chapter 4
Because this is a new database and no objects or special startup settings exist yet, you see a Navigation pane with only one object defined. For new databases, Access, by default, creates a new table in Datasheet view called Table1 with an ID field already defined. However, Access has not saved this table, so if you do not make any changes to it, Access will not prompt you to save the table if you close it. The following sections show you various methods for creating a new table.
Creating Your First Simple Table by Entering Data If you’ve been following along to this point, you should still have your new Kathy’s Wedding List database open with Table1 open in Datasheet view, as shown in Figure 4-8. (You can also follow these steps in any open database.) What you see is an empty datasheet, which looks quite similar to a spreadsheet. Access 2010 automatically created the first field, called ID, in the left column. Leave this field intact for now. In the second column, Access has placed another field with the Add New Field heading. You can enter just about any type of data you want in this field—text, dates, numbers, or currency. But unlike a spreadsheet, you can’t enter any calculated expressions in a datasheet. As you’ll see later in this chapter, you can easily display a calculated result using data from one or more fields by entering an expression in a Calculated data type. Because we’re starting a list of wedding invitees, we’ll need columns containing information such as title, last name, first name, middle initial, street address, city, state, postal code, number of guests invited, number of guests confirmed, gift received, and a gift acknowledged indicator. Be sure to enter the same type of data in a particular column for every row. For example, enter the city name in the seventh column (named Field6 by Access) for every row. You can see some of the data entered for the wedding invitee list in Figure 4-9. When you start to type in a field in a row, Access 2010 displays a pencil icon on the row selector at the far left to indicate that you’re adding or changing data in that row. Press the Tab key to move from column to column. When you move to another row, Access 2010 saves what you typed. If you make a mistake in a particular row or column, you can click the data you want to change and type over it or delete it. Notice that after you enter data in a column, Access 2010 guesses the most appropriate data type and displays it in the Data Type box on the Fields tab on the ribbon.
Creating Your First Simple Table by Entering Data
177
Chapter 4
Figure 4-9 You can create the wedding invitee list table by entering data.
If you create a column of data that you don’t want, click anywhere in the column and click Delete in the Add & Delete group of the Fields contextual tab on the ribbon. Click Yes when Access asks you to confirm the deletion. If you want to insert a blank column between two columns that already contain data, right-click the column header to the right of where you want to insert the new column and then click Insert Field from the shortcut menu that appears. To move a column to a different location, click the field name at the top of the column to select the entire column, and then click again and drag the column to a new location. You can also click an unselected column and drag your mouse pointer through several adjacent columns to select them all. You can then move the columns as a group. You probably noticed that Access 2010 named your columns Field1, Field2, and so forth— not very informative. You can enter a name for each column by double-clicking the column’s field name. You can also right-click a column header and then click Rename Field from the shortcut menu that appears. In Figure 4-10, we have already renamed one of the columns and are in the process of renaming the second one.
178
Chapter 4 Designing Client Tables
Chapter 4 Figure 4-10 Double-click the column heading to rename a column in Datasheet view.
Save
After you enter several rows of data, it’s a good idea to save your table. You can do this by clicking the Save button on the Quick Access Toolbar or by clicking the File tab and then click Save. Access 2010 displays a Save As dialog box, as shown in Figure 4-11. Type an appropriate name for your table, and then click OK. If you deleted the ID field by mistake, Access 2010 displays a message box warning you that you have no primary key defined for this table and offers to build one for you. If you accept the offer, Access adds a field called ID and assigns it a special data type named AutoNumber that automatically generates a unique number for each new row you add. See “Understanding Field Data Types,” on page 190, for details about AutoNumber. If one or more of the data columns you entered would make a good primary key, click No in the message box. In Chapter 5, “Modifying Your Table Design,” you’ll learn how to use Design view to define your own primary key(s) or to change the definition of an existing primary key. In this case, Access 2010 should not display a message box because it already generated the field called ID to serve as the primary key.
Figure 4-11 Access 2010 displays the Save As dialog box when you save a new table so that you can specify a table name.
Creating a Table Using Application Parts If you look in the Wedding List sample database (WeddingList.accdb) included on the companion CD, you’ll find it very simple, with one main table and a few supporting tables for data such as titles, cities, and groups. Most databases are usually quite a bit more complex. For example, the Proseware Housing Reservations sample database contains six main tables, and the Conrad Systems Contacts sample database contains more than a dozen tables. If you had to create every table manually, it could be quite a tedious process. Fortunately, Access 2010 comes with a new feature called Application Parts to help you build a few common tables and other database objects. Let’s move on to a more complex
Creating a Table Using Application Parts
179
task—building tables like those you find in Conrad Systems Contacts. To do this, click the File tab on the Backstage view and then click New. This returns you to the New tab, ready to define a new blank database. For this exercise, create a new blank database and give it the name “Contact Tracking.” We’ll use this database to start building tables like some of those you saw in Chapter 3, “Access 2010 Overview.” To build a table using one of the Application Parts, close the table that Access 2010 created when you opened the database (Table1), click the Create tab on the ribbon, and then click the Application Parts button in the Templates group. Access displays a list of 10 form types under the Blank Forms category and five Application Parts under the Quick Start category, as shown in Figure 4-12. Microsoft also uses the term Models to refer to this oneclick object creation feature. You’ll learn more about using the 10 form Application Parts in Chapter 13, “Building a Form.”
Figure 4-12 Application Parts help you create common types of database objects.
The five Application Parts under Quick Start, which represent some of the more common types of table structures and objects found in databases, are as follows: ●●
Comments Use this Application Part when you need a table to track various comments. Clicking this option creates one table with a comment date and comment fields.
●●
Contacts Use this Application Part when you need to track your personal or business contacts. Clicking this option not only creates a Contacts table, but it also creates a query, three forms, and four reports to work with that Contacts table. With one click, you are well on your way to creating a functional application to track your contacts. Key fields in the Contacts table include the contact’s company, job title, and phone numbers.
Chapter 4
180
Chapter 4 Designing Client Tables
Chapter 4
●●
Issues Use this Application Part for recording various personal or business issues. Clicking this option creates an Issues table as well as two forms to work with that table. Some key fields in the Issues table include the title of the issue and the issue status.
●●
Tasks Use this Application Part for keeping track of various tasks and projects needing completion. Clicking this option creates a Tasks table as well as two forms to work with that table. Key fields in the Tasks table include start and due dates for the task and percentage complete.
●●
Users Use this Application Part for maintaining a list of users for your database. Clicking this option creates a Users table as well as two forms to work with that table. Key fields in the Users table include the email, full name, and login information.
Inside Out
What Happened to the Table Templates?
The five Table Templates from Access 2007 do not exist in Access 2010. Microsoft replaced the Table Templates with various Application Parts in Access 2010 so you can quickly build fields, tables, and other database objects commonly found in most databases.
Click Contacts in the Quick Start list, and Access 2010 builds a complete table structure for a contacts table as well as other supporting objects, as shown in Figure 4-13. Access creates a total of 20 fields to identify the data elements for this contacts table. Use the horizontal scroll bar or press Tab to see the field names to the right. This contacts table Application Part includes fields such as Company, First Name, Last Name, E-mail Address, Job Title, and so on to identify a single subject—a contact. The Quick Start command also automatically defines a data type for each of these fields. See Table 4-1, on page 190, for a full discussion of the various data types available within Access 2010.
Creating a Table Using Application Parts
181
Chapter 4
Figure 4-13 The Quick Start command builds a complete table with appropriate field types and supporting objects.
By default, Access 2010 assigned the name ID to the first field in this Contacts table. This field name is not very descriptive, so we will rename this field ContactID. There are several ways to rename a field using Access 2010, but for now we will focus on one of the easiest methods—renaming the field directly from Datasheet view. Double-click the heading of the ID field and then type ContactID, as shown in Figure 4-14. After you press Enter, Access immediately renames the field. Save the change to this table now by clicking the Save button on the Quick Access Toolbar.
Figure 4-14 You can double-click a column heading in Datasheet view to change the name of the field.
182
Chapter 4 Designing Client Tables
Chapter 4
You will further change this Contacts table later in this chapter and in Chapter 5 so that it is more like the final tblContacts table in the Conrad Systems Contacts database. For now, close the Table window so that you can continue building other tables you need. Also, let’s delete all the other supporting objects the Application Part command created so we can concentrate just on the tables for now. Highlight the query called ContactsExtended in the Navigation pane and then press Delete. Click OK in the confirmation dialog box when Access prompts you to delete the object. Continue deleting the remaining three forms and four reports until you are left with just the Contacts table in the Navigation pane.
Creating a Table Using Data Type Parts Access 2010 includes another new feature, called Data Type Parts, to assist you with creating tables and fields. Application Parts, as you just learned, help you build complete tables and other database objects, but Data Type Parts help you create individual fields or groups of fields. As you design more databases, you might find yourself needing to create similar field structures in your tables. For example, you’ll probably find yourself needing to have fields in at least one table that tracks address information such as street address, city, state, and ZIP code. With Access 2010, you can now add a group of fields to track address information easily using Data Type Parts. You can also save your own custom field or groups of fields to be used in other Access applications that you create. If you’ve been following along to this point, you should still have your new Contact Tracking database open with just the Contacts table in the Navigation pane. (You can also follow these steps in any open database.) To build a table using one of the Data Type Parts, you first need to have a table opened in Datasheet view. Click the Create tab on the ribbon and then click the Table button in the Tables group. Access creates a new table called Table1 with one field called ID and displays it in Datasheet view. Click the More Fields button in the Add & Delete group on the Fields tab and Access displays a large list of field types grouped by category, as shown in Figure 4-15.
Creating a Table Using Data Type Parts
183
Chapter 4
Figure 4-15 Click More Fields to see many field types and formatting choices you can use in your table.
Under the Basic Types, Number, Date and Time, and Yes/No categories, Access displays many options for different field types and field formats you can use in your table. You can click any of the options in these categories and Access creates a new field in your table. You’ll learn more about the different field types and formats later in this chapter. Scroll down to the bottom of the list under the More Fields button, and Access displays a list of nine Data Type Parts under the Quick Start category, as shown in Figure 4-16.
184
Chapter 4 Designing Client Tables
Chapter 4 Figure 4-16 Data Type Parts help you create common types of fields.
The nine Data Type Parts under Quick Start, which represent some of the more common types of fields used in a database, are as follows: ●●
Address Use this Data Type Part when you need fields to list address information. Clicking this option creates the following five fields—Address, City, State Province, Zip Postal, and Country Region.
●●
Category Use this Data Type Part when you need to create a list of categories. Clicking this option creates a list box with three generic category names.
●●
Name Use this Data Type Part to create fields to store the names of people. Clicking this option creates the following fields—Last Name, First Name, Contact Name, and File As.
Creating a Table Using Data Type Parts
185
●●
Payment Type Use this Data Type Part when you need a list of payment types for order tracking or contribution tracking purposes. Clicking this option creates a list box called Payment Type with four options—Cash, Credit Card, Check, and In Kind.
●●
Phone Use this Data Type Part when you need to create fields to store phone numbers. Clicking this option creates the following fields—Business Phone, Home Phone, Mobile Phone, and Fax Number.
●●
Priority Use this Data Type Part when you need to create a list of priority levels. Clicking this option creates a list box with three generic priority levels—(1) High, (2) Normal, and (3) Low.
●●
Start and End Dates Use this Data Type Part when you need fields to track start dates and end dates. Clicking this option creates two Date/Time fields.
●●
Status Use this Data Type Part when you need to create a list of status levels. Clicking this option creates a list box with five generic status levels—Not Started, In Progress, Completed, Deferred, and Waiting.
●●
Tag Use this Data Type Part when you need to create a list that allows you to select multiple items. Clicking this option creates a multi-value list with three generic items—Tag 1, Tag 2, and Tag 3.
See Table 4-1, on page 190, for a full discussion of the various data types available within Access 2010.
Click Name under the Quick Start category and Access creates four fields ready for you to use to track names of your contacts, as shown in Figure 4-17. You can add more Data Type Parts to this table by clicking another option under the Quick Start category.
Figure 4-17 Use the Name Data Type Part when you need to create fields to record the names of people.
Chapter 4
186
Chapter 4 Designing Client Tables
Chapter 4
To add the Address Data Type Part to this table, first click the Click To Add entry to move the focus to the right of the File As field in the table Datasheet view. Access always adds new fields to the left of where the current focus is located in the Datasheet view grid. Now click the More Fields button in the Add & Delete group on the ribbon and then click Address under the Quick Start category. Access creates five more fields in your table, as shown in Figure 4-18. Your table now has fields to track the address information for your contacts.
Figure 4-18 You can add fields to hold address information by clicking the Address Data Type Part.
Using Data Type Parts can save you time when you’re designing your tables in Access 2010 by giving you a jump start on creating common field types. Close the Table window now, and do not save the changes to this table when Access prompts you to save the changes.
Creating a Table in Design View You could continue to use Application Parts and Data Type Parts to build some of the other tables in the Contact Tracking database to mimic those in Conrad Systems Contacts. However, you’ll find it very useful to learn the mechanics of building a table from scratch, so now is a good time to explore Design view and learn how to build tables without using Application Parts or Data Type Parts. Application Parts offer only a few choices for sample tables, and there is no way to pick and choose which fields to include or exclude. By working in Design view, you’ll see many additional features that you can use to customize the way your tables (and any queries, forms, or reports built on these tables) work when creating a table from scratch. To begin creating a new table in Design view, click the Create tab on the ribbon and then click the Table Design button in the Tables group. Access 2010 displays a blank Table window in Design view, as shown in Figure 4-19.
Defining Fields
187
Chapter 4
Figure 4-19 The Table Design command opens a new table in Design view.
In Design view, the upper part of the Table window displays columns in which you can enter the field names, the data type for each field, and a description of each field. After you select a data type for a field, Access 2010 allows you to set field properties in the lower-left section of the Table window. In the lower-right section of the Table window is a box in which Access displays information about fields or properties. The contents of this box change as you move from one location to another within the Table window. For details about data type values, see “Understanding Field Data Types,” on page 190.
Defining Fields Now you’re ready to begin defining the fields for the Companies table that mimics the one you can find in the Conrad Systems Contacts sample database (Contacts.accdb). Be sure the insertion point is in the first row of the Field Name column, and then type the name of the first field, CompanyID. Press Tab once to move to the Data Type column. A button with an arrow appears on the right side of the Data Type column. Here and elsewhere in Access 2010, this type of button signifies the presence of a list. Click the arrow or press Alt+Down Arrow to open the list of data type options, shown in Figure 4-20. In the Data Type column, you can either type a valid value or select from the values in the list. Select AutoNumber as the data type for CompanyID.
188
Chapter 4 Designing Client Tables
Chapter 4 Figure 4-20 You can choose the data type of a field from a list of data type options.
In the Description column for each field, you can enter a descriptive phrase. Access 2010 displays this description on the status bar (at the bottom of the Access window) whenever you select this field in a query in Datasheet view or in a form in Form view or Datasheet view. For example, enter Unique Company ID in the Description column for the CompanyID field.
Inside Out
Why Setting the Description Property Is Important
Entering a Description property for every field in your table helps document your application. Because Access 2010 also displays the description on the status bar, paying careful attention to what you type in the Description field can later pay big dividends as a kind of mini-help for the users of your database. Also, because this data propagates automatically, you probably don’t want to type something nonsensical or silly. Typing “I don’t have a clue what this field does” is probably not a good idea—it will show up later on the status bar!
Defining Fields
189
Tab down to the next line, enter CompanyName as a field name, and then choose Text as the data type. After you select a data type, Access 2010 displays some property boxes in the Field Properties section in the lower part of the Table window. These boxes allow you to set properties—settings that determine how Access handles the field—and thereby customize a field. The properties Access displays depend on the data type you select; the properties appear with some default values in place, as shown in Figure 4-20. For details about the values for each property, see “Setting Field Properties,” on page 193.
Choosing Field Names Access 2010 gives you lots of flexibility when it comes to naming your fields. A field name can be up to 64 characters long, can include any combination of letters, numbers, spaces, and special characters except a period (.), an exclamation point (!), an accent grave (`), and brackets ([ ]); however, the name cannot begin with a space and cannot include control characters (ANSI values 0 through 31). In general, you should give your fields meaningful names and should use the same name throughout for a field that occurs in more than one table. You should avoid using field names that might also match any name internal to Access or Microsoft Visual Basic. For example, all objects have a Name property, so it’s a good idea to qualify a field containing a name by calling it CustomerName or CompanyName. You should also avoid names that are the same as built-in functions, such as Date, Time, Now, or Space. See Access Help for a list of all the built-in function names. Although you can use spaces anywhere within names in Access 2010, you should try to create field names and table names without embedded spaces. Many Structured Query Language (SQL) databases to which Access can link (notably Oracle and Ingres) do not support spaces within names. Although Microsoft SQL Server does allow spaces in names, you must enclose such names in brackets, or use quotes and execute a Set Quoted Identifier On command. If you ever want to move your application to a client/ server environment and store your data in a SQL database such as SQL Server or Oracle, you’ll most likely have to change any names in your database tables that have an embedded space character. As you’ll learn later in this book, table field names propagate into the queries, forms, and reports that you design using these tables. So any name you decide to change later in a table must also be changed in all your queries, forms, and reports. See “Setting Table Design Options,” on page 226, for details about options to propagate changes automatically.
Chapter 4
190
Chapter 4 Designing Client Tables
Chapter 4
If you use reserved words or function names for field names, Access 2010 catches most of these and displays a warning message. This message warns you that the field name you chose, such as Name or Date, is a reserved word and you could encounter errors when referring to that field in other areas of the database application. Access still allows you to use this name if you choose, but take note of the problems it could cause. To avoid potential conflicts, we recommend you avoid using reserved words and builtin functions for field names.
Understanding Field Data Types Access 2010 supports 11 types of data, each with a specific purpose. You can see the details about each data type in Table 4-1. Access also gives you a 12th option, Lookup Wizard, to help you define the characteristics of foreign key fields that link to other tables. You’ll learn about the Lookup Wizard in Chapter 6, “Designing Web Tables.” Table 4-1 Access Data Types
Data Type
Usage
Size
Text
Alphanumeric data.
Up to 255 characters.
Memo
Alphanumeric data—sentences and paragraphs.
Up to about 1 gigabyte (GB), but controls to display a memo are limited to the first 64,000 characters.
Number
Numeric data.
1, 2, 4, 8, or 16 bytes.
Date/Time
Dates and times.
8 bytes.
Currency
Monetary data, stored with 4 decimal places of precision.
8 bytes.
AutoNumber
Unique value generated by Access for each new record.
4 bytes (16 bytes for ReplicationID).
Yes/No
Boolean (true/false) data; Access 1 byte. stores the numeric value zero (0) for false, and –1 for true.
OLE Object
Pictures, graphs, or other ActiveX objects from another Windowsbased application.
Up to about 2 GB.
Defining Fields
191
Usage
Size
Hyperlink
A link “address” to a document or Up to 8,192 (each part of a Hyperfile on the Internet, on an intranet, link data type can contain up to on a local area network (LAN), or on 2048 characters). your local computer.
Attachment
You can attach files such as pictures, Up to about 2 GB. documents, spreadsheets, or charts; each Attachment field can contain an unlimited number of attachments per record, up to the storage limit of the size of a database file.
Calculated
You can create an expression that uses data from one or more fields. You can designate different result data types from the expression.
Dependent on the data type of the Result Type property. Text data type result can have up to 243 characters. Memo, Number, Yes/No, and Date/ Time should match their respective data types.
Lookup Wizard
The Lookup Wizard entry in the Data Type column in Design view is not actually a data type. When you choose this entry, a wizard starts to help you define either a simple or complex lookup field. A simple lookup field uses the contents of another table or a value list to validate the contents of a single value per row. A complex lookup field allows you to store multiple values of the same data type in each row.
Dependent on the data type of the lookup field.
For each field in your table, select the data type that is best suited to how you will use that field’s data. For character data, you should normally select the Text data type. You can control the maximum length of a Text field by using a field property, as explained later. Use the Memo data type only for long strings of text that might exceed 255 characters or that might contain formatting characters such as tabs or line endings (carriage returns). When you select the Number data type, you should think carefully about what you enter as the Field Size property because this property choice will affect precision as well as length. (For example, integer numbers do not have decimals.) The Date/Time data type is useful for calendar or clock data and has the added benefit of allowing calculations in seconds, minutes, hours, days, months, or years. For example, you can find out the difference in days between two Date/Time values.
Chapter 4
Data Type
192
Chapter 4 Designing Client Tables
Chapter 4
Inside Out
Understanding What’s Inside the Date/Time Data Type
Use the Date/Time data type to store any date, time, or date and time value. It’s useful to know that Access 2010 stores the date as the integer portion of the Date/Time data type and the time as the fractional portion—the fraction of a day, measured from midnight, that the time represents, accurate to seconds. For example, 6:00:00 A.M. internally is 0.25. The day number is actually the number of days since December 30, 1899 (there will be a test on that later!) and can be a negative number for dates prior to that date. When two Date/Time fields contain only a date, you can subtract one from the other to find out how many days are between the two dates.
You should generally use the Currency data type for storing money values. Currency has the precision of integers, but with exactly four decimal places. When you need to store a precise fractional number that’s not money, use the Number data type and choose Decimal for the Field Size property. The AutoNumber data type is specifically designed for automatic generation of primary key values. Depending on the settings for the Field Size and New Values properties you choose for an AutoNumber field, you can have Access 2010 create a sequential or random long integer. You can include only one field using the AutoNumber data type in any table. If you define more than one AutoNumber field, Access displays an error message when you try to save the table. Use the Yes/No data type to hold Boolean (true or false) values. This data type is particularly useful for flagging accounts paid or not paid, or orders filled or not filled. The OLE Object data type allows you to store complex data, such as pictures, graphs, or sounds, which can be edited or displayed through a dynamic link to another Windowsbased application. For example, Access 2010 can store and allow you to edit a Microsoft Word document, a Microsoft Excel spreadsheet, a Microsoft PowerPoint presentation slide, a sound file (.wav), a video file (.avi), or pictures created using the Paint or Draw application. The Hyperlink data type lets you store a simple or complex “link” to an external file or document. (Internally, Hyperlink is a memo data type with a special flag set to indicate that it is a link.) This link can contain a Uniform Resource Locator (URL) that points to a location on the World Wide Web or on a local intranet. It can also contain the Universal Naming Convention (UNC) name of a file on a server on your LAN or on your local computer drives. The link can point to a file that is in Hypertext Markup Language (HTML) or in a format that is supported by an ActiveX application on your computer.
Defining Fields
193
The Attachment data type, introduced in Access 2007, is very similar to the OLE Object data type in that you can use it to store complex data. However, unlike the OLE Object data type, you can store multiple attachments in a single record. These files are stored in a binary field in a hidden system table. OLE objects usually result in database bloat because the files are not compressed, and Access also stores a bitmap thumbnail of the embedded file that can often be larger than the original file. For the Attachment data type, Access compresses each file, if it isn’t already, and uses the original file rather than a generated thumbnail to minimize the amount of database bloat. The Calculated data type, newly introduced in Access 2010, allows you to create a calculated result using an expression. The expression can include data from one or more fields. If you have a number field, for example, that holds quantity information for products purchased and a currency field that holds the price of a product, you can create a calculated field that multiplies the quantity and price fields and stores it with a result type of currency. You could also create a calculated field that concatenates first name, middle name, and last name fields and stores it with a result type of text for a field called Full Name. Access recalculates the value of the calculated field any time the dependent fields are changed.
!
CAUTION
You can use the Attachment and Calculated data types only with databases in the .accdb file type. If you plan to create a database in the older .mdb format and have users with previous versions of Access use this database, you cannot define any fields as Attachment or Calculated.
Setting Field Properties You can customize the way Access 2010 stores and handles each field by setting specific properties. These properties vary according to the data type you choose. Table 4-2 lists all the possible properties that can appear on a field’s General tab in a table’s Design view, and the data types that are associated with each property.
Chapter 4
194
Chapter 4 Designing Client Tables
Table 4-2 Field Properties on the General Tab
Chapter 4
Property
Data Type
Options, Description
Field Size
Text
Text can be from 0 through 255 characters long, with a default length of 255 characters.
Number
Byte. A 1-byte integer containing values from 0 through 255. Integer. A 2-byte integer containing values from –32,768 through +32,767. Long Integer. A 4-byte integer containing values from –2,147,483,648 through +2,147,483,647. Single.1 A 4-byte floating-point number containing values from –3.4 × 1038 through +3.4 × 1038 and up to seven significant digits. Double.1 An 8-byte floating-point number containing values from –1.797 × 10308 through +1.797 × 10308 and up to 15 significant digits. Replication ID.2 A 16-byte globally unique identifier (GUID). Decimal. A 12-byte integer with a defined decimal precision that can contain values from approximately –7.9228×1028 through +7.9228×1028. The default precision (number of decimal places) is 0 and the default scale is 18.
New Values AutoNumber only
Increment. Values start at 1 and increment by 1 for each new row. Random. Access assigns a random long integer value to each new row.
Defining Fields
195
Property
Data Type
Options, Description
Format
Text, Memo
You can specify a custom format that controls how Access displays the data. For details about custom formats, see “Setting Control Properties for Client Forms,” on page 865, or the Access Help topic “Format Property—Text and Memo Data Types.”
Number (except Replication ID), Currency, AutoNumber
General Number (default). No commas or currency symbols; the number of decimal places shown depends on the precision of the data. Currency.3 Currency symbol (from Regional And Language Options in Windows Control Panel) and two decimal places. Euro. Euro currency symbol (regardless of Control Panel settings) and two decimal places. Fixed. At least one digit and two decimal places. Standard. Two decimal places and separator commas. Percent. Moves displayed decimal point two places to the right and appends a percentage (%) symbol. Scientific. Scientific notation (for example, 1.05E+06 represents 1.05 × 106). You can specify a custom format that controls how Access displays the data. For details about custom formats, see “Setting Control Properties for Client Forms,” on page 865, or the Access Help topic “Format Property—Number and Currency Types.”
Date/Time4
General Date (default). Combines Short Date and Long Time formats (for example, 7/1/2010 5:30:10 PM). Long Date. Uses Long Date Style from the Regional And Language Options item in Control Panel (for example, Thursday, July 1, 2010). Medium Date. 1-Jul-2010. Short Date.5 Uses Short Date Style from the Regional And Language Options item (for example, 7/1/2010). Long Time. Uses Time Style from the Regional And Language Options item (for example, 5:30:10 PM). Medium Time. 5:30 PM. Short Time. 17:30.
Yes/No
Yes/No (default) True/False On/Off You can specify a custom format that controls how Access displays the data. For details about custom formats, see “Setting Control Properties for Client Forms,” on page 865, or the Access Help topic “Format Property—Yes/No Data Type.”
Calculated
Format options for calculated fields depend on the Result Type. The format options and defaults for the Result Type align with the other data types.
Chapter 4
196
Chapter 4 Designing Client Tables
Chapter 4
Property
Data Type
Options, Description
Precision
Number, Decimal
You can specify the maximum number of digits allowed. The default value is 18, and you can specify an integer value between 1 and 28.
Scale
Number, Decimal
You can specify the number of digits stored to the right of the decimal point. This value must be less than or equal to the value of the Precision property.
Decimal Places
Number (except Replication ID), Currency, Calculated
You can specify the number of decimal places that Access displays. The default specification is Auto, which causes Access to display two decimal places for the Currency, Fixed, Standard, and Percent formats and the number of decimal places necessary to show the current precision of the numeric value for General Number format. You can also request a fixed display of decimal places ranging from 0 through 15.
Input Mask Text, Number (except Replication ID), Date/ Time, Currency
You can specify an editing mask that the user sees while entering data in the field. For example, you can have Access provide the delimiters in a date field such as __/__/__, or you can have Access format a U.S. phone number as (###) 000-0000. See “Defining Input Masks,” on page 204, for details.
Caption
All
You can enter a more fully descriptive field name that Access displays in form labels and in report headings. (Tip: If you create field names with no embedded spaces, you can use the Caption property to specify a name that includes spaces for Access to use in labels and headers associated with this field in queries, forms, and reports.)
Default Value
Text, Memo, Number, Date/Time, Currency, Hyperlink, and Yes/No
You can specify a default value for the field that Access automatically uses for a new row if no other value is supplied. If you don’t specify a Default Value, the field will be Null if the user fails to supply a value. (See also the Required property.)
Validation Rule
All (except OLE Object, Replication ID, Attachment, Calculated, and AutoNumber)
You can supply an expression that must be true whenever you enter or change data in this field. For example,
Converts to uppercase all characters that follow.
!
Causes the mask to fill from right to left when you define optional characters on the left end of the mask. You can place this character anywhere in the mask.
Defining Fields
Mask Character
Meaning
\
Causes the character immediately following to be displayed as a literal character rather than as a mask character.
"literal"
You can also enclose any literal string in double quotation marks rather than use the \ character repeatedly.
205
An input mask consists of three parts, separated by semicolons. The first part defines the mask string using mask definition characters and embedded literal data. The optional second part indicates whether you want the embedded literal characters stored in the field in the database. Set this second part to 0 to store the characters or to 1 to store only the data entered. The optional third part defines a single character that Access 2010 uses as a placeholder to indicate positions where data can be entered. The default placeholder character is an underscore (_). Perhaps the best way to learn to use input masks is to take advantage of the Input Mask Wizard. In the Companies table of the Contact Tracking database, the PhoneNumber field could benefit from the use of an input mask. Click the PhoneNumber field in the upper part of the Table window in Design view, and then click in the Input Mask property box in the lower part of the window. You should see a small button with three dots on it (called the Build button) to the right of the property box.
Build
Click the Build button to start the Input Mask Wizard. If you haven’t already saved the table, the wizard will insist that you do so. Save the table and name it Companies. When Access 2010 warns you that you have not defined a primary key and asks if you want to create a primary key now, click No. We’ll define a primary key in the next section. On the first page, the wizard gives you a number of choices for standard input masks that it can generate for you. In this case, click the first one in the list—Phone Number, as shown in Figure 4-22. Note that you can type something in the Try It box below the Input Mask list to test the mask.
Figure 4-22 You can choose from several built-in input masks in the Input Mask Wizard.
Chapter 4
206
Chapter 4 Designing Client Tables
Chapter 4
Click Next to go to the next page. On this page, shown in Figure 4-23, you can see the mask name, the proposed mask string, a list from which you select the placeholder character, and another Try It box. The default underscore character (_) works well as a placeholder character for phone numbers.
Figure 4-23 You can choose the placeholder character in the Input Mask Wizard.
Click Next to go to the next page, where you can choose whether you want the data stored without the formatting characters (the default) or stored with the parentheses, spaces, and hyphen separator. In Figure 4-24, we’re indicating that we want the data stored with the formatting characters. Click Next to go to the final page, and then click the Finish button on that page to store the mask in the property setting. Figure 4-25 shows the resulting mask in the PhoneNumber field. You’ll find this same mask handy for any text field that is meant to contain a U.S. phone number (such as the phone number fields in the Contacts table).
Figure 4-24 You can choose to store formatting characters.
Defining Fields
207
Chapter 4
Figure 4-25 The wizard stores the input mask for PhoneNumber based on the criteria you selected.
Note If you look closely at Figure 4-25, you can see a backslash before the area code and quotation marks around the second parenthesis. When you complete the Input Mask Wizard, Access initially does not display these extra characters. After you click off that field or save the table, Access adds the missing characters. The mask generated by the wizard is incorrect, but the table editor fixes it before saving.
!
CAUTION
Although an input mask can be very useful to help guide the user to enter valid data, if you define an input mask incorrectly or do not consider all possible valid values, you can prevent the user from entering necessary data. For example, we just showed you how to build an input mask for a U.S. telephone number, but that mask would prevent someone from entering a European phone number correctly.
208
Chapter 4 Designing Client Tables
Defining a Primary Key Chapter 4
Every table in a relational database should have a primary key. Telling Access 2010 how to define the primary key is quite simple. Open the table in Design view and click the row selector to the left of the field you want to use as the primary key. If you need to select multiple fields for your primary key, hold down the Ctrl key and click the row selector of each additional field that you need. For details about designing primary keys for your tables, see Article 1, “Designing Your Database Application,” on the companion CD.
After you select all the fields you want for the primary key, click the Primary Key button in the Tools group of the Design contextual tab on the ribbon. Access 2010 displays a key symbol to the left of the selected field(s) to acknowledge your definition of the primary key. To eliminate all primary key designations, see “Adding Indexes,” on page 222. When you’ve finished creating the Companies table for the Contact Tracking database, the primary key should be the CompanyID field, as shown in Figure 4-26. Be sure to click the Save button on the Quick Access Toolbar to save this latest change to your table definition.
Figure 4-26 You can define the primary key for the Companies table easily by selecting the field in Design view and clicking the Primary Key button on the ribbon.
Defining a Table Validation Rule
209
The last detail to define is any validation rules that you want Access 2010 to apply to any fields in the table. Although field validation rules get checked as you enter each new value, Access checks a table validation rule only when you save or add a row. Table validation rules are handy when the values in one field depend on what’s stored in another field. You need to wait until the entire row is about to be saved before checking one field against another. One of the tables in the Contact Tracking database—Products—needs a table validation rule. Define that table now using the specifications in Table 4-7. Be sure to define ProductID as the primary key, and then save the table and name it Products. Table 4-7 Field Definitions for the Products Table
Field Name
Data Type
Description
ProductID
AutoNumber
Unique product identifier
Field Size
ProductName
Text
Product description
100
CategoryDescription
Text
Description of the category
50
UnitPrice
Currency
Price
TrialVersion
Yes/No
Is this a trial version?
TrialExpire
Number
If trial version, number of days Long Integer before expiration
To define a table validation rule, be sure that the table is in Design view, and then click the Property Sheet button in the Show/Hide group of the Design contextual tab on the ribbon, shown in Figure 4-27.
Chapter 4
Defining a Table Validation Rule
210
Chapter 4 Designing Client Tables
Chapter 4 Figure 4-27 You can define a table validation rule in the property sheet for the table.
To learn more about expressions, see “Using the Expression Builder,” on page 572.
On the Validation Rule line in the table’s property sheet, you can enter any valid comparison expression, or you can use one of the built-in functions to test your table’s field values. In the Products table, we want to be sure that any trial version of the software expires in 30, 60, or 90 days. Zero is also a valid value if this particular product isn’t a trial version. As you can see in Figure 4-27, we’ve already entered a field validation rule for TrialExpire on the General tab to make sure the TrialExpire value is always 0, 30, 60, or 90—IN (0, 30, 60, 90). But how do we make sure that TrialExpire is zero if TrialVersion is False, or one of the other values if TrialVersion is True? For that, we need to define a table-level validation rule in the table’s property sheet. To refer to a field name, enclose the name in brackets ([ ]), as shown in Figure 4-27. You’ll use this technique whenever you refer to the name of an object anywhere in an expression. In this case, we’re using a special built-in function called Immediate If (or IIF for short) in the table validation rule to perform the test on the TrialExpire and TrialVersion fields.
Defining a Table Validation Rule
211
The IIF function can evaluate a test in the first argument and then return the evaluation of the second argument if the first argument is true or the evaluation of the third argument if the first argument is false. As you will learn in Chapter 24, “Understanding Visual Basic Fundamentals,” on the companion CD, you must separate the arguments in a function call with commas. Note that we said evaluation of the argument—this means we can enter additional tests, even another IIF, in the second and third arguments. In the Products table, you want to make sure that the TrialVersion and TrialExpire fields are in sync with each other. If this is not a trial version, the TrialExpire field value should be zero (indicating the product never expires), and if it is a trial version, TrialExpire must be set to some value greater than or equal to 30. The expression we used to accomplish this is as follows: IIf([TrialVersion]=True,[TrialExpire]>=30,[TrialExpire]=0) Therefore, the first argument uses IIF to evaluate the expression [TrialVersion] = True—is the value in the field named TrialVersion True? If this is true (this is a trial version that must have a nonzero number of expiration days), IIF returns the evaluation of the second argument. If this is not a trial version, IIF evaluates the third argument. Now all we need to do is type the appropriate test based on the true or false result on TrialVersion. If this is a trial version, the TrialExpire field must be 30 or greater (we’ll let the field validation rule make sure it’s exactly 30, 60, or 90), so we need to test for that by entering [TrialExpire] >= 30 in the second argument. If this is not a trial version, we need to make sure TrialExpire is zero by entering [TrialExpire] = 0 in the third argument. Got it? If TrialVersion is True, then [TrialExpire] >= 30 must be true or the validation rule will fail. If TrialVersion is False, then [TrialExpire] = 0 must be true. As you might imagine, once you become more familiar with building expressions and with the available built-in functions, you can create very sophisticated table validation rules. On the Validation Text line of the table’s property sheet, enter the text that you want Access to display whenever the table validation rule is violated. You should be careful to word this message so that the user clearly understands what is wrong. If you enter a table validation rule and fail to specify validation text, Access displays the following message when the user enters invalid data: “One or more values are prohibited by the validation rule ‘< your validation rule expression here >’ set for ‘
’. Enter a value that the expression for this field can accept.” Not very pretty, is it? And you can imagine what the user will say about your IIF expression!
Chapter 4
212
Chapter 4 Designing Client Tables
Understanding Other Table Properties Chapter 4
As you can see in Figure 4-27, Access 2010 provides several additional table properties that you can set in Design view. You can enter a description of the table in the Description property, and you’ll see this description in the Navigation pane if you ask for the Details view. For Default View, you can choose from Datasheet (the default), PivotTable, or PivotChart. You can read more about PivotTable and PivotChart views in Chapter 15, “Advanced Form Design.” The Filter property lets you predefine criteria to limit the data displayed in the Datasheet view of this table. If you set Filter On Load to Yes, Access applies the filter that you defined when you open the datasheet. You can use Order By to define one or more fields that define the default display sequence of rows in this table when in Datasheet view. If you don’t define an Order By property, Access displays the rows in primary key sequence. You can set the Order By On Load property to Yes to request that Access always applies any Order By specification when opening the datasheet.
Note If you apply a filter or specify a sorting sequence when you have the table open in Datasheet view, Access 2010 saves the filter in the Filter property and the sorting sequence in the Order By property. If you have Filter On Load or Order By On Load set to Yes, Access reapplies the previous filter or sort sequence criteria the next time you open the datasheet.
You can find five properties—Subdatasheet Name, Link Child Fields, Link Master Fields, Subdatasheet Height, and Subdatasheet Expanded—that are all related. Access 2000 introduced a feature that lets you see information from related tables when you view the datasheet of a table. For example, in the Contacts Tracking database you have been building, you can set the Subdatasheet properties in the definition of Contacts to also show you related information from ContactEvents or ContactProducts. In the Proseware Housing Reservations sample database, you can see Departments and their Employees, or Employees and their Reservation Requests. Figure 4-28 shows you the Departments table in Housing. accdb open in Datasheet view. For this table, we defined a subdatasheet to show related employee information for each department.
Understanding Other Table Properties
213
Chapter 4
Figure 4-28 The datasheet for the Departments table in the Proseware Housing Reservations sample database shows an expanded subdatasheet.
Notice the small plus and minus signs at the beginning of each department row. Click on a plus sign to expand the subdatasheet to show related employees. Click the minus sign to shrink the subdatasheet and show only department information. Table 4-8 explains each of the Table Property settings that you can specify to attach a subdatasheet to a table. Table 4-8 Table Properties for Defining a Subdatasheet
Property
Setting
Description
Subdatasheet Name
[Auto]
Creates a subdatasheet using the first table that has a many relationship defined with this table.
[None]
Turns off the subdatasheet feature.
Table.name or Query. name
Uses the selected table or query as the subdatasheet.
214
Chapter 4 Designing Client Tables
Chapter 4
Property
Setting
Description
Link Child Fields
Name(s) of the foreign key fields(s) in the related table, separated by semicolons
Defines the fields in the subdatasheet table or query that match the primary key fields in this table. When you choose a table or query for the Subdatasheet Name property, Access uses an available relationship definition or matching field names and data types to automatically set this property for you. You can correct this setting if Access has guessed wrong.
Link Master Fields
Name(s) of the primary key field(s) in this table, separated by semicolons
Defines the primary key fields that Access uses to link to the subdatasheet table or query. When you choose a table or query for the Subdatasheet Name property, Access uses an available relationship definition or matching field names and data types to set this property automatically for you. You can correct this setting if Access has guessed wrong.
Subdatasheet Height
A measurement in inches
If you specify zero (the default), each subdatasheet expands to show all available rows when opened. When you specify a nonzero value, the subdatasheet window opens to the height you specify. If the height is insufficient to display all rows, a scroll bar appears to allow you to look at all the rows.
Subdatasheet Expanded
Yes or No
If you specify Yes, all subdatasheets appear expanded when you open the table datasheet. No is the default.
Inside Out
Don’t Set Subdatasheet Properties in a Table
For a production application, it’s a good idea to set Subdatasheet Name in all your tables to [None]. First, when Access 2010 opens your table, it must not only fetch the rows from the table but also fetch the rows defined in the subdatasheet. Adding a subdatasheet to a large table can affect performance negatively. However, you might find the table and query subdatasheets feature useful in your own personal databases. We’ll show you how to build a query with a subdatasheet in Chapter 10, “Building Complex Queries,” and a form that uses a subdatasheet in Chapter 15.
Defining Relationships
215
You can use the Orientation property to specify the reading sequence of the data in Datasheet view. The default in most versions of Access is Left-to-Right. In versions that support a language that is normally read right to left, the default is Right-to-Left. When you use Right-to-Left, field and table captions appear right-justified, the field order is right to left, and the tab sequence proceeds right to left. The Read Only When Disconnected property by default is set to No, which means you can still update or add new records to a table that is linked to a Microsoft SharePoint Services site when you are offline. We’ll discuss working with data in an Access Services application in Chapter 22, “Using Web Applications in a Browser.”
Defining Relationships After you have defined two or more related tables, you should tell Access 2010 how the tables are related. You do this so that Access 2010 will be able to link all your tables when you need to use them in queries, forms, or reports. Thus far in this chapter, you have seen how to build the main subject tables of the Contact Tracking database—Companies, Contacts, and Products. Before we define the relationships in this sample database, you need to create a couple of linking tables that define the many-to-many relationships between the Companies and Contacts tables and between the Products and Contacts tables. Table 4-9 shows you the fields you need for the Company Contacts table that forms the “glue” between the Companies and Contacts tables. Table 4-9 Field Definitions for the Company Contacts Table
Field Name
Data Type
Description
Field Size
CompanyID
Number
Company/organization
Long Integer
ContactID
Number
Person within company
Long Integer
Position
Text
Person’s position within the company
50
DefaultForContact
Yes/No
Is this the default company for this contact?
Define the combination of CompanyID and ContactID as the primary key for this table by clicking the selection button next to CompanyID and then holding down the Ctrl key and clicking the button next to ContactID. Click the Primary Key button in the Tools group of the Design tab on the ribbon to define the key and then save the table as CompanyContacts. Table 4-10 shows you the fields you need to define the Contact Products table that creates the link between the Contacts and Products tables.
Chapter 4
216
Chapter 4 Designing Client Tables
Table 4-10 Field Definitions for the Contact Products Table
Chapter 4
Field Name
Data Type
Description
Field Size
CompanyID
Number
Company/ organization
Long Integer
ContactID
Number
Related contact
Long Integer
ProductID
Number
Related product
Long Integer
DateSold
Date/Time
Date product sold
SoldPrice
Currency
Price paid
The primary key of the Contact Products table is the combination of CompanyID, ContactID, and ProductID. You can click CompanyID to select it and then hold down the Shift key while you click ProductID (if you defined the fields in sequence) to select all three fields. Click the Primary Key button in the Tools group of the Design tab on the ribbon to define the key, and then save the table as ContactProducts. You need one last table, the Contact Events Table, to define all the major tables you’ll need for Contact Tracking. Table 4-11 shows the fields you need. The primary key for this table is the combination of ContactID and ContactDateTime. Note that we took advantage of the fact that a Date/Time data type in Access 2010 can store both a date and a time, so we don’t need the two separate date and time fields. Save this last table as ContactEvents. Table 4-11 Field Definitions for the Contact Events Table
Field Name
Data Type
Description
Field Size
ContactID
Number
Related contact
Long Integer
ContactDateTime
Date/Time
Date and time of the contact
ContactNotes
Memo
Description of the contact
ContactFollowUpDate
Date/Time
Follow-up date
Now, you’re ready to start defining relationships. To define relationships, first close any Table windows that are open and then click the Relationships command in the Relationships group of the Database Tools tab on the ribbon to open the Relationships window. If this is the first time you have defined relationships in this database, Access 2010 opens a blank Relationships window and opens the Show Table dialog box, shown in Figure 4-29.
Defining Relationships
217
Chapter 4
Figure 4-29 Access displays the Show Table dialog box when you open the Relationships window for the first time.
In the Show Table dialog box, select each table and click Add in turn. Click Close to dismiss the Show Table dialog box.
Defining Your First Relationship A company can have several contacts, and any contact can belong to several companies or organizations. This means that companies have a many-to-many relationship with contacts. Defining a many-to-many relationship between two tables requires a linking table. Let’s link the Companies and Contacts tables by defining the first half of the relationship—the one between Companies and the linking table, CompanyContacts. You can see that for the CompanyID primary key in the Companies table, there is a matching CompanyID foreign key in the CompanyContacts table. To create the relationship you need, click in the CompanyID field in the Companies table and drag it to the CompanyID field in the CompanyContacts table, as shown in Figure 4-30.
218
Chapter 4 Designing Client Tables
Chapter 4 Figure 4-30 Drag the linking field from the “one” table (Companies) to the “many” table (CompanyContacts) to define the relationship between the tables.
You can read about determining the type of relationship between two tables in Article 1, “Designing Your Database Application,” on the companion CD.
When you release the mouse button, Access opens the Edit Relationships dialog box, shown in Figure 4-31.
Figure 4-31 The Edit Relationships dialog box lets you specify the linking fields in two tables.
Inside Out
Creating Relationships from Scratch
You can also click the Edit Relationships command in the Tools group of the Design contextual tab on the ribbon to create a new relationship, but you have to fill in the table and field names yourself. The dragging operation does some of this work for you.
Defining Relationships
219
You’ll notice that Access 2010 has filled in the field names for you. If you need to define a multiple-field relationship between two tables, use the additional blank lines to define those fields. (We’ll do that in just a second.) Because you probably don’t want any rows created in CompanyContacts for a nonexistent company, select the Enforce Referential Integrity check box. When you do this, Access 2010 ensures that you can’t add a row in the CompanyContacts table containing an invalid CompanyID. Also, Access won’t let you delete any records from the Companies table if they have contacts that are still defined. Note that after you select the Enforce Referential Integrity check box, Access 2010 makes two additional check boxes available: Cascade Update Related Fields and Cascade Delete Related Records. If you select the Cascade Delete Related Records check box, Access 2010 deletes child rows (the related rows in the many table of a one-to-many relationship) when you delete a parent row (the related row in the one table of a one-to-many relationship). For example, if you removed a company from the table, Access 2010 would remove the related company contact rows. In this database design, the CompanyID field has the AutoNumber data type, so it cannot be changed once it is set. However, if you build a table with a primary key that is Text or Number (perhaps a ProductID field that could change at some point in the future), it might be a good idea to select the Cascade Update Related Fields check box. This option requests that Access automatically update any foreign key values in the child table (the many table in a one-to-many relationship) if you change a primary key value in a parent table (the one table in a one-to-many relationship). You might have noticed that the Show Table dialog box, shown earlier in Figure 4-29, gives you the option to include queries as well as tables. Sometimes you might want to define relationships between tables and queries or between queries so that Access 2010 knows how to join them properly. You can also define what’s known as an outer join by clicking the Join Type button in the Edit Relationships dialog box and selecting an option in the Join Properties dialog box. With an outer join, you can find out, for example, which companies have no contacts or which products haven’t been sold. For details about outer joins, see “Using Outer Joins,” on page 634.
Chapter 4
220
Chapter 4 Designing Client Tables
Chapter 4
Inside Out
Avoid Defining a Relationship with an Outer Join
We recommend that you do not define an outer join relationship between two tables. As you’ll learn in Chapter 10, Access 2010 automatically links two tables you include in a query design using the relationships that you have defined. In the vast majority of cases, you will want to include only the matching rows from both tables. If you define the relationship as an outer join, you will have to change the link between the two tables every time you include them in a query. We also do not recommend that you define relationships between queries or between a table and a query. If you have done a good job of naming your fields in your tables, the query designer will recognize the natural links and define the joins for you automatically. Defining extra relationships adds unnecessary overhead in your database application.
Click the Create button to finish your relationship definition. Access draws a line between the two tables to indicate the relationship. Notice that when you ask Access to enforce referential integrity, Access displays a 1 at the end of the relationship line, next to the one table, and an infinity symbol next to the many table. If you want to delete the relationship, click the line and press the Delete key. You now know enough to define the additional one-to-many simple relationships that you need. Go ahead and define a relationship on ContactID between the Contacts and CompanyContacts tables to complete the other side of the many-to-many relationship between companies and contacts, a relationship on ContactID between the Contacts and ContactEvents tables, and a relationship on ProductID between the Products and ContactProducts tables. For each relationship, be sure to select the Enforce Referential Integrity check box.
Creating a Relationship on Multiple Fields There’s one last relationship you need to define in the Contact Tracking database between CompanyContacts and ContactProducts. The relationship between these two tables requires multiple fields from each table. You can start by dragging the CompanyID field from the CompanyContacts table to the ContactProducts table. Access 2010 opens the Edit Relationships dialog box, shown in Figure 4-32.
Defining Relationships
221
Chapter 4
Figure 4-32 Select multiple fields in the Edit Relationships dialog box to define a relationship between two tables using more than one field.
When you first see the Edit Relationships dialog box for the relationship you are defining between CompanyContacts and ContactProducts, Access 2010 shows you only the CompanyID field in the two lists. To complete the relationship definition on the combination of CompanyID and ContactID, you must click in the second line under both tables and select ContactID as the second field for both tables, as shown in Figure 4-32. Select the Enforce Referential Integrity check box, as shown, and click Create to define the compound relationship. Figure 4-33 shows the Relationships window for all the main tables in your Contact Tracking database. Notice that there are two linking lines that define the relationship between CompanyContacts and ContactProducts.
Figure 4-33 The Relationships window shows a graphical representation of all the main tables in your Contact Tracking database.
222
Chapter 4 Designing Client Tables
Chapter 4
If you want to edit or change any relationship, double-click the line to open the Edit Relationships dialog box again. If you want to remove a relationship definition, click on the line linking two tables to select the relationship (the line appears highlighted) and press the Delete key. Access 2010 presents a warning dialog box in case you are asking it to delete a relationship in error. Note that once you define a relationship, you can delete the table or query field lists from the Relationships window without affecting the relationships. To do this, click the table or query list header and press the Delete key. This can be particularly advantageous in large databases that have dozens of tables. You can also display only those tables that you’re working with at the moment. To see the relationships defined for any particular table or query, include it in the Relationships window by using the Show Table dialog box, and then click the Direct Relationships button in the Relationships group of the Design contextual tab on the ribbon. To redisplay all relationships, click the All Relationships button in the Relationships group. When you close the Relationships window, Access 2010 asks whether you want to save your layout changes. Click Yes to save the relationships you’ve defined. That’s all there is to it. Later, when you use multiple tables in a query in Chapter 9, “Creating and Working with Simple Queries,” you’ll see that Access 2010 builds the links between tables based on these relationships.
Inside Out
Additional Features in the Relationships Window
You can right-click any table in the Relationships window and then choose Table Design from the shortcut menu to open that table in Design view. You can also click Relationship Report in the Tools group of the Design contextual tab on the ribbon to create a report that prints what you laid out in the window.
Adding Indexes The more data you include in your tables, the more you need indexes to help Access 2010 search your data efficiently. An index is simply an internal table that contains two columns: the value in the field or fields being indexed and the physical location of each record in your table that contains that value. Access 2010 uses an index similarly to how you use the index in this book—you find the term that you want and jump directly to the pages containing that term. You don’t have to leaf through all the pages to find the information you want.
Adding Indexes
223
Let’s assume that you often search your Contacts table by city. Without an index, when you ask Access 2010 to find all the contacts in the city of Chicago, Access has to search every record in your table. This search is fast if your table includes only a few contacts but very slow if the table contains thousands of contact records collected over many years. If you create an index on the City field, Access 2010 can use the index to find more rapidly the records for the contacts in the city you specify.
Single-Field Indexes Most of the indexes you’ll need to define will probably contain the values from only a single field. Access uses this type of index to help narrow the number of records it has to search whenever you provide search criteria on the field—for example, City = Chicago or PostalCode = 60633. If you have defined indexes for multiple fields and provided search criteria for more than one of the fields, Access uses the indexes together (using a technology called Rushmore from Microsoft FoxPro) to find the rows that you want quickly. For example, if you have created one index on City and another on LastName, and you ask for City = Redmond and LastName = Conrad, Access uses the entries in the City index that equal Redmond and matches those with the entries in the LastName index that equal Conrad. The result is a small set of pointers to the records that match both criteria. Creating an index on a single field in a table is easy. Open the Contacts table (which you created earlier using an Application Part) in Design view, and select the field for which you want an index—in this case, City. Click the Indexed property box in the lower part of the Table window, and then click the arrow to open the list of choices, as shown in Figure 4-34.
Figure 4-34 You can use the Indexed property box to set an index on a single field.
Chapter 4
224
Chapter 4 Designing Client Tables
Chapter 4
When you create a table from scratch (as you did earlier in this chapter for the Companies table), the default Indexed property setting for all fields except the primary key is No. If you use an Application Part or a Data Type Part to help create a table (as you did for the Contacts table in this chapter), the Application Part or Data Type Part indexes fields that might benefit from an index. If you followed along earlier using an Application Part to build the Contacts table, you will find that the template built an index only for the ContactID and ZIPPostal fields. Any tables created using an Application Part or Data Type Part could obviously benefit from some additional indexes. If you want to set an index for a field, Access 2010 offers two possible Yes choices. In most cases, a given field will have multiple records with the same value—perhaps you have multiple contacts in a particular city or multiple products in the same product category. You should select Yes (Duplicates OK) to create an index for this type of field. By selecting Yes (No Duplicates), you can have Access 2010 enforce unique values in any field by creating an index that doesn’t allow duplicates. Access 2010 always defines the primary key index with no duplicates because all primary key values must be unique.
Note You cannot define an index using an OLE Object, Attachment, or Calculated field.
Multiple-Field Indexes If you often provide multiple criteria in searches against large tables, you might want to consider creating a few multiple-field indexes. This helps Access 2010 narrow the search quickly without having to match values from two separate indexes. For example, suppose you often perform a search for contacts by last name and first name. If you create an index that includes both of these fields, Access can satisfy your query more rapidly. To create a multiple-field index, you must open the Table window in Design view and open the Indexes window by clicking the Indexes button in the Show/Hide group of the Design contextual tab on the ribbon. You can see the primary key index and the index that you defined on City in the previous section as well as the index defined by the Application Part (ZIP_PostalCode index on the ZIPPostal field). Each of these indexes comprises exactly one field. To create a multiple-field index, move the insertion point to an empty row in the Indexes window and type a unique name. In this example, you want a multiple-field index using the Last Name and First Name fields, so FullName might be a reasonable index name. Select the Last Name field in the Field Name column of this row. To add the other field, skip down to the next row and select First Name without typing a new index name. When you’re done, your Indexes window should look like the one shown in Figure 4-35.
Adding Indexes
Inserting New Rows in the Indexes Window
To insert a row in the middle of the list in the Indexes window, right-click in the Index Name column and then choose Insert Rows from the shortcut menu.
Figure 4-35 The FullName index includes the Last Name and First Name fields.
You can remove an existing single-field index by changing the Indexed property of a field to No on the field’s property list. The only way to remove a multiple-field index is via the Indexes window. To remove a multiple-field index, select the rows (by holding down the Ctrl key as you click each row selector) that define the index and then press Delete. Access 2010 saves any index changes you make when you save the table definition. Access 2010 can use a multiple-field index in a search even if you don’t provide search values for all the fields, so long as you provide search criteria for consecutive fields starting with the first field. Therefore, with the FullName multiple-field index shown in Figure 4-35, you can search for last name or for last name and first name. There’s one additional limitation on when Access can use multiple-field indexes: Only the last search criterion you supply can be an inequality, such as >, >=, = "Bobby" But Access will not use the FullName index shown in Figure 4-35 if you ask for Last Name > "Davolio" And First Name > "John" because only the last field in the search (First Name) can be an inequality. Access also will not use this index if you ask for
Chapter 4
Inside Out
225
226
Chapter 4 Designing Client Tables
First Name = "John" Chapter 4
because the first field of the multiple-field index (Last Name) is missing from the search criterion.
Setting Table Design Options Now that you understand the basic mechanics of defining tables in your desktop database, it’s useful to look at a few options that you can set to customize how you work with tables in Design view. Close any open tables so that all you see is the Navigation pane. Click the File tab on the Backstage view and then click Options to see all the custom settings offered. You can find the first options that affect table design in the Client Settings category, as shown in Figure 4-36. One option that we highly recommend you use is Use Four-Digit Year Formatting, found in the General section. When you enable four-digit year formatting, Access 2010 displays all year values in date/time formats with four digits instead of two. This is important because when you see a value (in two-digit medium date format) such as 15 MAR 12, you won’t be able to tell easily whether this is March 15, 1912 or March 15, 2012. Although you can affect the display of some formats in your regional settings in Control Panel, you won’t affect them all unless you set four-digit formatting in Access.
Figure 4-36 You can find settings that affect table design in the General section in the Client Settings category of the Access Options dialog box.
Setting Table Design Options
227
As you can see in Figure 4-36, you have two options under Use Four-Digit Year Formatting in the General section. If you select the This Database check box, the setting creates a property in the database you currently have open and affects only that database. If you select the All Databases check box, the setting creates an entry in your Windows registry that affects all databases that you open on your computer. In the Current Database category of the Access Options dialog box, you can configure an option that was introduced in Access 2000 called Name AutoCorrect that asks Access to track and correct field name references in queries, forms, and reports. If you select the Track Name AutoCorrect Info check box in the Name AutoCorrect Options section, Access maintains a unique internal ID number for all field names. This allows you to use the Object Dependencies feature explained in Chapter 5. It also allows you to select the next check box, Perform Name AutoCorrect, as shown in Figure 4-37.
Figure 4-37 You can set Name AutoCorrect options in the Current Database category of the Access Options dialog box.
If you select the Perform Name AutoCorrect check box, when you change a field name in a table, Access 2010 automatically attempts to propagate the name change to other objects (queries, forms, and reports) that use the field. However, Track Name AutoCorrect Info requires some additional overhead in all your objects, so it’s a good idea to choose names carefully as you design your tables so that you won’t need to change them later. Note that Access does not attempt to propagate the name change to any Visual Basic code you
Chapter 4
228
Chapter 4 Designing Client Tables
Chapter 4
created in your database. Finally, if you select the Log Name AutoCorrect Changes check box, Access 2010 logs all changes it makes in a table called AutoCorrect Log. You can open this table to verify the changes made by this feature. (Access doesn’t create the table until it makes some changes.) The next category that contains useful settings affecting table design is Object Designers. Click that category to see the settings shown in Figure 4-38.
Figure 4-38 You can find settings that affect table design in the Object Designers category of the Access Options dialog box.
In the Table Design View section, you can set the default field type and the default field size for Text and Number fields. The Default Field Type setting allows you to choose the default data type that Access 2010 selects when you type a new field name in table design and then tab to the Data Type column. When you select a data type of Text (either because it is the default data type or you select the Text data type in a new field), Access will automatically set the length you select in the Default Text Field Size box. When you select a data type of Number, Access sets the number size to your choice in the Default Number Field Size box of Byte, Integer, Long Integer, Single, Double, Decimal, or Replication ID. Use the AutoIndex On Import/Create box to define a list of field name prefixes or suffixes for which Access automatically sets the Index property to Yes (Duplicates OK). In the default list, for example, any field that you define with a name that begins or ends with ID will have an index automatically.
Setting Table Design Options
229
If you select the Show Property Update Options Buttons check box, a smart tag appears that offers to update related properties automatically in queries, forms, and reports when you change certain field properties in a table design. You can see more details about this option in the next chapter. You can find the last option that affects how your tables are stored (and, in fact, all objects in your database) in the General category, as shown in Figure 4-39. When you create a new database in Access 2010, you actually have a choice of three different file formats. These options also appear in the File New Database dialog box, but this setting in the Access Options dialog box controls which file format appears as the default. You should use the Access 2000 format if others with whom you might share this database are still using Access version 9 (2000), or you should use the 2002-2003 format if others sharing this database are still using Access version 10 (2002) or Access version 11 (2003). Selecting the Access 2007 format—used by both Access 2007 and Access 2010—ensures maximum compatibility of what you build in Access with future versions of the product. Note that if you choose to use an older file format, you won’t be able to use some of the new features found only in the .accdb file format, such as Attachment, Multi-Value Field, and Calculated data types.
Figure 4-39 You can select your default database file format in the Creating Databases section of the General category in the Access Options dialog box.
Chapter 4
230
Chapter 4 Designing Client Tables
Creating a Default Template for New Databases Chapter 4
Access 2007 introduced a new feature that allows you to create your own default database template for use with all new blank databases. Rather than set options for each new database after you create it, you can set your preferred options only one time and have those settings apply to each new database. To accomplish this, you first need to open a new blank database from the Backstage view. Click the File tab on the Backstage view and then click the Blank Database command on the New tab to display the Blank Database task pane on the right, as shown in Figure 4-40.
Figure 4-40 The Blank Database task pane appears on the right when you click the Blank Database command.
You must name this new database Blank for this procedure to work. Type Blank in the File Name text box, and then click Browse to open the File New Database dialog box. So that Access 2010 will use this template file for all new databases, you must place this file in a specific subfolder in the Microsoft Office folder. Navigate to the following folder on your system drive by clicking the folder icons in the left pane of the File New Database dialog box: \Program Files\Microsoft Office\Templates\1033\Access, as shown in Figure 4-41. This file path assumes a default installation of the Microsoft Office 2010 system on a 32-bit Windows installation, so your exact file path might be different if you chose a custom installation and selected a different installation path.
Creating a Default Template for New Databases
231
Chapter 4
Figure 4-41 Save the Blank.accdb file in the correct subfolder in the Microsoft Office folder.
Click OK in the File New Database dialog box to return to the New tab on the Backstage view. If you followed the preceding instructions, the Blank Database task pane on the right should look like Figure 4-42. The File Name text box says Blank.accdb, and the path to the correct template location is displayed above the Create button.
Figure 4-42 After you enter the correct name and select the correct location, you’re ready to create your new database template.
232
Chapter 4 Designing Client Tables
!
CAUTION Chapter 4
If you are using Windows Vista or Windows 7, you might not be able to save the Blank. accdb database into the needed template folder. Windows Vista and Windows 7 use User Account Control, which protects critical program folders. If your computer is connected to a domain, you get a prompting dialog box and then you can save to the correct folder. You might need to turn off User Account Control temporarily to save the database into the template folder. If you are in a corporate network environment, you should ask your system administrator for assistance with this procedure.
Click Create, and Access 2010 creates the new file and saves it in the appropriate template folder. By default, Access opens a new blank table called Table1. You do not need this table, so close it and do not save it. Now that you have an empty database with no objects, open the Access Options dialog box by clicking the File tab on the Backstage view and then Options. Select all the options you want to set for any new databases in the various categories of the Access Options dialog box. Included on the companion CD is a database called Blank.accdb that has the Access Options settings that we recommend for new databases. In the Current Database category, in the Name AutoCorrect Options section, we cleared the Track Name AutoCorrect Info check box. In the General section of the Client Settings category, we selected the Use FourDigit Year Formatting and This Database check boxes. We left all other options set to the defaults.
Note You can also open the Visual Basic Editor (VBE) and select Options from the Tools menu to select options that apply to Visual Basic in all new databases. In the sample Blank. accdb database, we selected the Require Variable Declaration check box. We will discuss the VBE Options dialog box in detail in Chapter 24.
After you have defined all the settings you want, close the database and exit Access 2010. Each new blank database you create from the New tab on the Backstage view will now include all the settings you selected for the Blank.accdb file. To make revisions to those settings, open the Blank.accdb file in the template folder and make whatever modifications are necessary. Figure 4-43 shows our Blank.accdb file in the appropriate template folder along with the other local database templates discussed at the beginning of this chapter.
Printing a Table Definition
233
Chapter 4
Figure 4-43 The Blank.accdb file must be located in the same folder as the local database templates.
Creating a custom blank database template saves you time by not having to continually set your personal Access options and VBE options each time you create a new database. In addition to this timesaver, you can also include specific code modules, forms, and any other database objects with new databases. If, for example, you have some common functions and procedures stored in standard code modules that you use in all your database files, you can include them in this Blank.accdb file. Instead of having to manually import these modules into all new databases, Access does all the work for you by including them in new databases. We will discuss creating form templates in Chapter 14. You’ll learn about creating public functions in Chapter 24.
Printing a Table Definition After you create several tables, you might want to print out their definitions to provide a permanent paper record. You can do this by clicking Database Documenter in the Analyze group of the Database Tools tab on the ribbon. Access 2010 displays several options in the Documenter dialog box, as shown in Figure 4-44.
Figure 4-44 You can select the objects you want to document in the Documenter dialog box.
You can select not only the types of objects you want to document but also which objects you want to document. Click Options to select what you want reported. For example, you can ask for the properties, relationships, and permissions for a table; the names, data types, sizes, and properties for fields; and the names, fields, and properties for indexes. Click OK in the Documenter dialog box to produce the report and view it in Print Preview, as shown in Figure 4-45.
Figure 4-45 The Database Documenter previews its reports on your screen.
Database Limitations As you design your database, you should keep in mind the following limitations: ●●
A table can have up to 255 fields.
●●
A table can have up to 32 indexes.
Note Keep in mind that defining relationships with Referential Integrity turned on creates one additional index in each participating table that counts toward the 32-index limit per table.
●●
A multiple-field index can have up to 10 fields. The sum of the lengths of the fields cannot exceed 255 bytes.
●●
A row in a table, excluding memo fields and ActiveX objects, can be no longer than approximately 4 kilobytes (KB).
●●
A memo field can store up to 1 GB of characters, but you can’t display a memo larger than 64 KB in a form or a datasheet.
Note Clearly, if you try to store a 1-GB memo (which requires 2 GB of storage because of double-byte character set support) or a 2-GB ActiveX object in your database file, your file will be full with the data from one record.
●●
An ActiveX object can be up to 2 GB in size.
●●
There is no limit on the number of records in a table, but an Access 2010 database cannot be larger than 2 GB. If you have several large tables, you might need to define each one in a separate Access database and then attach it to the database that contains the forms, reports, macros, and modules for your applications. See Chapter 8, “Importing and Linking Data,” for details.
Now that you’ve started to get comfortable with creating databases and tables, you can proceed to Chapter 5 to learn how to make modifications to existing tables in a database.
c hapte r n C 5o
Chapter Title Modifying Your Table Design
Before You Get Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
o matter how carefully you design your database, you can be sure that you’ll need to change it at some later date. Here are some of the reasons you might need to change your database.
●●
You no longer need some of the tables.
●●
You need to perform some new tasks that require not only creating new tables but also inserting some linking fields in existing tables.
●●
You need to perform some new tasks that require not only creating new tables but also inserting some linking fields in existing tables.
●●
You find that you use some fields in a table much more frequently than others, so it would be easier if those fields appeared first in the table design.
●●
You no longer need some of the fields.
●●
You want to add some new fields that are similar to fields that already exist.
●●
You discover that some of the data you defined would be better stored as a different data type. For example, a field that you originally designed to be all numbers (such as a U.S. ZIP Code) must now contain some letters (as in a Canadian postal code).
237
238
Chapter 5 Modifying Your Table Design
Chapter 5
●●
You have a number field that needs to hold larger values or needs a different number of decimal places than you originally planned.
●●
You can improve your database design by splitting an existing table into two or more tables using the Table Analyzer Wizard.
●●
You discover that the field you defined as a primary key isn’t always unique, so you need to change the definition of your primary key.
●●
You find that some of your queries take too long to run and might execute more quickly if you add an index to your table.
Note The examples in this chapter are based on the tables and data in Housing.accdb and Contacts.accdb on the companion CD included with this book and the Contact Tracking database you built in Chapter 4, “Designing Client Tables.” If you did not create the Contact Tracking database, you can find ContactTracking.accdb in the sample files that you can use to follow along in this chapter. The results you see from the samples you build in this chapter might not exactly match what you see in this book if you have changed the sample data in the files. Also, all the screen images in this chapter were taken on a Windows 7 system with the Access color scheme set to Silver, and Use Windows-Themed Controls on Forms has been turned on in the sample databases.
This chapter takes a look at how you can make these changes easily and relatively painlessly with Microsoft Access 2010. If you want to follow along with the examples in this chapter, you should first create the Contact Tracking database described in Chapter 4.
Note You might have noticed that the Contacts table you defined for the Contact Tracking database in Chapter 4 is different from the tblContacts table in the Conrad Systems Contacts database on the companion CD. In this chapter, you’ll modify the Contacts table you built in Chapter 4 so that it is more like the one on the companion CD. You’ll also learn how to use the Table Analyzer Wizard to help you normalize an existing table that contains data from several subjects.
Before You Get Started
239
Access 2010 makes it easy for you to change the design of your database, even when you already have data in your tables. You should, however, understand the potential impact of any changes you plan and take steps to ensure that you can recover your previous design if you make a mistake. Here are some things to consider before you make changes. ●●
Access 2010 does not automatically propagate changes that you make in tables to any queries, forms, reports, macros, or modules. You must make changes to dependent objects yourself or configure Access to propagate the changes for you. To do so, click the File tab on the Backstage view, click Options, and then in the Current Database category, select the Perform Name AutoCorrect check box. See “Setting Table Design Options,” on page 226, for more details.
●●
You cannot change the data type of a field that is part of a relationship between tables. You must first delete the relationship and then change the field’s data type and redefine the relationship.
●●
You cannot change the definition of any table that you have open in a query, a form, or a report. You must close any objects that refer to the table you want to change before you open that table in Design view. If you give other users access to your database over a network, you won’t be able to change the table definition if someone else has the table (or a query or form based on the table) open.
Inside Out
Access Always Prompts You to Save Your Work
Before saving any changes that permanently alter or delete data in your database, Access 2010 always prompts you for confirmation and gives you a chance to cancel the operation.
Making a Backup Copy The safest way to make changes to the design of your database is to make a backup copy of the database before you begin. If you expect to make extensive changes to several tables in your database, you should also make a copy of the accdb file that contains your database. You could use a utility such as Windows Explorer, but Access 2010 includes a handy feature for making backups easily. When you have the database open that you want to back up, click the File tab on the Backstage view, click the Save & Publish tab, and then click Back Up Database, as shown in Figure 5-1. Access offers to create a copy of your database with the current date appended to the file name.
Chapter 5
Before You Get Started
240
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-1 The Back Up Database command creates a backup of your entire database file.
If you want to change a single table, you can make a backup copy of that table easily, right in your database. Use the following procedure to copy any table—the structure and the data together.
1. Open the database containing the table you want to copy. If the database is already open, make sure the list of tables is showing in the Navigation pane. Click the top of the Navigation pane to open the Navigation Pane menu and click Object Type beneath Navigate To Category. Click the top of the Navigation pane again and then click Tables under Filter By Group, as shown in Figure 5-2, to display only the tables contained in your database.
Before You Get Started
241
Chapter 5
Figure 5-2 Click Object Type and Tables on the Navigation Pane menu to display only the tables in your database.
2. Select the table you want to copy by clicking the table’s name or icon in the Navigation pane. The table name will be highlighted.
3. Click the Copy command in the Clipboard group on the Home tab on the ribbon, as shown in Figure 5-3. This copies the entire table (structure and data) to the Clipboard.
Figure 5-3 Click the Copy command to copy a table from the Tables list.
4. Click the Paste command in the Clipboard group on the Home tab on the ribbon. Access opens the Paste Table As dialog box, shown in Figure 5-4. Type a new name for your table. (When naming a backup copy, you might simply add Backup and the date to the original table name, as shown in Figure 5-4.) The default option is to copy both the structure and the data. (You also have the option of copying only the table’s structure or of appending the data to another table.)
242
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-4 Enter the new name for the copied table in the Paste Table As dialog box.
Checking Object Dependencies If you’re just starting out and learning Access 2010 by reading this book from the beginning, you probably haven’t built anything but tables yet. In Chapter 3, “Access 2010 Overview,” you learned that you can ask Access to show you what queries, forms, and reports are dependent on each table, but the Object Dependencies command in Access won’t provide very interesting results in a database with nothing but tables. You’ll find this tool invaluable later after you have built dozens of objects and then need to make some changes to your tables. As you learned in Chapter 4, you can select options to track and perform Name AutoCorrect for objects by clicking the File tab on the Backstage view, clicking Options, and then selecting the check boxes for these features in the Current Database category. Access 2010 uses this AutoCorrect information not only to correct names automatically but also to provide you with detailed information about which objects depend on one another. If you’re about to make a change to a field in a table, wouldn’t it be good to know which queries, forms, and reports use that table before you make the change? The Perform Name AutoCorrect option will help you if you have selected it, but it can’t always detect and fix field names when you have used them in an expression. You’ll learn more about creating expressions in Chapter 9, “Creating and Working with Simple Queries,” and in the chapters on using Microsoft Visual Basic in Part 8, “Automating an Access Application Using Visual Basic,” on the companion CD. If you would like to see object dependencies in action on your computer, open one of your own databases that contains tables, queries, forms, and reports, or open the Conrad Systems Contacts sample database (Contacts.accdb) that you installed from the companion CD. You can find out which other objects depend on a particular object (such as a table) by selecting the object that you’re planning to change in the Navigation pane and then clicking Object Dependencies in the Relationships group on the Database Tools tab of the ribbon. If you haven’t selected the Track Name AutoCorrect Info option, Access 2010 shows you the dialog box in Figure 5-5.
Before You Get Started
243
Figure 5-5 The Object Dependencies feature tells you it needs to turn on Track Name AutoCorrect Info and examine all objects in your database.
Click OK to turn on Track Name AutoCorrect Info. The Object Dependencies command will take a few seconds or minutes to examine all your objects depending on the number of objects you have in your database. Access shows you the result in the Object Dependencies pane, as shown in Figure 5-6. At the bottom of the Object Dependencies pane, in Figure 5-6, you can see a warning message that some objects were ignored. Access displays this message if there are macros or modules present in your database because macros and modules are not checked for object dependencies. Object Dependencies pane
Figure 5-6 The Object Dependencies pane shows you the list of objects that depend on the object you selected in the Navigation pane.
Chapter 5
244
Chapter 5 Modifying Your Table Design
Chapter 5
Notice that in many cases, you will have to follow a chain of dependencies to find all the objects that might be affected by the change of a field name in a table. For example, in the Conrad Systems Contacts sample database, we use a query (qryContacts) rather than the table (tblContacts) to provide records to the form that edits contact information (frmContacts). If we were to scroll further down the Object Dependencies pane looking for forms dependent on tblContacts, we would not find the form frmContacts listed. You can click the plus sign next to any object name to open an expanded list of dependent objects, as we did with qryContacts in Figure 5-6. Notice that we find frmContacts listed there as a dependent object of qryContacts, which is ultimately dependent on the table we’re thinking about changing. When you find an object that you want to investigate further, you can click the object name in the Object Dependencies pane to open it in Design view. As you can imagine, this command can make maintaining your application much easier. Even if you have selected the Perform Name AutoCorrect option, you can use this tool after you have modified your table to verify that the changes you expect were made.
Deleting Tables You probably won’t need to delete an entire table very often. However, if you set up your application to collect historical information—for example, total product sales by year— you’ll eventually want to delete information that you no longer need. You also might want to delete a table if you’ve made extensive changes that are incorrect and it would be easier to delete your work and restore the table from a backup. To delete a table, select it in the Navigation pane and press the Delete key (or click the Delete command in the Records group on the Home tab of the ribbon). Access 2010 opens the dialog box shown in Figure 5-7, which asks you to confirm or cancel the delete operation.
Inside Out
Access Is Forgiving When You Delete Something by Mistake
Even if you mistakenly confirm the deletion, you can click the Undo command on the Quick Access Toolbar to get your table back. In fact, you can undo up to the last 20 changes that you made in a window—either in the table’s Design view or in the Navigation pane. However, after you save changes to a table design, you will not be able to undo those changes.
Renaming Tables
245
Figure 5-7 This dialog box gives you the option of canceling the deletion of a table.
Inside Out
Using Cut to Move an Object to the Clipboard
You can use the Cut command in the Clipboard group on the Home tab on the ribbon to delete a table. This method moves a copy of the table to the Clipboard. If you open another instance of Access, you can paste the table into a different database from the Clipboard into it. However, if you close the database you deleted the table from, you cannot paste the table into a different database.
If you have defined relationships between the table you want to delete and other tables, Access 2010 displays another dialog box that alerts you and asks whether you want to also delete the relationships. If you click Yes, Access deletes all relationships between any other table and the table you want to delete and then deletes the table. (You can’t have a relationship defined to a nonexistent table.) Even at this point, if you find you made a mistake, you can click Undo on the Quick Access Toolbar to restore both the table and all its relationships.
!
CAUTION
When you undo a table deletion, Access 2010 might not restore all the previously defined relationships between the table and other tables. You should verify the table relationships in the Relationships window.
Renaming Tables If you keep transaction data (such as receipts, deposits, or checks written), you might want to save that data at the end of each month in a table with a unique name. One way to save your data is to rename the existing table (perhaps by adding a date to the name). You can then create a new table (perhaps by making a copy of the backup table’s structure) to start collecting information for the next month.
Chapter 5
246
Chapter 5 Modifying Your Table Design
Chapter 5
To rename a table, right-click it in the Navigation pane and click Rename on the shortcut menu. Access 2010 places the name in edit mode in the Navigation pane so that you can type in a new name, as shown in Figure 5-8. Type the new name, and press Enter to save it.
Figure 5-8 After clicking Rename on the shortcut menu, you can rename a table in the Navigation pane.
Inside Out
Using the Keyboard to Rename an Object
You can also edit the name of the object by selecting it in the Navigation pane and pressing the F2 key. This puts the object name in edit mode so that you can type a new name.
If you enter the name of a table that already exists, Access 2010 displays a dialog box that asks whether you want to replace the existing table, as shown in Figure 5-9. If you click Yes, Access deletes the old table before performing the renaming operation. Even if you replace an existing table, you can undo the renaming operation by clicking the Undo command on the Quick Access Toolbar.
Figure 5-9 This dialog box asks whether you want to replace an existing table with the same name.
Changing Field Names
Renaming Other Access Objects
You can use the techniques you just learned for copying, renaming, and deleting tables to copy, rename, and delete queries, forms, reports, macros, or modules.
Changing Field Names Perhaps you misspelled a field name when you first created one of your tables, or perhaps you’ve decided that one of the field names isn’t descriptive enough. As you learned in Chapter 4, you can change the displayed name for a field by setting its Caption property. But you won’t necessarily want the hassle of giving the field a caption every time it appears in a query, a form, or a report. Fortunately, Access 2010 makes it easy to change a field name in a table—even if you already have data in the table.
Note The next several examples in this chapter show you how to change the Contacts table that you created in the previous chapter to match the tblContacts table in the Conrad Systems Contacts sample database more closely.
You created the first draft of the Contacts table by using an Application Part. Now you need to make a few changes so that it will hold all the data fields that you need for your application. The Contacts Application Part does not give you the option to rename the fields before creating them, but now you decide to rename one of the fields before beginning to work on the rest of your application. Renaming a field is easy. For example, the Application Part created a field called Address, but you’ve decided that you want to have two address fields because a contact could have a work address and a home address in this database. It makes sense to change the field name to reflect the actual data you intend to store in the field, so let’s change Address to WorkAddress. To do this, open the Contacts table in the Contact Tracking database in Design view, use the mouse to move the insertion point to the beginning of the Address field name, and then type Work. You can also click in the field name, use the arrow keys to position the insertion point just before the letter A, and type Work. As you learned in Chapter 4, we recommend that you not have any spaces in your field names, so do not put a space between the
Chapter 5
Inside Out
247
248
Chapter 5 Modifying Your Table Design
Chapter 5
words Work and Address. Your field should now be called WorkAddress. Press F6 to move down to the Field Properties section of the window, tab down to the Caption property, and change the field caption to Work Address. Your result should look like Figure 5-10.
Figure 5-10 You can change a field name and a field caption in Design view.
Comparing the Two Contacts Tables As you follow along with the examples in this chapter, it might be useful to compare the structure of the Contacts table you built in Chapter 4 and the actual tblContacts table in the Conrad Systems Contacts sample database. If you exactly followed the instructions in Chapter 4, your Contacts table in the Contact Tracking database should look like Table 5-1. You can see the actual design of tblContacts in Table 5-2. Table 5-1 Contacts
Field Name
Type
Length
ContactID
AutoNumber
Company
Text
255
LastName
Text
255
FirstName
Text
255
Changing Field Names
Type
Length
EmailAddress
Text
255
JobTitle
Text
255
BusinessPhone
Text
255
HomePhone
Text
255
MobilePhone
Text
255
FaxNumber
Text
255
Address
Text
255
City
Text
255
StateProvince
Text
255
ZipPostal
Text
255
CountryRegion
Text
255
WebPage
Hyperlink
Notes
Memo
Attachments
Attachment
ContactName
Calculated
FileAs
Calculated
Chapter 5
Field Name
Table 5-2 tblContacts
Field Name
Type
ContactID
Auto Number
LastName
Text
Length 50
FirstName
Text
50
MiddleInit
Text
1
Title
Text
10
Suffix
Text
10 50
ContactType
Text
BirthDate
Date/Time
DefaultAddress
Integer
249
WorkAddress
Text
255
WorkCity
Text
50
WorkStateOrProvince
Text
20
WorkPostalCode
Text
20
WorkCountry
Text
50
WorkPhone
Text
30
250
Chapter 5 Modifying Your Table Design
Chapter 5
Field Name
Type
Length
WorkExtension
Text
20
WorkFaxNumber
Text
30
HomeAddress
Text
255
HomeCity
Text
50
HomeStateOrProvince
Text
20
HomePostalCode
Text
20
HomeCountry
Text
50
HomePhone
Text
30 30
MobilePhone
Text
EmailName
Hyperlink
Website
Hyperlink
Photo
Attachment
SpouseName
Text
SpouseBirthDate
Date/Time
Notes
Memo
CommissionPercent
Number
Inactive
Yes/No
75
Double
As you can see, we have a lot of work to do—renaming fields, moving fields, inserting fields, adding new fields, and changing data types and lengths—to make the two tables identical.
Before we go any further, you should rename the remaining fields and add captions so that they more closely match the fields in the tblContacts table in the Conrad Systems Contacts sample database. Following the preceding steps for renaming fields and changing the Caption property, go through each of the fields and change them as follows: Old Name
New Name
Caption
EmailAddress
EmailName
Email Name
JobTitle
Title
Title
BusinessPhone
WorkPhone
Work Phone
FaxNumber
WorkFaxNumber
Fax Number
City
WorkCity
Work City
StateProvince
WorkStateOrProvince State/Province
ZIPPostalCode
WorkPostalCode
Postal Code
Moving Fields
Old Name
New Name
Caption
CountryRegion
WorkCountry
Work Country
WebPage
Website
Website
Attachments
Photo
251
Your table should now look like Figure 5-11. Click the Save button on the Quick Access Toolbar to save the changes to the table.
Figure 5-11 After renaming the fields in the Contacts table created from the template, it is beginning to look more like the table in the Conrad Systems Contacts sample database.
Moving Fields You might want to move a field in a table definition for a number of reasons. Perhaps you made an error as you entered or changed the information in a table, or perhaps you’ve discovered that you’re using some fields you defined at the end of a table quite frequently in forms or reports, in which case it would be easier to find and work with those fields if they were nearer the beginning of your table definition.
Chapter 5
252
Chapter 5 Modifying Your Table Design
Chapter 5
Inside Out
How Important Is the Sequence of Fields in Your Table?
The actual sequence of field definitions in a table is not all that important. In the relational database model, there really is no defined sequence of fields in a row or rows in a table. Access 2010, like most databases that implement the relational model, does allow you to define a field order when you create a table. This order, or sequence of fields, becomes the default order you see in a table datasheet or in a list of field names when you’re designing a query, form, or report. We like to at least group fields together in some reasonable order so that they’re easy to find, and we like to place the primary key fields at the top of the list. There’s really no hard and fast rule that you must follow for your database to work efficiently.
You can use the mouse to move one or more rows. Simply follow these steps.
1. To select a row you want to move, click its row selector. If you want to move multiple contiguous rows, click the row selector for the first row in the group and scroll until you can see the last row in the group. Hold down the Shift key and click the row selector for the last row in the group. The first and last rows and all rows in between will be selected. Release the Shift key.
2. Click and drag the row selector(s) for the selected row(s) to a new location. A small shaded box attaches to the bottom of the mouse pointer while you’re dragging, and a highlighted line will appear, indicating the position to which the row(s) will move when you release the mouse button. In the design for the tblContacts table in the Conrad Systems Contacts database, the EmailName field appears after all the address fields and before the Website field. It certainly makes sense to place all the web-related fields together. Select the EmailName field by clicking its row selector. Click the row selector again, and drag down until the line between the WorkCountry field and the Website field is highlighted, as shown in Figure 5-12.
Moving Fields
253
Chapter 5
Figure 5-12 You can drag the EmailName field to a new position between the WorkCountry and Website fields.
Inside Out
Using the Keyboard Instead of the Mouse in Table Design View
When it comes to moving fields, you might find it easier to use a combination of mouse and keyboard methods in Table Design view. Use the mouse to select the row or rows you want to move. Then activate Move mode by pressing Ctrl+Shift+F8, and use the arrow keys to position the row(s). Press Esc to deactivate Move mode. As you experiment with Access 2010, you’ll discover more than one way to perform many tasks, and you can choose the techniques that work the best for you.
In Figure 5-13, the fields are positioned correctly.
254
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-13 The EmailName field now is placed correctly.
In this exercise, we’ll move a couple of additional fields to make the design of Contacts more similar to tblContacts. In the tblContacts table, the HomePhone and MobilePhone fields appear just before the EmailName field. Click the row selector for HomePhone, hold down the Shift key, and click the row selector for MobilePhone to select both fields. Drag and drop the two fields before the EmailName field. Now that you’ve moved HomePhone and MobilePhone out of the way, you can select both WorkPhone and WorkFaxNumber and drag them to where they belong after the WorkCountry field. Finally, move the Notes field after the Photo field. After you’ve done this, your table should look like Figure 5-14.
Inserting Fields
255
Chapter 5
Figure 5-14 After moving several fields, the sequence of fields in your Contacts table is similar to that in tblContacts.
Inserting Fields Perhaps one of the most common changes you’ll make to your database is to insert a new field in a table. Up until now, we’ve renamed and moved the available fields to match tblContacts more closely. If you take a look at the comparison of the two tables again (Tables 5-1 and 5-2, on pages 248 and 249), you can see that we need to add several more fields. Now you’re ready to insert fields to store the middle initial, suffix, contact type, default address indicator, and more. As you go through adding these new fields, be sure to enter a description for each new field as well as the existing fields. First, select the row or move your insertion point to the row that defines the field after the point where you want to insert the new field. In this case, if you want to insert a field for the middle initial between the FirstName and Title fields, place the insertion point anywhere in the row that defines the Title field. You can also select the entire row by using the arrow keys to move to the row and then pressing Shift+Spacebar or by clicking the row selector. Next, click the Design contextual tab, which is located below Table Tools on the ribbon. Finally, click the Insert Rows command in the Tools group, as shown in Figure 5-15. (You can also click a field row and press the Insert key to insert a row above your selection.)
256
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-15 The Insert Rows command inserts a new row above a selected row or above the row in which the insertion point is located.
Access 2010 adds a blank row that you can use to define your new field. Type the definition for the MiddleInit field. Choose the Text data type, and set the Field Size property to 1. Now move down to the WorkAddress field, and insert another row above it. Enter a Suffix field that has the Text data type with a field size of 10. Do it one more time and insert a ContactType field between Suffix and WorkAddress, set its data type to Text, and set its length to 50. Insert a field between ContactType and WorkAddress, name it BirthDate, and set its data type to Date/Time. Insert another field between BirthDate and WorkAddress, name it DefaultAddress, set its data type to Number, and set the field size to Integer. The actual Conrad Systems Contacts application uses this field to indicate whether the work or home address is the default mailing address. Move down to WorkFaxNumber and insert a field above it. Enter a field name of WorkExtension, set its data type to Text, and set the field size to 20. Now move down to the bottom of the field list and insert another new field above Notes. Enter a field name of SpouseName, set its data type to Text, and set the field size to 75. Insert another row between the SpouseName and Notes fields, enter a field name of SpouseBirthDate, and set its data type to Date/Time. Move down to the ContactName field and insert a field above it. Create a field named CommissionPercent with a data type of Number and a field size of Double. Finally, insert another new field above ContactName named Inactive and set its data type to Yes/No. At this point, your Table window in Design view should look something like the one shown in Figure 5-16. (We entered information in the Description properties of all fields we’re going to keep. You can change your descriptions to match the figure.) Don’t worry about setting other properties just yet. As you can see, we are getting closer to the exact design specifications of tblContacts in the Conrad Systems Contacts database, but we still have more things to change.
Copying Fields
257
Chapter 5
Figure 5-16 The Contacts table with additional fields inserted and descriptions defined.
Inside Out
Using the Keyboard to Move Between Windows
You can move the insertion point between the upper part and the lower part of any Table or Query window in Design view by pressing F6.
Copying Fields As you create table definitions, you might find that several fields in your table are similar. Rather than enter each of the field definitions separately, you can enter one field definition, copy it, and then paste it as many times as necessary. To finish defining our Contacts table, we need five additional fields—HomeAddress, HomeCity, HomeStateOrProvince, HomePostalCode, and HomeCountry. You could insert a new row and type all the properties as you just did in the previous section, but why not copy a field that is similar and make minor changes to it?
258
Chapter 5 Modifying Your Table Design
Chapter 5
For this part of the exercise, select the row for the WorkAddress field definition by clicking the row selector at the left of the row. Click the Copy command in the Clipboard group on the Home tab, as shown in Figure 5-17.
Figure 5-17 Select the WorkAddress field and click the Copy command on the Home tab on the ribbon to copy the field to the Clipboard.
Move the insertion point to the row that should follow the row you’ll insert. (In this case, move the insertion point to the HomePhone field, which should follow your new field.) Insert a blank row by clicking Insert Rows in the Tools group of the Design contextual tab below Table Tools on the ribbon. (In this procedure, you switch back and forth between the Home tab and the Design contextual tab.) Select the new row by clicking the row selector. Click the Paste command in the Clipboard group on the Home tab on the ribbon, as shown in Figure 5-18.
Copying Fields
259
Chapter 5
Figure 5-18 You can paste the copied WorkAddress field into a new blank row.
!
CAUTION
If you click the Paste command when a row containing data is selected, the copied row will replace the selected row. Should you make this replacement in error, click the Undo command on the Quick Access Toolbar to restore the original row.
You can use the Paste command repeatedly to insert a copied row more than once. Remember to change both the name and the description of the resulting field or fields before you save the modified table definition. In this case, it’s a simple matter to change the name of the copied row from WorkAddress to HomeAddress and to correct the description and caption accordingly. Note that this procedure also has the benefit of copying any formatting, default value, or validation rule information. If you’re careful, you don’t actually have to insert a blank row to paste a field definition from the Clipboard. You can also copy and paste multiple fields at a time. After you fix the HomeAddress field name in the upper part of the window and caption in the lower part of the window, select the WorkCity field, hold down the Shift key, and select the WorkCountry field. Click the Copy command to copy all four fields to the Clipboard. Move down to the HomePhone field again and click in the row, but do not select the row. Click the Paste button in the Clipboard group of the Home tab to insert the four fields just above HomePhone. Change the name of the first one to HomeCity, the second to HomeStateOrProvince, the third to HomePostalCode, and the fourth to HomeCountry, and then correct the captions.
260
Chapter 5 Modifying Your Table Design
Chapter 5
You should now have a table that’s almost identical to the tblContacts table in the Conrad Systems Contacts sample database, as shown in Figure 5-19. Be sure to save your changed table.
Figure 5-19 The Contacts field list is now almost identical to tblContacts.
Deleting Fields Removing unwanted fields is easy. With the Table window open in Design view, select the field that you want to delete by clicking the row selector. You can extend the selection to multiple contiguous fields by holding down the Shift key and pressing the Up and Down Arrow keys to select multiple rows. You can also select multiple contiguous rows by clicking the row selector of the first row and, without releasing the mouse button, dragging up or down to select all the rows you want. After you select the appropriate fields, click Delete Rows in the Tools group of the Design tab below Table Tools on the ribbon. Or, press the Delete key to delete the selected fields.
Changing Data Attributes
261
We have three extra fields in our current Contacts table that we do not need—the Company, ContactName, and FileAs fields that were created by the Contacts Application Part. (Remember that in Chapter 3, you created a Company Contacts table to link contacts to their respective companies.) To delete the Company field, click the row selector next to the Company field and then click the Delete Rows button in the Tools group of the Design tab on the ribbon. Access prompts you that calculated columns depend on the Company field. Click Yes to confirm that you want to delete the field. Now move down to the last two fields and also delete the ContactName and FileAs fields from your contacts table. Your Contacts table now matches the tblContacts table from the Conrad Systems Contacts database in terms of the correct number of fields and field names. Save these latest changes to the Contacts table by clicking the Save button on the Quick Access Toolbar. If a table contains one or more rows of data, Access displays a warning message when you delete field definitions in Design view, as shown in Figure 5-20. Click No if you think you made a mistake. Click Yes to proceed with the deletion of the fields and the data in those fields. Keep in mind that you can still undo this change up to the point that you save the table.
Figure 5-20 This dialog box asks you to confirm a field deletion.
If you want to test this in the sample table you have been building, make sure you have saved your latest changes and then switch to Datasheet view by clicking the small arrow below the View button in the Views group on the Home tab and then clicking Datasheet View. Type your name in the Last Name and First Name fields and switch back to Design view by clicking the small arrow below the View button again. Try deleting any field in the design, and Access will warn you that you may be deleting some data as well.
Changing Data Attributes As you learned in the previous chapter, Access 2010 provides a number of different data types. These data types help Access work more efficiently with your data and also provide a base level of data validation; for example, you can enter only numbers in a Number or Currency field. When you initially design your database, you should match the data type and length of each field to its intended use. You might discover, however, that a field you thought would contain only numbers (such as a U.S. ZIP Code) must now contain some letters (perhaps
Chapter 5
262
Chapter 5 Modifying Your Table Design
Chapter 5
because you’ve started doing business in Canada). You might find that one or more number fields need to hold larger values or a different number of decimal places. Access allows you to change the data type and length of many fields, even after you’ve entered data in them.
Changing Data Types Changing the data type of a field in a table is simple. Open the table in Design view, click in the Data Type column of the field definition you want to change, click the arrow button at the right to see the available choices, and select a new data type. You cannot convert an OLE Object, an Attachment, Calculated, or a ReplicationID data type to another data type. With several limitations, Access can successfully convert every other data type to any other data type, even when you have data in the table. Table 5-3 shows you the possible conversions and potential limitations when the table contains data.
!
CAUTION
When the field contents don’t satisfy the limitations noted in Table 5-3, Access 2010 deletes the field contents (sets it to Null) when you save the changes.
Table 5-3 Limitations on Converting One Data Type to Another
Convert To
From
Limitations
Text
Memo
Access truncates text longer than 255 characters.
Hyperlink
Might lose some data if the hyperlink string is longer than 255 characters.
Number, except ReplicationID
No limitations.
AutoNumber
No limitations except ReplicationID.
Currency
No limitations.
Date/Time
No limitations.
Memo
Yes/No
Yes (–1) converts to Yes; No (0) converts to No.
Text
No limitations.
Hyperlink
No limitations.
Number, except ReplicationID
No limitations.
AutoNumber
No limitations.
Currency
No limitations.
Date/Time
No limitations.
Changing Data Attributes
Convert To Hyperlink
Number
263
From
Limitations
Yes/No
Yes (–1) converts to Yes; No (0) converts to No.
Text
If the text contains a valid Hyperlink string consisting of a display name, a # delimiter, a valid link address, a # delimiter, and optional bookmark and ScreenTip, Access changes the data type without modifying the text. If the text contains only a valid link address, Access surrounds the address with # delimiters to form the Hyperlink field. Access recognizes strings beginning with http://, ftp://, mailto:, news:, \\servername, and d:\ as link addresses. Access also assumes that a text string in the form text@ text is an email address, and it adds mailto: to the beginning of the string before converting it. If Access does not recognize the text as a link, it converts the text to [text]#http://[text]#, where [text] is the original contents of the field; the result is probably not a valid link address.
Memo
Same restrictions as converting from Text.
Number, except ReplicationID
Possible, but Access converts the number to a text string in the form [number]#http://[number]#, where [number] is the text conversion of the original numeric value; the result is probably not a valid link address.
AutoNumber
Possible, but Access converts the AutoNumber to a text string in the form [number]#http://[number], where [number] is the text conversion of the original AutoNumber; the result is probably not a valid link address.
Currency
Possible, but Access converts the currency value to a text string in the form [currency]#http://[currency], where [currency] is the text conversion of the original currency value; the result is probably not a valid link address.
Date/Time
Possible, but Access converts the date/time to a text string in the form [date/time]#http://[date/time]#, where [date/time] is the text conversion of the original date or time value; the result is probably not a valid link address.
Yes/No
Possible, but Access converts the yes/no to a text string in the form [yes/no]#- http://[yes/no], where [yes/no] is the text conversion of the original yes (–1) or no (0) value; the result is probably not a valid link address.
Text
Text must contain only numbers and valid separators. The number value must be within the range for the Field Size property.
Memo
Memo must contain only numbers and valid separators. The number value must be within the range for the Field Size property.
Hyperlink
Not possible.
Chapter 5
264
Chapter 5 Modifying Your Table Design
Convert To Chapter 5
From
Limitations
Number (different field size or precision)
Number must not be larger or smaller than can be contained in the new field size. If you change precision, Access might round the number.
AutoNumber
The number value must be within the range for the Field Size property.
Currency
Number must not be larger or smaller than can be contained in the Field Size property.
Date/Time
If the Field Size is Byte, the date must be between April 18, 1899,1 and September 11, 1900. If the new Field Size is Integer, the date must be between April 13, 1810, and September 16, 1989. For all other field sizes, there are no limitations.
Yes/No
Yes (–1) converts to –1; No (0) converts to 0.
AutoNumber Text
Currency
Date/Time
Not possible if the table contains data.
Memo
Not possible if the table contains data.
Hyperlink
Not possible.
Number
Not possible if the table contains data.
Currency
Not possible if the table contains data.
Date/Time
Not possible if the table contains data.
Yes/No
Not possible if the table contains data.
Text
Text must contain only numbers and valid separators.
Memo
Memo must contain only numbers and valid separators.
Hyperlink
Not possible.
Number, except Replication ID
No limitations.
AutoNumber
No limitations.
Date/Time
No limitations, but value might be rounded.
Yes/No
Yes (–1) converts to $1; No (0) converts to $0.
Text
Text must contain a recognizable date and/or time, such as 18-Jul-10 5:15 PM.
Memo
Memo must contain a recognizable date and/or time, such as 18-Jul-10 5:15 PM.
Hyperlink
Not possible.
Number, except Replication ID
Number must be between –657,434 and 2,958,465.99998843.
AutoNumber
Value must be less than 2,958,466 and greater than –657,433.
Currency
Number must be between –$657,434 and $2,958,465.9999.
Changing Data Attributes
Convert To
Yes/No
265
From
Limitations
Yes/No
Yes (–1) converts to 12/29/1899; No (0) converts to 12:00:00 AM.
Text
Text must contain only one of the following values: Yes, True, On, No, False, or Off.
Memo
Text must contain only one of the following values: Yes, True, On, No, False, or Off.
Hyperlink
Not possible.
Number, except Replication ID
Zero or Null converts to No; any other value converts to Yes.
AutoNumber
All values evaluate to Yes.
Currency
Zero or Null converts to No; any other value converts to Yes.
Date/Time
12:00:00 AM or Null converts to No; any other value converts to Yes.
1 Remember, Access stores a date/time value as an integer date offset and fraction of a day. April 18, 1899, happens to be –256 internally, which is the smallest number you can store in a Byte.
If you want to see how this works in the Contacts table you have been building, open the table in Datasheet view and enter any last name and first name in one or two rows. We want to change the EmailName field from the Text data type that the Contacts Application Part provided to Hyperlink. Scroll right and enter an invalid email address in one of the rows in the form: Proseware email address. In another row, add the correct URL prefix in the form: mailto:[email protected]. Now, switch to Design view and change the data type of the EmailName field from Text to Hyperlink and save the change. Notice that Access 2010 gives you no warning about any conversion problems because it knows it can store any text field that is not larger than 255 characters in a hyperlink, which can be up to 8,192 bytes. Save this change to the table, switch back to Datasheet view, and scroll to the right to find the changed field. You should see a result something like Figure 5-21.
Figure 5-21 Access 2010 can convert the Text data type to Hyperlink correctly, but only if the text contains a recognizable protocol string.
Both entries look fine. However, if you click the first one, Access 2010 attempts to open your browser because the full text stored in the hyperlink is Proseware email address#http:// Proseware email address#. Because the link address portion indicates the http protocol, your browser attempts to open instead of your email program. Access displays a message
Chapter 5
266
Chapter 5 Modifying Your Table Design
Chapter 5
box that says it cannot follow the hyperlink. When you click on the second link, it should open a blank message in your email program with the To: line filled in correctly. Access recognized the mailto: prefix and converted the text correctly. You can read more about working with hyperlinks in Chapter 12, “Using Forms in an Access Application.” We show you how to make sure that Access correctly recognizes an email name typed into a hyperlink field in Chapter 25, “Automating Your Application with Visual Basic,” on the companion CD.
Changing Data Lengths For text and number fields, you can define the maximum length of the data that can be stored in the field. Although a text field can be up to 255 characters long, you can restrict the length to as little as 1 character. If you don’t specify a length for text, Access 2010 normally assigns the length you specify in the Table Design section in the Object Designers category of the Access Options dialog box. (The default length is 255.) Access won’t let you enter text field data longer than the defined length. If you need more space in a text field, you can increase the length at any time; but, if you try to redefine the length of a text field so that it’s shorter, you will get a warning message (like the one shown in Figure 5-22) stating that Access will truncate any data field that contains data longer than the new length when you try to save the changes to your table. Note also that it warns you that any validation rules you have designed might fail because of the changed data.
Figure 5-22 This dialog box informs you of possible data truncation problems.
Inside Out
Setting Field Defaults Through Access Options
Remember, you can change the default data type for a new field and the default length of new text and number fields by clicking the File tab on the Backstage view, clicking Options, clicking the Object Designers category of the Access Options dialog box, and then selecting your defaults in the Table Design View section.
Changing Data Attributes
267
If you want to try this in your Contacts table, open it in Design view, change the length of the MiddleInit field to 10, and save the change. Switch to Datasheet view and type more than one character in MiddleInit. Now switch back to Design view and set the length of MiddleInit to 1. When you try to save the change, you should see the error message in Figure 5-22 (because you’re shortening the length of the MiddleInit field). Click Yes to allow the changes and then switch back to Datasheet view. You should find the data you typed truncated to one character in MiddleInit. Review Table 5-2 (on page 249) and verify that each field’s length in your Contacts table matches tblContacts in the Conrad Systems Contacts database and make any necessary adjustments before proceeding further. Sizes for numeric data types can vary from a single byte (which can contain a value from 0 through 255) to 2 or 4 bytes (for larger integers), 8 bytes (necessary to hold very large floatingpoint or currency numbers), or 16 bytes (to hold a unique ReplicationID or decimal number). Except for ReplicationID, you can change the size of a numeric data type at any time, but you might generate errors if you make the size smaller. Access also rounds numbers when converting from floating-point data types (Single or Double) to integer or currency values.
Dealing with Conversion Errors When you try to save a modified table definition, Access 2010 always warns you if any changes to the data type or field length will cause conversion errors. For example, if you change the Field Size property of a Number field from Integer to Byte, Access warns you if any of the records contain a number larger than 255. (Access deletes the contents of any field that it can’t convert at all.) If you examine Table 5-3, you’ll see that you should expect some data type changes to always cause problems. For example, if you change a field from Hyperlink to Date/Time, you can expect Access to delete all data. You’ll see a dialog box, similar to the one shown in Figure 5-23, warning you about fields that Access will set to a Null value if you proceed with your changes. Click Yes to proceed with the changes. You’ll have to examine your data to correct any conversion errors.
Figure 5-23 This dialog box informs you of conversion errors.
If you click No, Access 2010 opens the dialog box shown in Figure 5-24. If you deleted any fields or indexes, added any fields, or renamed any fields, Access will save those changes. Otherwise, the database will be unchanged. You can correct any data type or field length changes you made, and then try to save the table definition again.
Chapter 5
268
Chapter 5 Modifying Your Table Design
Chapter 5
Figure 5-24 This dialog box appears if you decide not to save a modified table definition.
Changing Other Field Properties As you learned in Chapter 4, you can set a number of other properties that define how Access 2010 displays or validates a field that have nothing to do with changing the data type. These properties include Description, Format, Input Mask, Caption, Default Value, Validation Rule, Validation Text, Required, Allow Zero Length, and Indexed. If you have data in your table, changing some of these properties might elicit a warning from Access. If you change or define a validation rule, or set Required to Yes, Access offers to check the new rule or requirement that a field not be empty against the contents of the table when you try to save the change. If you ask Access to test the data, it checks all the rows in your table and opens a warning dialog box if it finds any rows that fail. However, it doesn’t tell you which rows failed—we’ll show you how to do that in Chapter 9. If you changed the rules for more than one field, you’ll see the error dialog box once for each rule that fails. As you’ll learn later, when you define queries, forms, and reports, these objects inherit several of the properties that you define for your table fields. In previous versions of Access before Access 2007, the catch was that once you defined and saved another object that used table fields, any subsequent change that you made to properties in table design didn’t change automatically in other dependent objects. You had to go find those properties yourself and fix them. You would get the new property settings in any new objects you created, but the old ones remained unchanged. The good news is there’s a feature in Access 2010 that takes care of this problem for some properties. To see how this works, you must first make sure that you have this option selected in Access Options as we showed you in the previous chapter. Click the File tab on the Backstage view, click Options, click the Object Designers category, and verify that you have selected the Show Property Update Options Buttons check box. Click OK to close the Access Options dialog box. Next, open the Contacts table in Design view in the Contact Tracking database you have been building. Remember from the previous chapter that Access displays the description on the status bar when the focus is on the Description field in any datasheet or form.
Reversing Changes
269
Click in the Description column next to the ContactID field and change the description from “Unique contact ID” to just “Contact ID,” and then press Tab. As soon as you do this, you’ll see an AutoCorrect smart tag that looks like a lightning bolt. If you rest your mouse pointer near the smart tag, it tells you that it offers property update options. Click the arrow next to the tag to see the options you can choose from, as shown in Figure 5-25. Access offers you these options whenever you change the Description, Format, or Input Mask properties.
Figure 5-25 When you change a field description, you see a smart tag offering property update options.
You can click Update Status Bar Text Everywhere ContactID Is Used to ask Access to change this property wherever the ContactID field is used in other objects as well. Of course, you don’t have anything but tables in your sample database right now, so clicking this command won’t do anything. You can select Help On Propagating Field Properties to open the Help window to read how this works.
!
CAUTION
You must click the Update Status Bar Text Everywhere ContactID Is Used command immediately after you make the change in your table definition. If you move to another field or move to another property and make another change, the smart tag disappears. You can make it reappear by returning to the property you changed and changing it again. If you choose to make changes, Access opens an Update Properties dialog box that lists all the objects it plans to change. You can reject all changes or selectively apply the change to only some of the objects.
Reversing Changes If you make several changes and then decide you don’t want any of them, you can close the Table window without saving them. When you do this, Access opens the dialog box shown in Figure 5-26. Simply click No to reverse all your changes. Click Cancel to return to the Table window in Design view without saving or reversing your changes.
Chapter 5
270
Chapter 5 Modifying Your Table Design
Chapter 5
Figure 5-26 This dialog box gives you the option of reversing unsaved changes to a table.
Inside Out
Reversing Multiple Changes
You can always reverse up to the last 20 changes you made since you last saved the table design by clicking the Undo button. You can also open the list next to the Undo button to undo a series of changes selectively.
Using the Table Analyzer Wizard Even if you use good design techniques (see Article 1, “Designing Your Database Application,” on the companion CD) and build a normalized database, you might not arrive at the best design. In fact, you often cannot fully evaluate a database design until you use the database and store data. Access 2010 includes the Table Analyzer Wizard that can examine data in your tables (or data you import from another source) and recommend additional refinements and enhancements to your database design. One of the key elements of good database design is the elimination of redundant data. The Table Analyzer Wizard is particularly good at scanning data in your tables, identifying data repeated in one or more columns, and recommending alterations to your design that break out the redundant data into separate tables. You can find an example of such redundant data in the Conrad Systems Contacts database (Contacts.accdb). Imagine that a customer sent you a file containing company and contact information. Sounds like a good, easy place to start collecting or adding to your contact data. However, when you open the file, you see that most companies are listed several times because the original data isn’t normalized. You’ll find just such a table, saved as tblContacts4TableAnalyzer, in the Conrad Systems Contacts sample database. You can see how the Table Analyzer Wizard works by using it on the tblContacts4TableAnalyzer table. First, open the Conrad Systems Contacts database. Click the Database Tools tab and then click the Analyze Table command in the Analyze group. Access starts the Table Analyzer Wizard and displays the first window, shown in Figure 5-27.
Using the Table Analyzer Wizard
271
Chapter 5
Figure 5-27 The opening page of the Table Analyzer Wizard informs you about the problems it is designed to correct.
This first page is one of two introductory pages that explain what the wizard can do. Click the Show Me An Example buttons to get a better understanding of the kinds of problems the wizard can solve and to see how the wizard works. Click Next twice to get to the first action page in the wizard, shown in Figure 5-28.
Figure 5-28 Select the table you want to analyze in the Table Analyzer Wizard.
On this page, you select the table you want to analyze. For this exercise, select the tblContacts4TableAnalyzer table. (Note that you have a check box on this page to continue to show the two introductory pages each time you start the wizard. If you think you understand how the wizard works, you can clear the check box to skip the introductory pages the next time you start the wizard.) Click Next.
272
Chapter 5 Modifying Your Table Design
Chapter 5
In the next window, the wizard asks if you want to rearrange the fields in the target table or if you want the wizard to decide the arrangement for you. If you know which fields contain redundant data, you can make the decision yourself. Because the wizard handles all the tedious work of splitting out lookup data, you might choose the latter option in the future to normalize tables in your application further. For now, select the Yes, Let The Wizard Decide option to see how effective it is. Click Next to start the analysis of your table. Figure 5-29 shows the result of the wizard’s analysis. (We’ve shifted the contents of this figure to fit the result in a single window.) Rename Table button
Figure 5-29 The Table Analyzer Wizard examines the data in your table and makes an initial recommendation.
In this case, the wizard did a pretty good job of identifying the separate company and contact information and splitting the fields into two tables. It also recognized that ContactType and Department have lots of repeating values and perhaps should each be in separate lookup tables. There isn’t enough data (only 18 rows—and each contact is related to only one company) in the table for the wizard to have noticed a many-to-many relationship between companies and contacts. We really don’t need to do much work to fix this if we’re happy with the one-to-many relationships. Click the Lookup To Table3 field in Table2 and drag it to Table1 to relate the contact type lookup information to contacts instead of companies. Now move the Department field from Table4 to Table2 between CompanyName and Address. This last move should remove Table4 from the design window. After you have adjusted the way the wizard split your tables, the next step is to give each of the new tables a new name. To rename a table, first click the table name and then click the Rename Table button in the upper part of the window. (You can also double-click the
Using the Table Analyzer Wizard
273
table’s title bar.) The wizard opens a dialog box in which you can enter a new name. You should change Table1 to Contacts, Table2 to Companies, and Table3 to ContactTypes. Click Next when you are finished. The next page asks you to verify the primary key fields for these tables. You can select new fields for the primary key of each table or add fields to the primary key. The wizard couldn’t identify any naturally occurring unique value, so it generated a unique ID (which will be an AutoNumber in the final tables) for two of the tables. You need to select the Contacts table and click Add Generated Key to create a primary key for that table. Figure 5-30 shows the result of moving fields, assigning new names to the tables, and adding a primary key. Click Next to accept the settings and go on to an analysis of duplicate values in the lookup tables. Undo Add Generated Key Set Unique Identifier
Figure 5-30 After adjusting what the wizard proposed, you’re ready to create the new tables.
The Table Analyzer Wizard looks at values in the new tables to try to eliminate any possible duplicates created by typing errors. Figure 5-31 shows the result of this analysis on the sample table. Because the wizard sees several rows with Marketing or Sales in them, it suggests that some of these values might, in fact, be the same. You can use this page to tell the wizard any correct values for actual mistyped duplicates. This could be extremely useful if your incoming data had the same company listed several times but with a slightly different spelling or address. The wizard will store only unique values in the final table. You could, if necessary, tell the wizard to substitute one set of similar values for another to eliminate the near duplicates. In this case, you should tell the wizard to use the original value for all the values listed as duplicates by clicking the arrow in the Correction field and selecting the (Leave As Is) option, as shown in Figure 5-31. Click Next when you are finished to go on to the next page.
Chapter 5
274
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-31 The Table Analyzer Wizard gives you the opportunity to fix potentially duplicate lookup values.
Finally, the wizard offers to create a new query that has the same name as the original table (see Figure 5-32). If you’ve already been using the old table in queries, forms, and reports, creating a new query that integrates the new tables into the original data structure means you won’t have to change any other objects in your database. In most cases, the new query will look and operate just like the original table. Old queries, forms, and reports based on the original table will now use the new query and won’t know the difference.
Figure 5-32 The final page of the Table Analyzer Wizard lets you decide whether you want a query to duplicate the original unnormalized data structure.
Taking a Look at Lookup Properties
275
This is only an example, so select No, Don’t Create The Query. Click Finish to build your new tables. The wizard also creates relationships among the new tables to make sure you can recreate the original data structure in queries easily. Figure 5-33 shows the three new tables built by the wizard.
Figure 5-33 The Table Analyzer Wizard automatically separates your old data into the new table structure.
Notice that the wizard left behind an ID field in the Contacts table as a link to the ContactTypes table. The values in the ContactTypes table are actually unique, so there’s no reason not to use the actual value as the primary key instead of an artificial ID. We’ll show you how to change the primary key later in this chapter.
Taking a Look at Lookup Properties As you have been working with table design, you’ve probably noticed that there’s a Lookup tab available in the lower part of the Table window in Design view. You might have also noticed that Access 2010 offers you a Lookup Wizard entry in the drop-down list of data types and a Modify Lookups option in the Tools group on the Design tab. This feature allows you to predefine how you want the field displayed in a datasheet, form, or report.
Chapter 5
276
Chapter 5 Modifying Your Table Design
Chapter 5
For example, if you have a DepartmentID field in an Employees table that stores the primary key value of the department for which the employee works, you might want to display the department name rather than the number value when you look at the data. If you’re displaying a Yes/No field, you might want to provide a drop-down list that shows options for invoiced and not invoiced instead of yes and no or true and false. In the sample databases, we defined Lookup properties for only a few fields—ones for which we knew that we would later need a combo box with the relevant available choices on one or more forms or reports. (You will also see combo boxes described as drop-down lists.) One such example is in the Housing Reservations sample database (Housing.accdb). Open the database, view the table objects, select tblEmployees, and open it in Design view. Click the DepartmentID field and then click the Lookup tab to see the settings, as shown in Figure 5-34.
Figure 5-34 The DepartmentID field in tblEmployees in the Housing Reservations sample database has Lookup properties defined.
As you can see, we have set the Display Control property to Combo Box. You see combo boxes in Windows applications all the time. It’s a box that you can type in with a button on the right that you can click to drop down a list of values to select. In Access, you tell the
Taking a Look at Lookup Properties
277
combo box what type of list you want (Row Source Type) and specify the source of the list (Row Source). Access is a bit unusual because it lets you define a list that contains more than one column that you can display (Column Count), and it requires you to specify which of the columns (Bound Column) actually supplies the value to be stored when you pick an item from the list. This means that you might see a text value, but the combo box stores a number. You can see this combo box in action by switching to Datasheet view. You can click in the Department field and type a name from the list, or click the arrow on the right and select an item from the list, as shown in Figure 5-35. Remember, DepartmentID is actually a number. If you didn’t define the special settings on the Lookup tab, you would see a list of numbers in the Department column. For details about these settings, see Table 5-4 on page 278.
Figure 5-35 The Lookup tab settings show you a combo box in Datasheet view.
We decided to go ahead and define these properties in this table because we knew we were probably going to use a combo box in one or more forms that we would build later to display related department information while editing an employee record. By setting the values in the table, we can avoid having to define the combo box settings again when we build the forms. If you want to see how this works on a form, you can open frmEmployeesPlain in the Housing Reservations database. (Although you can open the “production” version of frmEmployees from the Navigation pane, code in that form prevents you from updating any data unless you are signed on to the application.) You can see the result in Figure 5-36.
Chapter 5
278
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-36 The table Lookup tab properties were inherited by the combo box on frmEmployeesPlain.
Inside Out
Lookup Tab Settings: For Advanced Users Only
We recommend that only experienced users set the Lookup tab properties of a field in a table’s Design view. Unless you are fully aware of what the settings do, you can have problems later when you look at the information in a datasheet or try to build a query on the table. For example, if you look at the data in tblEmployees, you could mistakenly decide that “Housing Administration” is a valid value in the DepartmentID field. If you try to build a query and filter the DepartmentID field looking for that department name, your query won’t run.
Table 5-4 gives you an overview of what the lookup settings mean. When you study combo box controls later, in Chapter 13, “Building a Form,” you’ll see how you can also use lookup properties to display lists from related tables in a form. In Chapter 13, we’ll also explore the Combo Box Wizard, which makes it easy to correctly define these settings. Table 5-4 Lookup Properties
Lookup Property
Setting
Meaning
Display Control
Check Box (Yes/No fields only), Setting this property to Text Box or Check Text Box, List Box, or Combo Box disables lookups. List Box shows a list Box of values in an open window. Combo Box shows the selected value when closed and shows the available list of values when opened.
Taking a Look at Lookup Properties
Setting
Meaning
PROPERTIES AVAILABLE WHEN YOU SET DISPLAY CONTROL TO LIST BOX OR COMBO BOX
Row Source Type
Table/Query, Value List, or Field List
Table/Query specifies that you want rows from a table or query to fill the list. If you select Value List, you must enter the values you want displayed in the Row Source property, separated by semicolons. The Field List setting shows the names of the fields from the table or query you enter in Row Source—not the data in the rows.
Row Source
Table Name, Query Name, or a list of values separated by semicolons
Use a table name, query name, or enter the text of the query in Structured Query Language (SQL) that provides the list values when Row Source Type is Table/ Query. See Chapters 9 and 10 for details about building queries, and Article 2 on the companion CD for details about SQL. Enter a list of values separated by semicolons when Row Source Type is Value List. Use a table or query name when Row Source Type is Field List.
Bound Column
An integer value from 1 to the Specify the column in the Row Source that number of columns in the Row provides the value stored by the list box or Source combo box.
Column Count An integer value from 1 to 255 This determines the number of columns available to display. (See Column Widths.) When Row Source Type is Value List, this setting determines how many consecutive values that you enter in Row Source make up a logical row. Column Heads No (default) or Yes
Choose Yes to display the field name at the top of any displayed column when you open the list.
Column Widths
Specify a zero width if you do not want the combo box or list box to display the column. It is common not to display an AutoNumber ID field, but you might need that field in Row Source as the bound column.
One width value per column, separated by semicolons
Allow Multiple No (default) or Yes Values
Choose Yes to allow the user to select multiple values from Row Source for each record. Caution: If you set this property to Yes and save the table definition, you cannot change the value back to No later.
Chapter 5
Lookup Property
279
280
Chapter 5 Modifying Your Table Design
Chapter 5
Lookup Property
Setting
Meaning
Allow Value List Edits
No (default) or Yes
Choose Yes to allow the user to add and edit items in the underlying Row Source.
List Item Edit Form
Form Name
Specify the name of a form that Access will open for the user to add items to the Row Source when the user enters a new value that is not in the list specified in Row Source.
Properties That Apply to Combo Boxes Only
List Rows
An integer value between 1 and 255 (default is 16)
Specify how many rows the combo box displays when you open the list. If this setting is less than the number of rows in Row Source, the combo box makes a scroll bar available to move through the list.
List Width
Auto or a specific width
Specify the width of the list when you open it. Auto opens the list the width of the field display.
Limit To List
No (default) or Yes
Choose No to allow the user to enter a value that’s not in the list. When the bound column is not the first displayed column, the combo box acts as though Limit To List is Yes regardless of the setting.
Inside Out
Allowing Space for the Scroll Bar
When we’re designing a combo box that displays multiple columns when dropped down, we always specify a List Width value that’s the sum of the Column Width values plus 0.25 inch to allow for the vertical scroll bar.
Working with Multi-Value Lookup Fields In Chapter 1, “What Is Access?” we introduced you to the concept of complex data. Access 2010 includes a feature (first introduced in Access 2007), called Multi-Value Lookup Fields, to handle complex data. The purpose of lookup fields, as you just learned, is to display one value in a field but actually store a different value. For example, a lookup field could store the company ID in a field for an invoice but display the company name to the user for easier data entry on a form or to show the name on a printed invoice report. Lookup fields in this scenario take the guesswork out of trying to remember a specific company ID number.
Working with Multi-Value Lookup Fields
281
Multi-Value Lookup Fields take this concept a step further by allowing you to store multiple values in a single lookup field. When you define a field as a Multi-Value Lookup Field, Access provides a special control in the Datasheet view of the table similar to a combo box to display the list of valid values. When you drop down the combo box list, you’ll see what looks like a list box that has a check box next to each of the available value choices. Selecting the check box next to one or more of the values stores the selected values in the field. Figure 5-37 shows an example of a Multi-Value Lookup Field in the Conrad Systems Contacts database. Open the Contacts.accdb database and then open the tblContacts table in Datasheet view. Any specific contact could be one or more contact types. The Contact Type field is designated as a Multi-Value Lookup Field, so the user can select from any of the contact types in the database and mark them as related to the current record. In Figure 5-37, you can see that John Viescas is both a developer and a distributor. By selecting the check boxes next to the available contact types, you tell Access to store multiple values for this single record. Notice that after you tab away from this field, Access separates the values with commas.
Figure 5-37 A Multi-Value Lookup Field control allows you to select more than one value for a particular field.
Access also provides the list box control you see in a table in Datasheet view on a form in Form view. Close the tblContacts table and then open the frmContactsPlain form in Form view. In Figure 5-38, you can see the Contact Type field, which displays an arrow on the right side. Clicking the arrow drops down the list with the available choices of contact types.
Chapter 5
282
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-38 Access also provides a Multi-Value Lookup Field control in the frmContactsPlain form of the Conrad Systems Contacts database.
To set up a Multi-Value Lookup Field, you must set the properties in the table in Design view. Close the frmContactsPlain form and then open the tblContacts table in Design view. (Because this is a linked table, Access will warn you that you cannot modify the design. Click Yes in the warning dialog box to open the table design and view the field properties.) Click the ContactType field and then click the Lookup tab under Field Properties to see the settings, as shown in Figure 5-39. The Allow Multiple Values property has been set to Yes, which tells Access that it can store multiple values in this field.
Figure 5-39 Set the Allow Multiple Values property to Yes to enable a field as a Multi-Value Lookup Field.
Changing the Primary Key
283
How Do Multi-Value Lookup Fields Maintain Data Normalization Rules? If you are familiar with data normalization rules, you might be asking yourself how it is possible to store multiple values into a single field and still follow normalization rules. Under the covers and hidden from the standard user interface, Access 2010 actually creates a many-to-many relationship with a hidden join table. All the work of creating this join table and establishing the relationship rules is handled by Access when you set the Allow Multiple Values property to Yes or choose to allow multiple values in the Lookup Wizard. To ensure that only possible related values can be entered into the Multi-Value Lookup Field, Access displays a combo box or list box control containing only the valid related values for data entry. These Multi-Value Lookup Fields allow for better integration with Microsoft SharePoint complex data structures. However, you cannot upsize any table that has a Multi-Value Lookup Field to Microsoft SQL Server. Although Multi-Value Lookup Fields can help novice developers create applications that deal with complex many-to-many relationships in a simple way, we recommend that you learn to create such relationships properly when you need them in your database using the appropriate linking table.
Changing the Primary Key Article 1, “Designing Your Database Application,” on the companion CD, discusses the need to have one or more fields that provide a unique value to every row in your table. This field or group of fields with unique values is identified as the primary key. If a table doesn’t have a primary key, you can’t define a relationship between it and other tables, and Access 2010 has to guess how to link tables for you. Even if you define a primary key in your initial design, you might discover later that it doesn’t actually contain unique values. In that case, you might have to define a new field or fields to be the primary key. Let’s go back to the three tables we built earlier with the Table Analyzer Wizard. Suppose you discover that users are becoming confused by the fact that ContactTypes_ID is a number instead of the actual text. You could keep the lookup table to help avoid duplicate values, but there’s no reason not to store the actual text value in the Contacts table instead of storing a linking ID.
Chapter 5
284
Chapter 5 Modifying Your Table Design
To fix this, you need to perform the following steps. Be sure to save your work at the end of each step. Chapter 5
1. Open the Contacts table in Design view and insert a new field below ContactTypes_ID named ContactType, data type Text, length 50.
2. Update the new ContactType field with related information from the ContactTypes table. We’ll show you how to do this easily with an update query in Chapter 11, “Modifying Data with Action Queries.” For now, you can switch to Datasheet view and copy what you see in the Lookup to ContactTypes field to your new ContactType field. (There are only 18 rows, so this shouldn’t take you very long.)
3. Open the Relationships window and click the All Relationships button in the Relationships group of the Design tab below Relationship Tools so that you can see the additional relationships that the Table Analyzer Wizard built. Click on the line between Contacts and ContactTypes and press the Delete key to remove the relationship. (You must delete any relationship involving the primary key of a table before you can change the key.) Click Yes to confirm this action.
4. Open the Contacts table in Design view and delete the ContactTypes_ID field. 5. Open the ContactTypes table in Design view and change the primary key from ID to ContactType. (You can also select the ID field and delete it if you like.) Access provides several ways for you to accomplish this task. You could open the Indexes window (as you learned in Chapter 4), delete the primary key definition, and build a new one. A simpler way is to select the new field you want as the primary key and then click the Primary Key button in the Tools group of the Design contextual tab below Table Tools, as shown in Figure 5-40.
6. Finally, reopen the Relationships window and define a new relationship between ContactType in the ContactTypes table and your new ContactType field in the Contacts table.
Compacting Your Database
285
Chapter 5
Figure 5-40 Select the new field that will become the primary key and then click Primary Key on the Design tab to define the key.
Keep in mind that you can change the primary key directly for any table that does not have any relationships defined. Also, when the table contains data, the new fields that you choose for a primary key must have unique values in all the rows.
Compacting Your Database As you delete old database objects and add new ones, the space within your .accdb file can become fragmented. The result is that, over time, your database file can grow larger than it needs to be to store all your definitions and data. To remove unused space, you should compact your database periodically. No other users should be accessing the database you intend to compact. You can compact the database you currently have open by clicking the File tab on the Backstage view and then clicking Compact & Repair Database on the Info tab. If you want to compact another database, you must close your current database and then click the Compact & Repair Database command in the Tools group on the Database Tools tab. Access 2010 opens the dialog box shown in Figure 5-41.
286
Chapter 5 Modifying Your Table Design
Chapter 5 Figure 5-41 Click the Compact & Repair Database button in the Tools group on the Database Tools tab to open the dialog box for specifying a database to compact.
Select the database you want to compact, and then click Compact. Access asks you for a name for the compacted database. You can enter the same name as the database you are compacting, or you can use a different name. If you use the same name, Access warns you that the original database of the same name will be replaced. If you proceed, Access compacts your database into a temporary file. When compaction is completed successfully, Access deletes your old database and gives its name to the new compacted copy.
Inside Out
Compacting a Database When You Close It
You can also set an option to compact the database each time you close it. Open your database, click the File tab on the Backstage view, and then click Options. In the Access Options dialog box, select the Current Database category and then select the Compact On Close check box under Application Options. If multiple users are sharing the same database, Access compacts the database when the last user closes it.
You now have all the information you need to modify and maintain your client database table definitions. In Chapter 6, “Designing Web Tables,” you’ll explore how to create and modify tables for web databases.
c hapte r n C 6o
Chapter Title Designing Web Tables
Working with the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Defining a Table Validation Rule for Web Databases. . . 332
Creating a New Web Database. . . . . . . . . . . . . . . . . . . . . . 290
Defining a Primary Key for Web Databases. . . . . . . . . . . 335
Creating Your First Simple Web Table by Entering Data. . 297
Understanding Other Web Table Properties. . . . . . . . . . 336
Creating a Web Table Using Application Parts . . . . . . . . 300
Creating Lookup Fields in a Web Database. . . . . . . . . . . 337
Creating Web Tables in Datasheet View. . . . . . . . . . . . . . 306
Using the Web Compatibility Checker. . . . . . . . . . . . . . . 351
T
he process of defining web tables in a Microsoft Access 2010 web database (.accdb file) is similar to designing client tables in a desktop database. In general, you create the fields you need, assign properties to those fields, and create relationships between the tables. The differences in the process of table creation for web databases lie in the design surface options you can use and the available data types and properties for web fields. In this chapter, we’ll show you how to begin creating your first web application by starting with the tables. You’ll learn how to:
●●
Create a new web database application using a web database template
●●
Create a new empty web database for your own custom application
●●
Create a simple web table by entering data directly in the table
●●
Get a jump start on defining custom web tables by using Application Parts
●●
Create new web fields by using Data Type Parts
●●
Define your own web tables and web fields from scratch by using Datasheet view
●●
Create Calculated fields in your web tables
●●
Set validation rules for your web fields and web tables
●●
Create lookups to other web fields to define relationships between your web tables
●●
Run the Compatibility Checker to verify your fields and tables are web-legal
●●
Prepare a client database for the web
287
288
Chapter 6 Designing Web Tables
Note Chapter 6
All the screen images in this chapter were taken on a Windows 7 system with the Access color scheme set to Silver.
Inside Out
Take Time to Learn About Table Design
At the start of Chapter 4, “Designing Client Tables,” we mentioned the importance of planning up front the tasks you want to perform, the data structures you need to support those tasks, and the flow of tasks within your client database application. The importance of this planning stage is the same when designing a web application. Proper planning at the start of the web application building process can save you from constantly redesigning your application over and over. If you haven’t already, we encourage you to learn at least the fundamentals of table and application design by reading Article 1, “Designing Your Database Application,” that you can find on the companion CD.
Working with the Web The topic of web databases in Access 2010 is a very broad subject—certainly not a topic we can fully cover in just one chapter. In fact, a large portion of the Access development team at Microsoft worked solely on all the various features of web databases during the Access 2010 development cycle. The process of developing a web application is very much the same as developing a client application—you identify the tasks you want to accomplish with the application, chart the flow of tasks, identify the data elements, organize the data elements, design a user interface for the application, construct the application, and then test and refine the application. We’ve organized this book to closely follow the application building process for both client and web databases. We start by building the fields and tables of an application and then continue with building queries, forms, reports, macros, and modules throughout the various chapters. This chapter begins the discussion of developing a web database by starting with creating fields and tables—the foundation of your web application. We’ll continue the discussion of creating a fully functional web database in subsequent chapters. You’ll learn how to create data macros and attach them to table events, create queries to pull out the data you need, create forms and reports that run in a web browser, and how to create macros to automate your web application. In Chapter 22, “Using Web Applications in a Browser,”
Working with the Web
289
we’ll pull everything together and show you how to publish your application to a Microsoft SharePoint 2010 server running Access Services, work with your objects in a web browser, and how to make modifications to your web application. Before we start the discussion of building tables for web databases, we should first discuss some terminology you’ll be hearing throughout this chapter and subsequent chapters to follow. A web database (or web application) is a database that has web tables—tables that will successfully publish to a SharePoint server running Access Services. A web database must be in the .accdb file format and created in Access 2010 or later. A client database is a standard Access database with client tables that you’ve been working with for many Access releases. A client database can be in the .mdb or .accdb file format and can be created in Access 2010 or earlier versions. A web database can have client objects, such as queries, forms, reports, macros, and modules, as well as web objects. Tables are the one exception to this rule. In a web database, you can only have web tables. The tables in a web database, also called the schema of the database, must be compatible with SharePoint server lists. You are allowed to have links to other data sources in a web database because they are not local tables. However, linked tables will not work in your web browser—you will not be able to use the data from those external data sources in your queries, forms, and reports that run in the browser. When a web database contains client objects as well as web objects, Microsoft uses the term hybrid application to describe this type of database. It’s important to note that you don’t need a SharePoint server to use a web database in Access. You can use a web database in Access 2010 and never publish the database to a SharePoint server. The web database will function just fine in Access, and you can continue to modify the application as your needs grow. However, if you want to take advantage of all the extra features that publishing your web database to a server can offer, you’ll need to set up a SharePoint server running Access Services within your business. If you are in a corporate domain, your IT department might already have a SharePoint server installed and running Access Services. You should check with your network administrator to see if this is the case. If you do not want to take the time and expense to setup and install a SharePoint server within your business, you can also use a third party that offers SharePoint hosting services. There are many third party companies, including Microsoft, that can host your Access Services applications. When you publish your web database to a SharePoint server, you can use the application from within Access 2010 and you can use the application within a web browser. When you use or design the database from within Access, Microsoft often uses the term rich client in these discussions. Web databases, as you just learned, can contain web objects as well as client objects. The client objects do not run in the browser, but they will run in Access 2010. When you see the term rich client, we are referring to designing or using the web database from within Access 2010 where you have all the design facilities available to you, including
Chapter 6
290
Chapter 6 Designing Web Tables
Chapter 6
the ability to work with client objects. Access Services on SharePoint does not have any design facilities to modify your web database and the server cannot run or execute something it doesn’t understand. Rich client refers to the fact that Access 2010 has all the rich design and functional capabilities that the server might not have available. If you’re already familiar with creating client databases in previous versions of Access, you’re already well on your way to understanding how to create web databases. In general, the server has less functionality than the rich client so when you are designing web objects, Access 2010 presents design surfaces that only show options, properties, controls, and other design mechanisms that will seamlessly move to the server. We use the term weblegal to describe those objects, controls, properties, etc. that can move successfully to the server.
Creating a New Web Database When you first start Access 2010, you see the New tab on the Microsoft Office Backstage view, as shown in Figure 6-1. We explored the New tab in detail in Chapter 2, “Exploring the Access 2010 Interface,” and in Chapter 4, “Designing Client Tables.”
Figure 6-1 You can see the New tab of the Backstage view when you first launch Access 2010.
Creating a New Web Database
291
Using a Database Template to Create a Web Database Web databases are a new templafeature for Access 2010, so even if you’re an experienced developer, you might find that studying the built-in web application templates will help you understand how to design and work with web databases. You might find that one of these applications meets most of your needs without any modifications. You can also build on and customize the basic web application design and add new features as your application needs grow. On the New tab of the Backstage view, you can access the built-in locally installed web templates by clicking Sample Templates under Available Templates in the middle of the screen. When you click Sample Templates, the center section of the New tab changes to show a graphic representing each of the local database templates available in Access 2010, as shown in Figure 6-2.
Figure 6-2 You can choose to work with any of the five web templates from the Sample Templates section.
Chapter 6
292
Chapter 6 Designing Web Tables
Chapter 6
Access 2010 includes over 10 locally installed database templates, five of which are web templates—Assets, Charitable Contributions, Contacts, Issues, and Projects. You can differentiate which templates under Sample Templates are web templates by looking for the world icon in the template graphic and by the word Web included in the file name. When you click one of the web template graphics in the center of the New tab, Access displays the file name and a larger graphic in the right task pane. Click the Projects Web Database template in the middle of the screen to see the file name and graphic for the Projects Web Database Template, as shown in Figure 6-2. You can work with all five local web templates from the New tab in the same way. This example will show you the steps that are needed to build a Projects web database. Access suggests a name for your new web database in the File Name text box and a location to save the file beneath the File Name text box. You can modify the name of this web database by typing in the File Name text box. If you want to change the suggested save location, click Browse to open the File New Database dialog box, as shown in Figure 6-3.
Figure 6-3 Use the File New Database dialog box to select a folder for saving the new local web database template.
Creating a New Web Database
293
You can select the drive and folder you want by clicking the links on the left and browsing to your destination folder. After you select the specific folder to which you want to save this new web database, click OK to return to the New tab on the Backstage view. Your new folder location is shown beneath the File Name text box. If you decide at this point not to create the web database, click the Home button near the top of the screen to return to the main Home page of the New tab to stop the process. Click Create to start the template instantiation process. A progress bar appears on the screen informing you to please wait while Access creates the web template. After a few seconds of preparation, Access opens the new Projects web database and displays the Login form, as shown in Figure 6-4.
Figure 6-4 After you create the Projects web database from a template, Access opens the database and displays the Login form.
Dismiss this Login form for now by clicking the X button in the upper-right corner of the form window. After you close this form, Access displays the Main navigational form for the Projects web database, as shown in Figure 6-5.
Chapter 6
294
Chapter 6 Designing Web Tables
Chapter 6 Figure 6-5 When you close the Login form, Access displays the Main navigational form in the Projects web database.
This Projects web database is a complete application that can track the progress of your various projects. The database comes with tables, queries, forms, reports, and macros. We’ll discuss all the form elements you are currently looking at beginning in Chapter 12, “Using Forms in an Access Application.” For now, close this form by clicking the X button in the upper-right corner of the form window or by right-clicking the Main tab and clicking Close Form on the shortcut menu. Expand the Navigation pane now to see all the various objects contained in this database, as shown in Figure 6-6.
Creating a New Web Database
295
Chapter 6
Figure 6-6 The Projects web database contains many web objects to track the status of your various projects.
In a web database, like the Projects one here, any web objects—tables, queries, forms, reports, and macros—have a globe on the object icon to indicate they are web objects. In this Projects web database, as well as the other four built-in local web templates, all objects are web objects which means they will publish and render in a web browser. You can also use this application in Access client if you do not want to publish to a SharePoint server. We’ll discuss designing and working with all the various web queries, forms, reports, and macros in later chapters. For now, close this new web database by clicking the File tab on the Backstage view and then clicking Close Database to return to the New tab.
Creating a New Empty Web Database To begin creating a new empty web database when you start Access 2010, go to the Available Templates section in the middle of the New tab (as shown in Figure 6-1) and click Blank Web Database. The right side of the New tab changes to display the Blank Web Database task pane, as shown in Figure 6-7.
296
Chapter 6 Designing Web Tables
Chapter 6 Figure 6-7 From the New tab on the Backstage view, click Blank Web Database to open the Blank Web Database task pane on the right.
You can click Browse to open the File New Database dialog box, shown in Figure 6-3, to select the drive and folder you want. In this example, we selected the Documents folder in Windows 7 for the current user. Next, type the name of your new database in the File Name text box—Access 2010 appends an .accdb extension to the file name for you. For this example, let’s create a database with a table containing employee names and addresses. Type Employees Web in the File Name box and click Create to create your web database. Access 2010 takes a few moments to create the system tables in which to store all the information about the tables, queries, forms, reports, and macros that you might create. Access then displays the Navigation pane for your new web database and opens a new blank web table in Datasheet view, shown in Figure 6-8.
Creating Your First Simple Web Table by Entering Data
297
Chapter 6
Figure 6-8 Access 2010 opens a new web table in Datasheet view when you create a new blank web database.
Because this is a new web database and no objects or special startup settings exist yet, you see a Navigation pane with only one object defined. For new web databases, Access, by default, creates a new web table in Datasheet view called Table1 with an ID field already defined. However, Access has not saved this table, so if you do not make any changes to it, Access will not prompt you to save the table if you close it. The following sections show various methods for creating a new table.
Creating Your First Simple Web Table by Entering Data If you’ve been following along to this point, you should still have your new Employees Web database open with Table1 open in Datasheet view, as shown in Figure 6-8. (You can also follow these steps in any open web database.) Access 2010 automatically created the first web field, called ID, in the left column. Leave this web field intact for now. In the second column, Access has placed another web field with the Add New Field heading. Just like client tables, you can enter just about any type of data you want in this web field—text, dates, numbers, or currency.
298
Chapter 6 Designing Web Tables
Chapter 6
Let’s start with a simple list of employee names so you can become more comfortable working in Datasheet view with web tables. For this quick example, we’ll only need two columns containing the employee’s first name and last name. Be sure to enter the same type of data in a particular column for every row. For example, enter Jeff’s and John’s last names in the third column (named Field2 by Access) for every row. You can see some of the data entered for the employee list in Figure 6-9. Access behaves the same in this situation for web fields and tables just as it does for client fields and tables. When you start to type in a web field in a row, Access displays a pencil icon on the row selector at the far left to indicate that you’re adding or changing data in that row. Press the Tab key to move from column to column. When you move to another row, Access saves what you typed. If you make a mistake in a particular row or column, you can click the data you want to change and type over it or delete it. Notice that after you enter data in a column, Access guesses the most appropriate data type and displays it in the Data Type box in the Formatting group of the Fields tab on the ribbon.
Figure 6-9 You can create the employee list table by entering data.
If you create a column of data that you don’t want, click anywhere in the column and click Delete in the Add & Delete group of the Fields contextual tab on the ribbon. Click Yes when Access asks you to confirm the deletion. If you want to insert a blank column between two columns that already contain data, right-click the column header to the right of where you want to insert the new column and then click Insert Field from the shortcut menu that appears. To move a column to a different location, click the field name at the top of the column to select the entire column, and then click again and drag the column to a new location. You can also click an unselected column and drag your mouse pointer through several adjacent columns to select them all. You can then move the columns as a group. Access named your columns Field1 and Field2 just as it does if you are creating client tables in Datasheet view. You can change the name of a field by highlighting the column and then clicking the Name & Caption command in the Properties group on the Fields tab. Access opens the Enter Field Properties dialog box, as shown in Figure 6-10. In this dialog box, you can enter the field name you want to use in the Name text box, the field caption in the
Creating Your First Simple Web Table by Entering Data
299
Caption text box, and the field description in the Description text box. Note that for web tables, the Enter Field Properties dialog box is your only entry point in the user interface to set and update the field caption and field description for your web fields.
Figure 6-10 The Enter Field Properties dialog box allows you to change the name, caption, and description for your web fields.
Note Just as with client tables in Datasheet view, you can change the name of a column by double-clicking the column’s field name or right-clicking a column header and then clicking Rename Field from the shortcut menu that appears.
After you enter several rows of data, it’s a good idea to save your table. You can do this by clicking the Save button on the Quick Access Toolbar or by clicking the File tab and then clicking Save. Access 2010 displays a Save As dialog box, as shown in Figure 6-11.
Figure 6-11 Access 2010 displays the Save As dialog box when you first save a new web table so that you can specify a table name.
Chapter 6
300 Chapter 6 Designing Web Tables
Choosing Web Table Names Chapter 6
Access 2010 gives you lots of flexibility when it comes to naming your web tables; however, there are some restrictions to be aware of. A web table name can be up to 64 characters long, can include any combination of letters, numbers, spaces, and special characters except a period (.), exclamation point (!), square brackets ([]), leading space, leading equal sign (=), or nonprintable character such as a carriage return. The name also cannot contain any of the following characters: / \ : ; * ? “” < > | # { } % ~ &. In general, you should give your web tables meaningful names. You cannot name your web tables the same as any built-in SharePoint list names that Access Services uses to maintain your site. Specifically, you cannot use any of the following web table names: Lists, Docs, WebParts, ComMd, Webs, Workflow, WFTemp, Solutions, Report Definitions, or AppImages.
Creating a Web Table Using Application Parts If you were to look in the Contacts Map sample web database (ContactsMap.accdb) included on the companion CD, you’ll find it to be very simple, with one main table to store contact information. Most databases are usually quite a bit more complex. For example, the built-in Projects sample web template you saw earlier in this chapter contains five main tables, and the Back Office Software System sample web database (BOSS.accdb) included on the companion CD contains nearly two dozen tables. If you had to create every web table manually, it could be quite a tedious process. Fortunately, Access 2010 comes with a new feature called Application Parts to help you build a few common web tables and other web database objects. In Chapter 4, we first introduced you to this new feature when we discussed creating client tables. The good news with this feature is that you can also use Application Parts when creating web fields, web tables, and other web objects. In this section, we’ll show you another feature with Application Parts that we did not discuss in Chapter 4—using Application Parts to create lookup fields with relationships to other web tables. To complement the simple employee web table you created previously, it would be helpful to create another web table that can track any issues assigned to the employees. To build this second web table using one of the Application Parts, close the employees table if you still have it open, click the Create tab on the ribbon, and then click the Application Parts button in the Templates group. Access displays a list of 10 form types under the Blank Forms category and five Application Parts under the Quick Start category, as shown in Figure 6-12. Microsoft uses the term Models to refer to this one-click object creation feature. You’ll learn more about using the 10 form Application Parts in Chapter 13, “Building a Form.”
Creating a Web Table Using Application Parts
301
Chapter 6
Figure 6-12 Application Parts help you create common types of web database objects.
When you are using the five Application Parts under Quick Start in a web database, Access creates the same fields, tables, and objects as it does for a client database. The only difference when creating these objects in a web database is that Access marks everything as a web object. The five web Application Parts under Quick Start, which represent some of the more common types of web table structures and objects found in databases, are Comments, Contacts, Issues, Tasks, and Users. See “Creating a Table Using Application Parts,” on page 178, for a description of each of these Application Parts. Click Issues in the Quick Start list, and Access opens the Create Relationship wizard, as shown in Figure 6-13. Whenever you select to build an Application Part under Quick Start in a database that already includes at least one existing table, Access displays the Create Relationship wizard to see if you want to create a relationship between one of your existing tables and the new table. In this case, Access identified the existing employees table you created earlier and now asks if you want to build a relationship with the new Issues table Access is about to create.
302
Chapter 6 Designing Web Tables
Chapter 6 Figure 6-13 Use the Create Relationship wizard to help create relationships between tables through Application Parts.
On the first page of the Create Relationship wizard, Access displays three options. Next to the first two options, Access displays combo boxes that list all the existing saved tables in your database. Above these combo boxes, Access displays text to help identify how it will create the relationship between the two tables. If you select either of these two first options, Access creates a one-to-many relationship between the selected table in the combo box and the new issues table Access will create. Select the first option if you want Access to create a new lookup field in the issues table, representing the many part of the relationship. (We’ll discuss more about lookup fields and relationships in web tables later in this chapter.) Select the second option if you want Access to create a new lookup field in the selected table, representing the many part of the relationship. You can choose to select a different table in the combo boxes; by default, Access displays the tables in alphabetical order. Select the third option if you do not want Access to create a relationship between the new issues table and any existing table. Note that if you choose this option, Access does not create an additional lookup field in any tables. For your example, we want to have the employees table (tblEmployees) represent the one side of the relationship and the issues table represent the many side of the relationship— each employee can have many issues assigned to them. Select the first option and leave the default tblEmployees selected in the combo box. (We only have one existing table in this sample database so you don’t need to change any settings on the first page of the wizard.) Click Next to move to the second page of the wizard, as shown in Figure 6-14.
Creating a Web Table Using Application Parts
303
Chapter 6
Figure 6-14 Select options for the lookup field on the second page of the wizard.
On the second page of the wizard, Access displays options where you can customize the new lookup field in the issues table. In the first combo box, Access displays a list of field names from the table you selected on the first page of the wizard. Access displays the field you choose here as the drop-down list of options in the new lookup field. Select FirstName in this combo box, selected by default, to display the first name of each employee in the lookup field. The second option, Sort This Field, allows you to sort the values of the field you selected in the first combo box option. You can choose Sort Ascending, Sort Descending, or None (the default) to sort the values. Select Sort Ascending, for this example, to sort the first names in ascending order. In the third option, enter the name of your new lookup field in the text box provided (AssignedTo, for our example). The last option on this page of the wizard—Allow Multiple Values—tells Access to create a Multi-Value Lookup Field. We don’t want to assign issues to more than one employee, so leave this option cleared. Note that if you selected There Is No Relationship on the first page of the wizard, you won’t see the second page of the wizard.
Note If you click Cancel on either page of the Create Relationship wizard, Access immediately closes the wizard but does not cancel the creation of the objects associated with the Application Part you selected. Access, in this case, still continues the process of creating the objects but does not create any lookup fields in the tables representing relationships.
304
Chapter 6 Designing Web Tables
Chapter 6
Click Create and Access builds a complete table structure for an issues web table, as well as other supporting objects. Open the Issues table and notice Access created 13 fields to identify the data elements for this Issues table, as shown in Figure 6-15. This Issues Application Part includes fields such as AssignedTo (your new lookup field), Summary, Status, Priority, Category, Project, Opened Date, Resolution, and so on to identify a single subject—an issue. The Issues Application Part also automatically defines a data type for each of these fields. Notice, in Figure 6-15, that if you click the drop-down list in the AssignedTo lookup field, you can see the first names of the employees from the tblEmployees table.
Figure 6-15 The Issues command under Quick Start builds a complete table with appropriate field types and supporting objects.
You can save time creating a web table by using an Application Part even if the table structure Access creates does not exactly match your needs. You can rename fields, add new fields, and delete unneeded fields to customize the table to your specific application needs. When you use an Application Part to help you create a web table, you also get the added benefit of Access creating other supporting objects to work with that table. Close the Issues table window now so you can continue with the next section.
Using Data Type Parts In Chapter 4, you learned about the new feature in Access 2010, called Data Type Parts, which assist you in creating fields in your tables. Similar to Application Parts, Data Type Parts help give you a jump start on creating your application. Data Type Parts create individual fields or groups of fields in existing tables. As you design more web databases, you
Using Data Type Parts
305
might find yourself needing to create similar field structures in your tables. For example, you’ll probably find yourself needing to have fields in at least one table that track address information such as street address, city, state, and ZIP code. Fortunately, this new feature in Access 2010 can also be used when you are creating web tables. However, you only have the Quick Start options for Data Type Parts available for web tables. If you’ve been following along to this point, you should still have your test web database open with the tblEmployees web table, Issues web table, and supporting two forms in the Navigation pane. To create fields using one of the Data Type Parts, you first need to have a table opened in Datasheet view. Select the tblEmployees web table you created earlier in the Navigation pane, open it in Datasheet view, and then put your cursor in the Click To Add empty field to the right of the LastName field. Click the More Fields button in the Add & Delete group on the Fields tab, and Access displays various field types, as shown in Figure 6-16.
Figure 6-16 Click More Fields to see the Data Type Parts you can use to create groups of web fields.
Under the Basic Types category, Access displays four field types you can use in your web table—Attachment, Hyperlink, Memo, and Lookup & Relationship. You’ll be creating these types of fields later in this chapter. Beneath the Quick Start category, you can see a list of the nine Data Type Parts—Address, Category, Name, Payment Type, Phone, Priority, Start And End Dates, Status, and Tag. These are the same Data Type Parts you can use in client tables, except in this case, Access creates web fields because you are using a web database. See “Creating a Table Using Data Type Parts,” on page 182, for a description of each of these Data Type Parts.
Chapter 6
306
Chapter 6 Designing Web Tables
Chapter 6
Click Address under the Quick Start category and Access creates five fields to hold address information ready for you to use in your employees table, as shown in Figure 6-17. You can add additional Data Type Parts to your web table by clicking another option under the Quick Start category. If you want any new Data Type Part fields to appear at the end of your web table (as you saw with the address fields you just created), make sure to set the focus in the Click To Add empty field at the far right. Access always adds new Data Type fields to the left of where the current focus is located in the Datasheet view grid.
Figure 6-17 Use the Address Type Part when you need to create fields to track address information.
Using Data Type Parts can save you time when you’re designing your web tables in Access 2010, just like for client tables, by giving you a jump start on creating common field types. Close the Table window now and do not save the changes to this table when Access prompts you to save the changes. You can now close this database to begin the next section.
Creating Web Tables in Datasheet View You could continue to use Data Type Parts and Application Parts to build web fields and other web tables. However, you’ll find in most cases, you need to create your web schema from scratch to meet your specific application needs. Even if you’re already very familiar with creating new client tables in Design View, you’ll find it necessary to learn the mechanics of building a web table from scratch in Datasheet view because Design view is not available for web objects. You can only use Datasheet View to design web tables. By learning how to create web tables in Datasheet view, you can also use that knowledge to design client tables in Datasheet view. To begin creating a new web table in Datasheet view, let’s start with a new, empty web database. Click the Blank Web Database button on the New tab of the Backstage view, name your new web database Restaurant Database, and then click Create. Access 2010 displays a blank web Table window in Datasheet view, as shown in Figure 6-18.
Creating Web Tables in Datasheet View
307
Chapter 6
Figure 6-18 Access displays an empty web table in Datasheet view when you create a blank web database.
When you work in Design view with client tables, the upper part of the Table Design window displays columns in which you can enter the field names, the data type for each field, and a description of each field. Access allows you to set various field properties in the lower-left section of the Table Design window. When you design web tables in Datasheet view, however, all your design elements are in the two contextual ribbon tabs—Fields and Table—under Table Tools. For details about web data type values, see “Understanding Web Field Data Types,” on page 311.
Defining Web Fields Now you’re ready to begin defining some of the web fields and web tables in this new empty web database that you can find in the Back Office Software System sample web database (BOSS.accdb). The Back Office Software System sample web application is used to track various facets of a restaurant business such as purchases, employee file maintenance, scheduling, and so forth. To understand how to create web tables like the ones you can find in the Back Office Software System, we’ll start by creating a new web table from scratch to use for a vendor list. You should still have your empty Table1 open in Datasheet view that Access created when you opened a new web database. Be sure the insertion point is in the Click To Add field in the first row, and then click the Text command in the Add & Delete group on the Fields contextual tab, as shown in Figure 6-19.
308
Chapter 6 Designing Web Tables
Chapter 6 Figure 6-19 You can add new web fields to your table by clicking the various data type commands in the Add & Delete group.
Access creates a new text field called Field1 to the right of the ID field. You’ll notice in Figure 6-19 that Access now displays Text in the Data Type list in the Formatting group and sets the default Field Size to 255 in the Properties group. When you are creating and modifying web fields in Datasheet view, you’ll need to look at the Properties, Formatting, and Field Validation groups on the Fields contextual ribbon to view and edit the various properties for each field. Access sets your focus to the top of the new Field1 column where you can change the name. You can change the default name Field1 Access provided by highlighting the existing text and typing in a new field name. We need to also set a caption and description for this new field so we’ll set all of these at the same time. Click the Name & Caption button in the Properties group, and Access opens the Enter Field Properties dialog box, as shown in Figure 6-20.
Figure 6-20 Click the Name & Caption command to set the field name, caption, and description properties for your new field.
Creating Web Tables in Datasheet View
309
In the Name field, type the name of this first new field, VendorName. Press Tab once to move to the Caption column and then type Vendor Name. Access displays this caption property at the top of the column when you view this table in Datasheet view. Finally, press Tab once more to move to the Description property. In the Description property for each web field, you can enter a descriptive phrase. Access 2010 displays this description on the status bar (at the bottom of the Access window) whenever you select this field in a query in Datasheet view or in a form in Form view or Datasheet view. For your new VendorName field, enter Vendor’s Name in the Description property and then click OK to close the dialog box.
Inside Out
Why Setting the Description Property Is Important
In Chapter 4, we discussed the importance of entering a Description property for every field in your client table to help document your application. Access 2010 also displays the description on the status bar, which can serve as a kind of mini-help for the users of your database. Our advice on using the Description property also applies to web fields in web databases. Documenting your web database is just as important for web databases as it is for client databases because it can help you as well as other people who might need to modify your work in the future.
In addition to using the data type commands in the Add & Delete group to create your new web fields, you can also click the column header of the Click To Add empty field to display a list of the data types you can use in web tables, as shown in Figure 6-21. Click Text or press the shortcut key T to create another new text field for your vendor table. Access creates another new text field and gives it the default name of Field1.
Figure 6-21 Click the column header on the Click To Add empty field to drop down a list of data types to use for your new web field.
Chapter 6
310
Chapter 6 Designing Web Tables
Chapter 6
You can use the options in the Click To Add empty field for rapid creation of your web fields and then go back through and add captions and descriptions to your fields later. For example, the focus should currently be on the column header of the new text field you just created. Enter CustomerNumber as the name of this new text field. (We’re using a text data type for this field, because the customer number can contain alphanumeric characters.) Once you’ve entered the new field name, press Tab and Access moves the focus to the Click To Add empty field and drops down the list of data types again for you, as shown in Figure 6-22. You can press the shortcut key corresponding to the data type you want to create your next field without ever having to use the mouse. Use this technique to create two new text fields called ContactFirstName and ContactLastName.
Figure 6-22 Use the shortcut keys for the corresponding data type options in the Click To Add empty field to quickly create new web fields for your table.
Your table up to this point should now look like Figure 6-23. Click the Save button on the Quick Access Toolbar to save this table in its present state and name the new web table Vendors.
Figure 6-23 Your changes for your new web Vendors table should now look like this.
Creating Web Tables in Datasheet View
311
Access 2010 gives you lots of flexibility when it comes to naming your web fields. A web field name can be up to 64 characters long, can include any combination of letters, numbers, spaces, and special characters except a period (.), exclamation point (!), square brackets ([]), leading space, leading equal sign (=), or nonprintable character such as a carriage return. The name also cannot contain any of the following characters: / \ : ; * ? “” < > | # { } % ~ &. In general, you should give your fields meaningful names and should use the same name throughout for a field that occurs in more than one table. You should avoid using field names that might also match any name internal to Access or Microsoft Visual Basic. For example, all objects have a Name property, so it’s a good idea to qualify a field containing a name by calling it VendorName or CompanyName. You should also avoid names that are the same as built-in functions, such as Date, Time, Now, or Space. See Access Help for a list of all the built-in function names. Although you can use spaces within your field names in a web database, you should try to create field names without embedded spaces. Many Structured Query Language (SQL) databases to which Access can link (notably Oracle and Ingres) do not support spaces within names. Although Microsoft SQL Server does allow spaces in names, you must enclose such names in brackets or use quotes and execute a Set Quoted Identifier On command. If you ever want to move your web application to a client/server environment and store your data in an SQL database such as SQL Server or Oracle, you’ll most likely have to change any names in your web database tables that have an embedded space character. As you’ll learn later in this book, table field names propagate into the queries, forms, and reports that you design using these tables. So any name you decide to change later in a table must also be changed in all your queries, forms, and reports. If you use reserved words or function names for web field names, Access 2010 catches most of these and displays a warning message. This message warns you that the field name you chose, such as Name or Date, is a reserved word and you could encounter errors when referring to that field in other areas of the database application. Access still allows you to use this name if you choose, but take note of the problems it could cause. To avoid potential conflicts, we recommend you avoid using reserved words and builtin functions for web field names.
Understanding Web Field Data Types When you are creating fields for a web database, Access allows you to use only data types that are supported in SharePoint lists. Access 2010 web databases support 10 types of data, each with a specific purpose. You can see the details about each data type in Table 6-1.
Chapter 6
Choosing Web Field Names
312
Chapter 6 Designing Web Tables
Chapter 6
The Lookup & Relationship option helps you define the characteristics of foreign key fields that link to other tables or value lists. You’ll learn about the Lookup & Relationship option later in this chapter in “Creating Lookup Fields in a Web Database,” on page 337. Table 6-1 Access Web Data Types
Data Type
Usage
Size
Text
Alphanumeric data.
Up to 255 characters
Number
Numeric data.
All numbers in web tables are 8-byte Double
Currency
Monetary data, stored with four decimal places of precision.
8 bytes
Date/Time
Dates and times.
8 bytes
Yes/No
Boolean (true/false) data; SharePoint 1 byte stores the numeric value zero (0) for false, and one (1) for true.
Dependent on the data type of Lookup & When you choose this entry, a wizard Relationship starts to help you define either a simple the lookup field or complex lookup field. A simple lookup field uses the contents of another table or a value list to validate the contents of a single value per row. A complex lookup field allows you to store multiple values of the same data type in each row. Memo
Alphanumeric data—sentences and paragraphs.
Values are truncated if they contain more than 8,192 characters
Varies based on SharePoint list Attachment You can attach files such as pictures, documents, spreadsheets, or charts; each and site settings Attachment field can contain an unlimited number of attachments per record, up to the storage limit of the SharePoint list. You can only have one Attachment field per web table. Hyperlink
A link “address” to a document or file on the World Wide Web, on an intranet, on a local area network (LAN), or on your local computer.
SharePoint Hyperlink fields can only store 255 characters for the Uniform Resource Locator (URL) and 255 characters for the description
Calculated
You can create an expression that uses data from one or more fields. You can designate different result data types from the expression.
Dependent on the data type of the Result Type property. Text data type result can have up to 243 characters. Memo, Number, Yes/No, and Date/Time should match their respective data types.
Creating Web Tables in Datasheet View
313
For each field in your table, select the data type that is best suited to how you will use that field’s data. For character data, you should normally select the Text data type. You can control the maximum length of a Text field by using a field property, as explained later in this chapter. Use the Memo data type only for long strings of text that might exceed 255 characters or that might contain formatting characters such as tabs or line endings (carriage returns). The Date/Time data type is useful for calendar or clock data and has the added benefit of allowing calculations in seconds, minutes, hours, days, months, or years. For example, you can find out the difference in days between two Date/Time values.
Inside Out
Understanding the SharePoint Date/Time Data Type
Use the Date/Time data type to store any date and time value. It’s useful to know that SharePoint lists, like Access 2010, store the date as the integer portion of the Date/ Time data type and the time as the fractional portion—the fraction of a day, measured from midnight that the time represents. For example, 6:00:00 A.M. internally is 0.25. In SharePoint Date/Time fields, the day number is actually the number of days since January 1, 1900, and cannot display dates prior to that date. The Date/Time data type in Access client tables starts with December 30, 1899, and can be a negative number for dates prior to that date. If you are working in a web database with web tables, however, you cannot store any date values prior to January 1, 1900, because SharePoint Date/ Time fields do not support data before that date.
You should generally use the Currency data type for storing money values. Currency has the precision of integers, but with exactly four decimal places. Use the Yes/No data type to hold Boolean (true or false) values. This data type is particularly useful for flagging accounts paid or not paid or orders filled or not filled. SharePoint Boolean fields store True values as 1, unlike Access Boolean fields, which store True as –1. To work around this disparity, you should only use check boxes to display Boolean fields in web databases so the users of your database are not looking at an integer value for the field. (When you create a Boolean field in a web table, you’ll notice Access only gives you the option to display check boxes.) If you attempt to use any restrictions, filters, or comparisons on the integer value of Boolean fields on server forms, you’ll see a runtime error. Note that it is still possible to use the integer value of Boolean fields in restrictions, filters, and comparisons in Access client with data published to the server; however, we recommend you always use True and False constants when working with Boolean fields in web databases to ensure consistent behavior in both client and server.
Chapter 6
314
Chapter 6 Designing Web Tables
Chapter 6
The Hyperlink data type lets you store a simple or complex “link” to an external file or document. (Internally, Hyperlink is a memo data type with a special flag set to indicate that it is a link.) This link can contain a URL that points to a location on the World Wide Web or on a local intranet. It can also contain the Universal Naming Convention (UNC) name of a file on a server on your LAN or on your local computer drives. The link can point to a file that is in Hypertext Markup Language (HTML) or in a format that is supported by an ActiveX application on your computer. If you are using existing data in a Hyperlink field before publishing your database to a SharePoint server, be careful about how many characters are stored in your hyperlinks. Hyperlink fields in client tables (and web tables before publishing to the server) can support more than 255 characters; however, Hyperlink fields in SharePoint lists support only up to 255 characters. Access prevents you from publishing your data to the server if any Hyperlink fields contain more than 255 characters. You need to edit or remove any hyperlinks that contain more than 255 characters before you can successfully publish your web database to the server. The Attachment data type, introduced in Access 2007, allows you to store multiple attachments in a single record. These files are stored in a binary field in a hidden system table. For the Attachment data type, Access compresses each file, if it isn’t already, and uses the original file rather than a generated thumbnail to minimize the amount of database bloat. You are restricted to only having one Attachment field per web table in web databases. Access displays an error message if you try to create more than one Attachment field in a single web table. SharePoint lists have a default size limit of 50 MB for each attachment. If you have attachments larger than 50 MB, you might encounter problems publishing your application to the server or syncing your data to the server. The attachment size limit is an administrative configurable setting. Contact your SharePoint server administrator if you are experiencing issues publishing larger attachments. The Calculated data type, newly introduced in Access 2010, can also be published to the server. When you publish a web table to the server that includes a Calculated data type, Access creates a Calculated column in the SharePoint list and sets the expression to match what you defined in Access client. Calculated fields allow you to create a calculated result using an expression. The expression you use can include data from one or more fields in the same table. If you have a number field, for example, that holds quantity information for products purchased and a currency field that holds the price of a product, you can create a calculated field that multiplies the quantity and price fields and stores it with a result type of currency. You could also create a calculated field that concatenates a first name, middle name, and last name fields and stores it with a result type of text for a field called Full Name. Access recalculates the value of the calculated field any time the dependent fields are changed.
Creating Web Tables in Datasheet View
315
You might have noticed that you cannot create an AutoNumber field in web tables. All SharePoint lists include an ID field which increments sequentially like Access AutoNumber data types. Whenever you create a new web table, Access automatically creates an ID field for you because SharePoint lists require it. You cannot delete the ID field from your web tables; however, you can rename the field if you choose. In client databases, you have a hard limit of 255 fields allowed in a table, but for web databases, you have a hard limit of 220 fields (including the ID field) because SharePoint lists have many hidden fields. Unlike Access tables, SharePoint lists have default limits on the number of columns for each data type. SharePoint lists also have a logical row-size limit of 8,000 KB and a configurable limit of physical rows per list item. This means that you might encounter publishing errors if you have more fields of one data type allowed in a web table, you are over the limit of row size for all fields combined, or a combination of the two. As a baseline, you can publish 48 Date/Time fields, 71 Number or Currency fields, 96 Yes/ No fields, 191 Hyperlink fields, 191 Memo fields, or 219 Text fields in a single web table with default SharePoint list settings.
Setting Field Properties for Web Databases You can customize the way Access 2010 stores and handles each field in web databases by setting specific properties. These properties vary according to the data type you choose and are available in the Properties, Formatting, and Field Validation groups on the Fields contextual ribbon tab. Table 6-2 lists all the possible properties that can appear for fields in a web database displayed in Datasheet view, and the data types that are associated with each property.
Chapter 6
316
Chapter 6 Designing Web Tables
Table 6-2 Field Properties on the Fields Contextual Tab
Chapter 6
Property
Data Type
Options, Description
Field Size
Text
Text can be from 0 through 255 characters long, with a default length of 255 characters.
Format
Number
General Number (default). No commas or currency symbols; the number of decimal places shown depends on the precision of the data. Standard. Two decimal places and separator commas. Percent. Moves displayed decimal point two places to the right and appends a percentage (%) symbol.
Currency
Currency.1 Currency symbol (from Regional And Language Options in the Control Panel) and two decimal places. Euro. Euro currency symbol (regardless of Control Panel settings) and two decimal places.
Date/Time
General Date (default). Combines Short Date and time (for example, 7/1/2010 5:30:10 PM). Short Date.2 Uses Short Date Style from Regional And Language Options (for example, 7/1/2010).
Calculated
Format property options for calculated fields depend on the Result Type. The format property options and defaults for the Result Type align with the other data types.
Increase/ Decrease Decimals
Number and Currency You can specify the number of decimal places that Access displays. The default specification is to display two decimal places for the Currency, Standard, and Percent formats and the number of decimal places necessary to show the current precision of the numeric value for General Number format. You can request a fixed display of decimal places by clicking these buttons.
Caption
All
You can enter a more fully descriptive field name that Access displays in form labels and in report headings. (Tip: If you create field names with no embedded spaces, you can use the Caption property to specify a name that includes spaces for Access to use in labels and headers associated with this field in queries, forms, and reports.)
Default Value
Text, Number, Currency, Date/Time, and Boolean
You can specify a default value for the field that Access automatically uses for a new row if no other value is supplied. If you don’t specify a Default Value, the field will be Null if the user fails to supply a value. (See also the Required property.)
Creating Web Tables in Datasheet View
Property
Data Type
317
Options, Description
Validation Rule Text, Number, Currency, and Date/Time
You can supply an expression that must be true whenever you enter or change data in this field. For example, 0. You can use one or more pairs of comparisons to ask Access to check that the value falls within certain ranges. For example, if you want to verify that a number is in the range of 100 through 200, enter either >=100 And 10 is equivalent to =
Greater than or equal to.
=
Equal to.
Not equal to.
IN
Test for equal to any member in a list; comparison value must be a comma-separated list enclosed in parentheses.
LIKE
Test a Text field to match a pattern string.
IS NOT NULL
Requires the user to enter a value in the field.
If you need to validate a Text field against a matching pattern (for example, a postal code or a phone number), you can use the LIKE comparison operator in web databases. You can provide a text string as a comparison value that defines which characters are valid in which positions. Access understands a number of wildcard characters, characters which you can use to define positions that contain any single character, zero or more characters, or any single number. These characters are shown in Table 6-5 and are identical to what you can use for client databases. Table 6-5 LIKE Wildcard Characters
Character
Meaning
?
Any single character.
*
Zero or more characters; use to define leading, trailing, or embedded strings that don’t have to match any specific pattern characters.
#
Any single digit.
You can also specify that any particular position in the Text field can contain only characters from a list that you provide. You can specify a range of characters within a list by entering the low value character, a hyphen, and the high value character, as in [A-Z] or [3-7]. If you want to test a position for any characters except those in a list, start the list with an exclamation point (!). You must enclose all lists in brackets ([ ]). You can see examples of validation rules using LIKE in web databases here.
Creating Web Tables in Datasheet View
329
Validation Rule
Tests For
LIKE "#####" or
A U.S. 5-digit ZIP Code
LIKE "#####-####"
A U.S. 9-digit ZIP+ Code
LIKE "[A-Z]#[A-Z] #[A-Z]#"
A Canadian postal code
LIKE "###-##-####"
A U.S. Social Security number
LIKE "Smith*"
A string that begins with Smith1
LIKE "*smith##*"
A string that contains smith followed by two numbers, anywhere in the string
LIKE "??00####"
An eight-character string that contains any first two characters followed by exactly two zeros and then any four digits
LIKE "[!0-9BMQ]*####"
A string that contains any character other than a number or the letter B, M, or Q in the first position and ends with exactly four digits
1 Character string comparisons in Access and on the server are case-insensitive, so smith, SMITH, and Smith are all equal.
In the Vendors table of the Restaurant Database you’ve been building, the EmailAddress field could benefit from the use of a validation rule. Open the Vendors table in Datasheet view, if it isn’t already open, tab over to the EmailAddress field, click the Validation button in the Field Validation group, and then click the Field Validation Rule option from the dropdown list, as shown in Figure 6-33.
Figure 6-33 Click the Validation button on the Fields contextual tab to add or edit field validation rules.
Chapter 6
330
Chapter 6 Designing Web Tables
Chapter 6
Access opens the Expression Builder dialog box, as shown in Figure 6-34. In the EmailAddress field, we want to be sure the email address provided by the user appears to be a valid email address. We can verify the email address meets most standards of valid syntax by using a combination of the LIKE operator and wildcard characters in a field validation rule. In the blank text box at the top of the Expression Builder dialog box, type Is Null OR ((Like “*?@?*.?*”) AND (Not Like “*[ ,;]*”)) for the field validation rule, as shown in Figure 6-34. This field validation rule ensures that every email address provided by the user starts with at least one character followed by the @ symbol, contains at least one more character following the @ symbol, and contains the dot symbol followed by at least one more character after the dot symbol. Also, this field validation rule does not allow a space, a comma, or a semicolon anywhere in the email address.
Figure 6-34 Type your field validation rule into the Expression Builder dialog box.
Click OK to save your changes to the field validation rule and dismiss the Expression Builder dialog box. You should now add an appropriate custom validation text to display to users if they provide data to the EmailAddress field that does not pass your new field validation rule. Make sure the focus is still in the EmailAddress field, click the Validation button in the Field Validation group, and then click the Field Validation Message option from the drop-down list, as shown in Figure 6-35. If you look closely at Figure 6-35, you’ll notice that Access adds an orange square around the graphic next to the Field Validation Rule option. Access highlights these graphics on the drop-down list as a visual cue if you define a property for that specific option.
Creating Web Tables in Datasheet View
331
Chapter 6
Figure 6-35 Click the Field Validation Message option to add a custom field validation text.
Access now opens the Enter Validation Message dialog box, as shown in Figure 6-36. Type the following custom message into the dialog box—The email address you provided does not appear to be valid. Click OK to save your changes to this property and dismiss the dialog box. You now have a completed field validation rule and message for the EmailAddress field that will be enforced whether you use the database in client or on the server. Be sure to click the Save button on the Quick Access Toolbar to save this latest change to your web table definition.
Figure 6-36 Enter your custom validation text into the Enter Validation Message dialog box.
332
Chapter 6 Designing Web Tables
Defining a Table Validation Rule for Web Databases Chapter 6
You can create table validation rules in web databases just like you can for client databases. Although field validation rules get checked as you enter each new value, Access checks a table validation rule only when you save or add a complete record. Table validation rules are handy when the values in one field are dependent on what’s stored in another field. You need to wait until the entire row is about to be saved before checking one field against another. In the Restaurant Database you have been creating, we need an Appointments table to track our day to day appointments of managing the restaurant. This table requires a table validation rule. Click the Table button in the Tables group on the Create Ribbon tab to get started. Define that table now using the specifications in Table 6-6. Be sure to rename the ID field Access provides for you to AppointmentID and then save the table and name it Appointments. Be sure to also set both the StartTime and EndTime fields as required fields by selecting the Required option in the Field Validation group. You can set the Format property for the fields in the Format text box in the Formatting group on the Fields tab. Table 6-6 Field Definitions for the Appointments Table
Field Name
Data Type Description
Field Size Format
AppointmentID
ID
Unique appointment identifier
AppointmentDescription
Text
Description of appointment
StartTime
Date/Time
Start time of appointment
General Date
EndTime
Date/Time
End time of appointment
General Date
Notes
Memo
Extended notes from appointment
Rich Text
100
To define a table validation rule in a web database, open the table in Datasheet view, click the Validation button in the Field Validation group on the Fields contextual tab, and then click the Record Validation Rule option from the drop-down list, as shown in Figure 6-37.
Defining a Table Validation Rule for Web Databases
333
Chapter 6
Figure 6-37 You can define table validation rules in web databases by clicking the Record Validation Rule option.
Access opens the Expression Builder dialog box, as shown in Figure 6-38. For this web table, we want to ensure the start time of the appointment provided by the user comes before the end time. (It certainly would not make sense to have an appointment end before it even started.) We can accomplish this by using the less than () button to copy that field to the Selected Fields list. You can also click the double right arrow (>>) button to copy all available fields to the Selected Fields list. If you copy a field in error, you can select the field in the Selected Fields list and click the single left arrow (="A" And [Last Name]< "H" to limit the records to this range of letters, as shown in Figure 15-57. Note that in the Navigation Where Clause, you do not need to start the expression with an equals sign (=). Reduce the width of this navigation button to one-half of an inch.
Figure 15-57 Change the Navigation Where Clause property to filter the records in the frmContactList form.
1010 Chapter 15 Advanced Form Design
Chapter 15
Using the example you just learned, make the following changes to the remaining three navigation buttons in the second-level navigation control:
1. For the third button, change the Caption property to H–M, reduce the width to onehalf of an inch, and enter the expression [Last Name]>="H" And [Last Name]="N" And [Last Name]="U" in the Navigation Where Clause property.
Save your changes to the form, and then switch to Form view to see your completed changes, as shown in Figure 15-58. When you click the first-level Contact List navigation button, you can see all the navigation buttons in the second-level navigation control. When you click the Datasheet, Address Book, or Phone List navigation buttons, you do not see the second-level navigation buttons. When you click the second-level navigation buttons below Contact List, Access filters the records to show only the contacts with last names that start with the letters specified. The second-level navigation buttons are referred to as children of the first-level navigation buttons. If you want to add child navigation buttons below a parent navigation button, you need to select the parent navigation button in Layout view, and then drag forms and reports into the child-level navigation control (or use the [Add New] button to do so). You can find this form saved as frmXmplNavigationForm2 in the sample database.
Working with Navigation Controls 1011
Chapter 15
Figure 15-58 Your second-level navigation buttons filter the frmContactList form.
If you’d like, you can experiment with applying different formatting options to the navigation buttons. Access 2010 includes several new formatting options you can apply to buttons—the new navigation buttons as well as the standard Access command buttons. Switch back to Layout view for your form, select one of your navigation buttons, and then click the Quick Styles button in the Control Formatting group on the Format tab. Access displays a gallery of 42 Quick Styles that you can apply to your button, as shown in Figure 15-59. You can click any of these Quick Styles, and Access changes the colors and styles of your navigation button. By using a Quick Style, you can quickly adjust several color properties of your buttons for a modern look compared to previous versions of Access. When you click a Quick Style, Access changes the Back Color, Border Color, and Fore Color properties to Quick Style to indicate it is using Quick Style formatting properties.
1012 Chapter 15 Advanced Form Design
Chapter 15 Figure 15-59 You can choose from a gallery of 42 Quick Styles to apply to buttons.
In addition to the Quick Styles, you can choose many other formatting options for buttons under the Shape Effects command. Select a navigation button in one of the navigation controls and then click the Shape Effects command in the Control Formatting group on the Format tab. Access displays a drop-down gallery with four main options—Shadow, Glow, Soft Edges, and Bevel—as shown in Figure 15-60. When you click any of these main options, Access displays additional galleries in a submenu gallery. You can choose many different formatting options from these submenu galleries. For example, you can add different shadow styles to your buttons to give them a three-dimensional look. You can also apply different glow color variations, different levels of soft edging around the borders, and even different styles of beveled edging to your buttons. You can click any of these options and see how they change the appearance of your buttons. If you don’t like an option, you can always undo your last action or click a different formatting option. With all the many new formatting style options for buttons in Access 2010, you might have a hard time trying to decide which options to use!
Working with Navigation Controls 1013
Chapter 15
Figure 15-60 You can choose many shadow, glow, soft edge, and bevel formatting options for buttons in the Shape Effects gallery.
INSIDE OUT
Opening a Form with a Navigation Control in Access 2007
If you try and open a database that contains a client form with a navigation control in Access 2007, Access displays a compatibility warning message in the Business Bar. The warning says that the database uses some features that are incompatible with that version of Access. If you try to open that form in Access 2007 in any view, Access displays an error message indicating it cannot read the data in the form. You cannot edit or work with navigation controls in Access 2007.
1014 Chapter 15 Advanced Form Design
Using Web Browser Controls Chapter 15
Access 2010 includes a new control type, called a web browser control, which you can use on both web forms and client forms in your database. A web browser control displays the content of web pages directly inside a form. You can use a web browser control, for example, to display a map of an address stored in a table. You can optionally bind the web browser control to a field in your form’s record source by using the Control Source property of the control. You can also use a web browser control to display a static web page, such as a link to a specific website (for example, http://www.AccessJunkie.com), or you can use a web browser control to display a video hosted on a web page. The Contacts Navigation sample web database (ContactsNavigation.accdb) you’ve been working with in the last section includes a web browser control on one of the forms. Open this database (if you’ve closed it) and then open the frmContactDetails form in Layout view. This form displays all the detail information about each contact in the database on the General tab of the tab control. Click the Map tab on the tab control, and Access displays a map of the contact’s address using Bing Maps, as shown in Figure 15-61. If you navigate to different records using the navigational buttons at the bottom of the form, you can see the map change to display the current contact’s address.
Figure 15-61 The web browser control displays a map of the contact’s address using Bing Maps.
Using Web Browser Controls 1015
If you look to the right of the web browser control, you’ll see a text box control that displays a Uniform Resource Locator (URL) to the Bing Maps website. This text box is bound to a field in the Contacts table called MapAddress. The MapAddress field is a Calculated data type that concatenates the URL to the Bing Maps base website along with the Address, City, and StateProvince fields from the contact’s record. The completed URL is what you see displayed in the text box control on the form. (You can open the Contacts table in Datasheet view and examine the expression we used by selecting the MapAddress field, and then clicking the Modify Expression button in the Properties group on the Fields tab.) The web browser control is also bound to the MapAddress field. When you navigate to a different record, Access fetches the data from the MapAddress field, sends a request to that completed URL, and then displays the result in the web browser control.
Note To view a website in a web browser control in Access, you must enable the content of the database. The simplest way to trust this database is to click the Enable Content button on the Message Bar. You can also go to the Trust Center and mark the folder containing this database as Trusted. Click the File tab on the Backstage view and then click Options. In the left column, choose Trust Center and then click Trust Center Settings. In the Trust Center dialog box, select Trusted Locations in the left column and then click Add New Location. Add the folder containing this sample database to the Trusted Locations list. For more information on enabling content in a database, see “Understanding Content Security,” on page 47.
Let’s create a new form with a web browser control so you can see how to work with this new control. First, close any objects you have open in the database. Next, open the Contacts table in Datasheet view and tab into the MapAddress field for one of the records in this table. Finally, click the Copy command in the Clipboard group on the Home tab to copy one of these address URLs to the Clipboard. (We’ll use this URL as an example in just a moment.) Close the Contacts table and then click the Blank Form command in the Forms group on the Create tab to create a new blank web form in Layout view. Make sure you have Control Wizards enabled in the Controls group on the Design tab, select the Web Browser Control button in the Controls group, and then click in the form grid. Access adds a new web browser control to the form grid and then opens the Insert Hyperlink dialog box with the Hyperlink Builder button selected, as shown in Figure 15-62.
Chapter 15
1016 Chapter 15 Advanced Form Design
TROUBLESHOOTING Chapter 15
Why can’t I see web browser control listed in the Controls group? If you are working with a continuous form in Design or Layout view, Access does not display the Web Browser Control button in the Controls group on the Design tab. Web browser controls are not supported in the Detail section of continuous client or web forms, so Access does not display that control in the Controls group. If you want to display a web browser control in the form Header section of a continuous form, change the Default View property of the client form to Single Form, drop the web browser control in the form’s Header section, and then change the Default View property back to Continuous Form. If you have a web browser control in the Detail section of a client datasheet form, Access does not display the web browser control when you view the form in Datasheet view.
Figure 15-62 Access opens the Insert Hyperlink dialog box when you place a web browser control onto the form grid.
You used the Insert Hyperlink dialog box before when you studied how to insert and edit hyperlinks in Chapter 12, “Using Forms in an Access Application.” You can use the Hyperlink Builder button in this dialog box to help break down a URL that includes parameters into the base URL, paths, and parameters. You’ll notice the Text To Display box at the top is disabled when you build a hyperlink for a web browser control. There is really no need to have a text to display information for a web browser control when Access displays the contents of the web page inside the form. In the Address field, you can type in a website address.
Using Web Browser Controls 1017
You should still have the URL of one of the contact addresses in your Clipboard, so press Ctrl+V to paste that address into the Address field on the Insert Hyperlink dialog box. (The Insert Hyperlink dialog box is a pop-up form, so you cannot click the Paste command on the ribbon to perform this operation.) When you tab out of the Address text box, Access breaks down the various parts of the URL, as shown in Figure 15-63. Access displays the base URL in the Base URL text box, any paths in the Paths list box, and any parameters in the Parameters list box. In Figure 15-63, you can also see that Access displays the name and value of each parameter in the Parameters list box. You can type a new value in the list box and Access saves the information into the completed URL. This feature is especially helpful when building complex URLs that include different parameters. (If you like, try entering your address information into the Value field next to Where1 under Parameters.) You can also click the button to the right of the Base URL text box to open the Expression Builder if you’d like to build an expression.
Figure 15-63 Access can break down a URL into its various parts using the Hyperlink Builder on the Insert Hyperlink dialog box.
Click OK to save your changes in the Insert Hyperlink dialog box and then resize the web browser control so it is bigger than the default size Access created. You should now see the web browser control pointing to the Bing Maps website, with a map displaying the address you provided, as shown in Figure 15-64. Note that if the address is invalid one, you’ll see a generic page for the Bing Maps map control. Click the Save button on the Quick Access Toolbar and name your form WebBrowserForm. You can find this form saved as frmXmplWebBrowserForm in the sample database.
Chapter 15
1018 Chapter 15 Advanced Form Design
Chapter 15 Figure 15-64 Access displays the web page content of the Bing Maps site in the web browser control.
Click the Property Sheet button in the Tools group on the Design tab, and let’s take a quick look at some of the properties for the web browser control. In the Control Source property for the web browser control, you can see that Access saves the URL you provided on the Insert Hyperlink dialog box, as shown in Figure 15-65. If you are typing a URL directly into the Control Source, you must start the expression with an equals sign (=) and enclose the URL in quotation marks. You can also bind a web browser control to a field in the form’s record source by selecting a field from the drop-down list on the Control Source property. (You can look at the Control Source property of the web browser control on the frmContactDetails in this database for an example of this.) Note that the form must be bound to bind the web browser control to a field. You can choose to turn off displaying scroll bars for the web browser control by changing the Scroll Bars Visible property from Auto to No. In client forms, you can also set the Scroll Bar Top and Scroll Bar Left properties of the web browser control to automatically scroll the web content to a specific area of a web page. The Scroll Bar Top and Scroll Bar Left properties of web browser controls on client forms take values in pixels to scroll the window down or to the right. By default, these properties are set at 0 pixels.
Using Web Browser Controls 1019
Chapter 15
Figure 15-65 You can set the Control Source property of web browser controls to a URL or bind it to a field in the form’s record source.
INSIDE OUT
Review the Web Browser Controls in the Web Templates
You can see another use for web browser controls by opening any of the five sample web templates that come with Access 2010. If you look at the Getting Started tab of any of the sample web templates, you’ll see that the forms use a web browser control to point to a video stored on a web page that displays help content on how to use the templates.
This is the last chapter about designing forms for desktop applications and web applications. You’ll learn some additional design techniques that you can automate with macros in Part 6 and with Visual Basic code in Chapter 25.
ou can certainly format and print tables and queries in Datasheet view, and that technique is useful for producing printed copies of simple lists of information. Although you primarily use forms to view and modify data, you can also use forms to print data—including data from several tables. However, because the primary function of forms is to allow you to view single records or small groups of related records displayed on the screen in an attractive way, forms aren’t the best way to print and summarize large sets of data in your database.
This chapter explains why and when you should use a report instead of another method of printing data, and it describes the features that reports offer. The examples in this chapter are based on the Conrad Systems Contacts and Housing Reservations sample databases. After you learn what you can do with reports, you’ll look at the process of building both client and web reports in the next two chapters.
Note The examples in this chapter are based on the reports, tables, and data in ContactsDataCopy.accdb and Housing.accdb on the companion CD included with this book. You can find similar reports in the Conrad Systems Contacts sample application, but all the reports in that sample file have custom ribbons defined, so you won’t see the main ribbon tabs when you open those reports. The results you see from the samples in this chapter might not exactly match what you see in this book if you have changed the sample data in the files. Also, all the screen images in this chapter were taken on a Windows 7 system with the Access color scheme set to Silver. Your results might look different if you are using a different operating system or a different theme.
1023
1024 Chapter 16 Using Reports
Uses of Reports Chapter 16
Reports are the best way to create a printed copy of information that is extracted or calculated from data in your database. Reports have two principal advantages over other methods of printing data: ●●
Reports can compare, summarize, subtotal, and total large sets of data.
●●
Reports can be created to produce attractive invoices, purchase orders, mailing labels, presentation materials, and other output you might need to efficiently conduct business.
Reports are designed to group data, to present each grouping separately, and to perform calculations. They work as follows: ●●
You can define up to 10 grouping criteria to separate the levels of detail.
●●
You can define separate headers and footers for each group.
●●
You can perform complex calculations not only within a group or a set of rows, but also across groups.
●●
In addition to page headers and footers, you can define a header and a footer for the entire report.
●●
You can have your reports respond to events such as opening forms so that you can view detailed information.
●●
You can filter the report to show specific records before printing.
As with forms, you can embed pictures or charts in any section of a report. You can also embed subreports or subforms within report sections.
A Tour of Reports You can explore reports in Microsoft Access 2010 by examining the features of the sample reports in the ContactsDataCopy.accdb sample database. A good place to start is the rptContactProducts report. Open the database, and go to the Navigation pane. Click the Navigation Pane menu, click Object Type under Navigate To Category, and then click Reports under Filter By Group to display a list of reports available in the database. Scroll
A Tour of Reports 1025
down the list of reports in the Navigation pane until you see the rptContactProducts report, as shown in Figure 16-1. Double-click the report name (or right-click it and click the Open command on the shortcut menu) to see the report in Print Preview—a view of how the report will look when it’s printed.
Note All the reports in the sample databases are set to print to the system default printer. The default printer on your system is probably not the same printer that we used as a default when we designed the report. Some of the sample reports are designed with margins other than the default of 1 inch on all sides. If your default printer cannot print as close to the edge of the paper as the report is designed, Access 2010 will adjust the margins to the minimums for your printer. This means that some reports might not appear exactly as you see them in this book, and some data might appear on different pages.
Figure 16-1 You can use the object shortcut menu to open a report from the Navigation pane.
Chapter 16
1026 Chapter 16 Using Reports
Print Preview—A First Look Chapter 16
The rptContactProducts report is based on the qryRptContactProducts query, which brings together information from the tblContacts, tblProducts, and tblContactProducts tables. When the report opens in Print Preview, you’ll see a view of the report in the Contact Products window, as shown in Figure 16-2. When you open the report from the Navigation pane, the report shows information for all contact product sales. Print Preview Zoom
Zoom control Figure 16-2 The rptContactProducts report in Print Preview shows sales data gathered from several tables.
A Tour of Reports 1027
You can see all the reports described in this chapter in the Conrad Systems Contacts application. Start the application by opening the database (Contacts.accdb), opening frmSplash, and then signing on as either Jeff or John—you don’t need a password. To see the final version of the Contact Products report, for example, click the Products button on the main switchboard form, and then click the Print button on the CSD Contacts - Products form to open the Product Reports dialog box. Select Product Sales By Contact. Also select the Current Product Only and All Records options, and then click Print. You’ll see the report in Print Preview for the product that was displayed on the Products form. You can also explore the reports by clicking the Reports button on the main switchboard. All reports in the application have custom ribbons that prevent you from switching to Design view when running the application. When you’re finished looking at the reports in Contacts.accdb, be sure to go back to the ContactsDataCopy.accdb file to follow the remaining examples in this chapter.
You can expand the window in Print Preview by collapsing the Navigation pane to see more of the rptContactProducts report horizontally. Use the vertical and horizontal scroll bars to position the report so that you can see most of the upper half of the first page. If you are using a smaller Super Video Graphics Array (SVGA) screen (800 × 600 pixels), click the arrow below the Zoom button in the Zoom group on the ribbon and select 75% to see more of the report. If your screen resolution is 1024 × 768 or higher, you should be able to easily view the report at 100%. You can also use the Zoom control in the lower-right corner of your window to adjust the zoom level. To view other pages of the report, use the navigation bar in the lower–left corner of the window, as shown here.
The four buttons, from left to right, are the First Page button, Previous Page button, Next Page button, and Last Page button. The Page Number box is in the middle. To move forward one page at a time, click Next Page. You can also click the Page Number box (or press Alt+F5 to select it), change the number, and press Enter to move to the exact page you want. Press Esc to exit the Page Number box. As you might guess, the Previous Page button moves you back one page, and the two outer buttons move you to the first or the last page of the report. You can also move to the top of the page by pressing Ctrl+Up Arrow, move to the bottom of the page by pressing Ctrl+Down Arrow, move to the left edge of the page by pressing Home or Ctrl+Left Arrow, and move to the right edge of the page by pressing End or Ctrl+Right Arrow. Pressing Ctrl+Home moves you to the upper-left corner of the page, and pressing Ctrl+End moves you to the lower-right corner of the page.
Chapter 16
Checking Out Reports in the Sample Application
1028 Chapter 16 Using Reports
Headers, Detail Sections, Footers, and Groups Chapter 16
Although the rptContactProducts report looks simple at first glance, it actually contains a lot of information. Figure 16-3 shows you the report again with the various sections of the report marked. You can see a page header that appears at the top of every page. As you’ll see later when you learn to design reports, you can also define a header for the entire report and choose whether to print this report header on a page by itself or with the first page header. The data in this report is grouped by contact name, and the detail lines are sorted within contact name by date sold. You can print a heading for each group in your report, and this report has a heading for each contact. This report could easily be modified, for example, to display the product category in a header line (to group the products by category), followed by the related detail lines.
Page header
Detail lines Contact Group header
Contact Group footer Figure 16-3 The rptContactProducts report has a subtotal for each contact.
A Tour of Reports 1029
Next, Access prints the detail information, one line for each row in the recordset formed by the query. In the Detail section of a report, you can add unbound controls to calculate a result using any of the columns in the record source. Below the detail product lines for each contact, you can see the group footer for the contact. You could also calculate percentages for a detail record or for a group by including a control that provides a summary in the group footer (total for the group) or report footer (total for the report). To calculate the percentage, you would create an additional control that divides the detail or group value by the total value in an outer group or in the report footer. Access can do this because its report writer can look at the detail data twice—once to calculate any group or grand totals and a second time to calculate expressions that refer to those totals. If you scroll down to the bottom of the page, you’ll see a page number, which is in the page footer.
Note If you’re working with a report that has many pages, it might take a long time to move to the first or last page or to move back one page. You can press Esc to cancel your movement request. Access 2010 then closes the report.
A slightly more complex report is rptProductSalesByProduct. Open that report, and go to the last page. At the end of this report, as shown in Figure 16-4, you can see the quantity and sales totals for the last product in the report, for the last category in the report, and for all sales in the database (Grand Total). There are two products in the Single User category, but the first is a demonstration edition that has a price of zero, so the total sales amount of the category matches the total sales amount of the second product. The grand total is in the report footer.
Chapter 16
1030 Chapter 16 Using Reports
Product Group header
Chapter 16 Product Group footer Category Group footer Report footer Figure 16-4 The rptProductSalesByProduct report’s grand total calculation is in the report footer.
Subreports Just as you can embed subforms within forms, you can embed subreports (or subforms) within reports. Subreports are particularly useful for showing related details or totals for the records that make up the source rows of your report. In the Conrad Systems Contacts database, you can bring together information about contacts and products—either contacts and the products they own or products and the contacts who own them. You can place detailed data about contacts and products in a subreport and then embed that subreport in the Detail section of a report that displays company data—much as you did for the fsubContactProducts form exercise in Chapter 15, “Advanced Form Design.”
A Tour of Reports 1031
Subreports are not supported on web reports with Access Services. When you are working with web reports, the Subform/Subreport control is not available in the Controls group on the Design tab. You can still embed subreports in client reports in web databases and use them within Access.
You can see an example of this use of a subreport in the rptCompanyProducts report and in the rsubCompanyProducts subreport in the Conrad Systems Contacts database. In the Navigation pane, right-click the rsubCompanyProducts subreport, and then click Design View on the shortcut menu to open the subreport in Design view, as shown in Figure 16-5. The Report window in Design view is shown in Figure 16-6.
Figure 16-5 Select Design View from the shortcut menu to open rsubCompanyProducts in Design view.
Figure 16-6 This is the Report window for the rsubCompanyProducts report in Design view.
Chapter 16
Note
1032 Chapter 16 Using Reports
Chapter 16
You can see that this report looks very much like the continuous form that you designed earlier to be a subform. If you look at the Record Source property for the subreport, you’ll find that it uses the qryRsubCompanyProducts query, which isn’t at all simple. The query brings together information from the tblProducts, tblContactProducts, tblContacts, and tblCompanyContacts tables. This subreport doesn’t display any company information at all. Switch to Print Preview by clicking the arrow in the Views group on the ribbon and clicking Print Preview in the list of available views. You’ll see a list of various products and the contacts who own them, in date sold order, as shown in Figure 16-7.
Figure 16-7 Switch to Print Preview for the rsubCompanyProducts report to see a complex list of a sales history.
Close the subreport and open the rptCompanyProducts report in Print Preview, as shown in Figure 16-8. As you move from company to company, notice that the data displayed in the subreport changes to match the company currently displayed. The data from the rsubCompanyProducts report now makes sense within the context of a particular company. Access links the data from each subreport in this example using the Link Master Fields and Link Child Fields properties of the subreport (which are set to the linking CompanyID field)—just as with the subforms you created in Chapter 15.
A Tour of Reports 1033
Chapter 16
Figure 16-8 The rptCompanyProducts report has an embedded subreport to display each company’s purchase history.
As you’ll see in the next section, when we examine some features of the rptInvoices report, that report also uses subreports to link information from three related tables to each row displayed from the tblInvoices table.
Objects in Reports As with forms, you can embed objects in reports. The objects embedded in or linked to reports are usually pictures or charts. You can embed a picture or a chart as an unbound object in the report itself, you can link a picture or a chart as an object bound to data in your database, or you can use a shared image. The rptInvoices report in the Conrad Systems Contacts database has an image object. When you open the rptInvoices report in Print Preview, you can see the Conrad Systems logo (a stylized font graphic) embedded in the report title as an unbound bitmap image object, as shown in Figure 16-9. This object is actually a part of the report design.
1034 Chapter 16 Using Reports
Chapter 16 Figure 16-9 The rptInvoices report has an unbound bitmap image object (the Conrad Systems logo) embedded in the report header.
To see an example of how an object prints when it’s stored in a table, open rptContacts, as shown in Figure 16-10. This picture is a bitmap image object stored in an attachment field in the tblContacts table—a picture of the contact.
Figure 16-10 The Photo field in the rptContacts report is a bitmap image object stored in an attachment field.
A Tour of Reports 1035
You might notice that the Notes field in Figure 16-10 doesn’t show all the text for some of the records. There’s a special version of this report called rptContactsExpandNotes that fixes this problem with Microsoft Visual Basic code. See Chapter 25, “Automating Your Application with Visual Basic,” for details.
Report View—A First Look As you learned in Chapter 3, “Access 2010 Overview,” Access 2010 includes a view for reports called Report view. Unlike Print Preview, which presents static data, you can use Report view to interact with data in the report. You can explore reports that take advantage of this view in the Housing.accdb sample database. A good place to start is the rptEmployeesPlain report. Open the database, and go to the Navigation pane. Click the Navigation Pane menu, click Object Type under Navigate To Category, and then click Reports under Filter By Group to display a list of reports available in the database. Scroll down the list of reports until you see the rptEmployeesPlain report, as shown in Figure 16-11. Right-click the report and click Open to see the report in Report view.
Figure 16-11 When you click Open on the shortcut menu for the rptEmployeesPlain report, Access opens it in Report view.
Chapter 16
Note
1036 Chapter 16 Using Reports
Chapter 16
INSIDE OUT
Understanding the Open Command for Reports
You might be wondering why clicking the Open command for the rptEmployeesPlain report opens it in Report view, but the same command opens the rptContactProducts report (discussed earlier in the chapter) in Print Preview. Access 2010 includes a report property called Default View. You can define whether a report opens in Report view or Print Preview by using this property. The default setting when you create a new report is Report view. For the rptEmployeesPlain report, we left this property set to Report view, so when you double-click the report in the Navigation pane or click the Open command on the object shortcut menu, Access opens the report in Report view. We will discuss this property further in Chapter 18, “Advanced Report Design.”
The rptEmployeesPlain report is based on the qryRptEmployees query, which brings together information from the tblEmployees and tblDepartments tables. When the report opens in Report view, you’ll see the data from these tables in the Housing database formatted in the report, as shown in Figure 14-12.
Figure 16-12 The rptEmployeesPlain is set to open in Report view.
A Tour of Reports 1037
If you look closely at Figure 16-12, you will no doubt notice that there is no Page Number box in the lower-left corner of the window. You can also see that the Print Preview contextual ribbon tab is not available. Access displays the four main ribbon tabs in Report view so that you can use filters to interact and display specific records and then print only this smaller group of records. If you were to print this report right now, all 16 employee records would be sent to your printer. Suppose, though, that you want to print only the records of employees who are in the Finance department. You could create a separate report that would show only the employees in the Finance department, but from within Report view, you can ask Access to filter the records to display only the employee records you need. With the rptEmployeesPlain open in Report view, right-click in the Department field for the first record and click Equals “Finance” on the shortcut menu, as shown in Figure 16-13.
Figure 16-13 In Report view, you can filter the records to show just the ones you want to print.
After you click the Equals “Finance” command, Access filters all the records in the report record source to obtain the three employees in the Finance department, as shown in Figure 16-14. If you print the report at this point, Access prints only a one-page report with the three records.
Chapter 16
1038 Chapter 16 Using Reports
Chapter 16 Figure 16-14 After you apply the filter shown in Figure 16-13, Access shows only the three employees in the Finance department.
By using Report view, you can create a single report that returns all records and then use the filtering capabilities of Access to show subsets of the data. To remove the filter applied to this report, click the Toggle Filter button in the Sort & Filter group on the Home tab, and Access again displays all 16 employee records. Report view gives you as many of the filtering and sorting capabilities as you have in forms, but in an object that’s designed to be printed rather than to edit data. In Report view, you can also define controls that respond to events, similar to what you can do with forms. We defined a Click event for the employee number text box and styled it as a hyperlink to provide a visual cue to the user. In Figure 16-15, you can see that the Employee Number field looks like a hyperlink with the data in blue and underlined. Clicking the Employee Number field opens the frmEmployeesPlain form as a dialog box displaying all information for that specific employee so that you can make any necessary changes. After closing the form and returning to the report, click the Refresh All command in the Records group on the Home tab to see any changes you made to the data using the form reflected in the report.
Printing Reports 1039
Chapter 16
Clicking the Employee Number in Report view…
…opens the frmEmployeesPlain form for that employee. Figure 16-15 You can use Report view to respond to control events such as opening data entry forms.
Printing Reports Earlier in this chapter, you learned the basics of viewing a report in Print Preview and in Report view. Here are a few more tips and details about setting up reports for printing.
Print Setup Before you print a report, you might first want to check its appearance and then change the printer setup. Open the ContactsDataCopy database, right-click the rptContacts report (which you looked at earlier) in the Navigation pane, and click the Print Preview command on the shortcut menu to see the report. After Access shows you the report, click the arrow under the Zoom button in the Zoom group on the Print Preview contextual tab, and then size the window to see the full-page view by clicking Fit To Window. Click the Two Pages button in the same group to see two pages side by side, as shown in Figure 16-16.
1040 Chapter 16 Using Reports
Chapter 16 Figure 16-16 Click the Two Pages button on the ribbon to display a two-page view of the rptContacts report in Print Preview.
This report is narrow enough to print two contacts side by side in landscape orientation on 14-inch-long paper. To print it that way, you need to modify some parameters in the Page Setup dialog box. Open the Page Setup dialog box by clicking the Page Setup button in the Page Layout group. Access displays a dialog box similar to the one shown in Figure 16-17.
Figure 16-17 You can open the Page Setup dialog box from the Print Preview tab.
Printing Reports 1041
To print the rptContacts report with two logical pages per physical page, you first need to adjust the margins. You haven’t changed the page orientation yet, so the settings that are currently the top and bottom will become the left and right margins, respectively, after you rotate the page. (And the left and right margins become the top and bottom, respectively.) The pages need to print very close to the edges of the paper, so set the top margin (this becomes the left margin in landscape orientation) to 0.25 inch, set the bottom margin to about 0.5 inch, and set the left and right margins to 0.5 inch. Effectively, the left margin will be the smallest after you change the orientation. Click the Page tab to display the next set of available properties, as shown in Figure 16-18.
Figure 16-18 You can set page orientation options on the Page tab of the Page Setup dialog box.
On the Page tab, you can select the orientation of the printed page—Portrait to print vertically down the length of the page, or Landscape to print horizontally across the width of the page. Because we’re trying to print two pages across a single sheet of paper, select the Landscape option. The report is also about 6½ inches wide, so you’ll need wider paper to fit two logical pages to a printed page. Select Legal (8½-by-14-inch) paper from the Size list under Paper. In general, it’s best to leave the printer set to the default printer that you specified in your Windows settings. If you move your application to a computer that’s attached to a different type of printer, you won’t have to change the settings. You can print any report that you design in Access on any printer supported by Windows with good results. However, if you’ve designed your report to print on a specific printer, you can save those settings by using the Page Setup dialog box. To do this, select the Use Specific Printer option on the Page tab and then click Printer to open a dialog box in which you can select
Chapter 16
1042 Chapter 16 Using Reports
Chapter 16
any printer installed on your system. (The Printer button is available only if you have more than one printer installed on your computer.) Click the Properties button to adjust settings for that printer in its Properties dialog box, shown in Figure 16-19. The Properties dialog box you see might look different, depending on the capabilities of the printer you selected and how Windows supports that printer.
Figure 16-19 You can define properties for a specific printer to be used with your report.
After you finish selecting options on the Page tab, click the Columns tab, as shown in Figure 16-20, to set up a multiple-column report. In this case, you want to print two “columns” of information. After you set the Number Of Columns property to a value greater than 1 (in this case, 2), you can set spacing between rows and spacing between columns. By default, Access selects the Same As Detail check box and displays the design Width and Height measurements of your report. You can also clear the Same As Detail check box and set a custom width and height that are larger or smaller than the underlying report design size.
Printing Reports 1043
Note that if you specify a smaller size, Access crops the report. When you have detail data that fits in more than one column or row, you can also tell Access whether you want the detail printed down and then across the page or vice versa.
Figure 16-20 You can set report column properties on the Columns tab of the Page Setup dialog box.
Note If you created the report or have permission to modify the design of the report, you can change the page layout settings and save them with the report. The next time you print or view the report, Access will use the last page layout settings you specified.
After you enter the appropriate settings in the Page Setup dialog box, click OK, and your report in Print Preview should look like the one shown in Figure 16-21. You can find this modified version of the Contacts report saved in the sample database as rptXmplContacts2Page.
Chapter 16
1044 Chapter 16 Using Reports
Chapter 16 Figure 16-21 Print Preview now displays the rptContacts report in landscape orientation and in two columns.
The most common use for setting multiple columns is to print mailing labels. You can find four example reports in the sample database that do this: rptCompanyLabels5160 and rptContactLabels5160, which print company and contact labels two across in Avery 5160 format; and rptCompanyLabels5163 and rptContactLabels5163, which print company and contact labels three across in Avery 5163 format. That covers the fundamentals of reports and how to view them and set them up for printing. The next two chapters will show you how to design and build client and web reports for your application.
onstructing a report is very similar to building a form. In this chapter, you’ll apply many of the techniques that you used when working with client and web forms, and you’ll learn about some of the unique features of reports. After a quick tour of the report design facilities, you’ll build a simple report for the Conrad Systems Contacts client database, and then you’ll use the Report Wizard to create the same report. You’ll see how to use the quick create Report command to create a report with one mouse click. Finally, you’ll learn how to create and modify web reports using Layout view in web databases.
Note The examples in this chapter are based on the reports, tables, and data in the ContactsDataCopy.accdb and BOSSDataCopy2.accdb sample databases on the companion CD included with this book. You can find similar reports in the Conrad Systems Contacts and Back Office Software System sample client and web applications, but all the reports in those sample files have custom ribbons defined, so you won’t see the four main ribbon tabs when you open those reports. The results you see from the samples in this chapter might not exactly match what you see in this book if you have changed the sample data in the files. Also, all the screen images in this chapter were taken on a Windows 7 system with the Access color scheme set to Silver. Your results might look different if you are using a different operating system or a different theme.
Starting from Scratch—A Simple Report In a contact tracking application, the user is going to want to look at recent events and perhaps work through a list of events that require follow-ups. Although the user could search for events in a form, the application should also provide a report that lists events by contact and shows the phone numbers the user needs. This report can be filtered by the application to print out only recent and upcoming events.
1045
1046 Chapter 17 Constructing a Report
Chapter 17
Most reports gather information from several tables, so you’ll usually design a query that brings together data from related tables as the basis for the report. In this section, you’ll build a relatively simple report to list contact events as you tour the report design facilities. The report you’ll build uses the tblContacts, tblContactEvents, and tlkpContactEventTypes tables in the ContactsDataCopy.accdb sample database. The report groups contact event data by contact, prints a single line for each contact event, and calculates the number of contact events and the number of follow-ups for each contact.
Building the Report Query To construct the underlying query for the report, you need to start with the tblContactEvents table. Click the Query Design button in the Queries group on the Create tab. In the Show Table dialog box, select the tblContactEvents table, click the Add button to add it to the query design grid, and then add the tblContacts and the tlkpContactEventTypes tables as well. Click the Close button in the Show Table dialog box to dismiss it. You should see join lines between tblContacts and tblContactEvents on ContactID, and between tlkpContactEventTypes and tblContactEvents on ContactEventTypeID. From the tblContacts table, add ContactID to the query design grid. The report needs to show the contact name, but it would be better to show the information concatenated in one field rather than separate title, first name, middle name, last name, and suffix fields. In the next column, enter this expression on the Field line: Contact: ([tblContacts].[Title]+" ") & [tblContacts].[FirstName] & " " & ([tblContacts].[MiddleInit]+". ") & [tblContacts].[LastName] & (", "+[tblContacts].[Suffix])
Notice that the expression uses the plus sign concatenation operator to eliminate extra blanks when one of the fields contains a Null value—a technique you learned in Chapter 9, “Creating and Working with Simple Queries.” The query also needs to include the contact’s phone number, but the tblContacts table includes both a work and a home phone number. You can create an expression to examine the DefaultAddress field to decide which one to display. Microsoft Access 2010 provides a handy function, Choose, which accepts an integer value in its first argument and then uses that value to choose one of the other arguments. For example, if the first
Starting from Scratch—A Simple Report 1047
argument is 1, the function returns the second argument; if the first argument is 2, the function returns the third argument, and so on. The DefaultAddress field contains a 1 to indicate work address and a 2 to indicate home address. In the third field cell on the query design grid, enter the following: Phone: Choose([tblContacts].[DefaultAddress], [tblContacts].[WorkPhone], [tblContacts].[HomePhone])
To complete your query, include the ContactDateTime field from the tblContactEvents table and the ContactEventTypeDescription field from the tlkpContactEventTypes table. (ContactEventTypeID in tblContactEvents is a meaningless number.) Then include the ContactNotes, ContactFollowUp, and ContactFollowUpDate fields from the tblContactEvents table. Figure 17-1 shows the query you need for this first report. Click the Save button on the Quick Access Toolbar to save your new query. (You can find this query saved as qryRptContactEvents in the sample database.)
Figure 17-1 This query selects contact and contact event data for your report.
Note that although you’re designing a report that will summarize the data, you are not building a totals query. If you used a totals query as the record source for the report, you would see only the summary in the report. One of the great advantages of reports is that you can see the detail information and also ask the report to produce summaries. In addition, you don’t need to specify any sorting criteria here—you’ll do that later in the report’s Group, Sort, And Total pane.
Chapter 17
1048 Chapter 17 Constructing a Report
Designing the Report Chapter 17
Now, you’re ready to start designing the report. Click the Report Design button in the Reports group on the Create tab to tell Access 2010 that you want to begin creating a report in Design view, as shown in Figure 17-2.
Figure 17-2 Click Report Design to start creating your report.
The field list, the property sheet, and the Font and Controls groups on the Design and Format contextual tabs under Report Design Tools are similar to the features you used in building forms. See Chapter 13, “Building a Form,” for detailed descriptions of their uses.
Access 2010 opens a new Report window in Design view, as shown in Figure 17-3. You can see the Report Design Tools collection of ribbon tabs at the top of the Access window. The Report window is in the middle of the screen, and the property sheet is open to assist you in building your report. (If necessary, you can click the Property Sheet button in the Tools group on the Design tab to open this window.) To begin constructing your report, you need to tell Access to use the qryRptContactEvents query as its record source. In the property sheet, select qryRptContactEvents (or the name of the query you just created) in the Record Source property, as shown in Figure 17-3.
Starting from Scratch—A Simple Report 1049
Themes group Grouping & Totals group
Property sheet Report contextual tabs Controls group
Figure 17-3 When you open a new Report window in Design view, Access displays all the tools you need to create the report.
The blank report has Page Header and Page Footer sections and a Detail section between them, which is 5.25 inches (13.333 cm) high and 6.1694 inches (15.668 cm) wide. The rulers along the top and left edges of the Report window help you plan space on the printed page. If you want standard 1-inch side margins, the body of the report can be up to 6½ inches wide on an 8½-by-11-inch page. The available vertical space depends on how you design your headers and footers and how you define the top and bottom margins. As with forms, you can drag the edge of any report section to make the section larger or smaller. Note that the width of all sections is the same, so if you change the width of one section, Access 2010 changes the width of all other sections to match.
Chapter 17
1050 Chapter 17 Constructing a Report
Chapter 17
Within each section, you see a grid that has 24 dots per inch horizontally and 24 dots per inch vertically, with a solid gray line displayed at 1-inch intervals. If you’re working in centimeters, Access 2010 divides the grid into 5 dots per centimeter both vertically and horizontally. You can change these settings using the Grid X and Grid Y properties in the report’s property sheet. (If the dots are not visible in your Report window, click the Grid command under the Size/Space in the Sizing & Ordering group on the Arrange contextual tab; if the Grid command is already selected and you still can’t see the dots, try resetting the Grid X and Grid Y properties to lower numbers in the property sheet.) The page header and page footer will print in your report at the top and bottom of each page. You can right-click anywhere on the report grid design surface and then click the Page Header/Footer button from the shortcut menu to add or remove the page header and page footer. You can also add a report header that prints once at the beginning of the report and a report footer that prints once at the end of the report. To add these sections to a report, right-click anywhere on the report grid design surface and then click the Report Header/Footer button from the shortcut menu. You’ll learn how to add group headers and group footers in the next section.
Grouping, Sorting, and Totaling Information A key way in which reports differ from forms is that in reports, you can group information for display using the Group, Sort, And Total pane. Click the Group & Sort button in the Grouping & Totals group on the Design tab (shown in Figure 17-3) to open the Group, Sort, And Total pane beneath the report design grid, as shown in Figure 17-4. (We collapsed the Navigation pane in Figure 17-4.) In this pane, you can define up to 10 fields or expressions that you will use to form groups in the report. The first item in the list determines the main group, and subsequent items define groups within groups. (You saw the nesting of groups in the previous chapter in the rptProductSalesByProduct report; each product category had a main group, and within that main group was a subgroup for each product.) Because we have not yet defined any grouping or sorting in this report, the Group, Sort, And Total pane opens to a blank pane that allows you to click either Add A Group or Add A Sort.
Starting from Scratch—A Simple Report 1051
Chapter 17
Group, Sort, And Total pane Figure 17-4 You can create groups and specify their sort order in the Group, Sort, And Total pane.
In the simple report you’re creating for contact events, you need to group data by contact ID so that you can total the number of contact events as well as contact events that require follow-up for each contact. Click the Add A Group button in the Group, Sort, And Total pane. Access 2010 creates a new grouping specification and opens a list that contains all fields in the report’s record source next to the Group On option, as shown in Figure 17-5. (We collapsed the Navigation pane and closed the property sheet in Figure 17-5 so that you can see more of the Group, Sort, And Total pane.)
1052 Chapter 17 Constructing a Report
Chapter 17 Select Field box Figure 17-5 After you click Add A Group in the Group, Sort, And Total pane, Access creates a new grouping specification and opens a field list to let you select the field that defines the group.
If you click away from the field list before selecting a field to define the group, Access 2010 closes the field list. Click the arrow on the Select Field box (or press Alt+down arrow while the focus is on the Select Field box) to open the list of fields from the underlying query or table. Select the ContactID field to place it in the Select Field box. You can also use the Select Field box to enter an expression based on any field in the underlying table or query. Open the field list again and click the Expression option below the list of fields, and Access opens the Expression Builder to help you create the expression. You let Access know you’re entering an expression by first typing an equals sign (=) followed by your expression. We discussed the Expression Builder in Chapter 9.
Note When you define a grouping specification in a report, the report engine actually builds a totals query behind the scenes to perform the grouping. As you learned in Chapter 10, “Building Complex Queries,” you cannot use Group By in a totals query on memo, OLE object, hyperlink, or attachment fields. For this reason, you cannot use Memo, OLE Object, Hyperlink, or Attachment data types in the Group, Sort, And Total pane.
After you select ContactID in the Select Field box, Access 2010 adds a new ContactID group header to the report grid beneath the Page Header group level, as shown in Figure 17-6. By default, Access sets the height of this new group level to ¼ inch. Access also displays the Add A Group and Add A Sort buttons beneath the first grouping specification so you can create additional grouping or sorting levels. To the right of the Group On ContactID in the Group, Sort, And Total pane, Access now adds two new options—From Smallest To Largest and More.
Starting from Scratch—A Simple Report 1053
Chapter 17
ContactID group level
More Group Interval Add A Sort Add A Group
Move Priority Up Move Priority Down Delete Grouping And Sorting Level
Figure 17-6 After you add a group in the Group, Sort, And Total pane, Access creates a new group level on the grid.
By default, Access 2010 sorts each field or expression in ascending order. You can change the sort order by selecting From Largest To Smallest from the list that appears when you click the arrow to the right of the second option (From Smallest To Largest, in this example). In this case, you want to include the ContactID field so that you can form a group for each contact. Leave the sort order on From Smallest To Largest so that the report will sort the rows in ascending numerical order by the ContactID field. If you wanted to see the contacts in alphabetical order by last name, you would need to include the LastName field in your query (even if you didn’t display it on the report), and group and sort on the LastName field. You could use the Contact expression that you included in the query, but then the report would sort the rows by title and first name.
1054 Chapter 17 Constructing a Report
Note Chapter 17
Access 2010 changes the choices in the second option in the grouping specification depending on the data type of the field or expression you specified in Group On. When the data type is Text, you’ll see With A On Top and With Z On Top options. When the data type is Date/Time, you’ll see From Oldest To Newest and From Newest To Oldest. If the data type is Yes/No, you’ll see From Selected To Cleared and From Cleared To Selected. As you saw in our example, Access uses From Smallest To Largest and From Largest To Smallest for fields with a Numeric data type.
Click the More option in the ContactID grouping specification to see all the grouping and sorting options, as shown in Figure 17-7. Access now displays a total of eight grouping and sorting options. If you look at Figure 17-7, you can see that Access creates a sentence structure to help you understand how this grouping level will take shape. If you want to collapse the list of options, click Less at the end of the list. Sort order Group interval Totals
Title
Header section
Less - collapse the option list Keep together Footer section Figure 17-7 Click More to expand the list of grouping and sorting options.
The third option in the grouping specification (By Entire Value, in our example) is called the group interval, which tells Access how to group the records. Click the arrow to the right of this option for a grouping based on the ContactID field, as shown in Figure 17-8. For AutoNumber, Number, and Currency data types, Access displays the following grouping options—By Entire Value, By 5s, By 10s, By 100s, By 1000s, and Custom, which lets you set your own interval. For Text data types, you can set the group interval to By Entire Value, By First Character, By First Two Characters, or Custom, which lets you set your own interval. For Date/Time data types, you can set the group interval to By Entire Value, By Day, By Week, By Month, By Quarter, By Year, or Custom, which lets you set your own interval. Leave the group interval set to By Entire Value for the ContactID group level.
Starting from Scratch—A Simple Report 1055
Figure 17-8 The group interval displays different options based on the field’s data type.
You use the fourth option in the grouping specification (which currently displays With No Totals in our example) to configure Access to list totals for a single field or for multiple fields. Click the arrow to the right of this option for a grouping based on the ContactID field, as shown in Figure 17-9. Select the field on which you want Access to calculate and display totals from the Total On list. In the Type box, you can choose from several types of calculations based on the data type of the field you chose in the Total On box. Beneath the Type box are four check boxes for additional totaling options. Select the Show Grand Total check box to add a grand total for this field in the report’s Footer section. Select the Show Group Subtotal As % Of Grand Total check box if you want Access to calculate the percentage of the grand total for each group and place that percentage in the group header or footer. Select the Show Subtotal In Group Header check box to place the total and optional percentage in the group’s Header section and the Show Subtotal In Group Footer check box to place the total and optional percentage in the group’s Footer section. Leave the option for the Totals list set at With No Totals for the ContactID group level.
Figure 17-9 You can ask Access to calculate and display totals in the Totals list.
You use the fifth option in the grouping specification to define a title. You can choose to create a title that appears in a label control in the Header section of the group. To create a title, click the blue Click To Add text. Access opens the Zoom dialog box, shown in Figure 17-10, where you can enter a title. You can click Font to define the font, font style, size, and color of the title letters. After you enter a title, click OK, and Access creates a new label control in the Group Header section on the report grid. For the grouping based on the ContactID field, click Cancel to not enter a title at this time.
Chapter 17
1056 Chapter 17 Constructing a Report
Chapter 17 Figure 17-10 Access displays the Zoom dialog box when you want to add a title to a group header.
You use the sixth option in the grouping specification to display a Header section for the specific group. Click the arrow to the right of this option and you can select either With A Header Section (the default selection) or Without A Header Section, as shown in Figure 17-11. When you select the option to include a header, Access creates the Header section for the group for you. Conversely, Access removes the group header, and all controls in it, if you select the second option. If you have defined controls in the Header section when you choose Without A Header, Access displays a confirmation dialog box explaining that you’re deleting both the header and all its controls, and asks you to confirm the deletion. For the ContactID field in our example, leave the option set to the default—With A Header Section.
Figure 17-11 You can choose to have Access create a group header for you.
Starting from Scratch—A Simple Report 1057
Similar to the Header section option, you can use the seventh option to display a Footer section for the grouping specification. Click the arrow to the right of this option and select either With A Footer Section or Without A Footer Section (the default selection), as shown in Figure 17-12. When you select the option to include a footer, Access creates the Footer section for you. Conversely, Access removes the group Footer, and all controls in it, if you select the second option. If you have defined controls in the footer section when you choose Without A Footer Section, Access displays a confirmation dialog box explaining that you’re deleting both the footer and all its controls, and asks you to confirm the deletion. For the ContactID field, you will need a place to put two calculated total fields (the count of contact events and the count of follow-ups). Click the arrow to the right of this option and select With A Footer Section.
Figure 17-12 Select the With A Footer Section option to include a Footer section for the ContactID group on the report.
You use the last option in the grouping specification, as shown in Figure 17-13, to control how Access will lay out the report when you print it. Click the arrow to the right of this option, and you have three choices—Do Not Keep Group Together On One Page (the default), Keep Whole Group Together On One Page, and Keep Header And First Record Together On One Page. The Do Not Keep Group Together On One Page option allows a section to flow across page boundaries. The Keep Whole Group Together On One Page option attempts to keep all lines within a section together on a page. If an entire group won’t fit on the current page (and the current page isn’t blank), Access moves to the top of the next page before starting to print the group, but the group still might overflow the end of the new page. If you select Keep Header And First Record Together On One Page, Access does not print the header for the group at the bottom of the page if it cannot also print at least one detail record. For the ContactID field, leave the option set to the default—Do Not Keep Group Together On One Page. You’ll learn more about how to use the group on, group interval, and keep together settings in the next chapter.
Chapter 17
1058 Chapter 17 Constructing a Report
Chapter 17
Figure 17-13 You can choose among several options to control how the report will look when printed.
It would also be nice to see the contact events in descending date order for each contact (most recent or newest events first). To add the ContactDateTime field below ContactID, click Add A Sort, and Access creates a new sort specification. Select ContactDateTime in the Select Field box and change the sort order to From Newest To Oldest. Click More to display the rest of the options available to you for the sort specification. Leave the group interval set to By Entire Value, and leave the Totals option set to the default With No Totals. Do not add a title for this field and make sure not to include a group header or group footer. (If you add a header or footer, Access changes your specification from a sorting specification to a grouping specification.) Finally, keep the last option set to Do Not Keep Group Together On One Page. Your completed sorting specification for the ContactDateTime field should look like Figure 17-14.
Figure 17-14 Access will now sort the contact event records for your report in descending order.
You can change the priority of two or more grouping or sorting specifications by using the arrows on the right side of the Group, Sort, And Total pane. If you need to move a group up one level, select that group and then click the up arrow one time. Similarly, if you need to move a group down one level, select that group and then click the down arrow one time. Access repositions any group headers and footers for you during this process. To delete a group level, select it and then click Delete (the X) to the right of the up and down arrows. Close the Group, Sort, And Total pane now by clicking the Close button on its title bar or by clicking the Group & Sort button in the Grouping & Totals group on the Design tab.
Starting from Scratch—A Simple Report 1059
Understanding Who Controls the Sorting
You can specify sorting criteria in the query for a report, but after you set any criteria in the Group, Sort, And Total pane, the report overrides any sorting in the query. The best way to ensure that your report data sorts in the order you want is to always specify sorting criteria in the Group, Sort, And Total pane and not in the underlying query.
Completing the Report Now, you’re ready to finish building a report based on the tblContactEvents table. Take the following steps to construct a report similar to the one shown in Figure 17-15. (You can find this report saved as rptXmplContactEvents1 in the sample database.)
Figure 17-15 This is the completed Contact Events report that you will create in Design view.
1. Click the Title button in the Header/Footer group on the Design tab to place a new label control in the Report Header section. By default, Access enters the name of the report (in this case Report1) into the label. Click inside this label and highlight or delete the existing characters, type Contact Events, and press Enter to change the label’s caption. Access placed this title in a new section it created—the Report Header. Any control placed in the Report Header section gets printed only on the first page of the report. We want to see this label on every page, so select the label control and then click the Move Down button in the Move group on the Arrange tab. Access moves the label control down into the Page Header section. (Note that
Chapter 17
INSIDE OUT
1060 Chapter 17 Constructing a Report
Chapter 17
Access created this new label in a control layout which means you can’t drag the label control down into a different section of the report.) Now, remove the Report Header section by right-clicking anywhere on the report grid design surface and then clicking the Report Header/Footer button on the shortcut menu. Access created an empty cell to the left of the label control which we don’t need. Select the empty cell and then press Delete to remove it. Select the label control and use the commands in the Font group on the ribbon to change the font to Arial and the font color to Black. Next, click the Bold and Underline buttons in the Font group, and then click the To Fit command under the Size/Space command in the Sizing & Ordering group on the Arrange tab to size the control to accommodate the new font adjustments.
2. Click the Add Existing Fields button in the Tools group on the Design tab to show the field list. If you see Fields Available In Related Tables and Fields Available In Other Tables, click Show Only Fields In The Current Record Source at the top of the field list to reduce the number of fields and tables you see. Drag the Contact field from the field list and drop it into the ContactID Header section. Use Arial 10-point bold for the label control and the text box control and set the font color to Black for both controls. Select the text box control and make it about 2 inches wide so that there’s room to display all the characters in the contact name. Also drag and drop the Phone field into the header, and set the resulting text box control and the label control to Arial 10-point bold and the font color to Black. Size all these controls to fit and line them up near the top of the section. Select the Phone text box control and set the Input Mask property to \(999") "000\-0000 to display the data formatted as a phone number.
3. You’ll need some column labels in the ContactID Header section. The easiest way to create them is to set up the text box control so that it has an attached label with no colon, set the defaults for the label control to the font you want, drag the fields you need to the Detail section, and then cut the label controls from their respective text box controls and paste them into the header. First, widen the design area of the report to about 6.5 inches and increase the height of the ContactID Header section to about 0.5 inch to give yourself some room to work. Next, to set the default properties for the text box and label controls, make sure the property sheet is open (click the Property Sheet button in the Tools group on the Design tab). Click the Text Box button in the Controls group on the Design tab. Select the All tab in the property sheet, scroll down, and check that the Auto Label property is set to Yes and that the Add Colon property is set to No. Also, set the Font Name property to Arial, the Font Size property to 8, and the Fore Color to Black (#000000). Click the Label button in the Controls group, and set its font to Arial 8-point bold, underlined, and black. (You set the font to bold by modifying the Font Weight property.) Click the Add Existing Fields button in the Tools group to hide the property sheet and open the field list. Now, drag the ContactDateTime, ContactEventTypeDescription, ContactNotes,
Starting from Scratch—A Simple Report 1061
ContactFollowUp, and ContactFollowUpDate fields from the field list and drop them into the Detail section one at a time. Select the label for ContactDateTime, and then choose the Cut command in the Clipboard group on the Home tab (or press Ctrl+X) to separate the label from the control and move it to the Clipboard. Click the ContactID Header bar, and then click the Paste command in the Clipboard group (or press Ctrl+V) to paste the label in the upper-left corner of the ContactID Header section. Notice that you can now move the label independently in the ContactID Header section. (If you move the label before you separate it from its control, the control moves with it.) Separate the labels from the ContactEventTypeDescription, ContactNotes, ContactFollowUp, and ContactFollowUpDate controls one at a time, and move them to the ContactID Header section of the report.
Note As you paste each label, you’ll see warning smart tags appear that notify you that the labels aren’t associated with any control. This is useful to know when you create labels in the Detail section. But in this case, this is what you want, so click the smart tag and select the Ignore Error option to turn off the warning for each label.
4. Line up the column labels in the ContactID Header section, placing the Date / Time label near the left margin, the Contact Type label about 1.1 inches from the left margin, the Notes label about 2.75 inches from the left margin, the Follow Up? label about 4.5 inches from the left margin, and the Follow-up Date label about 5.4 inches from the left margin. You can set these distances in the Left property of each label’s property sheet. Line up the tops of the labels by dragging a selection box around all five labels using the Select button in the Controls group on the Design tab and then clicking the Top command under the Align command in the Sizing & Ordering group on the Arrange tab.
5. You can enhance the appearance of the report by placing a line control across the bottom of the ContactID Header section. Click the Line button in the Controls group, and place a line in the ContactID Header section. To position this control at the bottom of the section, you need to find out the section’s height. Click the ContactID Header bar to select the section, open the property sheet, and find the Height property. Next, select the line control, and set the following properties: Left 0, Width 6.5, and Height 0. Set the Top property equal to the Height of the section. (It’s difficult to see this line in Figure 17-15, because it is hidden against the bottom of the section. You’ll see it when you switch to Print Preview.)
Chapter 17
1062 Chapter 17 Constructing a Report
6. You can make the text box control for ContactDateTime smaller (about 0.9 inch), and Chapter 17
you need to make the ContactEventTypeDescription text box control about 1.6 inches wide. Set the Text Align property for the ContactDateTime and ContactFollowUpDate text box controls to Left. Access sized the text box for the ContactNotes field too wide because ContactNotes is a Memo data type. Select the ContactNotes and ContactEventTypeDescription text box controls together, click the Size/Space command in the Sizing & Ordering group on the Arrange tab, and then click the To Narrowest button to make the ContactNotes text box the same width as the ContactEventTypeDescription text box.
7. Align the text box controls for ContactDateTime, ContactEventTypeDescription, ContactNotes, ContactFollowUp, and ContactFollowUpDate under their respective labels. You can align each one by placing each text box control to the right of the left edge of its label, selecting them both (hold down the Shift key while selecting each one), and then left aligning them by clicking the Align command in the Sizing & Ordering group on the Arrange tab, and then clicking the Left button. Align the ContactFollowUp check box control visually under the center of its label. Select all the controls in the Detail section and top align them by clicking the Top button under the Align command in the same group.
8. The height of the Detail section determines the spacing between lines in the report. You don’t need much space between report lines, so make the Detail section smaller, until it’s only slightly higher than the row of controls for displaying your data. (About 0.3 inch should suffice.)
9. Expand the height of the ContactID Footer section and then add a text box in this section under the ContactFollowUpDate text box control and delete its attached label. To calculate the number of events, click the text box control, and in the Control Source property in the property sheet, enter =Count([ContactID]) It’s a good idea to repeat the grouping information in the footer in case the detail lines span a page boundary. One way to do that is to add an expression in a text box. Add a second text box to the left of the first one (also delete its label) and stretch it to about 3.5 inches wide. Click the leftmost text box control to select it, and in the Control Source property in the property sheet, type ="Total contact events for " & [Contact] & ":" Change the text box alignment to Right and change its font to Bold.
10. Add a third text box control in the ContactID Footer section under the first one. In the Control Source property in the property sheet, enter = –Sum([ContactFollowUp])
Starting from Scratch—A Simple Report 1063
Keep in mind that a True value in a yes/no field is the value –1. So, summing the values and then displaying the negative should give you a count of the contact events that require a follow-up. Click the attached label control and change the Caption Property in the property sheet to Number of events that require a follow-up: Change Font Underline to No, right align the label, and size it to fit.
11. Add a line to the bottom of the ContactID Footer section to separate the end of the information about one contact from the next one. You can click the heading bar of the ContactID Footer to select the section and then look in the property sheet to find out the section’s height, which should be about 0.5 inch. Select the line again, and in the property sheet, set Left to 0, Top to the height of the section, Width to 6.5, Height to 0, and Border Width (the thickness of the line) to 2 pt.
12. Click the Page Numbers button in the Header/Footer group on the Design tab to open the Page Numbers dialog box shown here.
You want to display the current page number and the total number of pages on each page, so select the Page N Of M option under Format. The Page N option displays only the current page number. Next, to display these page numbers at the bottom of the report, select Bottom Of Page [Footer] under Position. The Top Of Page [Header] option places the control in the Page Header section of the report. In the Alignment list, select Right to display the page numbers on the right side of the page. The Left alignment option places the control that displays the page numbers on the left side of the report design grid, and the Center alignment option places the control in the center. The Inside alignment option places one control on the left side and one control on the right side of the report design grid. Access sets the Control Source property of these controls so that page numbers appear in the inside margin of pages in a bound book—odd page numbers appear on the left and even page numbers appear on the right. The Outside alignment option works just the opposite of Inside—even page numbers appear on the left and odd page numbers appear on the right.
Chapter 17
1064 Chapter 17 Constructing a Report
Chapter 17
Select the Show Number On First Page check box at the bottom of the dialog box to display the page numbers on all pages, including the first page. If you clear this check box, Access creates a control that will not show the page number on the first page. Click OK in the Page Numbers dialog box, and Access creates a new control in the Page Footer section.
13. Click the new text box control that you just created in the page footer, and look at the Control Source property in the property sheet. Access created the expression ="Page " & [Page] & " of " & [Pages] in the Control Source property of the text box. [Page] is a report property that displays the current page number. [Pages] is a report property that displays the total number of pages in the report. Change the Text Align property to Right for this new control.
14. By default, Access added borders around nearly all the label and text box controls you added. You don’t need the borders around these controls, so let’s remove them. Hold down the Shift key and then select each label and text box one by one in the ContactID Header section, the Detail section, and the ContactID Footer section. (You do not need to select the label in the Page Header section nor the two line controls.) Now, set the Border Style property on the Property Sheet window to Transparent to change all the controls at once. Finally, Access added an alternating back color to the ContactID Header and Footer section and the Detail section. When the Alternate Back Color property for a section is set to a color, Access alternates between showing that color and white when it formats each successive section. To remove the color, select the ContactID Header section, click the bottom half of the Alternate Row Color button in the Background group on the Format tab to open the Color Picker dialog box, and then click No Color. Repeat this step for the Detail and ContactID Footer sections.
After you finish, click the arrow below the View button in the Views group on the ribbon and click Print Preview to see the result, shown in Figure 17-16. Notice, in this figure, that the detail lines are sorted in descending order by contact date/time. You’ll recall from Figure 17-14 that the grouping and sorting specifications include a request to sort within a group on ContactDateTime.
Starting from Scratch—A Simple Report 1065
Chapter 17
Figure 17-16 This is how your completed Contact Events report looks in Print Preview.
Now that you’ve seen how to create a report from scratch, you should have a good understanding of how to work with the individual design elements. In the next sections, we’ll show you how to get a jump-start on your report design using the quick create Report command and the Report Wizard. You’ll probably find that using one of these features is a good way to get a report started, and then you can use what you’ve learned thus far to fully customize your reports.
INSIDE OUT
Summing Yes/No Fields on Web Reports
In this section, we showed you how to write an expression in the Control Source property of a text box to display a sum of True values in a Yes/No field in a group Footer section. We had you enter the following expression into the Control Source property: = –Sum([ContactFollowUp]) If you use this same expression on a web report, the expression evaluates to an error when you view the report in a web browser. On the server, you cannot use arithmetic expressions with values in a Yes/No field. If you are creating a web report and need to sum the True values in a Yes/No field, you should use the Immediate If function to evaluate the Yes/No field and then use 0 or 1 based on the field value for your Sum expression. Using the field name in the previous example, the following expression would correctly count the number of True values in the ContactFollowUp field on a web report and display them in a web browser: =Sum(IIf([ContactFollowUp]False,1,0))
1066 Chapter 17 Constructing a Report
Using the Report Command Chapter 17
Access 2010 includes a quick create Report command that makes it easy for you to quickly create quality reports. Similar to the quick create form commands, the Report command is a one-step process—you’re not presented with any options or dialog boxes; Access simply creates a generic report with one click. You can use either a table or query as the base for the report. We’ll create two quick reports to illustrate this process using the ContactsDataCopy.accdb sample database. Open ContactsDataCopy.accdb, click the Navigation Pane menu, click Object Type under Navigate To Category, and then click Queries under Filter By Group to display a list of queries available in this database. The qryContacts query includes all the fields from the tblContacts table and sorts them by last name and then first name. Let’s create a nice report of your contacts using this query. Scroll down to this query in the Navigation pane, select it, and then click the Report command in the Reports group on the Create tab, as shown in Figure 17-17.
Figure 17-17 Click the Report command to let Access build a report using the qryContacts query.
Using the Report Command 1067
After just a second or two, Access 2010 creates an entire report with all the fields in the query, complete with a logo, a title, the current date and time, a colored line beneath the column labels, and even a page count at the bottom of the pages, as shown in Figure 17-18. (You can best see the page count in Print Preview view.) Access opens the report in Layout view so that you can begin the process of making modifications.
Figure 17-18 With one click, Access creates an entire formatted report for your convenience.
If you look closely at the report, you’ll see that there are significant problems with this layout. Access spread all the fields out in a tabular control layout. If you switch to Print Preview, you can see that this report would not be easy to read because the data in many columns wraps to multiple lines, and you have to scan across three pages to find all the data for each contact. If the number of contact records were even larger, the report would be extremely hard to follow. Access did much of the hard work for you in creating the report, but you still need to make many modifications in either Layout view or Design view to make the report readable. (We’ll discuss Layout view in more detail later in this chapter.) Close this report now, and don’t save it when prompted. The qlkpProducts query includes all the fields from the tblProducts table and sorts them by product name. Select this query in the Navigation pane, and then click the Report command in the Reports group on the Create tab. Access 2010 creates another report very similar to the first one, as shown in Figure 17-19.
Chapter 17
1068 Chapter 17 Constructing a Report
Chapter 17 Figure 17-19 This report is easier to understand than the one created on a more complex query.
This query has only six fields, so Access was able to do a better job of laying out the fields horizontally. However, the Expire field spills over onto a second page. Using the techniques you learned earlier in this chapter, it would probably take you less than a minute to resize some of the controls to fit everything onto one page and change the title. The rest of the report looks very usable as is. As you can see, the Report command can save you time compared to starting a report from scratch. Close the report, and don’t save it when prompted.
INSIDE OUT
When to Use the Report Command
The Report command’s strength is speed, not finesse. As the previous two examples demonstrate, this report option is not suited for all occasions. For complex queries or tables with quite a few fields, it might take you longer to clean up a report created with this one-click approach compared to starting from scratch. Although the Report command does create a simple total for the Price field, it does not create any groups or sorts, so you would have to manually add these. We find that the Report command is best suited for simple tables or queries that do not require a lot of complex report analysis.
Using the Report Wizard 1069
The Report Wizard that Access 2010 provides to assist you in constructing reports is similar to the Form Wizard you used earlier to create forms. To practice using the Report Wizard, we’ll build the Contact Events report again. Click the Navigation Pane menu, click Object Type under Navigate To Category, and then click Queries under Filter By Group. Select the qryRptContactEvents query in the Navigation pane, and then click the Report Wizard button in the Reports group on the Create tab to open the Report Wizard.
Specifying Report Wizard Options On the first page of the Report Wizard, shown in Figure 17-20, select the fields you want in your report. (If you have a table or query selected in the Navigation pane and then click Report Wizard, Access automatically uses that object as the record source for the report.) You can select all available fields in the order in which they appear in the underlying query or table by clicking the double right arrow (>>) button. If you want to select only some of the fields, or if you want to specify the order in which the fields appear in the report, select one field at a time in the Available Fields list and click the single right arrow (>) button to move the field to the Selected Fields list. If you make a mistake, you can select the field in the Selected Fields list and then click the single left arrow () symbol separating the pairs. You can think of the Path argument with the greater than symbol as the following: Access loads the form specified to the right of the greater than symbol into the subform control specified to the left of the greater than symbol. The first form name you specify in the Path argument must be a form currently loaded in the Access window or in your browser window. You can only use the Path argument to change the contents of a subform control that is currently open.
Note When you enter the form, report, and subform container names in the Path argument for the BrowseTo macro action, do not include any brackets or quotation marks even if your object names contain spaces. If you include brackets or quotation marks, Access displays an error message indicating the Path argument is invalid when you execute the macro action.
If you’d like to see how this BrowseTo action works, close the Logic Designer if you still have it open, close the frmInvoiceAudit web form, and then open the frmMainMenu web form from the Navigation pane. (If you are prompted to save any changes to the macro or form when you attempt to close the objects, click No.) After the frmMainMenu opens, click the Purchases top-level navigation button and then click the Audit Invoices second-level navigation button to display the frmInvoiceAudit web form inside the navigation subform. Enter 9/6/2010 in the beginning date control, enter 9/12/2010 in the ending date control, leave the vendor option set on the defaults, and then click the Run Audit command button. Access runs the macro actions you just studied and then displays a message box indicating it found one unbalanced invoice (assuming you have not changed any of the sample data in this database). After you click OK in the message box, Access browses to the frmInvoiceUnbalancedList web form inside the subform container on the frmMainMenu web form and displays the one unbalanced invoice record, as shown in Figure 21-11. You’ll notice that Access selects the Unbalanced navigation button on the navigation control.
Chapter 21
1278 Chapter 21 Automating a Web Application Using Macros
Chapter 21 Figure 21-11 Access browses to the frmInvoiceUnbalancedList web form using the BrowseTo action defined in a different form.
When should you use BrowseTo instead of OpenForm? When you’re working with web forms, you can only open forms in Dialog mode when you use the OpenForm web macro action. You cannot open forms in Normal mode for web forms as you can with client forms. What this means to you as a developer is that you cannot open multiple parent forms using the OpenForm action in web forms. If you use the OpenForm action in a web form, for example, you cannot open a main parent form and then close the one you just opened. If you need this type of automated interface functionality in web forms, you’ll need to use the BrowseTo macro action to open (or browse, in the web context) a new main parent form and then close the parent form you just opened.
Trapping Error Messages In Chapter 7, you learned about the RaiseError data macro action and how you can specify your own error number for this error condition. In Chapter 20, you learned about trapping errors when running user interface macros. When you’re automating your application with user interface macros and calling named data macros, Access (or the server, if you’re running the web application in Access Services) could encounter an error at the user interface level or at the data level. You can trap for specific error message numbers you assign in RaiseError data actions at the user interface level exactly the same way as trapping other macro errors. You can add an If block in a submacro that tests the Number property of the MacroError object and perform different actions based on the error number returned. On the frmInvoiceAudit web form you’ve been studying, we included an error handling submacro in the embedded macro logic attached to the cmdRunAudit command button. If you examine the error handling submacro logic attached to the cmdRunAudit command button, you’ll see the macro first displays a message box to the user indicating an unexpected error occurred. The macro then calls a named data macro to record all the
Checking SharePoint User Permission Group Levels 1279
error details. We pass in the name of the form, the name of the control, the Macro Error number, the Macro Error description, the current user of the application, and the current computer time as parameters to the LogError named data macro. Note that in this specific case, we’ll log all errors in this submacro, but we could just as easily trap for and possibly ignore specific errors or display different messages based on any errors raised during macro execution.
Checking SharePoint User Permission Group Levels In the Back Office Software System sample web database, we verify the assigned group level for a user when the user navigates to the main web startup form in the browser. We then display one of two possible web forms based on the user’s assigned group. We’ll demonstrate how this functionality works in the browser in Chapter 22, but for now, we’ll show you the macro logic and conditional expressions we use to check the Microsoft SharePoint group level. Close any objects you might have open, right-click the web form called frmLoading in the Navigation pane, hold down the Shift key, and then click Layout view from the shortcut menu. Note that you must hold down the Shift key while opening this web form in Layout view to prevent the form’s Load event from firing. If you don’t hold down the Shift key, you won’t see the frmLoading form open because the macro logic, which we’ll discuss in a moment, opens a different form and then closes the frmLoading form. Open the Property Sheet window, select Form from the Select box, click the Event tab on the Property Sheet window, and then click the Build button on the On Load event property line to view the embedded macro logic attached to this event, as shown in Figure 21-12.
Figure 21-12 You can check the SharePoint group membership of a user by using the IsCurrentWebUserInGroup expression.
Chapter 21
1280 Chapter 21 Automating a Web Application Using Macros
Chapter 21
The first part of the macro logic in the form’s OnLoad event (not shown in Figure 21-12), runs a named data macro to see if the Access Services site is available for use by checking a field value stored in the tblSettings web table. Next, the macro logic runs another named data macro to retrieve the version number of the application for use as a display value on the main form of the application. Finally, we use an If block to test the SharePoint grouplevel membership of the current user. In Figure 21-12, you can see that we use the following conditional expression for this test: =IsCurrentWebUserInGroup(“RestaurantManagers”) Or IsCurrentWebUserInGroup(“RestaurantShiftManagers”)
You can use the IsCurrentWebUserInGroup expression to test for a specific SharePoint group name membership. This expression takes one argument—the name of a SharePoint permissions group. Note that you need to enclose the SharePoint group name in quotation marks. In published web applications, the IsCurrentWebUserInGroup expression returns a Boolean value indicating whether the user currently logged in is a part of the specified group. Note that if you use this expression in a client database, the expression always evaluates to false. See Chapter 22 to learn how to create SharePoint permission groups and assign users to your groups.
In our example, if the user is a member of the RestaurantManagers or RestaurantShiftManagers SharePoint group, we browse to the frmMainMenu web form where all the administrative and application features are available. If the user is not in either of these SharePoint groups, the macro browses instead to the frmMainMenuEmployees web form where the employee can see their work schedule only. (We don’t want employees other than managers to be able to view and edit administrative or confidential areas such as employee wages.) By using the IsCurrentWebUserInGroup Access Services web expression, we can display different forms depending which user is accessing the site. You can also selectively show, hide, enable, disable, or change form control elements by using this expression along with the SetProperty action you studied earlier in this chapter. For published web databases, you might also find the following two expressions useful: ●●
CurrentWebUser In published web applications, this expression returns a string representing the user currently logged in. This expression returns Null in client databases.
●●
CurrentWebUserGroups In published web applications, this expression returns a string listing the groups, separated by semi-colons, to which the user currently logged in belongs. This expression returns Null in client databases.
Performing Different Actions When Opening a Web Form in a Browser 1281
Performing Different Actions When Opening a Web Form in a Browser When you’re working with a web database, you might need to know whether a web form is currently open in Access client or in a web browser window. Close the Logic Designer if you still have it open, close any other open objects, and then open the web form called frmMainMenu in Form view from the Navigation pane. This web form is the main form we display to users when they are using the application. This web form also serves as an entry point to our main client form called frmMainMenuClient. If you double-click the image logo displayed at the top of the frmMainMenu web form, you’ll notice that Access closes the frmMainMenu web form and then opens the frmMainMenuClient client form. This little trick serves as a unique entry point to the client forms that complement the web objects in our hybrid application. Open the frmMainMenu in Layout view and let’s take a look at how we test the form’s current context using macros. Open the Property Sheet window, select imgLogo from the Select box, click the Event tab on the Property Sheet window, and then click the Build button on the On Dbl Click event property line to view the embedded macro logic attached to this event, as shown in Figure 21-13.
Figure 21-13 You can use the IsClient expression to test to see if your web form is open in client or in a browser.
In the conditional expression for the If block in this embedded macro, we use the IsClient web expression. The IsClient web expression returns true when evaluated on the client and returns false when evaluated on the server. If the user opens this web form in Access client and double-clicks on the image logo, Access runs this macro logic and determines the web form is open in Access client. Access then performs the BrowseTo macro action inside the If block and browses to the frmMainMenuClient client form. If the user double-clicks the image logo when the web from is open in a browser, Access evaluates the condition to false and, therefore, does not try to open the client form.
Chapter 21
1282 Chapter 21 Automating a Web Application Using Macros
Note Chapter 21
You cannot perform client functionality, such as calling Visual Basic code or using client macro actions, on a web form using the IsClient expression; you are limited to using web macro actions available on web forms. You can, however, open client forms and reports even though Access does not list client form and report names in the dropdown list of object names for OpenForm, OpenReport, or BrowseTo web macro actions. If you want to open a client form or client report in a web macro, you’ll need to manually type the object name in the Object Name argument for those actions.
INSIDE OUT
Using SetProperty under Different Form Contexts
If you’d like to see another example of using the IsClient expression in the Back Office Software System sample web database, look at the embedded macro logic attached to the OnLoad event of the frmInvoiceEdit web form. When you view a form in Access client, you cannot perform a SetProperty macro action that changes the ForeColor property of a tab page. You can, however, change the ForeColor of a tab page when you view a web form in a browser window. We use the IsClient expression to test if the user opened the frmInvoiceEdit web form in client. If the expression evaluates to false, we know the form is currently open in the browser window so the macro dynamically changes the ForeColor of the tab page on the form to green or red depending upon the balanced status of the current invoice.
Avoiding Type Coercion Issues One of the most challenging aspects you’ll find in automating your web application is avoiding type coercion issues. Access client is generally correct when it needs to guess the data type of a value in a control used in a user interface or data macro. When you’re viewing your web forms in a browser, however, Access Services does not always follow the client behavior. You might find that your macro actions on web forms function exactly the way you want when you work with the form in Access client, but the same macro actions result in different behavior, perhaps even displaying runtime error messages, when you work with the same web form in a browser. In general, if you have a web form control bound to a field in a web table, or a field in a web query that is bound to a field in a table, the server can correctly identify the data type of the data displayed in the control when you use that value in user interface and data macro actions. You might, however, encounter errors when you use unbound text boxes on
Avoiding Type Coercion Issues 1283
web forms displayed in the browser. By default, the server interprets an unbound text box as a string data type. If you’re working with string values in the text box, this won’t be an issue. If you’re working with Number, Currency, or Date/Time values, you’ll likely encounter unexpected results. Unfortunately, the server does not offer as many tools as client does to convert a value to another data type. For web forms, you can only use the CDbl function to convert a value in an unbound text box to a Double. To work around the limitations of unbound controls, make sure you set the Format property of the unbound control to a format appropriate for the data type. If you set a Format property for the unbound control, the server uses that property to determine the data type of the data to use in your macro actions. For example, if you examine the unbound date controls on the web forms in the Back Office Software System, you’ll notice we set the Format property to Short Date. If we have a text box control that displays a whole number value, we set the Format property to Standard and the Decimal Places property to 0. If we use an unbound combo box control that displays the ID and other values from a web table, we generally wrap the control value within a CDbl function inside macro action expressions before sending the data to other actions such as OpenForm, OpenReport, or RunDataMacro. If we want to display currency values, we set the Format property to Currency. See Article 4, “Function Reference,” on the companion CD, for a list of Access functions supported in web objects.
We’ve previously discussed the topic of Boolean values and web objects in Chapter 6, “Designing Web Tables,” but the topic bears repeating here. SharePoint Boolean fields store True values as 1, unlike Access Boolean fields which store True as –1. To work around this disparity, you should only use check boxes to display Boolean fields in web databases. (When you create a Boolean field in a web table, you’ll notice that Access only gives you the option to display check boxes.) If you attempt to use any restrictions, filters, or comparisons on the integer value of Boolean fields on web forms, you’ll see a runtime error when you view the web form in a browser. Note that it is still possible to use the integer value of Boolean fields in restrictions, filters, and comparisons in Access client with data published to the server; however, we recommend you always use True and False constants when working with Boolean fields to ensure consistent behavior in both client and server. If you need to concatenate a string value with other data types, you can use the FormatCurrency, FormatDateTime, FormatNumber, and FormatPercent functions to format the other data types to a string value. Earlier in this chapter, you saw how to display the date parameter values in the Page Header section of the rptInvoiceDetailed web report. If you examine the expression used for that unbound control, you’ll see we used the FormatDateTime function to concatenate the message text with the Date/Time values as the following: ="Includes invoices between " & FormatDateTime([txtBegDate],2) & " and " & FormatDateTime([txtEndDate],2)
Chapter 21
1284 Chapter 21 Automating a Web Application Using Macros
Chapter 21
We recommend you thoroughly test your web application macros not only in Access client, but also in a web browser after you publish your web database to an Access Services site. The Web Compatibility Checker tool does not usually catch these type coercion issues, so it’s in your best interest to carefully test your application end-to-end and verify everything works as you expect in both client and server. You’ll save yourself a lot of support calls identifying and correcting these issues before distributing your application to other users. In Chapter 22, you’ll learn how to publish your web database to a server running SharePoint 2010 and Access Services and work with your application in the browser.
Part 7
Working with the Web
Chapter 22
Using Web Applications in a Browser . . . . . 1287 Chapter 23
Using Business Connectivity Services . . . . . 1347
ou’ve created your web tables, queries, forms, reports, and macros, and now you’re ready to publish your web database to a server running Microsoft SharePoint 2010 and Access Services. The unique aspect of publishing a web database to an Access Services site is that everything about your application—the data, the web objects, the database properties, and even client objects—is stored on the SharePoint server.
Note The examples in this chapter are based on the Back Office Software System sample web database (BOSS.accdb), the BOSSLogsForServer.accdb web database, and the ContactsMap.accdt web template on the companion CD included with this book. The results you see from the samples in this chapter might not exactly match what you see in this book if you have changed the sample data in the files. Also, all the screen images in this chapter were taken on a Windows 7 system using Windows Internet Explorer version 8 and the Access color scheme set to Silver. Your results might look different if you are using a different operating system, different browser, or a different color scheme.
In this chapter, you will learn how to
●●
Publish your web database to a server running SharePoint 2010 to create an Access Services site.
●●
Work with the forms and reports in your web application inside a web browser.
●●
Create SharePoint permission groups for your site and assign users to groups.
●●
Use the Recycle Bin to restore deleted records.
1287
1288 Chapter 22 Using Web Applications in a Browser
Chapter 22
●●
Make changes to a published web application from Microsoft Access 2010 client and synchronize your changes with the server.
●●
Work offline with your web application from Access client.
●●
Remove your web application from the server.
●●
Instantiate a web template on the server to create an Access Services site.
Working with SharePoint SharePoint 2010 is a web-based server product from Microsoft that enables companies to create a central repository for many types of information that can be viewed and updated by authorized users. SharePoint 2010 runs as a service on servers running Windows Server 2008 or later and uses Microsoft SQL Server to store and manage the shared data. Any company that needs a way to improve team collaboration should find SharePoint very useful. A full discussion of SharePoint and all its features is beyond the scope of this book, so our goal in this chapter is to familiarize you with how to use Access Services in conjunction with SharePoint. Access Services is a set of services that runs on top of the SharePoint 2010 Enterprise Client Access License (CAL). Check with the information technology (IT) staff in your organization to see if they have installed Access Services and SharePoint 2010 so you can publish your Access web databases to the server and collaborate with other users. If your internal organization does not have Access Services, look for third-party companies, including Microsoft, who offer Access Services hosting services. In this chapter, we assume you already have access to and appropriate permissions for a server running SharePoint 2010 and Access Services so you can publish your web databases. A full discussion of installing and configuring SharePoint 2010 to run Access Services is also beyond the scope of this book. For more information on installing and configuring SharePoint 2010, see Microsoft SharePoint 2010 Administrator’s Companion (Microsoft Press, 2010).
Publishing Your Database to an Access Services Site Throughout this book, you’ve studied different parts of the Back Office Software System sample web database. This web database is a restaurant management application used by owners of restaurants to help keep track of various aspects of their business. This database can function perfectly in Access client without ever being published. However, to fully appreciate the benefits of Access Services, it’s time you published this database to a server
Publishing Your Database to an Access Services Site 1289
running SharePoint. To show you how to publish this web database, hold down the Shift key while you open the BOSS.accdb sample web database found on the companion CD. (Holding down the Shift key bypasses the startup properties we defined for this web database. Access also displays the default ribbon and Backstage view instead of our custom ribbons.)
Assigning a Web Display Form Before you publish your web database, it’s a good idea to first assign a web form as your web display, or startup, form. As you’ll learn later in this chapter, if you don’t assign a web display form for your web database, Access Services displays a web page that resembles the Navigation pane, displaying a list of all your database objects, when you navigate to the site. There is no requirement that you first assign a web display form before publishing your web database because you can also change this setting after publishing your web database. However, we recommend that you assign a web display form before allowing other users to use your Access Services site. To assign a web form as your display form for Access Services, click the File tab on the Backstage view, click Options, and then click the Current Database category in the Access Options dialog box. In the Web Display Form combo box, you can select a web form to use as the web display form, as shown in Figure 22-1.
Figure 22-1 Select a web form as your web display form on the Access Options dialog box.
Chapter 22
1290 Chapter 22 Using Web Applications in a Browser
Chapter 22
In Chapter 21, “Automating a Web Application Using Macros,” you studied the web form called frmLoading. For this web database, we initially defined frmLoading as the display form for our Access Services application. When a user browses to our published site Uniform Resource Locator (URL), Access Services opens the frmLoading web form first and checks the permissions of the current user. We haven’t defined permissions and set up SharePoint groups on the server yet, so for now, change the Web Display Form property to frmMainMenu by selecting frmMainMenu from the drop-down list, and then click OK to close the Access Options dialog box before proceeding to the next section. (You’ll see how the frmLoading web form works in the browser later in this chapter.)
Understanding the Publish Process To begin the publish process to the server, click the File tab on the Backstage view, click the Info tab, and then click Publish To Access Services. Access now displays the Save & Publish tab of the Backstage view with Publish To Access Services selected in the center pane of the Save & Publish tab, as shown in Figure 22-2.
Figure 22-2 On the Save & Publish tab, enter the server and site name for your new Access Services site.
In the Server URL text box on the right side of the screen, enter the URL for your server running SharePoint and Access Services. If you are publishing to the root site of your SharePoint server, your URL might be something like http://YourServerName or https:// YourServerName. In that URL example, YourServerName represents the name of your SharePoint server. If you are publishing to a sub-site on the SharePoint server, your URL might
Publishing Your Database to an Access Services Site 1291
be something like http://YourServerName/YourSubSiteName or https://YourServerName/ YourSubSiteName. If you are unsure of the URL to use, talk to your SharePoint server administrator. Note that if you do not include the http:// prefix in the Server URL text box, Access adds it when you publish your web database. Access displays the full URL path that it will publish to above the Server URL text box. In the Site Name text box under Server URL, enter a name for your new Access Services site. Note that when you first open the Save & Publish tab on the Backstage view with this sample web database, the Site Name text box displays the text Back Office Software System. By default, Access fills in the Site Name text box with the Application Title found in the Current Database category of the Access Options dialog box. For brevity of a site name for your new test site in this example, enter BOSS in the Site Name text box, as shown previously in Figure 22-2. Now that you’ve provided a location and name for your Access Services site, click Publish To Access Services on the right side of the screen. Access communicates with your SharePoint server and attempts to create a new empty Access Services site. Note that, at this point, you might be prompted for your login credentials to the server depending upon the security settings of the SharePoint server in your organization or the security settings of your third-party hosting provider. Enter your login credentials to continue the publish process. (If you have problems at this point with Access not accepting your login credentials for the SharePoint server you are trying to publish to, you’ll need to talk with your internal SharePoint server administrator or your third-party hosting company for help with troubleshooting this issue.) If you attempt to create an Access Services site with the same site name as an existing site in the same location, Access stops the publish process at this point and informs you that an existing site with that name already exists. You cannot create an Access Services site with the same name in the same SharePoint location. When Access successfully communicates with your SharePoint server and creates the new empty Access Services site, Access then closes the web database, makes a copy of your database in your Windows Temp directory, reopens the web database from that location, and then begins the publish process. Access next runs the Web Compatibility Checker tool on your web database. In Chapter 6, “Designing Web Tables,” you learned that the Web Compatibility Checker checks the web compatibility of all the tables in a database as well as any web objects. This tool, however, does not check any data in the tables, nor does it attempt to check any client objects other than local tables. Access displays a progress bar as the Web Compatibility Checker scans your web database, as shown in Figure 22-3. If you click Cancel, Access stops the publish process and deletes the empty Access Services site it created earlier.
Figure 22-3 Before publishing your objects to the server, Access checks your web database for compatibility issues.
Chapter 22
1292 Chapter 22 Using Web Applications in a Browser
Chapter 22
You can think of the Web Compatibility Checker tool as a gatekeeper, always making sure your objects are web-legal before you publish your database to the server, import objects into a web database, or make changes to existing objects and try to send those changes to the server. If the tool finds issues during this process, Access aborts the publish process and deletes the empty Access Services site. If the Web Compatibility Checker tool finds no issues with your web database, Access then begins the process of publishing your database objects to the server. Access first creates a new SharePoint list for each one of your tables. In SharePoint terminology, a table is referred to as a list that stores information about a single subject. In a list, you have columns (fields) that contain the different kinds of information about the subject. Access creates columns for each list that match your Access web table fields. Next, Access uploads the data from your web tables into the appropriate SharePoint lists. Access then proceeds to upload all the client and web objects, such as queries, forms, reports, macros, and modules, as well as all shared images and form control images from your web database to the Access Services site. In Figure 22-4, you can see a snapshot of a few different points in time during the publish process with the Back Office Software System web database.
Figure 22-4 During the publish process, Access uploads all your database objects to the Access Services site.
INSIDE OUT
Convert All Embedded Images in Client Objects to Shared Images in Web Databases
As you learned in Chapter 14, “Customizing a Form,” if you are using a web database that includes client forms and reports, we recommend that you change all embedded images on client forms and reports to shared images. When you publish a web database to a SharePoint Server running Access Services, Access converts embedded images to text in client objects before sending to the server. Publishing and synching client objects with embedded objects can significantly increase the publish and sync time because the image is converted to text. If you convert all embedded images in client objects to shared images in web databases, you’ll significantly decrease the amount of time it takes to publish and synch changes for your web database.
Publishing Your Database to an Access Services Site 1293
The entire publish process can take less than a minute, or it can take much longer, depending upon the number of objects in your web database and the amount of data in your web tables. For example, if you have thousands of records in your web tables, you can expect to see the publish process take much longer. Access should periodically update the Synchronizing Web Application progress bar with a percentage of data uploaded to the server. Your publish time also depends upon your connection speed. If your connection speed to the SharePoint server is slow, you can expect the publish time to take much longer to complete. If the publish process succeeds without any errors, Access displays a Publish Succeeded dialog box, as shown in Figure 22-5. Access displays a link to your completed Access Services site in this dialog box. If you click the link, Access opens your default web browser and navigates to your Access Services site. Click OK to close the dialog box.
Figure 22-5 Access displays this message when the publish process succeeds.
Note After successfully publishing your web database to the server, Access appends the name of your original web database with _Backup. Access then moves the published web database from the Temp directory and places it in your original directory. You now have a published web database and a backup copy of your web database (before publishing) in the same directory. For example, if your file name is MyFile.accdb, Access creates a backup copy of your web database called MyFile_Backup.accdb in the same directory. MyFile.accdb is the published web database.
Chapter 22
1294 Chapter 22 Using Web Applications in a Browser
Chapter 22
Below the Publish Succeeded confirmation and hyperlink to your published application, Access displays a message indicating the server might still need more time to process your application before you can use the site. After Access sends up all the objects to the server, Access Services then compiles all the web objects. Access Services compiles the tables first (this includes any data macros attached to the tables) and then the queries, forms, reports, and web macros. If you browse to your completed site using the hyperlink on the dialog box shown in Figure 22-5, you might not be able to view your site objects until Access Services finishes the compile process. We’ll discuss more about this process and what messages you’ll see on the server later in this chapter. If you start to use your published web database within Access immediately after the publish process, you can encounter errors if Access Services has not finished compiling your site. For example, if you enter or edit data that triggers data macros, you might see an error message in Access if Access Services is still in the process of compiling those data macros on the server.
INSIDE OUT
Using a Shortcut to Your Published Application
After you publish your first web database to a server running SharePoint and Access Services, Access creates a new folder called Access Applications in your default database folder for new applications. If you’re not sure of the location for your default database folder, you can open the Access Options dialog box and look for the path in the Default Database Folder text box on the General category page. In the Access Applications folder, you’ll see a shortcut link to your published web database, as well as any other databases you previously published. Access uses the name of your Access Services site and the server name you published to as the name of this shortcut file. For example, if you used a site name Test and published to a server called MyServer, Access creates a shortcut file called Test on MyServer.accdb. Do not be confused by the file extension in the name. Your published .accdb file still resides in the directory folder from where you published; this shortcut file is just a pointer to that local copy of the published web database. If you double-click this shortcut file, Access opens the local copy of the published web application in Access client.
At this point, what you see in Access client is a local copy of your published web application. Your data is now stored in SharePoint lists, and you have linked tables in your local copy of the web application pointing to those lists. Your data and database object separation, in this sense, is really no different than having your data stored in a different data source such as SQL Server—you have linked tables to your data source and you work with that data using database objects stored locally. If you delete the local .accdb database file
Publishing Your Database to an Access Services Site 1295
you just published from your computer, you haven’t really lost anything. You can download an entirely new copy of your web application from the SharePoint server and see all your linked data and use all your database objects. You can have other users navigate to your published Access Services site and download a copy of the application to their computers as well. (We’ll show you how to do that later in this chapter.)
Note We don’t recommend that you delete your local copies of published .accdb database files. In fact, we recommend that you always maintain good backups of all your Access client and web applications. Our comments in this section are merely to illustrate that you can obtain an entirely new copy of your published web application at any time by downloading it from your Access Services site. In good practice, the SharePoint server administrators should be conducting regular backups of their servers, which means your published Access Services applications should also be regularly backed up as well.
In Chapter 7, “Creating Table Data Macros,” we showed you how to use the USysApplicationLog local table to analyze errors during data macro execution. During the publish process, Access deletes the USysApplicationLog local table, if one exists, because Access Services creates its own USysApplicationLog list as part of the site creation process. After you publish your web database to the server, you’ll now have a link to the USysApplicationLog list stored in the Access Services site. If you need the data previously saved in the USysApplicationLog local table, you need to back up this data before publishing. If the publish process completes successfully, Access Services compiles all the web objects on the server. If Access Services cannot successfully compile any objects, Access Services writes a record to the USysApplicationLog list for each object that fails to compile. (In practice, this should not occur very often.) You should periodically check this table when you’re working with your Access Services site because this table contains information about data macro errors and object compilation errors. After you publish your web database, you can open the USysApplicationLog table by clicking the File tab on the Backstage view. On the Info tab, Access displays a View Application Log Table button, as shown in Figure 22-6. Click this button to open the USysApplicationLog web table in Datasheet view. You’ll notice in Figure 22-6 that Access displays a message indicating there are no new errors. If Access client or Access Services writes any new data to this table, Access displays the message, “Your application has new errors in the log,” and highlights the Application Log area in red.
Chapter 22
1296 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-6 You can open the USysApplicationLog from the Backstage view.
ID Value Changes After Publish After you publish a web database to an Access Services site, you’ll notice that the ID values in your web table records might change. For example, if you have three records in a web table with ID values of 1, 3, and 5, and then publish that web table to an Access Services site, your ID values change to 1, 2, and 3. The reason your ID values change after publish is because the ID value in SharePoint lists behave like AutoNumber fields in Access. SharePoint increments the ID value automatically; you cannot set a SharePoint ID value programmatically to a specific value. When Access uploads the records to the SharePoint lists, SharePoint assigns an ID value to each record in sequential order. What this means is that if you have gaps in your ID values in Access before publishing, perhaps because you deleted records, you won’t have gaps in the ID values initially after publish. At first glance, you might be quite concerned about the ID values changing during the publish process, especially if you use those ID values as foreign keys in other web tables for lookup fields. The good news is that Access accounts for this issue by remapping any changed ID values in the parent web table to their respective child web table records during the publish process. For example, if your ID value in a parent web tables is 5 before publish and then is changed to 3 after publish, Access changes the ID value from 5 to 3 in any child table records that referenced that specific ID.
Publishing Your Database to an Access Services Site 1297
Access saves your old ID values with the web table in case you ever need them, although in most cases you never would. To see these old ID values, open a web table in Datasheet view in Access after publishing the database to an Access Services site, right-click any column heading, and then click Unhide Fields from the shortcut menu. You’ll see a field called _OldID in the Unhide Columns dialog box. Select _OldID in this dialog box, click OK, and then you can see the ID value for this record before you published the database. You can safely delete this field if you want, or just leave it in the web database because the old ID value is irrelevant at this point. If you’re attaching any meaning to these ID values, such as for invoice numbers that cannot have gaps, you’re using ID values incorrectly. The ID values in SharePoint lists, like AutoNumber fields in Access, should be thought of only as a unique record identifier.
Analyzing Publish Errors So far in this chapter, we’ve discussed what happens when Access can successfully publish your web database to a SharePoint server running Access Services. But what happens when Access cannot successfully publish your web database? Even if the Web Compatibility Checker does not find any issues with your web database, you still might encounter publish errors. If Access cannot publish your web database to the server, you’ll see a Publish Failed dialog box, as shown in Figure 22-7. When you click OK or close this dialog box, Access deletes the Access Services site it created at the beginning of the publish process.
Figure 22-7 You’ll see this dialog box if Access cannot publish your web database to the server.
Chapter 22
1298 Chapter 22 Using Web Applications in a Browser
Chapter 22
In the Publish Failed dialog box, Access informs you that it encountered problems during the publish operation. Access records any publish failure information in a local table called Move To SharePoint Site Issues. If you encounter this Publish Failed dialog box during a publish procedure, click the Move To SharePoint Site Issues link to close the dialog box and open the Move To SharePoint Site Issues table, as shown in Figure 22-8. Note that in Figures 22-7 and 22-8, we triggered this publish failure example by attempting to publish a table that included a Hyperlink data type field. In the data for this field, we included a URL that was more than 255 characters long, which is not supported in SharePoint lists. (The Web Compatibility Checker, as you recall from Chapter 6, does not check any data in tables, so if you run the tool on this example web table, the tool reports that everything is fine.) The structure might be fine, but the data is not, and you might not know this until you attempt to publish your web database to the server.
Figure 22-8 If you encounter publish errors, open the Move To SharePoint Site Issues table to examine the cause.
The Move To SharePoint Site Issues table includes five fields—Issue, Reason, Object Type, Object Name, and Field Name. In the Issue field, Access lists a detailed explanation of the specific publish failure. In the Object Type field, Access lists the type of object that it couldn’t move to the server. In the Object Name field, Access lists the specific object name that it could not publish to the server. Note that Access does not enter any information in the Reason and Field Name fields in a publish failure scenario. In Figure 22-8, we tabbed into the Issue field and then opened the Zoom dialog box so you can see the error information Access created. You can see in the Zoom dialog box that Access could not copy the data to the server because the URL is invalid. If you encounter publish errors concerning data, you might need to run some client action queries before publishing to correct any data issues found in your web tables.
Working with Your Application in a Web Browser 1299
Now that you’re familiar with the publish process, let’s learn how to work with your application in a web browser. If Access successfully publishes your web database to the server, Access displays the Publish Succeeded dialog box, shown previously in Figure 22-5. As we mentioned, Access Services needs to compile all your web objects after Access sends all the database information to the server. If you immediately browse to your Access Services site, you might see a Preparing Site page, as shown in Figure 22-9.
Figure 22-9 You’ll see this web page when the server is compiling your Access Services site.
If you see the Preparing Site web page when you browse to your site, you’ll need to wait a minute or two until Access Services finishes compiling all your web objects. The length of time for the compile process depends on the number of web objects in your web database; the more web objects you have, the longer the compile process takes to complete. You can refresh your browser (press the F5 key if you’re using Internet Explorer) until Access Services displays the home page of your site.
Using Forms After you publish the Back Office Software System sample web database earlier in this chapter to an Access Service site and the site finishes compiling, you’ll see the main web form called frmMainMenu, as shown in Figure 22-10.
Chapter 22
Working with Your Application in a Web Browser
1300 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-10 Access Services displays the main web form of the Back Office Software System after it compiles all your web objects.
INSIDE OUT
Locating Your Published URL
If you cannot remember the URL to your Access Services site, but you have the published web database open in Access client, you can always find the URL on the Backstage view. Click the File tab on the Backstage view of a published web database and then click the Info tab. Access displays the URL as a link next to the Sync All button. Click this link to open your Access Services site in the web browser.
Navigating through the various web forms you’ve created in Access client should function the same way when you view your web forms in a browser. For example, if you click the navigation buttons on the main web form for the BOSS site, you’ll notice that Access Services displays the correct subform in the navigation control. You can also open other forms, run user interface macros, close forms, call named data macros, and open reports by using macros you’ve attached to control events in the same way you work with the database in Access client. For example, click the Employees top-level navigation button, and Access Services displays the correct subform in your browser, as shown in Figure 22-11.
Working with Your Application in a Web Browser 1301
Chapter 22
Figure 22-11 The navigation control functions the same way in the browser as it does in Access client.
Click the Edit command button for one of the employee records (we clicked the record for Jeff) and Access Services opens the frmEmployeeDetails form in Dialog mode, as shown in Figure 22-12. When you open a form in Dialog mode using the OpenForm web macro action, Access Services displays the form on top of other windows, in much the same way that Access client renders forms in Dialog mode. Notice, in Figure 22-12, that Access Services also dims the form displayed underneath the form opened in Dialog mode. You cannot interact with any form elements on any forms displayed underneath other forms open in Dialog mode. To close a form opened in Dialog mode, you can create a CloseWindow macro action attached to a control event (perhaps for a command button’s Click event) or use the X (Close) button displayed in the upper-right corner of the form window. Close this frmEmployeeDetails form by clicking the X (Close) button in the form window or by clicking the OK or Cancel command button on this form.
1302 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-12 Access Services displays forms opened in Dialog mode on top of other browser windows.
INSIDE OUT
Receiving Feedback on Validation Rule Failures
When you define a field validation rule on a table field, Access Services can provide a visual cue when you enter data that won’t pass the field validation rule on a bound web form. For example, if you enter a negative amount in the Pay Rate text box on the frmEmployeeDetails web form shown in Figure 22-12 and then tab out of the text box, Access Services changes the border color of the control to red as a visual cue that the data you entered won’t pass the field validation rule we defined for the PayRate field in the tblEmployees web table. If you tab back into the Pay Rate text box, Access Services displays our custom field validation message as an alert message beneath the control. When you change the data in the Pay Rate text box control to a positive number and then tab out of the control, Access Services removes the red border around the text box.
If you make data changes to a record in any type of web form and then attempt to close the browser window or browser tab without saving those changes, Access Services displays a Confirmation dialog box, as shown in Figure 22-13. If you click Yes, Access Services discards any uncommitted data changes and closes the browser window. If you click No,
Working with Your Application in a Web Browser 1303
Access Services cancels the close request and keeps the web form open but does not commit the record changes. Note that if you click the X (Close) button on this dialog box, Access Services saves any pending record changes, dismisses the dialog box, and cancels the close request for the web form. If Access Services cannot save your changes, possibly because the data won’t pass field or table level validation rules, Access Services displays a Record Not Saved dialog. You’ll need to change your data to pass the validation rules in order to commit your record changes.
Figure 22-13 Access Services displays this message if you attempt to close a web form with uncommitted data changes.
When you clicked the Employees top-level navigation button earlier, we designed the continuous form shown in the navigation subform to display all the active employees. By default, Access Services displays only 20 records in a continuous form page. If you scroll down to the bottom of this continuous form, you’ll see that Access Services displays navigation buttons in the lower-left corner of the form window, as shown in Figure 22-14. These navigation buttons in the web browser function similar to the built-in navigation buttons displayed on forms viewed within Access client. Access Services displays the current record number and the number of records in the form’s record source on the left. Access Services also displays First, Previous, Next, and Last buttons, which you can use to navigate to different pages displayed in the web form. If your form is a single record form, the navigation buttons navigate you through each record because each record is essentially a new page. If your form is a continuous form, the navigation buttons navigate you through each page of records. In the Current Page/Record box, you can enter a page number you want to display, press Enter, and Access Services navigates to that page of records. On the right side, you can click New Record to begin creating a new record or click Save Record to save any changes to the current record.
Record numbers
Previous
First
Next
Current Page/ Record box
New Record
Last
Save Record
Figure 22-14 Access Services displays navigation buttons so you can navigate to other records.
Chapter 22
1304 Chapter 22 Using Web Applications in a Browser
Chapter 22
INSIDE OUT
Adjusting the Page Size Form Property
You can display more records per page in a continuous form viewed in the browser by adjusting the Page Size form property in Access client. You’ll see this form property listed only in the Property Sheet window for continuous forms, not for single record or datasheet forms. Keep in mind that your form takes longer to load in the browser when you display more records.
Using Reports Navigate to the second page of employee records by clicking the Next or Last navigation button. Access Services now displays the second page of employee records. Access Services loads the second page of records, but the focus remains at the bottom of the page. Scroll up the second page until you see the employee record for John Viescas, and then click the Info command button next to his record. Access Services opens a report showing John’s employee information, as shown in Figure 22-15. Attached to the Click event of this command button, we have an OpenReport web macro action to open a web report showing the selected employee’s personal information. You’ll notice that Access Services opens the report in a new browser window. Access Services displays the report’s Caption property— Personal Report, in this example—in both the browser tab and the upper-left corner of the browser window.
Figure 22-15 When you open a web report using the OpenReport macro action, Access Services opens the report in a new browser window.
Working with Your Application in a Web Browser 1305
At the bottom of the report browser window, you’ll see a toolbar that contains buttons, as shown in Figure 22-16. These buttons are similar to the navigation buttons you saw previously for web forms. For web reports, you’ll see additional options next to the First Page, Previous Page, Page Number Box, Next Page, and Last Page elements. On the left side of the web report toolbar is the Actions button, which you can use to select options to print or export your report to different formats. (We’ll discuss these options in more detail in just a moment.) Next to the Actions button is the Refresh button. Click Refresh when you want Access Services to refresh the data shown in the report and display the most recent data changes. To the right of the Last Page button is the Find Text In Report box. Enter data you want to find in the report in this text box, press Enter or click the Find link, and Access Services searches the entire report, including data displayed in label controls, for the first instance of that search criterion. The Find Text In Report feature is very useful when you need to search for specific information in a report that contains a lot of data. For example, if you enter 03063 in this text box and click the Find link, Access Services highlights the data in the Postal Code field for John’s record on the report. You can click the Next link, and Access Services continues to search for the next instance of 03063. In this case, because there is no other data that matches that criterion, Access Services displays a message box indicating that the entire report has been searched. To the right of the Next link is the Zoom box. You can adjust the zoom level of the report by clicking the zoom level options in this drop-down list. Actions menu
First Page Number Last Page box Page
Refresh
Previous Page
Next Page
Find
Find Text in Report box
Next
Zoom box
Figure 22-16 Access Services reports can display a navigation toolbar.
INSIDE OUT
Hiding or Repositioning the Web Report Toolbar
When you open a web report by itself (not contained within a subform/subreport control) in a web browser, Access Services always displays the web report toolbar. If you display the web report inside a subform/subreport control, you can control whether to show or hide the web report toolbar in the browser. Open the web form that contains the subform/report control in Layout view in Access client, select the subform/subreport control, and then find the Show Toolbar property on the Property Sheet window. Select None, and Access Services will not display the web report toolbar when you view the form and embedded subreport in a web browser. Select Top to display the toolbar at the top of the report window or select Bottom, the default, to display the toolbar at the bottom of the report window.
Chapter 22
1306 Chapter 22 Using Web Applications in a Browser
Chapter 22
Click the Actions button on the web report toolbar to see the Actions menu, as shown in Figure 22-17. If you click Print, Access opens the Print dialog box, where you can select the printer that you want to print to and adjust any printer preferences. Note that the first time you click Print, you’ll see a prompt at the top of your browser window indicating you need to install the SQL Server Reporting Services 2008 add-in to print the report. Click this prompt and install the add-in to open the Print dialog box and print the web report. When you click Export on the Actions menu, you can select to export the web report to Excel (.xls), PDF (.pdf), or Word (.doc) format. Access Services exports the report and then prompts you for a location to save the file. You do not need to install Microsoft Excel, Microsoft Word, or Adobe Acrobat to export the web report because the server exports the file. You do, however, need to install Excel, Word, Acrobat, or Reader if you want to view the exported report on your computer.
Figure 22-17 You can print your web report or export it to other formats by clicking the options on the Actions menu.
Using Datasheet Forms Close the web report browser window currently open so you can see the main menu navigation form again. Click the Products top-level navigation button and then click the Datasheet View second-level navigation button to see a datasheet form displaying all the active products in the web application, as shown in Figure 22-18. Across the top of the datasheet form, you’ll see column headers for each column of data. If you hover over the column header, Access Services displays a down arrow on the right side. Click the arrow button to open the AutoFilter menu. You can see that in Figure 22-18, we clicked the column header above the Inventory Location field to display the AutoFilter menu options available for this column.
Working with Your Application in a Web Browser 1307
Chapter 22
Figure 22-18 Access Services displays AutoFilter menu options for datasheet forms.
At the top of the AutoFilter menu, you can click Hide Column, and Access Services hides the column from view. Note that this change to the datasheet form is not permanent. If you refresh the browser or close the datasheet form and then reopen it, Access Services displays the column again. Beneath Hide Column, you can click Sort Ascending or Sort Descending (not shown in Figure 22-18) to sort the records in ascending or descending order by that column. You can click one of the filter options to filter the records displayed in the datasheet form to just the records that match that filter criterion. You can filter by more than one option by dropping the AutoFilter menu down again and clicking another option. Click (Blank) when you want to filter the data to show records where no value exists in that column. Click Clear Filter near the top of the AutoFilter menu to clear the filters and see all the data again. You won’t see all the options available in the AutoFilter menu, depending upon the data type of the column. For Memo fields formatted as Rich Text and Multi-Value Fields that look up data in a table, Access Services displays only the Hide Column option in the AutoFilter menu. When you have a Hyperlink field, you won’t see any filter options. When you have a Lookup field that looks up data in a table, you won’t see the sorting options.
1308 Chapter 22 Using Web Applications in a Browser
Chapter 22
INSIDE OUT
Resize and Move Columns in Datasheet Forms
You can resize the width of the columns and reposition columns when you view datasheet forms in a web browser. To resize a column, position your mouse on the right edge of the column header until your cursor becomes a two-sided arrow. Click and drag the column header to the left to decrease the width of the column, or drag the column header to the right to increase the width of the column. To move a column, position your mouse over the column header until your cursor becomes a four-sided arrow. Click and drag the entire column header to the left or right to reposition the column. Access Services displays a vertical I-Bar to indicate where it will place the column when you release the mouse. Note that resizing and moving columns when you view the datasheet in a web browser is not permanent. If you refresh the browser or close and then reopen the form, Access Services displays the columns at their original widths and positions.
Datasheet forms displayed in the browser function very much like datasheet forms displayed in Access client. If you’ve enabled additions, edits, and deletions on the web form, you can create new records, make changes to the data, and delete records within the browser window. To create a new record in a datasheet form, you’ll need to scroll to the bottom of the datasheet form window until you see the new record line and then enter your data on the new datasheet record. To delete a record, right-click the row selector on the left side of the datasheet form and then click Delete on the shortcut menu to remove the record. To edit data, you can click in a cell and edit the data. If you don’t want to overwrite the existing data, you can press F2 after selecting a cell to go into edit mode, which positions your cursor at the end of the existing data. If you want to cancel any changes to the data in the cell, press Escape. You can use the Tab and arrow keys to move around the datasheet and press Enter to move down a column. When you move to a new record, Access Services automatically attempts to save the record. (You’ll see this same behavior with continuous forms, too.) When Access Services successfully saves any record changes, you’ll see a Record Updated message displayed briefly in the upper-right corner of the browser window, as shown in Figure 22-19.
Working with Your Application in a Web Browser 1309
Figure 22-19 You’ll see a Record Updated message when Access Services saves your record changes.
Waiting for Server Processing In the normal use of your web application, you might need to execute data macro operations that take a long time to complete. For example, you might run a named data macro from a user interface macro that needs to edit many records in a web table. When you call that named data macro, perhaps from an embedded macro attached to a Click event of a command button, Access Services sends the request to execute the action and then waits until the action completes. During this execution time, Access Services provides a visual cue to indicate a processing request is currently underway. To see an example of a server processing message, click the Scheduling top-level navigation button on the main menu of the Back Office Software System and then click the Copy Schedules second-level navigation button. The form you see displayed in the navigation subform allows you to create new employee schedule records by copying data from a labor template, copying existing records from a specific date, or by copying existing records from a selected date range. In the Select Labor Plan combo box, select one of the two saved labor plan templates, enter a date into the Date To Apply text box, and then click the Create Schedule command button to run a named data macro to create new schedule records. Access Services dims the browser window to let you know it is currently running a data macro operation. If the data macro takes more than a few moments to run, you’ll see a processing message. After a few more moments, Access Services displays another processing message, indicating that you can press Escape to return to the application, as shown in Figure 22-20. Note that if you press the Escape key, Access Services continues to run the data macro until completion or until it encounters an error. You might not see all your expected data additions, edits, and deletions if you press Escape before Access Services finishes running your data macro.
Chapter 22
1310 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-20 You’ll see this message when Access Services is processing a data macro operation.
The first time you execute a specific data macro after publishing your web database to the server, Access Services takes slightly longer to complete the operation than it does on subsequent attempts. The reason for this is because Access Services needs to compile each data macro and perform setup work the first time you try to run that data macro. You’ll notice it takes less time on subsequent attempts to execute the same data macro because Access Services does not need to perform the extra setup work. If you change the data macro, Access Services needs to recompile the data macro again on the first run.
Note If you run a data macro in a published web application when you are working in Access client, you’ll see a similar server processing message. In Access client, the message says “Please wait for server processing.”
Working with Your Application in a Web Browser 1311
Understanding Session Management One important and noticeable difference you’ll encounter when working with an Access Services application in a web browser involves session timeout. When you are working with a client database in Access client, you generally don’t have to worry about session timeout. If, for example, you are not using your computer for an extended period of time with uncommitted record changes or a database object open, you won’t see error messages in Access client when you resume work on your computer. If, however, you leave your browser window open for an extended period of time without making any changes to a web form and then attempt to add, edit, or delete records, Access Services displays a session timeout message in the upper-right corner of your browser window and in some cases, also in a message box, as shown in Figure 22-21. When you see a session timeout message, you’ll need to refresh your browser to continue working with your Access Services application. Note that if you have uncommitted record changes, you’ll lose these changes when you refresh your browser. In this case, you might want to copy your record changes to the Clipboard or another program before refreshing your browser if you don’t want to lose your uncommitted data.
Figure 22-21 You’ll see this message in your browser window if your session times out.
Access Services has several configurable server settings concerning session management that you should be aware of when working with your application in a web browser. By default, Access Services times out after 25 minutes of inactivity and you can have only 10 sessions per user. Each browser window or browser tab that displays an Access Services form uses one session. By default, this means you can actively work with only 10 browser windows or tabs pointing to the same Access Services site at the same time. Table 22-1 summarizes the server session management settings with a description of each setting and the default values. If you want to adjust the default values, you’ll need to talk with your SharePoint server administrator because these settings affect all Access Service applications in the entire SharePoint server farm and not just each individual Access Services site. If you are using a hosted service for your Access Services applications, you’ll need to talk with the hosting company about adjusting these settings.
Chapter 22
1312 Chapter 22 Using Web Applications in a Browser
Table 22-1 Server Settings for Session Management Chapter 22
Setting
Description
Maximum Request The maximum duration (in secDuration onds) allowed for a request from an application.
Default Value
Range
20
–1 (indicates no limit); 1 through 2073600 (24 days).
Maximum Sessions The maximum number of sessions 10 Per User allowed per user. If a user has the maximum number of sessions and starts a new session, the user’s oldest session is deleted.
–1 (no limit); 1 to any positive integer.
Maximum Sessions The maximum number of sessions 25 Per Anonymous allowed per anonymous user. If this User maximum is reached, the oldest session will be deleted when a new session is started.
–1 (no limit); 1 to any positive integer.
Cache Timeout
The maximum time (in seconds) 1500 that a data cache can remain available, as measured from the end of each request for data in that cache.
–1 (indicates no limit); 1 through 2073600 (24 days).
Maximum Session Memory
The maximum amount of memory 64 (in megabytes) that a single session can use.
0 (disable) through 4095
INSIDE OUT
Viewing Access Services Application Settings
If you have sufficient permissions to your server running SharePoint and Access Services, you can view all the application settings applicable for Access Services applications. Navigate to the SharePoint 2010 Central Administration page on your server. Next, click the Manage Service Applications link under Application Management. Finally, click the Access Services link on the Service Applications page to view all the configurable administration settings for Access Services applications.
Exploring the Access Services Shell Above your web form pages, you’ll see a few hyperlinks and buttons that appear on every page of your Access Services site—the name of your published Access Services site, the Options button, the Help button, and your login name, as shown in Figure 22-22. These elements are referred to as the shell of your Access Services site. In the upper-left corner, you’ll see the name of your Access Services site—BOSS, in our example. Click this hyperlink
Exploring the Access Services Shell 1313
to return to the default page (your web startup form) at any time. Click Options, and Access Services displays four options in a drop-down list—Open In Access, Site Permissions, Settings, and Navigate Up. You can use the options in this menu to open a copy of the web application in Access client, navigate to a page to edit site permissions for your Access Services site, navigate to other pages of your Access Services, or to navigate to the parent site of your SharePoint server. We’ll discuss these options in more detail in the next section.
Figure 22-22 In the Access Services shell, you can access options to view different areas of your application and sign out of your application.
Click the Help button in the upper-right corner of the shell to open a Help web page on SharePoint 2010 topics. Click your login name and Access Services displays three options in a drop-down list—My Settings, Sign In As Different User, and Sign Out. You can use these options to update your personal information, sign in to your Access Services site as a different user, or sign out of the Access Services site. Click My Settings to open the User Information page, and then click My Regional Settings to modify settings such as locale, time zone, and default calendar. (In Figure 22-22, we combined two figures so you could see both option menu drop-down lists. Under normal use, you cannot access two drop-down lists at the same time.)
Note Not all the options shown beneath your login name in Figure 22-22 are available depending upon how your SharePoint administrator configured the SharePoint server and what web page you might be viewing. For example, Access Services sites cannot use the Personalize This Page option shown on some web pages. If you click that option, you’ll see an error message on the web page.
Chapter 22
1314 Chapter 22 Using Web Applications in a Browser
Downloading a Web Application Back into Access Chapter 22
Click the Options button in the Access Services shell, and then click Open In Access. Access Services opens the File Download dialog box, as shown in Figure 22-23. Click Open and Access Services downloads—or rehydrates—a copy of your Access Services web application to your computer and opens the application in Access client. Click Save to download an Access Web Application shortcut to your local computer. An Access Web Application shortcut has an .accdw file extension. This shortcut is merely a pointer to the published Access Services web application URL. You can send this .accdw file via email to other people that need to work with your published Access Services site from within Access client. When a user double-clicks the .accdw file, Access opens, downloads a copy of the web application to his or her local computer and synchronizes any server changes with their local copy of the application. Note that if the user has a local copy of the web application already, Access opens the existing local application and synchronizes any server changes into that copy. During this synchronizing process with the server, Access checks to see if there are any changes from the server that need to be sent to your local web database. If Access determines there are updates to any objects on the server that don’t exist in your local copy of the published web application, Access retrieves those changes from the server and applies them to your local web database. (We’ll discuss the synchronization process in more detail later in this chapter.) Click Cancel on the File Download dialog box to close the dialog box.
Figure 22-23 In the File Download dialog box, you can open the web application from within Access client or save a shortcut to the web application.
When you click Open, Access opens the local copy of this published web application on your computer and synchronizes any server changes to the local copy. If you have not opened the specific Access Services web application from your computer, Access Services downloads a copy of the application to your computer with all the latest changes.
Exploring the Access Services Shell 1315
You must grant other people appropriate permissions to access your site for them to use your Access Services application. To create, edit, and delete site permissions, click the Options button in the Access Services shell and then click Site Permissions. Access Services opens the Permission page, as shown in Figure 22-24. Note that the command options and groups on the SharePoint ribbon for this page can vary based on how your internal organization’s SharePoint server administrator or third-party hosting services company configured the server you are using. For example, your Access Services site might inherit permissions from the parent site, (or from the hosting server’s site) in which case you might see fewer command options in the ribbon.
Figure 22-24 On the Permissions Tools page, you can edit the user and group permissions for your Access Services site.
For our BOSS Access Services site, we created three SharePoint groups—RestaurantEmployees, RestaurantManagers, and RestaurantShiftManagers. We assign each user of the Access Services site to one of these groups. It’s not a requirement that you create your own custom groups because SharePoint includes several built-in groups. However, we wanted to have the additional level of control by defining our own custom groups. To create a new SharePoint group, click the Create Group button on the SharePoint ribbon. You’ll then see the Create Group page, partially shown in Figure 22-25. In the Name box at the top of the page, you need to provide a unique name for your custom group. At the bottom of the Create Group page, you can specify the permission level that members of this group will have on your site. For the RestaurantManagers group, we selected Full Control (shown in Figure 22-25), for the RestaurantShiftManagers group, we selected Contribute, and for the RestaurantEmployees group, we selected View Only. Click Create to save your new custom SharePoint group and return to the Permissions page. Note that you might need to create new SharePoint groups at the parent site level, depending upon how your SharePoint server administrator or third-party hosting services company configured the server you are using.
Chapter 22
Setting Site Permissions
1316 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-25 You can create new SharePoint groups on the Create Group page.
To assign a user to a custom group, click Grant Permissions on the SharePoint ribbon. SharePoint opens the Grant Permissions dialog box, as shown in Figure 22-26. In the Select Users box, enter the name of a user you want to give access to your site. Under Grant Permissions, you can add a user to one of the built-in SharePoint groups or one of the custom groups you created. Select the Grant Users Permission Directly radio button if you want to assign a user to a specific permission level. Note that you’ll have an easier task managing permissions for everyone that uses your Access Services site if you assign users to groups instead of assigning permissions directly to each individual user. Click OK to save your changes.
Figure 22-26 On the Grant Permissions dialog box, you can assign users to SharePoint groups or specific permission levels.
Exploring the Access Services Shell 1317
In Chapter 21, you studied the user interface macro logic attached to the OnLoad event of the frmLoading web form. You learned that we use an If block to test the SharePoint group level membership of the current user with the following conditional expression: =IsCurrentWebUserInGroup("RestaurantManagers") Or IsCurrentWebUserInGroup("RestaurantShiftManagers")
This macro logic checks to see if the current user is a member of the RestaurantManagers or RestaurantShiftManagers SharePoint custom groups. If they are a member of either of those two groups, the macro logic uses the BrowseTo action to browse to the frmMainMenu web form, where all the administrative and application features are available. If the user is not in either of these SharePoint groups, the macro browses instead to the frmMainMenuEmployees web form, where the employee can see their work schedule only. (We don’t want employees other than managers to be able to view and edit administrative or confidential areas, such as employee wages.) At the start of this chapter, we had you change the Web Display Form property for this web database from frmLoading to frmMainMenu in Access client. Now that you’ve defined the appropriate SharePoint groups and permissions, change this property back to frmLoading in Access client. To do this, click the File tab on the Backstage view, click Options, and then click the Current Database category in the Access Options dialog box. In the Web Display Form combo box, select frmLoading and then click OK to save your change. Note that you’ll synchronize this change to the Access Services site later in this chapter.
Note For the Back Office Software System web database, we added this group-level test only to the frmLoading web form. If regular restaurant employees browse to the Access Services site URL, they will see the appropriate limited main menu for their group. However, if the employees browse to a specific form or report, they will be able to view the form or report in the web browser. In a production environment, we would want to add a similar group level test in the OnLoad or OnOpen event of every form or report for a higher level of interface control.
INSIDE OUT
Preventing Users from Downloading Your Web Application
By default, all users of your Access services application can click Open In Access in the Options menu on the Access Services shell and download a copy of the web application. You can set appropriate permissions to each list to prevent users from viewing data you don’t want them to view, but if you want to prevent users from downloading the web application, you’ll need to a create a custom permission group.
Chapter 22
1318 Chapter 22 Using Web Applications in a Browser
Chapter 22
To do this, click Site Actions on the parent site and then click Site Permissions. Next, click the Permission Levels command in the Manage group on the SharePoint ribbon. On the Permission Levels page, click Add A Permission Level. In the list of permissions, select all the same options that exist for a Contributor. Note that we used the Contributor options as a base for the permissions, but you could select more or less restrictive permissions to start. Next, make sure you clear the Use Remote Interfaces option. If you leave this option selected, any user with rights to the Access Services site can click the Open In Access option and rehydrate the web database into a compatible version of Access 2010. If you clear this option, any users with this permission level cannot make any external web service calls. As a result, when the user clicks the Open In Access option, they are blocked from rehydrating the published Access Services application into Access client. If you clear the View Application Pages settings, you can also prevent a user from viewing all SharePoint application pages (Settings Page, Permissions Page, etc.) as well as the default SharePoint view pages. Finally, save your changes and assign the appropriate users to this group. There is one caveat when clearing the Use Remote Interfaces permission level. When users are prevented from using Remote Interfaces, they cannot view any reports in the web browser. Access Services uses SQL Reporting Services to render reports and SQL Reporting Services relies on making Simple Object Access Protocol (SOAP) requests. If the users assigned to this permission level do not need to view reports, this should not be a problem. However, if those users do need to view reports in the browser, you will either need to display the data in forms for them to view or not use this approach.
Reviewing the Modify Application Page Each Access Services site includes a web page that resembles the Navigation pane found in Access client, where you can see a list of all the database objects in your application. Click the Options button in the Access Services shell and then click Settings. Access Services opens the Modify Application page, as shown in Figure 22-27. This web page lists the tables, queries, forms, reports, and macro objects in your web application. You can scroll down this page to see the object names in alphabetical order grouped by object type. (Note that in Figure 22-27, we’re showing only a few of the web table names for the BOSS Access Services site.) Next to the name of each object, you can see the date and time when the object was last changed and by whom. Access Services does not list any Module objects on this page, but they are stored on the server. You can use any procedures and functions defined in Modules when you work with the published application from within Access client.
Exploring the Access Services Shell 1319
Chapter 22
Figure 22-27 On the Modify Application page, you can see a listing of all the objects in your web database.
Across the top of the Modify Application page, you’ll see a link under Design With Access called Modify This Web Database, Add New Fields, Customize Forms And Reports. When you click this link, Access opens the File Download dialog box you saw previously in Figure 22-23. Click this link if you want to open the web application in Access client. Under Settings in the upper-right corner of the Modify Application page, you’ll see two additional links—Recycle Bin and Delete This Site. Click the Recycle Bin link to open the SharePoint Recycle Bin page, where you can restore deleted records from your application. (We’ll discuss the Recycle Bin in more detail later in this chapter.) Click the Delete This Site link to open a web page where you can delete your entire Access Services site.
Note If you do not assign a web display form for your web database, Access Services navigates you to the Modify Application page directly when you browse to your published site URL. You’ll also see a yellow Alert message saying that you have not selected a default web display form. We recommend that you assign a web display form before allowing other users to use your Access Services site.
The name of each database object displayed on the Modify Application page is essentially a link that you can click to see a list of options. In Figure 22-28, we combined several screenshots into one figure to show you the options available for all the database object types. When you click a table, you’ll see options to modify the table and export the table to Excel. If you click the modify option, Access Services opens the File Download dialog box, where you can open the web application in Access client or download an .accdw shortcut file. If you click Export To Excel, Access Services opens a different File Download dialog box, where you can open the web table in Excel or download a Microsoft Excel Web Query File (.iqy) file. Note that your browser might prompt you about downloading a file before seeing the File Download dialog boxes.
1320 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-28 You can click a database object name to see additional options.
When you click a web form or web report name, you’ll see options to modify the web object and view the object. If you click the modify option, Access Services opens the File Download dialog box, where you can open the web application in Access client or download an .accdw shortcut file. If you click the option to view the object, Access Services opens the web form or web report in your browser window. Note that you can open only web forms and web reports for a published Access Services site in a web browser. When you click web queries, web macro objects, or any client objects, you can see only the option to modify the object, which opens the web application in Access client. If you look closely in Figure 22-28, you’ll notice that all web objects have a globe icon to indicate that they are web objects. Client objects are stored on the server for rehydration back into Access client, but they do not run in a web browser.
INSIDE OUT
Using ACCDW Shortcut Files
When you click the option to modify a specific object on the Modify Application page, you can download an .accdw shortcut file to your computer. If you double-click this shortcut, Access opens, downloads a copy of the web application to your local computer, synchronizes any server changes with your local copy of the application, and then opens the specific object. If you clicked to open a table, for example, Access opens the table in Datasheet view, and if you clicked a form, Access opens the form in Layout view. If you open an .accdw file in Notepad, you can see the Extensible Markup Language (XML) for the shortcut. You’ll see XML tags for the object name, type, and mode to open the object. In Chapter 23, “Using Business Connectivity Services,” you’ll learn how to use XML.
Working with the Recycle Bin 1321
One of the great advantages to having your data stored in an Access Services site is the site Recycle Bin. In most cases, if you delete something in an Access client database, it is deleted permanently. If you delete one record (or a thousand) by mistake and then close the database, those records are lost. In some situations, it is possible to retrieve deleted client database elements using professional recovery services, but retrieval is not always guaranteed, and those services can be costly. If you’re fortunate, you might have a backup of your database that you can use to restore deleted records, but you still might lose some very important data, depending upon when you made the last backup. SharePoint has a built-in Recycle Bin, where you can easily recover deleted records. Suppose, for example, we accidentally delete an invoice record in our application that we have been working on. In our web table setup, we have a Cascade Delete relationship between the tblInvoiceHeaders and tblInvoiceDetails web tables. If you delete an invoice from the application, all related child invoice detail records also get deleted. We can navigate to the Recycle Bin on our Access Services site and recover these records. The Recycle Bin in SharePoint works in much the same way as the Recycle Bin in Windows. The one difference is SharePoint empties deleted items more than 30 days old automatically. To navigate to the site Recycle Bin, Click Options on the Access Services shell to open the Modify Application page. Now, click the Recycle Bin link in the upper-right corner of this page. Access Services opens the Recycle Bin page, as shown in Figure 22-29. In Figure 22-29, you can see an invoice record we previously deleted. SharePoint shows the type of object deleted (in this case a record), the ID of the deleted record, the original location of the list from which the record was deleted, who created the record, when the record was deleted, and the size of the record. To restore the invoice record, select the check box next to the invoice record and then click Restore Selection. SharePoint restores the parent invoice record and all related child invoice detail records.
Figure 22-29 You can restore records from the Recycle Bin on the Access Services site.
Chapter 22
Working with the Recycle Bin
1322 Chapter 22 Using Web Applications in a Browser
Troubleshooting Chapter 22
Why can’t I restore my record from the Recycle Bin? If you have a data macro attached to the BeforeChange event of a web table, you cannot restore records back into that table from the Recycle Bin. If you want to recover the deleted records, you’ll need to temporarily remove any data macro logic attached to the BeforeChange event for the web table from within Access client, save the changes to the server, restore the deleted records, and then reattach any data macro logic to the BeforeChange event. To facilitate this process, you could copy the data macro logic to Notepad and then paste the XML back into the BeforeChange event after restoring the deleted records.
Extending Your Access Services Application When you publish a web database to a server running SharePoint and Access Services, all your data is stored in SharePoint lists. The SharePoint platform offers a wealth of possibilities for extending your application beyond just what you can do from Access client. A full discussion of all the possibilities you can do with your data in SharePoint lists is beyond the scope of this book, but we’ll show you one way that you can capitalize on the gains of using SharePoint to store your data. SharePoint includes a feature that allows you to create a calendar view of your list data. The tblVacations web table in the Back Office Software System is a perfect candidate to build a calendar view. If you still have the Recycle Bin page open, click the All Site Content link on the left side of the web page. If you’re not currently on the Recycle Bin page, you can get there by clicking the Options button on the Access Services shell and then clicking the Recycle Bin link on the Modify Application page. You should now see the All Site Content page for your Access Services site, as shown in Figure 22-30. Under Document Libraries, you can see two lists that store the shared images and web report definitions—AppImages and Report Definitions. You should see a list for each one of your published web tables under Lists.
Extending Your Access Services Application 1323
Chapter 22
Figure 22-30 You can see the structure of your Access Services site on the All Site Content page.
!
CAUTION
Do not attempt to modify any of the system lists that control your Access Services site on the All Site Content page. If you modify any of these objects, you could cause damage to your Access Services site, and you also might encounter problems working with the web application from within Access client. If you need to make changes to your table schema, you should always make the changes in Access client and then synchronize your changes with the server.
Scroll down this page and then click the tblVacations link. You’ll now see a SharePoint datasheet view of the tblVacations list, as shown in Figure 22-31. There are four records already saved in this list for the Back Office Software System web database.
1324 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-31 Click List Settings to view the definition for the tblVacations list.
Click List Settings in the Settings group on the List contextual SharePoint ribbon tab to view the definition of this list. Access opens the List Settings page for the tblVacations list, as shown in Figure 22-32. On the List Settings page, you can access several links to control the various settings of each list in your Access Services list. If you need to make schema changes to your web tables in an Access Services site, we recommend that you always make those changes from within Access client. If you make changes to the list definition here, you could make changes that Access client cannot understand.
Figure 22-32 You can set many options for your list on the List Settings page.
Extending Your Access Services Application 1325
INSIDE OUT
Assign Permissions to Each List for Greater Security
You can use the IsCurrentWebUserInGroup function at the user interface layer to control which users can open forms and reports. However, for tighter security, you should set permissions for each list in your Access Services site. You can set permissions for each list by clicking the Permissions For This List link on the List Settings page.
Scroll to the bottom of the List Settings page and click the Create View link to open the Create View web page, as shown in Figure 22-33. On this page, SharePoint shows several links you can click to create different view of your list data. To create a calendar view of the data in the tblVacations list, click the Calendar View link.
Figure 22-33 Click the Calendar View link on the Create View page.
You should now see the Create Calendar View page, as shown in Figure 22-34.
Chapter 22
1326 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-34 You can set options for the calendar view on the Create Calendar View page.
Perform the following steps to make a calendar view of the tblVacations list:
1. In the View Name text box, enter VacationCalendar for the name of the view. 2. In the Time Interval section, select the StartDate field in the Begin combo box and select the EndDate field in the End combo box.
3. In the Calendar Columns section, select the Employee field for the Month View Title, Week View Title, and Day View Title combo boxes.
4. Click OK at the bottom of the page to save your changes. You can now see a nice graphical calendar view of the data in the tblVacations list, as shown in Figure 22-35. If you navigate the calendar to September 2010, you should see the employee names and start and end dates for their vacations that we created in the sample web database.
Extending Your Access Services Application 1327
Chapter 22
Figure 22-35 You can see a graphical representation of the employee vacations in a calendar view.
INSIDE OUT
Link the Vacation Calendar to the Main Menu
In the main menu for the Back Office Software System web database, we provided an entry point to the calendar view you just created for the tblVacations list. Copy the URL for the VacationCalendar view to the Clipboard. (You can see an example of the URL in the Address Bar shown previously in Figure 22-35.) Next, navigate to the main menu page of the site by clicking the BOSS link in the upper-left corner of the browser window. Click the Administration top-level navigation button on the main menu and then click the Settings second-level navigation button. Paste the URL to the VacationCalendar view page in the Vacation Calendar text box on the settings form, and then click the Save Changes command button to save the record changes. Finally, click the Employees top-level navigation button and then click the Vacation Calendar secondlevel navigation button on the main menu. You should now see the calendar view page you created earlier shown in the subform web browser control.
1328 Chapter 22 Using Web Applications in a Browser
Using Your Published Web Database in Access Chapter 22
Now that you’ve seen what happens during the publish process and understand how to work with your Access Services site in a web browser, let’s show you what happens when you open a published web database in Access client. If you still have the BOSS.accdb published web database open from the start of this chapter, close the database. Note that if you click the File tab on the backstage view, Access displays Close Web Application instead of Close Database. You can use this option to close the application or click the Close X button in the upper-right corner of the application window to close the database and Access. Open your published web database and you’ll notice that Access displays the dialog box shown in Figure 22-36.
Figure 22-36 Click OK in this dialog box and Access opens your published web application.
When you open a local copy of a published Access Services web application, Access prompts you that it needs to communicate with the Internet or intranet. Access informs you that this is a published web application and displays the URL for your application in the dialog box. If you click OK, Access opens the local copy of the web database and then synchronizes your application with the server. If you click Cancel in this dialog box, Access stops the process of opening the local web database and then displays the New page of the Backstage view. Select the Don’t Show This Message Again check box if you do not want Access to prompt you again before opening any published web applications.
INSIDE OUT
Re-enabling the Prompt When Opening Published Web Databases
If you select the Don’t Show This Message Again check box in the dialog box when opening a published web application and then click OK, you cannot change that option in any entry point in the Access user interface. If you want to display this dialog box again, you’ll need to edit the Registry for your computer. In the Registry Editor, navigate to the following registry folder: [HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Access\Settings]
Using Your Published Web Database in Access 1329
There are two registry keys that control showing this dialog box, one for .accdw files and the other for published .accdb files: "Show Accdw Warning"=dword:00000000 "Show Accdb Web Application Warning"=dword:00000000.
You can either change their values to 1 or delete these keys. Note that you should use extreme caution when editing any registry keys because you could inadvertently cause damage to your computer applications. We recommend that you make a backup of your registry first if you need to change or delete these values.
Click OK to open your local copy of the published Back Office Software System sample web database. Access synchronizes any server changes with your local copy of the published web database and then opens the main menu form of the application, as shown in Figure 22-37. If you expand the Navigation pane and then hover over one of the web table names, you’ll notice Access displays a tooltip that contains the URL to your Access Services site. In a published web database, Access also displays a Status Bar message in the lower-right corner of the application window, indicating you are working online with a SharePoint site.
Figure 22-37 In a published web application, you can see the URL for your site if you hover over a web table object.
Chapter 22
1330 Chapter 22 Using Web Applications in a Browser
Chapter 22
The BOSS.accdb uses custom ribbons and a custom Quick Access Toolbar to help control what users can view when they open the application in Access client. For the next sections of this chapter, we’ll use commands on the built-in Access ribbon, so you’ll need to change the Access Options so that it does not show the custom ribbon. To do this, click the File tab on the Backstage view, click Options, click the Current Database category, remove the rbnMain text from the Ribbon Name option, click OK to save your changes, and then close and reopen your web-published web database. You can now see the default Access ribbons.
INSIDE OUT
Using SharePoint Fields
After you publish a web database to an Access Services site, you can use the built-in SharePointEditor, SharePointAuthor, SharePointModifiedDate, and SharePointCreatedDate fields that exist in all SharePoint lists. For example, if you create a new query, you’ll notice that Access displays these fields in the query design window. You can reference these fields in both client and web objects in your published web application.
Making Changes to a Published Web Application There is no requirement that you must have your web database completely finished with all the objects you think you’ll ever need before publishing it to a server running SharePoint and Access Services. You could, in fact, publish nothing more than a one-field table to the server, although that wouldn’t be of much practical use. Access Services is designed to be flexible, allowing you to add, edit, delete objects, or make changes to the table schema as your application needs change. You can even have multiple people changing database objects and synchronizing their changes to the server in a collaborate environment. Let’s show you an example of how to add and edit objects in your published web application and then synchronize those changes to the Access Services site. Earlier in this chapter, as well as in Chapter 6, you learned about the USysApplicationLog table that records data macro execution errors and compile errors on the server. Unfortunately, you cannot have database objects bound to this table before you publish the web database to the server, because the Web Compatibility Checker prevents you from publishing if you have objects bound to this table. The good news, however, is that you can bind database objects to the USysApplicationLog linked table after you publish. In the BOSS.accdb sample web database, we’ve created an entry point in the main menu to see the data in the USysApplicationLog linked table, both in Access client and the browser. On the companion CD, you’ll find a web database file called BOSSLogsForServer.accdb that contains a web form and web report that we can import into our published application and then use in both Access client and the browser to easily view any data recorded in the USysApplicationLog table. Note that
Using Your Published Web Database in Access 1331
you can also create new objects and edit existing objects in your published application and send those changes to the server, but for our example, it was easier to have these web objects already created for you. To add this web form and web report into your published application, perform the following steps:
1. Close any database objects you might have open. 2. Click the Access button in the Import & Link group on the External Data ribbon tab. 3. In the Get External Data – Access Database dialog box, browse to the folder where you installed the sample files and select the BOSSLogsForServer.accdb file. Select the option to import objects and then click OK.
4. In the Import Objects dialog box, select frmErrorLogServer on the Forms tab and rptErrorLogServerWeb on the Reports tab. Click OK to import those two web objects into the published web application. Click Close in the dialog box after the import process completes.
5. Open the web form called frmErrorLogsMenu in Layout view. Select the Server Log –TBD navigation button on this web form. Change the Caption property of this navigation button to Server Log. In the Navigation Target Name property, select Form.frmErrorLogServer from the drop-down list of object names. The navigation subform on the frmErrorLogsMenu form should now be showing the frmErrorLogServer form. The command buttons on the frmErrorLogServer web form open the rptErrorLogServerWeb web report so you can print the data in the USysApplicationLog table. Note that the form might be blank if there are currently no records in your USysApplicationLog table on the server.
6. Save your changes to the frmErrorLogsMenu web form and then close the form.
Troubleshooting Why do I not see any controls on my form in Layout view? When you open a web or client form in Layout view, you won’t see any controls displayed on the form surface if there are no records in your form’s record source and the form’s Allow Additions, Allow Deletions, and Allow Edits properties are all set to No. To see and edit your form controls on the design surface, you can temporarily add a record to the form’s record source.
Chapter 22
1332 Chapter 22 Using Web Applications in a Browser
Chapter 22
Now that you have the new completed web form and web report in your local published web database, you need to synchronize these changes with the server. To synchronize your local changes with the server, click the File tab on the Backstage view. Access displays the Info tab for a published web application, as shown in Figure 22-38. Next to the Sync All button, Access displays a message indicating that there are local changes that have not been sent to the server. Beneath that message, Access displays a message indicating that there are no changes on the server. Access also displays a hyperlink that you can click to open the Access Services site in your web browser. Beneath the Sync All button, you’ll see the date and time when Access last checked the synchronization status between the client and the server. If you click Check Sync Status, Access checks to see if there are any pending local changes that need to be sent to the server, checks to see if there are any changes on the server that have not been downloaded to the local copy of the published application, and then updates the three messages. If there are changes on either client or the server, Access colors the section around the Sync All button in red.
Figure 22-38 You can check the synchronization status and synchronize changes with the server on the Info tab.
To send your local changes to the server, click Sync All. Access first synchronizes any changes from the server into your local copy and then runs the Web Compatibility Checker on your database. If the tool finds issues during this process, Access aborts the remaining synchronization process. You can check the Web Compatibility Issues table to see what caused the failure and then correct the issues. If the Web Compatibility Checker finds no issues with your web database, Access begins the process of synchronizing your local
Using Your Published Web Database in Access 1333
changes with the server. Access sends up any changes from the local copy of the database to the server. These changes could be new objects, changes to existing objects, or database properties (such as the Web Display Form database property we had you change earlier). Access Services then compiles your changes.
Note If you click Sync All when there are no changes in either client or the server, Access displays a message box indicating that your application is already in sync with the server.
INSIDE OUT
Working with Larger Web Databases
Whenever you synchronize your changes with the server, the Web Compatibility Checker needs to scan all the web objects. When you are working with a web database that has many web objects, this process can add up to lots of extra time waiting for the tool to complete the scan each time. You might consider dividing your web application into smaller test group applications during the development process and then importing the completed objects into the master web database after you’ve completed your testing of new objects.
Navigate to your Access Services site in the browser, refresh the main menu page if you still have the browser window open from the previous section, click the Administration toplevel navigation button, and then click the Error Log second-level navigation button. You should see the new web form and web report when you click the Server Log navigation button on the left side. You’ve now successfully added new elements to your web application and synchronized those changes with the server. Anyone else using the site in the browser will see these changes as well.
INSIDE OUT
Add the Sync All Command to your Quick Access Toolbar
When you are working with a published web application and making many changes to the database objects, you might find it useful to add the Sync All command to your Quick Access Toolbar. To do this, click the down arrow on the right side of the Quick Access Toolbar, and then click Sync All on the Customize Quick Access Toolbar dropdown list. You should now see the Sync All command listed on your Quick Access Toolbar.
Chapter 22
1334 Chapter 22 Using Web Applications in a Browser
Chapter 22
When you synchronize new or changed web objects to the server, Access Services needs to recompile those objects. If there are other objects that depend on the new or changed web object, Access Services needs to recompile those objects as well. During the compilation phase, Access Services locks the site, which means you might see the Preparing Site web page shown earlier in Figure 22-9. You might not be able to view some objects in the browser until the site compilation process completes. When you are making changes to any objects within Access to your published web application, Access does not synchronize those changes with the server until you click Sync All. When you make changes to web tables, however, Access sends up those changes to the server immediately. For example, if you change the Caption property of a table field in a published application, Access sends up that change to the server immediately. If you change another field property, Access sends up that change immediately, and so on. As a result of this setup, there are two things you should be aware of when making schema changes to a published web database. First, you cannot make schema changes in a published web application if you are not currently connected to your Access Services site. Second, your Access Services site will be compiling quite often when you are making schema changes because each change forces the web table on the server to recompile, which in turn forces dependent objects to recompile as well. If you have users using your Access Services site in the browser, they will likely encounter messages stating that the site is unavailable and record saving error messages because the data macros are recompiling. We recommend that you make schema changes to your published web application during times of low activity so as not to interrupt people using your Access Services site. You might want to schedule a specific time to work on schema changes and inform users of this schedule. If a web table, web query, or web macro fails to compile to the server, Access Services locks the site and prevents you from opening any objects in a web browser. If you navigate to the Access Services site in the browser, you’ll see a Site Is Down web page, as shown in Figure 22-39. Click the Click Here To View The Errors In Microsoft Access link to open the File Download dialog box, where you can open or save the .accdw file to view the error in Access client. If you have the web application open in Access, you can open the USysApplicationLog table to help analyze the compilation errors. Access Services
Using Your Published Web Database in Access 1335
creates a new record in this table for each object that failed to compile. The SourceObject field lists the name of the object that filed to compile. In the Category field, you’ll see the word Compilation. The Object Type field lists the type of object that failed to compile. In the Description field, you’ll see information detailing the cause of the compilation failure. You’ll need to fix these issues in Access and synchronize your changes to the server to use your Access Services application in the browser.
Figure 22-39 Access Services displays this web page if it could not compile a table, web query, or web macro object.
Resolving Synchronization Conflicts If multiple people are editing objects in an Access Services web application from their own computers using Access client, you might encounter a synchronization conflict when you attempt to synchronize your local changes to the server. A synchronization conflict occurs when two or more people modify the same database object and attempt to synchronize their changes. For example, suppose a user—User 1—makes a change to the web macro object mcrMessages in the Back Office Software System published web application from his copy of Access client, saves his changes, and then synchronizes the changes with the server. Another user—User 2—also makes a change to the mcrMessages web object from her own local copy, saves her changes, and then synchronizes the changes with the server. If User 1 synchronized his changes first, User 2 will see a synchronization conflict message when she attempts to synchronize her changes with the server, as shown in Figure 22-40.
Chapter 22
1336 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-40 Access displays this dialog box when you have an object synchronization conflict.
In the Sync Application dialog box, Access informs User 2 that it successfully synchronized changes from the server but encountered a synchronization conflict with at least one object. Access displays the object type (Macro, in this example), the name of the object (mcrMessages), which user changed the object (Jeff Conrad), and the new name Access gave the conflicting object (mcrMessages_jeff). User 2 also sees the mcrMessages object in the Navigation pane, as well as a new object called mcrMessages_jeff. In this scenario, User 1 does not see any synchronization conflict messages. User 1 synchronized his changes first, so the mcrMessages object stored on the server contains the changes made by User 1. When User 2 attempts to synchronize her changes with the server after User 1, the Access program on User 2’s computer notices that the mcrMessages object in the local copy needs to be sent to the server. But the same object also has a newer version on the server and needs to be brought down to the local copy. For User 2, Access renames the local copy of the mcrMessages object to mcrMessages_jeff. (Access appends the SharePoint user name to the name of the object so the object is renamed mcrMessages_jeff in our example.) Access then brings down the server copy of the mcrMessages object into the local copy of User 2’s database.
Using Your Published Web Database in Access 1337
User 2 now has the ability to see the changes made by User 1 by opening mcrMessages in her local copy and comparing the changes in that object with her own changes in the mcrMessages_jeff object. User 2 has to resolve these object conflicts. If User 2 wants to keep the changes made by User 1, User 2 can delete the mcrMessages_jeff object from the Navigation pane. If User 2 wants to keep her changes and discard the changes made by User 1, User 2 can delete the mcrMessages object from her Navigation pane, rename the mcrMessages_ jeff object to mcrMessages again, and then synchronize her changes with the server. If User 2 wants to keep both changes, User 2 can manually merge the changes between the two objects (possibly in the mcrMessages object), delete the other object, and then synchronize her changes with the server. One key point to remember when synchronizing changes with the server is that the object on the server is always the latest version.
Working Offline We’ve shown you how to work with your published web application in a browser, but what happens when the server running your Access Services site is unavailable or you have network connectivity issues? You have the ability to work with a published web application within Access client in offline mode—without a connection to the Access Services site. If Access detects that it cannot communicate with the server, you’ll see a message in the Status Bar indicating that the SharePoint tables are disconnected, as shown in Figure 22-41.
Figure 22-41 Access displays a notification on the Status Bar if you are offline and caches data changes locally.
When you are offline, you can continue to add, edit, and delete records, but these changes are only cached locally on your computer. Access temporarily assigns the ID value a negative number to new records you create in offline mode. Access also displays a dimmed pencil icon in the record selector for any new or changed records. In Figure 22-41, you can see that we edited an existing record (record ID 23) and created a new record in the tblInvoiceHeaders web table. You can see the dimmed pencil icon next to both of these records and the negative ID value for the new record.
Chapter 22
1338 Chapter 22 Using Web Applications in a Browser
Note Chapter 22
In Access 2007, if you had links to lists in a SharePoint site, you could manually disconnect from the server using the Work Offline command. This command is no longer available in Access 2010. You cannot force Access to disconnect from the SharePoint server except by manually disconnecting your network connection.
If you are working in offline mode, Access displays the Reconnect Tables section on the Info tab of the Backstage view, as shown in Figure 22-42. If you click Reconnect All Tables, Access synchronizes cached data changes only to the server. (The synchronization process fails if Access still cannot communicate with the Access Services site, though.) If you click Discard All Changes, Access displays a dialog box indicating that all data changes made in disconnected tables will be permanently discarded. If you click OK in this dialog box, Access deletes all cached data changes you’ve made while in offline mode. Note that clicking OK does not delete any object changes made in offline mode. Click Cancel to keep your changes and dismiss the dialog box. To the right of the Reconnect All Tables button, Access lists the names of any tables that have cached local changes not uploaded to the Access Services site and a status of the current communication with the site. When the connection is reestablished, Access displays the text “Ready To Be Reconnected” next to each table name.
Figure 22-42 Access displays options to reconnect with the server or discard any cached data changes on the Info tab.
Using Your Published Web Database in Access 1339
While you are working in offline mode, Access checks to see if it can connect with the Access Services site every 30 seconds (this setting cannot be changed). When Access successfully communicates again with your Access Services site, Access displays the Reconnect To SharePoint Server message bar and a Status Bar message indicating that one or more tables are available for reconnect, as shown in Figure 22-43. To synchronize your data with the Access Services site, you can click either the Synchronize button on the Reconnect To SharePoint Server message bar or the Reconnect All Tables button on the Info tab of the Backstage view.
Figure 22-43 Access displays a message bar indicating that Access can communicate with the Access Services site again.
When you encounter any data conflicts during the synchronization process, Access displays the Resolve Conflicts dialog box, also shown in Figure 22-43. In this example, we edited an existing invoice’s amount (record ID 23) within Access client while in offline mode. On a different computer, we opened a web browser, navigated to the Access Services site, entered a different invoice amount for the same record, and saved the record changes. Access correctly identifies that this record has data conflicts during the synchronization process.
Chapter 22
1340 Chapter 22 Using Web Applications in a Browser
Chapter 22
The Resolve Conflicts dialog box has Previous and Next buttons in the upper-right corner. You can use these buttons to move back and forth between the records that have data conflicts. (These buttons appear dimmed if only one conflict is found in a table.) Access displays the number of conflicts it finds near the top of the dialog box. In our example, Access shows a message of “Details – 1 of 1”—one record has data conflicts. The Resolve Conflicts dialog box also shows who changed the data on the server and the date and time it was changed. In the middle of the dialog box, Access displays all the fields in the list, highlights what the other user changed in the record on the Access Services site, and the changes you made to the same record. In our example, you can see that the InvoiceAmount field was changed to 165.65 on the server and we changed it to 155.65 in our local copy of the data while in offline mode. If you want to keep the record changes that the other user made, click Discard My Changes. Click Retry My Changes if you want to keep the changes you made to the record. For each record conflict (if you have more than one), you need to decide whether you want to keep your changes or discard them. If you want to discard all your data changes, click the Discard All My Changes button at the bottom of the dialog box. If you want to keep all your record changes, click Retry All My Changes. If you have additional data conflicts in other tables, you’ll need to resolve those conflicts as well. As you might recall, we added one new record to the tblInvoiceHeaders table. Access had no problems adding this record to the Access Services tblInvoiceHeaders list because there were no data conflicts. We want to keep all the changes we made, so click Retry All My Changes.
Note When you synchronize a large amount of data changes back to the server after reconnecting, it’s possible that Access Services needs to run many data macros as the record changes get added to the lists. You might cause the data synchronization process to time out if the process takes too long to complete. If this occurs, Access opens the Resolve Conflicts dialog box and displays the records that failed to be committed. You can click Retry All My Changes to try to commit the remaining records.
Here is a summary of other Access behavior that you should be aware of when working in offline mode: ●●
You cannot make design changes to any web tables in offline mode, but you can make design changes to other database objects. This means you also cannot modify any data macros in offline mode because data macros are attached to tables.
●●
All data operations—insert, edit, and delete—function normally. Your changes are stored locally until you synchronize your changes with the server.
Using Your Published Web Database in Access 1341
●●
Any RunDataMacro actions fail when you are in offline mode. This might cause web forms that call named data macros to fail when you’re working in offline mode.
●●
If you have data macro logic attached to Before table events, those events fire immediately in Access client as you add, edit, or delete data. After you reconnect to the server and synchronize your data changes, Access Services also runs the Before event on the server as it commits the data changes. If another user changes the data macro logic before you reconnect, you might encounter errors committing all your data changes if the new logic conflicts with your data updates.
●●
If you have data macro logic attached to After table events, those events do not fire in Access client as you add, edit, or delete data. After you reconnect to the server and synchronize your data changes, Access Services runs the After event data macro logic as it commits the data changes.
INSIDE OUT
Caching Data Locally
When you work with a published web application in Access client, Access caches data in the tables only when you use the data. For example, if you open the tblInvoiceHeaders web table in Datasheet view, run a query, or open a form or report that uses the data in that table, Access caches the data locally. However, if you don’t use the data in the tblAppointments web table, Access does not cache the data locally for that table. To guarantee that you have a cached copy of all the data in your Access Services site, you can open each table individually and move to the end of the datasheet. You can also write Microsoft Visual Basic code that opens a recordset on each table. If you want to clear the cache whenever you close the published web database, click the File tab on the Backstage view, click Options, click the Current Database category, and then select Clear Cache On Close under the Caching Web Service And SharePoint Tables category. This option is cleared by default. Select Never Cache in client databases if you do not want to cache any data from linked SharePoint lists. Note that you cannot select the Never Cache option in published web databases.
Saving a Web Application as a Local Database If you want to remove your Access Services site, navigate to the Delete This Site web page for your web application in a browser. You cannot delete a published web application from within Access client. Before you consider deleting your Access Services, we recommend that you first save a copy of your published web application as a local database. Throughout the last sections of this chapter, you’ve been working with a published web application that
Chapter 22
1342 Chapter 22 Using Web Applications in a Browser
Chapter 22
stores the data in SharePoint lists in an Access Services site. While it’s true you have a copy of all the database objects right now on your computer, your data is stored on the server. If you delete the Access Services site, your data, except for what might be cached locally, is deleted. When you save a copy of your published web application as a local database, you are essentially reversing the publish process. In this procedure, you’ll not only bring down a copy of all the objects in your web database but all the data as well. To do this, click the File tab on the Backstage view, click the Save & Publish tab, click Save Database As under File Types, and then double-click Save As Local Database. Access opens the Save As dialog box, where you can browse to a location to save the file. Click Save, and Access starts the process of downloading the entire application with data to your download location. When you open the database after this process, you’ll notice the web tables are local tables again and contain all your data. Now that you have a copy of the Access Services site saved locally, you can safely delete your Access Services site. To do this, click the Options button on the Access Services shell, and then click Settings to open the Modify Application page. Click the Delete This Site link to open the SharePoint Delete This Site page. Click the Delete button on this page to delete your Access Services site.
Instantiating an Access Services Template In addition to publishing a web database from Access client, you can create an Access Services site by instantiating a template on a server running SharePoint 2010 and Access Services. In Chapter 6, you learned how to create a web database by instantiating one of the five built-in web templates shown in the Backstage view. You can also instantiate web templates on a server running SharePoint 2010 and Access Services.
Instantiating an Access Services Template 1343
The five built-in Access Services web templates—Assets, Charitable Contributions, Contacts, Issues, and Projects—are preinstalled on a server running SharePoint 2010. You can instantiate one of these web templates on the server, even if you don’t have Access installed on your local computer. To instantiate one of these installed web templates, open your web browser and navigate to your server running SharePoint 2010. Note that you might need to navigate up to the parent site of your SharePoint server if you are currently viewing an existing Access Services site in your web browser. Next, click Site Actions in the upper-left corner of the SharePoint page and then click New Site from the drop-down list of options. SharePoint opens the Create dialog box, as shown in Figure 22-44.
Figure 22-44 You can instantiate one of the five built-in web templates from the Create page.
Click the Web Databases link on the left side of the dialog box under Filter By. Select one of the five built-in web templates to instantiate, enter a site name on the right side, enter the URL name to use for your application, and then click Create. Note that if you want to set additional options for your Access Services site, click More Options before clicking Create. You’ll see a Processing screen for a minute or two while SharePoint instantiates the web template, creates an Access Services site based on this web template, and then compiles the site. When SharePoint is finished compiling the site, SharePoint automatically takes you to your completed Access Services site, as shown in Figure 22-45. Your site is ready to be used in a web browser, or you can open the completed Access Services application within Access client if you have it installed on your computer.
Chapter 22
Using an Installed Web Template
1344 Chapter 22 Using Web Applications in a Browser
Chapter 22 Figure 22-45 You now have a complete Access Services site created from a built-in web template.
Instantiating a Custom Template In addition to instantiating one of the five built-in web templates on a server running SharePoint 2010, you can upload your own custom web template and instantiate it on the server to create a new Access Services site. In Chapter 27, “Distributing Your Application,” on the companion CD, you’ll learn how to create a template (.accdt) from an Access database file. You’ll also find a sample web template called ContactsMap.accdt on the companion CD, which you can use to follow along with the next section. To upload, activate, and instantiate your own custom web template, perform the following steps:
1. From the main page of your SharePoint server, click Site Actions in the upper-left corner of the SharePoint page, and then click Site Settings from the drop-down list of options. On the Site Settings page, click the Solutions link.
2. SharePoint navigates you to the Solutions Gallery page. Click the Upload Solution button in the New group on the Solutions ribbon tab.
3. On the Upload Document dialog box, browse to the location where you installed the sample files and select the ContactsMap.accdt file. Click OK to upload the .accdt file to the Solutions Gallery.
Instantiating an Access Services Template 1345
4. Select your web template (ContactsMap) on the Solutions Gallery page and then click Activate in the Commands group on the Solutions ribbon tab. When the Solution Gallery – Activate Solution dialog box loads, click Activate to activate the web template.
5. Click Site Actions in the upper-left corner of the SharePoint page and then click New Site from the drop-down list of options. Click the Web Databases link on the left side on the Create dialog box, and then select the ContactsMap custom web template that you previously uploaded and activated. Enter a site name on the right side, enter the URL name to use for your application, and then click Create.
After a minute or two of processing time, you’ll see your completed Access Services site instantiated on the server from a custom Access web template, as shown in Figure 22-46.
Figure 22-46 You can use a custom web template to create an Access Services site.
You now have a better understanding of how to publish and instantiate a web database to create an Access Services site on a server running SharePoint 2010. You also know how to work with your application in a web browser and make changes to your application. In Chapter 23, you’ll learn how to work with Business Connectivity Services using SharePoint Designer 2010 and Access 2010.
Chapter 22
c hapte r n C 2 3o
Chapter Using Business Title Connectivity Services
s you’ve learned in previous chapters, Microsoft Access 2010 can connect to a wide variety of data sources such as Microsoft SharePoint and Microsoft SQL Server. Web services are quickly becoming one of the most common ways to expose and use data in all types of applications. In Access 2010, you can now create a Data Service linked table to a Simple Object Access Protocol (SOAP)–based web service. When you create a Data Service linked table in Access, you can view the data returned from the web service and use expressions to make calls to the web service. This chapter shows you how to: ●●
Create a Business Connectivity Services model definition file using Extensible Markup Language (XML).
●●
Use SharePoint Designer to generate and export a Business Connectivity Service model definition.
●●
Import a model definition into Access to create a linked table to a web service.
Note The examples in this chapter are based on the supporting files you can find in the Web Services folder on the companion CD. The results you see from the samples in this chapter might not exactly match what you see in this book if you have changed the sample data in the files.
Understanding Web Services At their heart, web services exchange data encoded as XML over the Web. Many websites today are simply mashups—websites created by combining multiple web services into one application. Web services are generally categorized in two ways—public web services and
1347
1348 Chapter 23 Using Business Connectivity Services
Chapter 23
enterprise web services. Public web services expose data that is unrestricted to all computer users with Internet access. Some examples of public web services are Amazon’s E3 web service, eBay’s marketplace web service, and many Really Simple Syndication (RSS) feeds. Figure 23-1 shows you a conceptual diagram of a public web service.
Figure 23-1 Public web services expose data to the public over the Internet.
In Figure 23-1, you can see the public web service acting as a bridge between the data stores of a company and the local applications accessing the data from the Internet. The web service created by the company exposes data that client and web applications can manipulate. Enterprise web services are used to create a common interface across multiple data sources, as well as to provide a security model to control access to the data. For example, if your enterprise stores data stored in SQL Server and Oracle databases, you can create web services on top of each data store. Information Technology (IT) applications can then easily communicate to each of their respective web services. This method of exposing data in enterprises through common web service endpoints is referred to as a Service Oriented Architecture (SOA). Enterprise web services often tend to be smaller and simpler than large public web services, although there can be wide deviations within both categories. A conceptual diagram of an enterprise web service is shown in Figure 23-2.
Figure 23-2 Enterprise web services can create interfaces across different data sources.
Introducing Business Connectivity Services 1349
In Figure 23-2, you can see an IT-developed application that relies on multiple data stores such as SQL Server databases, Oracle databases, Customer Relationship Management (CRM) data, and other sources. In this case, the application does not need to have separate interfaces for the data sources but only needs to interface with the standardized web services that sit on top of these data stores.
Introducing Business Connectivity Services In Microsoft Office SharePoint Server 2007, Microsoft introduced a mechanism, called the Business Data Catalog (BDC), for utilizing back-end data sources in SharePoint applications. In SharePoint 2007, you could connect to data through Open Database Connectivity (ODBC) connections, Web Services, and SQL Server databases. The data connections in SharePoint 2007, however, were read-only, and you could communicate to protocols only through protocol shims that were developed by and shipped with the BDC. You can think of a protocol as a description of formats and rules for exchanging electronic messages and a protocol shim as a means for the BDC to talk different protocols. With the SharePoint 2010 release, Microsoft renamed the BDC service to Business Connectivity Services (BCS) and made significant improvements to the architecture. Here are some of the new BCS features with SharePoint 2010: ●●
BCS now has extensible protocol shim architecture. For example, a .NET developer can write a custom shim for speaking to any back-end protocol such as RSS, Atomformatted web feeds, Java Script Object Notation (JSON), and Representational State Transfer (REST).
●●
BCS supports full Create, Read, Update, Delete, and Query (CRUDQ) operations on data sources.
●●
BCS can expose data sources directly into SharePoint as virtual lists. These virtual lists appear and behave the same as traditional SharePoint lists.
●●
BCS Virtual Lists can be accessed from within Microsoft Outlook 2010.
In Figure 23-3, you can see a conceptual diagram showing how Access 2010 interacts with the BCS client to display enterprise web service data within Access client.
Figure 23-3 Here, you can see a conceptual diagram of BCS integration in Access.
Chapter 23
1350 Chapter 23 Using Business Connectivity Services
Chapter 23
The functional unit in BCS is the entity. Entities describe the connections and transform for a given data source. On a high level, entities are meant to represent conceptual objects. For example, you could define a BCS entity which represents a customer, which is connected to data from one or more web services. Using the BCS interface, you can then perform standard CRUDQ operations with that customer entity. Entities are contained in a BDC model definition file, also known as a metadata file. Metadata files are typically XML documents that describe a data structure. Access 2010 can use entities by installing the BCS model definition files. Before we begin our study of BCS metadata XML files, we need to discuss in more detail the topic of XML.
Using XML Today’s modern companies are increasing productivity and cutting costs by finding ways to share more and more information online. When data can be shared in a universal format, it doesn’t matter whether an employee is down the hall, across the street, or thousands of miles away. The online sharing of information also makes it easier for companies to expand into global markets. Customers half a world away can explore a company’s products and services and place orders online. Companies can tap into vendors worldwide to find the best products at the best price. The World Wide Web has certainly been an enabling technology for increasing productivity and expanding markets. The web works because of the universal acceptance of protocol and language standards. Hypertext Markup Language (HTML) enables a web page to be displayed on any computer and in any browser anywhere in the world. As an adjunct to HTML, XML defines a standard and universal way to share data files or documents. SharePoint Server 2010 uses both these technologies to provide an enhanced web-based data and information sharing mechanism to help companies increase productivity.
Exploring XML The current XML standard is based on an International Organization for Standardization (ISO) standard, but the most commonly used version is the one maintained and published by the World Wide Web Consortium (W3C). Because a file in XML format contains not only the data but also a description of the structure of the data, XML-enabled receiving systems know exactly how to process the data from the information included in the file. An XML document can contain data from a single table or from an entire database. An XML document can also have supporting files that describe details about the table schema (for example, field properties and indexes) or that describe how the recipient should lay out (format) the data for display (for example, fonts and column sizes).
Using XML 1351
Like HTML, XML uses tags to identify descriptive elements. Examples include the name of a table or the name of a field in an XML data file, the names of table properties or index properties in an XML schema file, and the size and color of a border or the name of a style sheet template in an XML layout file. However, where most browsers are forgiving of errors in HTML, such as a missing end tag in a table row, most software that can process XML insists that the tags in an XML file be very precise and follow strict rules. An XML document or set of documents that contain precise XML are said to be well formed.
Well-Formed XML Although you can create most XML documents using a program such as Access 2010 that always creates well-formed XML, you might occasionally need to view and edit XML files that you receive from outside sources. You should understand the following rules that apply to well-formed XML: ●●
Each XML document must have a unique root element that surrounds the entire document.
●●
Any start tag must have an end tag. Unlike HTML, which supports stand-alone tags (such as ), XML requires all tags to have explicit ends. However, some tags within XML are self-contained. For example, you code an object definition tag within a schema file like this (the /> characters at the end of the string define the end of the tag):
●●
Tags cannot overlap. For example, you cannot start the definition of one table field and then start the definition of a second table field without ending the first one.
●●
When you need to include certain characters that are reserved for XML syntax (such as , “, ’) within the data portion of an element, you must use a substitute character sequence. For example, you indicate a single quote within data using the special sequence &apos.
●●
All tags in XML are case-sensitive. For example, is an invalid end tag for the start tag .
As you examine the XML examples in this chapter, all XML samples you encounter should be well formed.
Chapter 23
1352 Chapter 23 Using Business Connectivity Services
Working with BDC Model Definition Files Chapter 23
Now that you have a better understanding of XML, let’s look at the basic XML file structure of a BDC model definition file at a high level. Listed here is an example of a BDC model definition file:
A LOBSystem, short for line-of-business system, in the XML document loosely correlates to a single data source, such as Amazon web service or an SQL database. LOBSystems contain properties that describe how to connect to and authenticate the data source. Within a LOBSystem, there are multiple entities, each representing the grouping of various web service methods into a single conceptual object. Each entity contains a method with a corresponding method instance. Methods map to web service function calls, while method instances map methods to one of the BCS method stereotypes. The stereotypes represent categories of interaction into which a given web service can fall. The only BCS stereotype Access can use is the Finder stereotype. The Finder stereotype can take input parameters and produce a table of entity type.
INSIDE OUT
Using Visual Studio to Create BDC Model Definition Files
If you use Microsoft Visual Studio to manually create or modify a BDC model definition file, you can use IntelliSense to help show you the attributes and elements available within each element context. To construct a new BDC model definition file in Visual Studio, start by creating a new XML document. In the Properties section of the new XML file, under Schemas, you can point to the bdcmetadata.xsd schema file. You can locate the schema file in the following folder, assuming you have installed Office 2010 in the default folder on a Windows 32-bit operating system: C:\Program Files\Microsoft Office\Office14\bdcmetadata.xsd
Working with BDC Model Definition Files 1353
If you install the 32-bit version of Office 2010 on a Windows 64-bit operating system, you can find the schema file in the following default folder: C:\Program Files (x86)\Microsoft Office\Office14\bdcmetadata.xsd
On the companion CD in the Web Services folder, you can find an example of a BDC model file, called BCSFullDemo.xml, containing three entities—Customers, Orders, and OrderTypes. Listed here is a portion of that BDC model file showing the Customers entity: PassThrough Disco http://conradaccsrv5:55653/service1.asmx?WSDL BCSServiceProxy * PassThrough http://conradaccsrv5:55653/service1.asmx
Chapter 23
1354 Chapter 23 Using Business Connectivity Services
Chapter 23
None
Generating Entities 1355
In this specific example, when you call the GetCustomers method on the Customer entity, BCS makes the appropriate web service call and returns the data in the Customer entity.
Generating Entities As you’ve seen from the previous example, BDC model definition files can be very complex. Thankfully, there are tools that allow you to point to a web service and then generate and export a BDC model definition. Once you’ve created a definition file for the first time, you can then share the definition file throughout an enterprise or even on public communities and forums. Other users can then use the definition file to connect to the specific web service. One of the tools you can use to generate and export a BDC model definition file of a web service is SharePoint Designer 2010. You can download a free copy of SharePoint Designer 2010 from Microsoft’s website. If you need the 32-bit version of SharePoint Designer 2010, go to http://www.microsoft.com/downloads/details.aspx?displaylang=en &FamilyID=d88a1505-849b-4587-b854-a7054ee28d66. If you need the 64-bit version, go to http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=566 d3f55-77a5-4298-bb9c-f55f096b125d.
Chapter 23
1356 Chapter 23 Using Business Connectivity Services
Chapter 23
You can find an example web service called WebService1 in the Web Services folder on the companion CD. Note that this section assumes you have a web service available and running.
Setting Up the Sample Web Service If you’d like to follow the steps outlined in the next section using your own server running SharePoint 2010, you’ll need to install the sample web service. You might need to enlist the help of your SharePoint server administrator to install this sample web service. On the SharePoint server, you first need to open the Internet Information Services (IIS) Manager and add a new website. We named our sample website Service1 and used port 55653 so as not to interfere with any other services running on the server. You then use Windows Explorer to navigate to the C:\inetpub\wwwroot folder and look for the Service1 folder. If there is no folder present in that directory, you can create one. On the companion CD, navigate to the Web Services folder. Open the WebService1 folder inside the Web Services folder and then copy the Service1.asmx and Web.config files from the WebService1 folder to your C:\inetpub\wwwroot\Service1 folder on your server computer. Now, copy the Bin folder (this folder contains two files) from inside the WebService1 folder on the companion CD to the C:\inetpub\wwwroot\Service1 folder as well. Now that you have the web service files copied, you’ll need to make sure the BDC Service is running on your SharePoint server. Click Start on your Windows taskbar, click Programs, click Microsoft SharePoint 2010 Programs, and then click SharePoint 2010 Central Administration to open the Central Administration page for your server running SharePoint. Click Manage Services On Server under the System Settings category to view a list of all the services and their status on your SharePoint server. Verify that BDC Service lists the word Started under the Status column. If the status currently reads Stopped, click the Start link in the Action column to start the service. If you’ve installed everything correctly, you’ll be able to see the sample web service by navigating to a Uniform Resource Locator (URL) similar to this on your SharePoint server: http://YourServerName:YourPortNumber/service1.asmx.
Note You are not required to use SharePoint Designer to create or use BDC model files— we’ve used it here because SharePoint Designer makes the creation experience easier. You can find third-party tools from other software developers for building BDC model definition files.
Generating Entities 1357
To create a BDC definition file using SharePoint Designer 2010, follow these steps:
1. Open SharePoint Designer 2010 and then click Open Site on the Sites tab of the Backstage view. In the Open Site dialog box, enter the URL for your server running the web service. Note that you might need to enter the port number, such as http://ServerName:PortNumber, in the URL to connect to your server. Once you’ve connected to the server, click External Content Types in the Navigation pane under Site Objects, as shown here.
2. BCS data sources in SharePoint and SharePoint Designer, as well as Outlook, are called External Content. Access uses the term Data Services to differentiate BCS from other external data types available in Access. An External Content Type is just another name for a BCS entity. Click External Content Type in the New group on the External Content Types tab, as shown here.
3. Under External Content Type Information, click the New External Content Type link next to Name and type Order as the name for your new External Content Type, as shown here.
Chapter 23
1358 Chapter 23 Using Business Connectivity Services
Chapter 23
4. Tab out of the control to commit your new name, and you’ll notice SharePoint Designer sets the Display Name to match the name Order, which you just created. SharePoint Designer automatically sets the Namespace (your server name) and Version fields for you under External Content Type Information. SharePoint uses the Version value to track this External Content type, so you do not need to change this value. Next to Identifiers, SharePoint Designer lists any identifiers for the entity. We don’t want to set any identifiers at this time, so do not enter anything for this setting. In the Office Item Type combo box, SharePoint Designer displays five complex types—Generic List, Appointment, Contact, Task, and Post. Note that Access can only read Generic List, so make sure that option is selected in the Office Item Type field. (Generic List is the default option.) The Offline Sync For External List option allows an entity to be synched with offline clients such as Outlook or SharePoint Workspaces. You can choose Enabled, the default option, or Disabled to prevent sync operations. Access does not require this option to be set for the entity to operate correctly in Access, so leave this option set to Enabled.
5. Next to External System, click the Click Here To Discover External Data Sources And Define Operations link to open the Operation Designer page. Click Add Connection on the Operation Designer Page, as shown here.
6. SharePoint Designer displays the External Data Source Type Selection dialog box, shown here. In the Data Source Type combo box, you can choose .NET Type, SQL Server, or WCF Service. Select WCF Service for this new connection and then click OK.
Generating Entities 1359
7. SharePoint Designer opens the WCF Connection dialog box, as shown here. In the Service Metadata URL field, enter the URL address to the Web Service Description Language (WSDL) for the web service on your server. In the Metadata Connection Mode field, you can choose between WSDL and Metadata Exchange. Select WSDL from the drop-down list because this is a SOAP service. Enter the URL address, including the http:// prefix, to your web service in the Service Endpoint URL field. The Name field is optional, but we recommend adding a readable reference name for your connection within SharePoint Designer. In our example, we named our WCF connection Order Info Service. Leave all other options set at their defaults on this dialog box, and then click OK to save your changes and continue.
8. SharePoint Designer takes a few moments to test your connection and then displays your Order Info Service connection information on the Data Source Explorer tab. Click the plus symbol (+) next to Order Info Service to expand the various nodes. You’ll see that under Web Methods, SharePoint Designer displays all the exposed functions of the web service. This example web service exposes methods that map to three different entities—Orders, Customers, and OrderTypes, as shown here.
Chapter 23
1360 Chapter 23 Using Business Connectivity Services
Chapter 23
9. For this example, we’ll focus on the Order entity. Let’s map these web service methods to the appropriate method stereotypes for our new entity. Right-click the GetOrder method to open the shortcut menu. You’ll notice the shortcut menu displays data actions that we can map to this web service, such as read, create, update, and delete operations. (Read item operation is another term for the BCS Specific Finder method stereotype.) Click New Read Item Operation from the shortcut menu, as shown here.
Generating Entities 1361
10. SharePoint Designer now opens the Read Item wizard, as shown here. On the first page of the wizard—Operation Properties—you can enter an Operation Name and Operation Display Name. Note that you will not see this name exposed in the Access user interface. By default, SharePoint Designer already lists an Operation Name and Operation Display Name for you. Leave the names set at their default, and click Next to continue.
11. On the second page of the Read Item wizard, Input Parameters, you can configure input parameters for each operation, as shown here. Select OrderNum under Data Source Elements in the middle pane of this wizard page. (The GetOrder web method takes an OrderNum as input. This OrderNum maps to the identifier for the Orders external content type we’re creating.) Under the Properties section, Element references the name of the input variable as it appears in the web service definition. The .NET Type is the type of variable defined in the web service definition. Select the Map To Identifier field, cleared by default, since we want OrderNum to act as the ID for this external content type. In the Identifier field, select OrderNum from the dropdown list as the identifier for the input of this method. The Display Name is the name by which the input variable will be exposed in the entity definition. In the Default Value field, you can define a default value for this input in the entity definition. An example might be to set the OrderNum to 0 so no value is specified when this method of the entity is executed, but for our purposes, this value should be left to the default, , as shown here. Click Next to continue to the last page of the wizard.
Chapter 23
1362 Chapter 23 Using Business Connectivity Services
Chapter 23
12. On the last page of the wizard, Return Parameter, you can configure return parameters for the data source elements, as shown here. You can define Display names and set the return values to be required or read-only. Select OrderNum in the left panel, and then select the Map To Identifier checkbox in the right panel to map the OrderNum identifier. Click Finish to save your changes and exit the wizard.
Generating Entities 1363
You’ll notice that under the External Content Type Operations header on the right side of the screen, you have a new Read Item called GetOrder, as shown here. Note that Read Item operations are required for SharePoint Designer to define an external content type, but they are not exposed in the Access Data Services user interface.
You’ve finished making the Read Item operation, but now you need to map the Finder method that Access uses for reading lists of data. In SharePoint Designer, Finder methods are called Read List operations. To map the Finder method, follow these steps:
1. Right-click the GetOrders web method under Order Info Service, and then click New Read List Operation from the shortcut menu, as shown here.
2. On the first page of the Read List wizard, provide a name for the operation in the Operation Name text box (you can use the default name of GetOrders). Click Next to proceed to the next page of the wizard. On the Input Parameters page of the wizard, select Location under Data Source Elements. Under Properties on the right side of the Input Parameters page, click the Click To Add link next to the Filter option, as shown here.
Chapter 23
1364 Chapter 23 Using Business Connectivity Services
Chapter 23
3. SharePoint Designer opens the Filter Configuration dialog box shown here. You can use the dialog box to assign a filter for the return results you get when you request a list of data. In the New Filter text box, type Location for the name of this filter. (You can view this filter name within Access.) In the Filter Type and Operator options, you can leave these set at their defaults of Comparison and Equals from the drop-down lists of options. Setting these options means that when we pass an input filter in from Access, the entity returns all values where Location equals the value you specify. Leave the other options set on their defaults as well, and then click OK to close the dialog box.
4. SharePoint Designer returns you to the Input Parameters page of the Read Item wizard. Click next to move to the last page of the Read Item wizard, called Return Parameter. Select OrderNum in the left panel and then select Map To Identifier, as you did with the GetOrder method in the previous section. Click Finish to save your changes and exit the wizard.
Generating Entities 1365
Type Operations, as shown here. Click the Save button on the Quick Access Toolbar, and SharePoint Designer saves your work to the Business Data Connectivity Metadata Store.
Note Although Access does not use method types, SharePoint Designer requires that each entity contain a Specific Finder or Read Item Operation method type. You can certainly create an entity definition without a Specific Finder included, but you’ll need to use a different tool besides SharePoint Designer or create the entity definition by hand.
You’ve now defined a BCS Entity using SharePoint Designer. You can use this entity to interact with your web service data on SharePoint sub-sites and applications. In our example, we want to use this entity within Access, so we need to export the entity to an XML file that we can import into Access. To export the entity to an XML file, follow these steps:
1. Navigate to the External Content Types listing by clicking External Content Types in the SharePoint navigation bar. SharePoint Designer displays a list of BCS entities on the server. You’ll see the Orders entity you created in the previous section listed here. Right-click the new Orders entity and then click Export BDC Model on the shortcut menu, as shown here. (You can also click the Export BDC Model button in the Manage group on the ribbon to export a BDC model file.) Note that you can export multiple entities in the same BDC model file; select all the entities you want to export, right-click, and then click Export BDC Model from the shortcut menu. When you import a model file into Access with multiple entities, Access displays all the entities.
Chapter 23
5. You’ll now see both the GetOrder and GetOrders operations under External Content
1366 Chapter 23 Using Business Connectivity Services
2. SharePoint Designer now opens the Export BDC Model dialog box shown here. Chapter 23
To create a BDC model that contains your entity and connection information, you need to supply a name in the BDC Model Name field. Enter OrderModel for the name, and then select Client from the Settings field drop-down list. If you select the other option—Server—in the Settings field, SharePoint Designer prepares the entity definition to instantiate on another SharePoint 2010 server but Access client cannot import the definition. Click OK, browse to a location to save the file, and then click Save in the File Save dialog box to save your BDC model file.
3. SharePoint Designer exports the BDC Model file with a .bdcm file extension. For Access to import this model, you need to change the file extension to .xml. Using Windows Explorer, navigate to the BDC Model file you just saved. Right-click the BDC Model file, click Rename from the shortcut menu, and then change the file extension to .xml before proceeding further. You’ve now completed your first BDC model file, also known as a BDC metadata file. Creating the BDC model files is the most challenging step of using the BCS components in Access 2010. If you’re fortunate, another developer might have already written a BDC model file for a web service you can use. After you or someone else exports a BDC model file, you don’t need access to the SharePoint server from that point on—BCS, in Access, connects directly to the data source. Once someone takes the time to map a web service to BCS, they can easily share and distribute their work with other Access and SharePoint developers. If you are in a business or enterprise that includes SharePoint developers, there’s a good chance other developers have already defined BCS entities that you could export and use in your Access projects. You can also find BDC model files posted on public sites for communicating with various public web services, such as Data.gov.
Connecting Data Services in Access Now that you have a usable BDC model definition XML file, let’s import it into Access. As we discussed previously, Access understands how to expose Read List Operations or Default Finder of a BCS Entity. Behind the scenes, Access loads a small managed Dynamic Link Library (DLL), which is the BCS client. Access sends the BCS client the BDC model file and asks for the Finder method. The BCS handles the communications, authentication, and authorization with the remote data source, all according to the specifications in the BDC model file.
Connecting Data Services in Access 1367
Let’s take a look at how Access creates these linked lists from a BDC model file in a new Access database file. Start Access, click Blank Database on the New tab of the Backstage view, provide a name for your new database in the File Name text box, and then click Create. After Access creates your new database, close and don’t save the default Table1 table that Access initially displays. Click More in the Import & Link group on the External Data tab and then click Data Services on the drop-down list of options beneath the More command, as shown in Figure 23-4.
Figure 23-4 Click Data Services to start importing your BDC model definition file.
TROUBLESHOOTING Why is the Data Services option disabled on the ribbon? When you’re connecting to web services data using the BCS client, Access requires Microsoft .NET Framework 3.5 or later to be installed on your computer. If you are missing this component, Access disables the Data Services button on the ribbon. You’ll need to download and install .NET Framework 3.5 or later to import BDC definition files into Access.
Access opens the Create Link To Data Services dialog box, as shown in Figure 23-5. To start importing your BDC model file, click Install Connection in the lower-left corner of the dialog box.
Chapter 23
1368 Chapter 23 Using Business Connectivity Services
Chapter 23 Figure 23-5 Click Install New Connection to create a connection to your web service.
Access opens the Select A Connection Definition File dialog box, where you can browse to the location you exported your BDC model file from SharePoint Designer in the previous section. Browse to the BDC model file, select it, and then click OK. (You can use the OrderModelSample.xml file found in the Web Services folder on the companion CD, but you’ll need to adjust the model file to point to the web service running on your server.) Access examines the XML file and then loads the model in the left pane on the Create Link To Data Source dialog box. After Access installs the new data services connection, expand the Order Info Service system name and select the underlying Order entity, as shown in Figure 23-6. Note that if there are multiple Finder methods in an Entity definition, Access exposes only the default Finder method.
Connecting Data Services in Access 1369
LOBSystem Instance name
Returned Field Schema
Chapter 23
Entity name
Input Filters Figure 23-6 You can specify your connection parameters on the Create Link To Data Services dialog box.
The four main elements shown in Figure 23-6 are as follows: ●●
LOBSystem Instance name Maps to the name of the web service that you gave when you defined the connection in SharePoint Designer.
●●
Entity name Maps to the display name of the External Content Type you gave when you generated the entity in SharePoint Designer. Note that if an entity doesn’t appear in the Create Link To Data Services dialog box, the entity doesn’t contain a finder stereotype method.
●●
Returned Field Schema Lists columns (name type) that make up the return table. Note that once you define the schema of an entity, it can be altered only by modifying the original entity definition, exporting the definition file, and then importing into Access again.
1370 Chapter 23 Using Business Connectivity Services
●●
Chapter 23
Input Filters Lists entities that can take input into their finders. This is usually used to filter down the returning result set, but it can be used for any input to the underlying web method, depending on the mapping. Once these values are set for a linked table, they cannot be changed for that linked table.
INSIDE OUT
Save BDC Model Files for Future Use
When you install a BDC model file, Access installs all the contained entities into your current database and stores the definitions with your Access database, even if you copy the file to another location. If you want to use a BDC model file in a different database, you’ll need to reinstall the BDC model file into that database. We recommend that you save those model files in a location that uses regular backup procedures.
If you want to delete an entity or LOBSystem from your database, right-click the item in the Create Link To Data Services dialog box and then click Delete from the shortcut menu. You will no longer be able to use any existing Data Services links in your database that depend on these items. For this example, type OrderTest in the Specify Link Name text box to name this linked table and then click Create Linked Table. You’ll notice a new linked table in the Navigation pane, as shown in Figure 23-7. You can distinguish Data Services linked tables from other linked table types by the blue spherical objects in the lower-right corner of the linked table icon.
Figure 23-7 You can see your new Data Services linked table in the Navigation pane.
Connecting Data Services in Access 1371
You might need to add an AccessControlList tag to your BDC model file if you receive a permissions error message opening your Data Services linked table. In the OrderModelSample.xml sample on the companion CD, we included the following AccessControlList tag information:
You can look at our sample XML file to see where you need to place this tag.
Web service lists of data are displayed in Access as read-only linked tables. You can use these tables linked to the web services data in Access like other linked data sources, except that you can only view the data. For example, you cannot directly change the data in a table datasheet. You can, however, create queries, forms, and reports that reference these linked tables, and you can use Microsoft Visual Basic code to call the web service methods. In addition, you can refresh the data in the linked table to show the latest changes by clicking the Refresh All button in the Records group on the Home tab on the ribbon. Access caches the data in the linked tables when you disconnect from the data source, which means the data is still available to use. The sample web service we’ve used does not filter data but returns the entire set of data for the Orders entity. In a real-world web service, for example, we could supply a ZIP code to the Location filter to display all orders from within a specific ZIP code.
INSIDE OUT
Updating BDC Model Files
If you have a new version of a BDC model file, you can install it in your current Access database. Access overwrites any LOBSystems or entities with the same name, and your linked tables continue to function as before. Be aware, however, that if the changes involve the return schema for entities, then any linked tables in Access based on those entities need to be recreated.
Chapter 23
Note
1372 Chapter 23 Using Business Connectivity Services
Chapter 23
If you have a BDC model file that contains a scalar method type, Access exposes that method as an expression. You can see what expressions are available by browsing the WebServices tree in the Immediate Window of the Visual Basic Editor. An example of this Visual Basic code is the following: WebServices.LOBSystem("WebServiceName").Entity("EntityName").Operation("MethodName") .Execute("PARAM_NAME1=;PARAM_NAME2=")
You can use the following Visual Basic code stored in a public module to list the names of all web services, entities, and operations in a database: Public Sub ListWebServices() Dim ws As WebService Dim ent As Entity Dim op As Operation ' Loop through the WebServices and list ' out the names, entities, and operations For Each ws In WebServices Debug.Print "WebService Name: " & ws.Name For Each ent In ws.Entities Debug.Print " Entity Name: " & ent.Name For Each op In ent.Operations Debug.Print " Operation Name : " & op.Name Next Next Next End Sub
This code loops through each installed web service and then prints out the name to the Immediate Window using the Debug.Print command. Next, the code loops through the Entities in each web service and prints their names to the Immediate Window. Finally, the code loops through the operations for a given entity and prints out their name to the Immediate Window. In Chapter 24, “Understanding Visual Basic Fundamentals,” on the companion CD, you’ll learn about working with Visual Basic, the Visual Basic Editor, and the Immediate Window.
Note To see additional example data services links to the Customers, Orders, and OrderTypes entities for our sample web service, you can open the Create Link To Data Services dialog box again, and then install the BCSFullDemo.xml sample found in the Web Services folder on the companion CD. You can create a separate link to each of the three entities we defined for our sample web service and open the links to see the sample data. Note that you’ll need to manually adjust the model file to point to the web service running on your server.
Connecting Data Services in Access 1373
This concludes the printed chapter portion of Microsoft Access 2010 Inside Out. However, you’ll find four additional chapters on the companion CD. In Part 8, “Automating an Access Application Using Visual Basic,” you’ll learn about Visual Basic for Applications (VBA) and see many examples of how we automated the sample databases using Visual Basic code. In Part 9, “After Completing Your Application,” you’ll learn how to create custom ribbons for your applications, create database templates, understand how run-time mode works, as well as many other topics. The companion CD also includes six reference articles that you’ll find essential for increasing your knowledge about building applications using Access.
his book assumes you have installed Microsoft Access 2010 as part of Microsoft Office Professional Plus 2010. To install Office and related software for a single user, you need a Microsoft Windows–compatible computer configured as follows:
●●
A Pentium 500 megahertz (MHz) or faster processor (Pentium III is recommended as a minimum), and 1 gigahertz (GHz) is required for Microsoft Outlook with Business Contact Manager.
●●
Microsoft Windows XP with Service Pack (SP) 3 (32-bit), Windows Vista with SP1 (32bit or 64-bit), Windows Server 2003 R2 (32-bit or 64-bit) with MSXML 6.0 installed, Windows Server 2008 (32-bit or 64-bit), or Windows 7 (32-bit or 64-bit). Terminal Server and Windows on Windows (WOW), which allows installing 32-bit versions of Office 2010 on 64-bit operating systems, are supported.
●●
At least 256 megabytes (MB) of random access memory (RAM); 512 MB is recommended.
●●
A hard drive with at least 527 MB of free space for a minimum installation when your network administrator has set up an install package for you on a server. When you perform a local installation, you need up to 3.5 gigabytes (GB) on your primary hard drive for the installation files and programs. At the end of the Office system install, you have the option to leave some of the installation files on your hard drive, which requires up to an additional 240 MB of free space.
●●
A CD-ROM or DVD-ROM drive. (A DVD-ROM is recommended.) If you are installing over a network, no disc drive is required.
●●
A mouse or other pointing device.
●●
A 1024 × 768 or greater monitor display.
1375
1376 Appendix Installing Your Software
Other options required to use all features include the following: Appendix
●●
A multimedia computer for sound and other multimedia effects.
●●
Dial-up or broadband Internet access.
●●
Certain inking features require running Windows XP Table PC edition or later. Speech recognition functionality requires a close-talk microphone and an audio output device. Information Rights Management features require access to a Windows Server 2003 with SP1 or later running Windows Rights Management Services.
●●
Connectivity to Microsoft Exchange 2000 Server or later is required for certain advanced functionality in Outlook 2010. Instant Search requires Windows Desktop Search 3.0. Dynamic Calendars require server connectivity.
●●
Microsoft Internet Explorer 6 or later, 32-bit browser only. Internet functionality requires Internet access (fees might apply).
●●
Connection to an Internet service provider or a local copy of Microsoft Internet Information Services (IIS) installed.
●●
512 MB of RAM or higher recommended for Outlook Instant Search. Grammar and contextual spelling in Microsoft Word 2010 is not turned on unless the computer has 1 GB memory.
Installing the Office System Before you run the Office system setup program, be sure that no other applications are running on your computer. If you’re installing from the Office Professional Plus 2010 CD-ROM or DVD-ROM, insert the first disc. On most systems, the Office system setup program starts automatically. If the setup program does not start automatically, click the Run command on the Start menu. In the Run dialog box, type x:\setup.exe (where x is the drive letter of your CD-ROM drive), and click OK. If you see the User Account Control dialog box and you’re logged on as a non-administrative user, specify the user name and password for an administrative account, and click Continue. If you’re logged on as an administrator, click Continue. To install from a network drive, use Windows Explorer to connect to the folder in which your system manager has placed the Office system setup files. Run Setup.exe in that folder by double-clicking it. If you’re installing the Office system from a Master License
Installing the Office System 1377
x:\setup.exe PIDKEY=1234567890123456789012345
Note that the setup program might take several minutes after it displays its opening screen to examine your computer and determine what programs you currently have installed—be patient! If you didn’t supply a license key on the command line, the setup program asks for a valid product key. If you’re installing from a CD or DVD, you can find the product key in the materials included with the Office 2010 release installation package. Enter a valid key, and click Continue to go to the next page. The setup program asks you to confirm that you accept the license agreement. Select the I Accept The Terms Of This Agreement check box, and then click Continue. The setup program asks whether you want to install now or to customize your installation.
Choosing Options When You Have No Previous Version of the Office System When you install the Office 2010 release on your computer, you can choose between two options—Install Now or Customize, as shown in Figure A-1. If you click Install Now, the setup program installs all the programs and components that Microsoft considers most useful to the majority of users. The fastest way to complete an install is to click Install Now. If you don’t want to tailor the installation to your specific needs by clicking Customize, click Install Now to include Access 2010 so that you can work through the examples in this book.
Figure A-1 Click Install Now to install the default Office Professional Plus 2010 programs.
Appendix
Pack, click Run on the Start menu, and include a PIDKEY= parameter and the 25-character volume-license key in the open box, as in the following example:
1378 Appendix Installing Your Software
Appendix
We like to click Customize to pick the options we need. The Customize install option allows you to choose only some applications or include additional features that Microsoft considers optional. When you click Customize, the setup program displays a window with three tabs—Installation Options, File Location, and User Information, as shown in Figure A-2.
Figure A-2 The Installation Options tab allows you to choose which programs and options to install.
The setup program shows you the available options for the Office system and each program in a hierarchical view. By default, the setup program selects all programs, but it selects only some of the features for several of the programs. Click the plus sign (+) next to any category to expand it and see the options in subcategories. When you see a category that interests you, click the arrow next to the disk drive icon to choose options for all items in that category and its subcategories. To work through all the examples in this book, you should select the Run All From My Computer option for Microsoft Access, as shown in Figure A-3. Choosing this option selects the Run From My Computer option for all subcategories. Note that when you select this option, the setup program installs the Package Solution Wizard add-in, which helps you create installation files that include your database application, the runtime modules necessary to run your application, and any supporting files (such as ActiveX controls or icons). The wizard creates a standard Windows Installer setup file (.msi). When you select Installed On First Use, the installation program creates a shortcut for the program on your Start menu, but you’ll be prompted to install the application when you select the shortcut the first time. Choosing Not Available causes the installation program to neither install the program nor provide a shortcut.
Installing the Office System 1379
Appendix
Figure A-3 Choose Run All From My Computer to have the setup program install Access 2010 components.
We personally like to begin by selecting the Run All From My Computer option for the toplevel item, Microsoft Office. We then go through each of the major categories and selectively choose Installed On First Use or, for options that we do not want, Not Available. For example, you might want to go to the Office Shared Features category and remove some of the extra fonts under International Support. If you’re unsure about any option, you can click the title of the option to see a brief description in the lower part of the window. On the File Location tab, you see a box with a default location chosen, as shown in Figure A-4. You can enter a different program file location or click Browse to select a location on your hard drive. We recommend that you keep the default location. You’ll see summary information on how much space is required and available on your hard drive in the middle of the window.
1380 Appendix Installing Your Software
Appendix Figure A-4 Select an installation folder on the File Location tab.
On the User Information tab, you can enter personal information about yourself and your company, as shown in Figure A-5. Type your name in the Full Name text box, your initials in the Initials text box, and your organization or company name in the Organization text box. (Note, if you do not fill in these boxes here, the first Office system program you open after installation prompts you for your full name and initials.)
Figure A-5 Enter your personal information on the User Information tab.
Installing the Office System 1381
After you have finished making your selections, click Install Now to proceed. If you’re not sure, you can click any of the three tabs to verify the options you selected. When the setup program finishes, it shows you a setup completed window, as shown in Figure A-6. In this final window, you can select options to open your web browser to check for additional updates. You can click the Help icon in the upper-right corner of the window to display information registering your copy of the Office 2010 release. Click Close to close the setup program window.
Figure A-6 The setup program displays this message when the installation process completes.
Choosing Options to Upgrade a Previous Version of the Office System When you have a previous version of any of the Office system programs installed on your computer, the setup program shows you different options after you accept the license agreement, as shown in Figure A-7. If you click Upgrade, the setup program installs all the programs and components that Microsoft considers most useful to the majority of users and removes any previous versions of the Office system programs. The fastest way to complete an install is to click Upgrade.
Appendix
1382 Appendix Installing Your Software
Appendix Figure A-7 When you have previous versions of the Office system programs installed, you can choose either Upgrade or Customize.
We like to click Customize to pick the options we need. The Customize install option allows you to choose only some of the applications to install and to not remove previous versions. When you click Customize, the setup program displays a window with four tabs—Upgrade, Installation Options, File Location, and User Information, as shown in Figure A-8.
Figure A-8 On the Upgrade tab, you can choose to keep or remove existing Office system programs.
Converting from a Previous Version of Access 1383
The Installation Options, File Location, and User Information tabs display the same options you learned about in the previous section. The setup program displays the Upgrade tab only when you have previous versions of Office system programs installed on your computer. If you select Remove All Previous Versions, the setup program removes any existing Office system programs before installing the Office 2010 release programs. If you select the Keep All Previous Versions option, the setup program does not remove any existing Office system programs before installing the Office 2010 release programs. Notice that you cannot choose to keep a previous version of Outlook if you have chosen to install Outlook 2010. If you select Remove Only The Following Applications, you can choose which existing Office system programs to keep. As professional Access developers, we keep several versions of Access installed on our primary development computers so that we can continue to support older applications that we wrote. You might also want to keep an older version of Microsoft Excel, Microsoft PowerPoint, or Word. To keep an older version, you must clear the appropriate check box for the application under Remove Only The Following Applications. As you learned in the previous section, you can change which of the Office 2010 release components are installed on the Installation Options tab, change the installation folder on the File Location tab, and specify your user name information on the User Information tab. After clicking Upgrade, the setup program proceeds and displays the Setup Completed window in Figure A-6 on page 1381 when it is finished. You can click the Help icon in the upper-right corner of the window to display information registering your copy of the 2010 Office release. Click Close to close the setup program window.
Converting from a Previous Version of Access Access 2010 (version 14 of Access) can work with the data and tables in a database file created by Access version 2, version 7 (Access for Windows 95), version 8 (Access 97), version 9 (Access 2000), version 10 (Access 2002), version 11 (Access 2003), and version 12 (Access 2007). For version 2, you can only import the tables and queries in the old database into a new database that you create using Access 2010. Depending on the complexity of the application, you might be able to open and run a version 7 or version 8 database application with version 14, but you won’t be able to modify any of the objects in the database. You can open a version 9, version 10, version 11, or version 12 database with version 14 and modify any of the objects in the database. You can convert a version 7 or version 8 database file to either the Access 2000 format (version 9), the Access 2002-2003 format (versions 10 and 11), or the Access 2007 .accdb format (version 12 and version 14). Before you begin the conversion process, make sure all Access Basic or Microsoft Visual Basic for Applications (VBA) modules are compiled in your earlier version database. If you want to convert your database to the .accdb file format,
Appendix
1384 Appendix Installing Your Software
Appendix
start Access 2010, click the File tab on the Backstage view, click Save & Publish, and then click Access Database (*.accdb) under Save Database As. Access opens the Save As dialog box. You must specify a different file name or location for your converted database because Access won’t let you replace your previous version file directly. Click Save to convert the database. If you want to convert your database to the Access 2000 or Access 2002–2003 format, start Access 2010, click the File tab on the Backstage view, click Save & Publish, and then click either Access 2000 Database (*.mdb) or Access 2002-2003 Database (*.mdb). Access opens the Save As dialog box. You must specify a different file name or location for your converted database because Access won’t let you replace your previous version file directly. Click Save to convert the database. If you open a version 2, version 7, or version 8 database in Access 2010, you will see a dialog box offering to convert the database to the current version or attempt to modify the database for shared use between versions. For these versions, we recommend that you attempt to convert them rather than modify them for shared use. You won’t be able to convert a database that contains anything other than tables and queries. You must create a new Access 2007/2010 format database and import tables and queries from a version 2 database that has forms, reports, macros, or modules. You can also convert an earlierversion database by creating a new Access 2007/2010 format database and then importing all the objects from the older version database.
Conversion Issues Access 2010 reports any objects or properties that it is unable to convert by creating a table called Convert Errors in your converted database. The most common problems you’re likely to encounter are Microsoft Visual Basic libraries that were available in a previous version but not in Access 2010, and obsolete code that you created in a user-defined function. Other changes that might affect the conversion of your application code or how your converted application runs include the following: ●●
In versions 7 and earlier, you had to use macros to construct custom menus. Access 2010 continues to support macros for custom menus, but you might want to rebuild custom ribbons using Extensible Markup Language (XML).
●●
As of version 8, DoMenuItem is no longer supported. The conversion utility replaces this command in all macros with the equivalent RunMenuCommand action or method. The DoMenuItem method in Visual Basic code is still supported for backward compatibility, but you should locate and change these statements after converting your database.
Installing the Office 64-Bit Version 1385
●●
In version 8, you could create a formatted Windows dialog box with the MsgBox action or function, separating the sections of the message with the @ character. Version 9 and later no longer support this feature. You should remove the @ character used in this way in code you wrote for version 8.
●●
Versions 7 and 8 supported the Microsoft DAO 2.5/3.x compatibility library for databases converted from previous versions. Version 9 and later no longer support this library. You will need to replace the reference to this library to the Microsoft Office 14.0 Access Database Engine Object Library after you convert the database, and you might need to change old Visual Basic statements that depended on the older version of Data Access Objects (DAO).
●●
If you convert a database by importing its objects, your new database might not compile or execute properly. The problem is most likely a reference to an obsolete Visual Basic code library. You can correct this by opening any module in the Visual Basic Editor and then clicking Tools, References. Remove any libraries marked MISSING and attempt to compile the project.
●●
Unless you also have Office 2003 installed on your computer, you won’t be able to edit any data access pages that you created in Access 2003.
Installing the Office 64-Bit Version The Office 2010 applications are also available in 64-bit versions. Before you run the Office system setup program, be sure that no other applications are running on your computer. Note that you can install the 64-bit versions of Office 2010 only on a computer running a 64-bit Windows operating system. If you’re installing from the Office Professional Plus 2010 CD-ROM or DVD-ROM, insert the first disc. On most computers, the Office system setup program starts automatically. By default, the Office setup program wants to install the 32-bit versions of the Office 2010 applications. To install the 64-bit versions, you need to exit the default setup program. Using Windows Explorer, browse to your CD-ROM or DVD-ROM drive, open the x64 folder on the install disc, and then double-click the Setup.exe file located inside the x64 folder. If the setup program does not start automatically, click the Run command on the Start menu. In the Run dialog box, type y:\x64\setup.exe (where y is the drive letter of your CD-ROM drive), and click OK. If you see the User Account Control dialog box and you’re logged on as a non-administrative user, specify the user name and password for an administrative account, and click Continue. If you’re logged on as an administrator, click Continue.
Appendix
1386 Appendix Installing Your Software
Appendix
If you have any previous 32-bit versions of Office applications already installed on your computer, you’ll see the Setup Error dialog box shown in Figure A-9. You must uninstall all 32-versions of Office applications on your computer before you can install the 64-bit versions of Office 2010 applications. Note that this rule also applies even if you have 32-bit versions of Office 2010 applications installed. You cannot have mixed versions of 32-bit and 64-bit Office applications installed on the same computer.
Figure A-9 You must uninstall all previous versions of 32-bit Office programs before installing 64-bit versions of the Office 2010 applications.
The setup procedures for installing the 64-bit Office 2010 applications after this point are the same as the 32-bit versions of Office 2010. You can follow the steps outlined in the previous sections for customizing the application options you’d like to install. Here are some caveats to using the 64-bit version of Access 2010 that you should be aware of before deciding to install the 64-bit version: ●●
Existing 32-bit ActiveX controls will not work with the 64-bit version of Access 2010. If you open a form or report that contains a 32-bit ActiveX control, you’ll see a red “X” within the box where the control should be. You’ll need to update those 32-bit ActiveX controls to work within 64-bit environments.
●●
Microsoft did not update the ComCtl collection of controls to work within 64-bit environments. If you open a form or report that contains a ComCtl control, you’ll see a red “X” within the box where the control should be. You’ll need to update those 32-bit ComCtl controls to work within 64-bit environments.
●●
Existing 32-bit Access add-ins will not work in 64-bit Access 2010. You’ll need to obtain a version of the add-in that works in 64-bit environments from the supplier of the add-in.
Installing the Sample Files 1387
●●
Existing Access .mde and .accde files compiled with 32-bit versions of Access will not work with the 64-bit version of Access 2010. You’ll need to create a new .mde or .accde from the original database and compile it in the 64-bit version of Access 2010.
●●
You’ll need to update some existing VBA code for it to work within the 64-bit version of Access 2010. In Chapter 25, “Automating Your Application with Visual Basic,” on the companion CD, you’ll learn what changes you need to make to your VBA code so that your application runs within a 64-bit environment.
For all the reasons mentioned above, Microsoft recommends using the 32-bit version of Access 2010 unless you have a specific reason for using the 64-bit version of Office 2010. The main reason for using the 64-bit versions of Office 2010 is the capacity to work with very large workbooks in Excel and very large projects in Microsoft Project. The maximum database size for Access 2010—2 GB—is identical for both the 32-bit and 64-bit versions of Access 2010.
Installing the Sample Files To install the sample files from the companion CD, you’ll first need to create a new folder on your C drive called Microsoft Press. Next, navigate to the folder called Sample Files on the companion CD using Windows Explorer. Inside the Sample Files folder you’ll find another folder called Access 2010 Inside Out. Finally, copy that entire Access 2010 Inside Out folder and all its subdirectories to the Microsoft Press folder. You should now have a folder structure like this on your C drive: C:\Microsoft Press\Access 2010 Inside Out Inside the Access 2010 Inside Out folder, you’ll see additional subfolders that contain supporting files, as well as the main sample databases used throughout the book. After you have your files copied over from the companion CD onto your computer, make sure you set the Microsoft Press folder and all its subdirectories as a trusted location to enable all the content in the sample databases. See the section, “Enabling Content by Defining Trusted Locations,” on page 55, for information about creating trusted locations.
Note All the sample applications in this book were created and tested using a 32-bit installation of the Office 2010 applications. The sample database files included on the companion CD are most likely not compatible with a 64-bit version of Access 2010.
Appendix
Index
Symbols and Numbers $ (dollar sign), as character in format strings, 868, 870 3-D objects, setting color for, 791 64-bit Access VB applications about, 1574–1575 LongLong data types, 1475, 1579–1580 LongPtr data types, 1576–1579 PtrSafe attributes, 1577 setting registry key to test upper memory, 1576 supporting previous versions of Access, 1577–1578 understanding pointer valued functions, 1578–1579 using .accde files, 1580–1581 using Declare statements, 1575–1576 VBA7 language updates, 1579–1580 64-bit version of Office 2010 installing, 1385–1387 .accdb files (Access database) about, 6 after publishing databases, 1295 architecture of, 125–128 compacting, 285–286 components of, 1494–1497 constructing literal expressions, 1780 crosstab queries in, 1774 DAO architecture and, 1497 DAO FindFirst vs. ADO Find methods, 1638 Database Tools tab and, 61–62 deleting, 1294–1295 extension to file name, 174 for web databases, 289 linking, 452, 482, 1716 making backup copies, 239–242 packaging and signing, 1741 photo size limit of, 1602 saving databases, 34 storing character fields using Unicode, 197 using data types in, 193 using SQL aggregate functions, 1780, 1837 Visual Basic procedures and, 1500 .accde files 32-bit version compatibility, 1387 as execute-only files, 34, 1732–1733 compiled versions of, 460 in 64-bit Access VB applications, 1580–1581 working in 64-bit environment, 1580–1581
.accdw shortcut files, using, 1320 .ade files compiled versions of, 460 linking tables from, 485 Make ADE button, 1732 .adp files (Access Data Projects) about, 6 After Del Confirm events, 1172 application architecture, 1494, 1497 Before Del Confirm events, 1172 creating, 15, 125 creating execute only copies, 1732 data validity and, 8 defining USysRibbons table two load custom ribbons, 1681 importing menus and toolbars from source databases, 461 linking tables from, 485 objects in SQL Server databases, 1850–1851 packaging and signing, 1741 support for, 161 using double quotation marks (“ “) in literal expressions, 1781 using single quotation marks (‘ ‘) in literal expressions, 1780 & (ampersand) concatenating expressions with, 563 concatenating strings, in web databases, 327 using to display available characters, 870 ‘ (apostrophe) using an alphanumeric constants, 1780 * (asterisk) as LIKE wildcard, 203 as wildcard, 328 description of, 566 record indicator icon, 596 using in web queries for SharePoint, 699 \ (backward slash) description of, 566 using to display character immediately following, 868 .bdcm files importing, 1366 [ ] (brackets) following exclamation point (!), 1507 in expressions, 564, 575, 1209 in query parameters, 660 using in desktop application, 1776 using in lists, 328 using to display color text, 868, 871
All index entries from page 1449 onward refer to content on the companion CD.
1389
1390 ^ (caret)
^ (caret), description of, 566 , (comma) as separator, 472 as thousands separator, 867 > (double right arrow) button, in Available Fields list, 345 = (equal sign) in field validation expressions, 327 meaning of, 328 # Error avoiding, 1135 correcting, 489 ! (exclamation point) forces left-alignment, 868 forces placeholders to fill left to right, 870 separating table and field names with, 575, 576 using, 1507–1508 using in lists, 328 / (forward slash), dividing numeric expressions with, 566 >= (greater than or equal to sign), meaning of, 328 > (greater than sign) to display all characters in uppercase, 870 to indicate positive numeric values, 327 (not equal to sign), meaning of, 328 ( ) (parentheses) adding to expressions, 572 adding to SQL expressions, 1780 as character in format strings, 868, 870 % (percentage sign), place at last character to be multiplied by 100, 868 . (periods) separating numbers and currency data types, 867 separating table and field names with, 575, 576 using, 1507–1508 + (plus sign) as character in format strings, 868, 870 description of, 566 using in web databases, 327 # (pound sign) as LIKE wildcard, 203 as placeholder character, 868 as wildcard, 328 date/time literals, 1780 designating fill characters, 868 using in date and time values, 557 ? (question mark) as LIKE wildcard, 203 wildcard, meaning of, 328 “ “ (quotation marks) creating string constants using, 563 fixing errors caused by importing delimited text, 479 using with literal strings, 1780, 1781 using with text strings, 472 option, 45 @ sign, using as placeholder character, 870 ‘ ‘ (single quotation marks) creating string constants, 563 creating string constants in SQL, 1780 using with text strings, 472 > (single right arrow) button, in Available Fields list, 345 # Type, avoiding, 1135
A Access about, xxxv, 161–163 about security for, 47–48. See also Trust Center architecture, 125–128 as application development system, 13–15
as object-oriented programming environment, 785–789 as RDBMS database, 6–13 as Windows event-driven application, 1167–1169 backward compatibility of, 1496 commands executing, 1550–1551 selecting, 41, 63 components of application architecture, 1494–1497 data types, 190–193 evaluating arithmetic expressions, 576 importing secured files, 462 interface elements, 27 maximum text data length, 481 .mdb files and, 7 new look, xxxvi, 23–24 objects. See objects opening access for the first time, 21–23 opening existing database, 25–27 prior versions of converting from, 1383–1385 opening forms with Navigation controls in, 1013 redesigning macro windows, from, 364–365 using embedded macros in, 1216 using older macros names from, 1228 reporting problems to Microsoft, 37 requiring Field row field names, 564 submitting suggestions to Microsoft, 37 system requirements, 1375–1376 table design in, 168 troubleshooting ODBC file sources, 458 Access 2010 converting from prior versions, 1383–1385 installing sample files from companion CD, 1387 system requirements, 1375–1376 installing Office with, 1376–1383 Access About dialog box, 38 Access database (.accdb files) about, 6 after publishing databases, 1295 architecture of, 125–128 compacting, 285–286 components of, 1494–1497 constructing literal expressions, 1780 crosstab queries in, 1774 DAO architecture and, 1497 DAO FirstFind vs. ADO Find methods, 1638 Database tools tab and, 61–62 deleting, 1294–1295 for web databases, 289 linking, 452, 482, 1716 making backup copies, 239–242 packaging and signing, 1741
Access Options dialog box 1391
photo size limit of, 1602 saving, 34 storing character fields using Unicode, 197 using data types in, 193 using SQL aggregate functions, 1780, 1837 Visual Basic procedures and, 1500 Access Database Engine (ACE), 459 Access Database Engine (DBEngine) about, 1494, 1496 DAO hierarchy and, 1498–1501 Access Data Projects (.adp files) about, 6 After Del Confirm events and, 1172 application architecture, 1494, 1497 Before Del Confirm events and, 1172 creating, 15, 125 creating execute only copies, 1732 data validity and, 8 defining USysRibbons table to load custom ribbons, 1681 importing menus and toolbars from source databases, 461 linking tables from, 485 objects in SQL Server databases, 1850 packaging and signing, 1741 support for, 161 using double quotation marks (“ “) in literal expressions, 1781 using single quotation marks (‘ ‘) in literal expressions, 1780 Access desktop applications. See Access database (.accdb files) Access Options dialog box configuring Name AutoCorrect Options, 227–229 customizing look of Access using, 110 modifying global settings by way of about, 112–113 Add-ins category, 54, 121–122 Client Settings category, 118. See also Client Settings category in Access Options dialog box Current Database category, 113–114. See also Current Database category in Access Options dialog box Customize Ribbon category, 63, 69, 119–120, 897 Datasheet category, 114–115 Language category, 117–118 Object Designers category, 115–116. See also Object Designers category in Access Options dialog box Proofing category, 116, 885 Quick Access Toolbar category, 40–41, 46–47, 120–121, 1677 Trust Center category, 52, 55, 122 opening to customize Ribbon, 64 Show Property Update Options Buttons, 229, 268 Show Table Names option, 623 Tabbed Documents settings, 111
1392 Access Services
Access Services about, 37 assigning web forms as displays, 1289–1290 avoiding modifying All Site Content page, 1323 compiling web objects on servers, 1295 creating Access Applications folders, 1294 displaying timeout message, 1311 extending to SharePoint server, 1322–1327 feedback on validation rule failures, 1302 functions, 1838 instantiating templates, 1342–1345 publishing databases to, 18–19, 157. See also publishing web databases reports navigation toolbar, 1305 saving record changes, 1308–1309 shell about, 1312–1313 downloading web applications, 1314 reviewing Modify Application Page, 1318–1320 setting site permissions, 1315–1318 supporting page breaks, 993 viewing application settings, 1312 waiting for server processing and, 1309–1310 Web Compatibility Checker and, 351 working with Recycle Bin, 1321–1322 ACE (Access Database Engine), 459 ACE/JET wildcard characters, 1522 Acrobat, viewing exported web reports, 1306 Action Catalog categories displayed in, 1256 displaying untrusted action names, 1228 searching, 1196 This Database node in, 1260 action queries confirming action queries, 709 delete deleting groups of rows, 725–730 using with Before Delete, 396 inserting data, 721–725 make-table creating, 714–717 running, 719–720 SQL DELETE statement, 1815–1816 INSERT statement (append query), 1816–1818 SELECT...INTO statement, 1819–1820 UPDATE statement, 1820–1822 troubleshooting, 730–732 updating groups of rows, 704–713 converting select queries to update queries, 706–707 generic update queries, 713 running update queries, 707–709
testing with select query, 704–705 updating multiple fields, 709–711 using multiple tables or queries, 711–713 updating web tables, 360 using with OpenQuery macro, 1857 ActiveX applications automation, 1585, 1862 linking name of file using, 314 Microsoft Graph feature, 681 Paint, 755–756 objects in forms, 753–756 OLE, 190 string data type and, 1475 using WithEvents keyword and, 1481 troubleshooting calendar control, 1601 ActiveX controls getting access to, 794, 799 in data manipulation, 9–10 options in Trust Center dialog box, 53–54 web forms and, 916 ActiveX Data Objects (ADO). See ADO (ActiveX Data Objects) ActiveX Data Objects (ADODB), 1502–1504 ActiveX objects in tables, database limitations, 235 add-in files, restrictions on, 53 Add-In Manager, 62 Add-ins category in Access Options dialog box, 54, 121–122 Add-Ins group, 62 Add New Action box, 372 Add New Action combo box, 1197, 1205, 1228, 1256, 1867 Add New Field heading, 176, 297 Administrator group, 62 ADO (ActiveX Data Objects) about, 1497–1498 architecture, 1502–1504 fetching and modifying information, 447 recordsets, working with, 1520–1524 Adobe Acrobat, viewing exported web reports, 1306 Adobe Reader, viewing exported web reports, 1306 ADODB (ActiveX Data Objects ), 1502–1504 ADO Extensions for DDL and Security (ADOX), 1502–1504 ADO Find method, 1638 ADOX (ADO Extensions for DDL and Security), 1502–1504 ADP objects. See also Access Data Projects (.adp files) macro actions, 1850–1851 advanced form design client forms conditional formatting in, 978–985 creating multipage, 992–996 PivotChart, 996–999
displaying option group values, 976–978 many-to-one forms creating, 946–947 designing, 948–952 many-to-one queries, designing, 947–948 navigation controls about, 1000–1001 applying Quick Styles to buttons, 1012–1013 as collection of controls, 1003–1004 creating navigation buttons, 1004–1011 options, 1001–1002 troubleshooting dragging forms in Layout view, 1006 subforms about, 952–953 creating Main form, 969–972 creating subdatasheet, 973–976 designing first level, 962–963 designing innermost, 956–962 editing from subform controls, 971 embedding, 964–968 sizing controls, 965 specifying main source, 968 specifying source, 954–956 tab controls formatting properties, 991–992 setting order of, 877–878 troubleshooting seeing, 992 working with, 985–990 using subreports in forms, 972 using web browser controls, 1014–1019 advanced report design adding PivotCharts, 1160–1163 adding values across a group, 1135–1136 building queries, 1108–1109 calculated values adding page numbers, 1130–1131 adding print dates, 1129–1130 calculating percentages, 1141–1142 concatenating text strings, 1140 performing detail line calculations, 1132–1135 using conditional formatting, 1146–1151 using running sums, 1143–1146 creating grand totals, 1137–1138 creating reports, 1109–1111 defining grouping and sorting criteria, 1111–1114 hiding redundant values, 1138–1139 properties for reports, 1119–1128 for report sections, 1115–1119 using subreports about, 1151–1152 building subreport queries, 1155–1156 challenges of, 1152–1155
API Declarations and Constants for Visual Basic 1393
designing subreports, 1156–1157 embedding, 1157–1160 After Del Confirm events, 1172 After Delete, 409–411 After Insert events, 398–403 After Update events, 404–408 aggregate functions description of, 647 descriptions of SQL, 1837 using as calculated values, 1135 using in desktop applications (accdb) files, 1780 Alias argument, 394 alignment buttons, 811, 909 commands, 843 Allow AutoCorrect option, 885 Allowed Value List Edits lookup property, 280 Allow Layout View property, 818 Allow Multiple Rows Per Reply check box, 502 Allow Multiple Values lookup property, 279 All Site Content page, 1323 All tab, properties in the property sheet, 892–896 Alternate Row Color button, 1064, 1116 American National Standards Institute (ANSI), 1522 Access support for, 674 ANSI-standard VALUES clause, 1818 control characters, 189 embedded blanks in, 1776 ODBC in Access, 445 portability of Access and, 1773 SQL Access support for, 674 DISTINCTROW equivalent, 1801 referencing output-column-name, 1781 wildcard characters, 1522 zeros, 1482 ampersand (&) concatenating expressions with, 563 concatenating strings, in web databases, 327 using to display available characters, 870 Analyze commands, 62 Anchoring button, 884, 903 anchoring, in web forms, 901–903 AND operator specifying, 201 specifying multiple comparisons using, 327 vs. OR, 557–560 ANSI (American National Standards Institute). See American National Standards Institute (ANSI) ANSI-standard SQL language, 674 ANSI-standard VALUES clause, 1818 API Declarations and Constants for Visual Basic, Windows, 1578
1394 APIs (application programming interfaces)
APIs (application programming interfaces) accessing Windows, 1575 calling VB in 64-bit values, 1576 common Windows calls, 1578 functions, Type statement and, 1492 passing pointers to, 1578 using LongLong data type interacting with, 1579 apostrophe (‘), using an alphanumeric constants, 1780 append queries creating, 721–724 running, 725 SQL, INSERT statement, 1816–1818 Append To row, 724 application development system, Access as, 13–15 Application Parts feature to create tables, 178–182 to create web tables, 300–304 Application Parts Forms, 835–839 application programming interface (API). See APIs (application programming interfaces) applications ActiveX automation, 1585, 1862 linking name of file using, 314 Paint, 755–756 creating shortcuts, 1733–1737 hybrid, 289 reviewing Modify Application Page, 1318–1320 Windows event-driven, 1167–1168 working in web browsers. See also publishing web databases about, 1299 downloading web, 1314 hiding a repositioning Web Report Toolbar, 1305 resizing and moving columns, 1308 understanding session management, 1311–1312 using Datasheet forms, 1306–1309 using web forms, 1299–1304 using web reports, 1304–1306 viewing application settings, 1312 waiting for server processing, 1309–1310 ApplyFilter command, 1177 ApplyFilter macro action, 1856 architecture Access, 125–128 ADO, 447 DAO, 447 arguments Alias, 394 ByVal, 1526 column, 365, 1194 Control Name, 1238, 1244, 1248, 1267, 1866 Data Mode, 1202, 1244, 1275, 1866 declaring data type of, 1485–1486, 1528 Description, 439
displaying boxes for, 1197–1198 entering, 364–365 Error Description, 379, 380, 383–384 Error Number, 379, 383 Expression AskEdit Submacro, 1244 in web-supported macro actions, 1867 SetLocalVar action, 428 SetReturnVar data action, 432 SetStateAndZip Submacro, 1248 SyncWeddingAndCity, 1236 Filter, 1855 Filter Name, 1202 Form Name, 1244, 1866 for OpenForm client action, 1202–1203 Go To, 1220, 1221, 1224, 1225 Item, 1236, 1244, 1248 Logic Designer adding to, 1196 displaying, 369 Macro Name, 1220, 1224, 1241, 1260, 1867 Message, 1198, 1213, 1221, 1867 Name AskEdit Submacro, 1244 in web-supported macro actions, 1867 RemoveTempVar macro action, 1219 SetLocalVar macro action, 428 SetReturnVar data macro action, 432 SetStateAndZip Submacro, 1248 SyncWeddingAndCity, 1236 not trusted, 1228 Object Name AskEdit Submacro, 1244 BrowseTo macro action, 1275, 1276 in web-supported macro actions, 1867 SyncWeddingAndCit, 1236 Object Type AskEdit Submacro, 1244 BrowseTo macro action, 1275 in web-supported macro actions, 1867 SyncWeddingAndCit, 1236 OnError action, 1220 Options, 1227 Order By, 1866 Page, 1275 passing no, 1545 Path To Subform Control, 1275, 1276–1277 Property, 1267–1268 Report Name, 1263, 1866 Save, 1212, 1227, 1244, 1866 SetStateAndZip Submacro, 1248 subroutines accepting, 1539 SyncWeddingAndCity, 1236 TestCity Submacro, 1241
testing data types using fixed, 1474 Title, 1198, 1213 Type, 1198, 1213 using mouse to display, 386 Value, 1244, 1267 View, 1202, 1227, 1244, 1855, 1857 web supported macro actions and, 1866–1867 Where BrowseTo macro action, 1275 Where Condition as web-supported argument, 1866 BrowseTo macro action, 1275 empty values in, 1237 LookupRecord data block, 394 OpenForm macro action, 1202, 1233 OpenReport, 1855 Window Mode, 1202–1203, 1244, 1866 arithmetic expressions, 566–571 operator precedence, 568–569 operators used in, 566 using DateDiff function, 566–568 arithmetic functions, 1831–1832 arrays conversion function, 1832 declaring static, 1492 within procedures, 1489–1490 determining Variants as, 1476 dimensions, 1481 loops and, 1542 ParamArray argument, 1526 passing, 1486 two-dimensional, 1836 using in example code, 1565 vs. counters, 1541 arrow buttons Move Up/Move Down, 85, 86 Up, 390 AskEdit submacro, using, 1244–1245 asterisk (*) as LIKE wildcard, 203 description of, 566 meaning of wildcard, 328 record indicator icon, 596 using in web queries for SharePoint, 699 Attachment button, 798, 801 attachment controls, 751 Attachment data type about, 8–9, 191 selecting, 193 Attachments dialog box, 751–752, 770 Attachment web data type about, 312 using, 314 attributes, 5
BDC (Business Data Catalog) 1395
AutoCorrect Options, 116, 885 AutoexecXmpl macro, 1201–1202 Auto Expand in combo boxes, 833 AutoFormats, 897 AutoKeys macros, creating, 1712–1713 AutoNumber data type about, 190 converting to, 264 duplicate data in forms and, 773–774 in web tables, 315 selecting, 192 Auto Order, to reorder controls, 878 Auto Resize property, 856 Available Fields list copying fields from, 345 Avg function description of, 647, 1837 using in reports, 1135
B Background button, 816 Background Color button, 810 Backstage view about, 27–29 Access Options dialog box. See Access Options dialog box attributes, 1700–1701 closing, 39 controls, 1701–1703 Help tab, 37–39 Info tab, 29 New tab, 31–33, 169–170, 291 Print tab, 33 Recent tab, 29–31 Save & Publish tab, 34–37 Security Warning on, 50 Back Up Database command, 240 backward slash (\) description of, 566 using to display character immediately following, 868 BCS (Business Connectivity Services) about, 1349–1350 connecting data services, 1366–1373 exporting BCS Entity to XML file, 1365–1366 mapping Finder methods, 1363–1365 BDC (Business Data Catalog) about, 1349 adding AccessControlList tag to model, 1371 creating model, 1365–1366 definition files, 1352–1353 creating, 1357–1363 working with, 1352–1355 importing model into Access, 1366–1373 saving model, 1370 updating model, 1371
1396 BDE (Borland Database Engine Closed)
BDE (Borland Database Engine Closed), 482 Before Change events, 370–396 collapsing and expanding actions, 385–388 defining multiple actions, 381–385 including comments in, 372–373 moving actions, 388–392 occurrences of, 370–371 preventing duplicate records, 392–396 using Group construct, 373–374 using If Blocks, 375–377 using RaiseError data action, 378–380 Before Del Confirm events, 1172 Before Delete event, 396–398 Between operator, 561–562 BETWEEN predicate, 1775–1776 blank space as character in format strings, 868, 870 Bold button, 810 Book button, 1644–1646 Boolean (true or false) values AND and OR operators specifying, 201 specifying multiple comparisons using, 327 AND vs. OR, 557–560 choosing control for, 833–835 control buttons that hold Check Box button, 797 Toggle Button, 797 data type, Visual Basic, 1475 NOT operator, 1797 prefix naming convention, 1480 SharePoint vs. Access, 313, 1283 specifying Default Value field property, 316 Yes/No data type about, 190 limitations of, 265 using, 312, 313 borders, setting border styles in forms, 891–892 Borland Database Engine (BDE), 482 Bound Column lookup property, 279 Bound Object Frame button, 798 brackets ([ ]) following exclamation point (!), 1507 in expressions, 564, 575, 1209 in query parameters, 660 using desktop application, 1776 using in lists, 328 using to display color text, 868, 871 breakpoints (stopping points) (VB) setting, 1463–1464, 1469 using, 1466 Browse dialog box, 771 browsers. See web browsers
BrowseTo macro actions Path argument guidelines, 1277 using to browse web forms and web reports, 1275–1279 vs. OpenForm, 1278 build button, 966, 968 Builder button, 572, 941, 980 building complex queries, 630–634 built-in Access commands selecting, 41, 63, 1550 built-in menu commands (VB), 1549–1551 Business Connectivity Services (BCS) about, 1349–1350 connecting data services, 1366–1373 exporting BCS Entity to XML file, 1365–1366 mapping Finder methods, 1363–1365 Business Data Catalog (BDC) about, 1349 adding AccessControlList tag to model, 1371 creating model, 1365–1366 definition files creating, 1357–1363 working with, 1352–1355 importing model into Access, 1366–1373 saving model, 1370 updating model, 1371 buttons ACCDE, 1732 alignment, 811, 909 Alternate Row Color, 1064, 1116 Anchoring, 884, 903 arrow Move Up/Move Down, 85, 86 UP, 390 Attachment, 798, 801 Background, 816 Background Color, 810 Bold, 810 Book, 1644, 1645, 1646 Bound Object Frame, 798 build, 966, 968 Builder, 572, 941, 980 Calendar, 1612 Change Shape, 812 Check Box, 797 Combo Box, 796, 829 command, 756–757, 795 Conditional Formatting, 812 Contact List navigation, 1005, 1008–1010 Control Wizards, Use, 798, 829, 916 Create E-Mail, 494–495 Crosstab, 658 Delete Rule, 982 Export BDC Model, 1365 Font Color, 909
Font Group, 810 footers/header group, 799 Format Painter, 810 Form Design, 969 header/footer group, 799 Hyperlink, Insert, 795 Image, 798 Image, Insert, 799 Import/Export customizations, 69 Insert ActiveX Control, 794, 799 Insert Chart, 796 Insert Hyperlink, 795 Insert Image, 799 Insert Or Remove Page Break, 796 Italic, 810 Label, 795 Line, 796 List Box, 797 Make ACCDE, 34 Make ADE, 1732 MsgBox Function, 1243–1244 Navigational Control, 795 navigation, creating, 1004–1011 ODBC Database, 448 Option, 798 Option Group, 796 PivotTable Tools, 687–688 Query Design, 947 Query Wizard, 641 Quick Styles, 811 Rectangle, 797 Redo, 1865 Remove Or Insert Page Break, 796 Report Wizard, 1110 Select, 795 Set Control Defaults, 798, 897, 898, 916 Shape Effects, 812 Shape Fill, 812 Shape Outline, 812 Show Property Update Options, 229, 268 Shutter Bar Open/Close, 71 Subform/Subreport, 798 Tab Control, 795 Text Box, 795 Toggle, 797 Totals, 645 Unbound Object Frame, 797 Underline, 810 Use Control Wizards, 798, 829, 916 web browser, 32 Web Browser Control, 795, 1016 ByRef keyword, 1486 Byte data types, Visual Basic, 1475 ByVal keyword, 1485–1486, 1536, 1539
Check Box button 1397
C caching data locally, 1341 Calculated data type about, 191 selecting, 193 vs. calculated expressions, 563 calculated fields, sorting on, 699 calculated values adding page numbers, 1130–1131 adding print dates, 1129–1130 adding values across a group, 1135–1136 calculating percentages, 1141–1142 calculating totals on expressions, 1136 concatenating text strings, 1140 creating grand totals, 1137–1138 hiding duplicate values, 1138–1139 performing detail line calculations, 1132–1135 using aggregate functions, 1135 using conditional formatting, 1146–1151 using running sums, 1143–1146 Calculated web data type about, 312 as display values for Lookup fields, 345 using, 314, 319–327 Calendar buttons, 1612 calendars, providing graphical, 1595–1602 calendar view of SharePoint list data, creating, 1322–1327 Call keywords, 1539 statement, 1538–1539 calls for Visual Basic in 64-bit values, 1576 Windows APIs, 1578 Caption field property, 316, 582 captions changing form, 1270 caret (^), description of, 566 Cartesian products, 622 Cascade Delete Relationships, defining, 349–350 categories, custom about, 78–80 creating, 83–84 display order rules, 86 hiding and renaming object shortcuts, 93–96 unhiding object shortcuts, 97–99 cells web form, splitting and merging, 912–914 web reports, splitting and merging, 1094 Change Shape button, 812 CHAR[ACTER] SQL data type, 459 Chart Wizard Insert Chart button, 796 Check Box button, 797
1398 check boxes
check boxes, 746, 833–835 Check For Truncated Number Fields check box, 1075 Choice data type, creating in SharePoint list, 341 Choose Builder dialog box, 1214 class modules (VB) about, 1454, 1529–1530 Property Get procedure, 1530–1532 Property Let procedure, 1532–1535 Property Set procedures, 1535–1538 ClearMacroError action, 1226 CLI (Common Language Interface), 446 client databases about, 289 preparing for the web, 357–360 referencing data types, 320 client forms conditional formatting in, 978–985 creating multiple-page, 992–996 drop-down list for Navigation Target Name property, 1005 PivotChart building, 996–998 embedding linked, 998–999 using multiple data bar rules, 982 client objects, on web databases, 289 client reports adding PivotCharts, 1160–1163 laying out, 1109–1111 using subreports building subreport queries, 1155–1156 designing subreports, 1156–1157 embedding, 1157–1160 Client Settings category in Access Options dialog box about, 118–119 confirming action queries, 709 displaying XML ribbon errors, 1674 keyboard shortcuts for entering data, 597 setting options for performance of linked tables, 483 setting table design options, 226–227 client tables adding indexes, 222–226 creating in design view, 186–187 creating simple, 176–178 databases in creating, 168–175 creating default templates, 230–233 limitations on, 235 defining fields about, 187–189 choosing field names, 189–190 data types, 190–193 defining input masks, 204–207 field properties, 193–200 defining primary key, 208 defining relationships, 215–222
printing table definitions, 233–234 setting table design options, 226–229 subdatasheet properties, 213–214 using application parts, 178–181 using data type parts, 182–186 validation rules defining field, 201–203 defining table, 209–211 client web forms adding scroll bars, 876 adding smart tags, 879–881 controls for, 881–886 enabling and locking controls, 876–877 establishing standard design on, 897–899 formatting properties about, 865–866 for Currency data types, 866–869 for date/time data types, 872–874 for Number data types, 866–869 for Text data types, 869–872 setting order of, 877–878 setting properties allowing users to change views, 887 controlling updates, 890 defining pop-up and modal forms, 888–889, 891 preventing user from opening control menu, 891 properties on All tab, 892–896 setting border styles, 891–892 setting navigation options, 888 Clipboard commands, 58 Office, 601 using cut to move databases, 245 Clipboard group copying and replacing data, 600–602 using Cut command to unlink tables, 492 Close Database command, 29 Close event property, 1170 CloseWindow macro action, 1227, 1866, 1867 Code Builder, creating embedded macros, 1213 Collect data commands, 61 collecting data via email. See emails; See HTML forms; See InfoPath forms collections, referencing, 1505–1509 color names and codes, 1841–1847 Color Picker dialog box, choosing theme colors, 928–929 colors adding color to report sections in Layout view, 1092 changing themes, 933–934 customizing colors in forms, 816–817 customizing gridlines, 883 custom property, 882 special effects and, 860–862 Colors dialog box, 862
Color setting dialog box changing background color for reports, 1116 Column Count lookup property, 279 Column Heads lookup property, 279 Column-Name, 1776–1777 column-names in SQL table or query, 1780–1781 Column Widths lookup property, 279 Combo Box button, 796, 829 combo boxes about, 748–749 allowing space for scroll bars, 280 as controls in, 829–833 formatting, 978 in web forms, 917 keyboard shortcuts for, 767 Lookup properties, 280 Combo Box Wizard, 798, 829–832 comma (,) as separator, 472 as thousands separator, 867 command buttons, 756–757, 795 Command Button Wizard, 798 command-line options, 1735–1736 commands Access executing, 1550–1551 ApplyFilter, 1177 Backstage view Close Database, 29 Open, 29 Save, 28 Save Database As, 28 Save Object As, 28 Back Up Database, 240 Compact And Repair Database, 62, 285–286 Copy, 600–602 Cut, 492 for moving records, 601 Database Tools tab Add-Ins, 62 Administer, 62 Analyze, 62 Macro, 62 Move Data, 62 Relationships, 62 Tools, 62 Delete, 244 External Data tab Collect Data, 61 Export, 61 Import & Link, 61 Web Linked Lists, 61 Filter By Form, 782
complex data, validating 1399
Gridlines, 919, 1100–1101 Home tab, 58–59 Clipboard, 58 Find, 59 Records, 59 Sort & Filter, 58 Text Formatting, 59 Window, 59 Insert Rows above selected fields rows, 255–257 in Indexes window, 225 macro, 1858–1860 Manage Attachments, 751 Open, for reports, 1036 Paste in Clipboard group, 601 undoing, 259 Paste Append, 601 Quick Access Toolbar about, 39–40 adding, 42, 47 changing order of, 45, 47 Quick Create, 819–823 Replace, 600 Report completing web report created by, 1083 modifying web report, 1077–1083 using, 1066–1068 Save & Publish Publish To Access Services, 34, 36 Save Database As, 34 Save Object As, 34, 35–36 Size To Fit, 845–847 SQL View, 445–446 Sync All, 1332–1333 system, 1861–1862 Undo, 244, 245, 259 Visual Basic executing, 1464–1469 menu, 1549–1551 WindowHide, 1708 Work Offline, 1338 Common Language Interface (CLI), 446 Compact And Repair Database command, 62, 285–286 comparison predicate, 1777–1778 comparison symbols, in validation rules, 202 Complex Data concept, 8 complex data, validating checking for duplicate names, 1605–1607 checking for overlapping data, 1611–1613 maintaining special unique values, 1610–1611 testing for related records when deleting records, 1607–1608 verifying prerequisites, 1608–1610
1400 complex queries
complex queries creating for web, 695–700 customizing query properties about, 663–664 applying to dynamically linked tables, 673–674 controlling output, 664–665 defining subdatasheets, 669–673 Record Locks property, 673 using Orientation property, 674 working with unique records and values, 665–668 designing, 630–634 in SQL view, 674–679 joins creating a inner, 622–630 outer joins, 634–641 PivotCharts about, 681–682 designing, 690–695 PivotTables about, 681–682 building a query for, 682–685 designing, 685–690 totals queries building crosstabs, 652–660 selecting records from groups, 650–652 totals within groups, 645–650 using query parameters, 660–663 using Query Wizard, 641 using select queries to update data, 680–681 complex reports adding PivotCharts, 1160–1163 adding values across a group, 1135–1136 building queries for, 1108–1109 calculated values adding page numbers, 1130–1131 adding print dates, 1129–1130 calculating percentages, 1141–1142 concatenating text strings, 1140 hiding redundant values, 1138–1139 performing detail line calculations, 1132–1135 using conditional formatting, 1146–1151 using running sums, 1143–1146 creating, 1109–1111 creating grand totals, 1137–1138 defining grouping and sorting criteria, 1111–1114 properties for reports, 1119–1128 for report sections, 1115–1119 using subreports about, 1151–1152 building subreport queries, 1155–1156 challenges of, 1152–1155 designing subreports, 1156–1157 embedding, 1157–1160
concatenation of expressions, 563 of Null values, 565 of strings, in web databases, 327 of text strings, 1140 conditional expressions in macros, 1207–1209 Conditional Formatting button, 812 conditional formatting rules in the client forms, 978–985 opening in prior Access versions, 981 using in calculated values, 1146–1151 Conditional Formatting Rules Manager dialog box, 979–985, 1146–1148 constants (VB) about, 1474 data types, 1475–1476 declaring, 1477, 1478 statements to define Const, 1479 Enum, 1483–1485 ReDim, 1489–1490 Const statement, 1479 Contact List navigation button, 1005, 1008–1010 control anchoring, in web forms, 901–903 Control Formatting group buttons, 811–812 control layouts, in web forms about, 901–903 creating label controls, 918 moving controls within, 905–908 removing in client forms, 911–912 Control Name argument, 1238, 1244, 1248, 1267, 1866 control padding, in web forms, 921–922 controls group buttons description of, 795–799 locking, 800 controls in forms about, 745 adjusting layout of, 849–850 aligning, 852–856 attachment control, 751–753 changing defaults, 897 check boxes, 746 combo boxes, 829–833. See also combo boxes command buttons, 756–757 enabling and locking controls, 876–877 enabling Snap To Grid, 850–852 image control, 754 list boxes, 747–748 moving, 808–810, 855 navigation controls, 757–758 about, 1000–1001 applying Quick Styles to buttons, 1012–1013 as collection of controls, 1003–1004 creating navigation buttons, 1004–1011
dragging forms in Layout view, 1006 opening in Access prior versions with, 1013 options, 1001–1002 option buttons, 746 option groups, 746, 976–978 resizing using arrows, 853 resizing using Auto Resize property, 856 selecting multiple controls, 844 sizing, 808–810, 844–849 tab controls, 749–750, 985–992 taste line, 844–847 toggle button, 746 unbound object from, 754 using multiple data bar rules, 982 web browser controls, 759–760, 1014–1018 controls in macros embedding macros, 1212 controls in web forms, working with events, 1260–1261 controls in web reports limitations of, 1105 moving to different sections, 1095 resizing in Layout view, 1096 Control Wizards button, Use, 798, 829, 916 conversion errors, dealing with, 267–268 conversion functions, descriptions of, 1832–1833 Copy command, copying and replacing data, 600–602 counters, 1541 Count function, 647, 1135, 1837 Create A New Data Source To SQL Server Wizard, 450–451 Create E-Mail button, 494–495 Create Relationship Wizard, 301–304 Create Shortcut Wizard, 1734–1735 Create tab, 59–60 creating Access Applications folder, 1294 .adp files, 15, 125, 1732 append queries, 721–724 Application Parts Forms, 838 application shortcuts, 1733–1737 AutoKeys macros, 1712–1713 BDC model definition files, 1357–1363 models, 1365–1366 calculated fields, 319–327 calendar view of SharePoint list data, 1322–1327 categories, 83–84, 86 Choice data type, 341 client forms, 992–996 client tables, 176–178, 186–187 Code Builder embedded macros, 1213 crosstab queries, 653–658 custom categories, 83–84 custom Data Type Parts, 1731–1732 custom Quick Access toolbar, 1703
creating 1401
custom Ribbons, 1665–1666, 1671 databases, 168–175, 1727–1730 database templates, 230–233, 1727–1730 data source linking ODBC databases, 448–451 Data Type Parts, 1731–1732 embedded macros, 1212–1215 embedded web macros, 1258–1260 equi-join queries, 622, 634 execute-only databases, 1732–1733 forms multi-page client, 992–995 using Quick Create Commands, 819–823 with Form Wizard, 823–826 grand totals, 1137–1138 groups, 84–87 HTML forms. See email collection wizard import procedures, 539–540 inner joins, 622–630 label controls, 918 links to ODBC databases, 448–451 to tables, 1769 lookup fields, 337–341 macros for web, 1254–1260 Main form, 969–972 make-table queries, 714–718 many-two-one forms, 946–947 multiple-page client forms, 992–995 named data macros, 412–416 navigation buttons, 1004–1011 object shortcuts in groups, 87–91 outer joins, 634–636 PivotCharts, 681–682, 690–695 PivotTables, 681–682, 685–690 primary keys, 1762–1763 procedures in modules, 1458–1459 Quick Access toolbar, 1703 Quick Create Commands forms, 819–823 relationships, using lookup fields about, 341–343 Cascade Delete Relationships, 349–350 Restrict Delete Relationships, 343–349 report labels, 1059–1061 reports, 1109–1111. See also reports reports are shot data, 1772 Ribbons with XML, 1665–1666, 1671 shortcuts for applications, 1733–1737 object, 87–91 snapshot data, reports, 1772 string constants, 563, 1780 subdatasheet subform, 973–976 submacros within objects, 1205 tables, 176–178, 186–187
1402 creating
creating (continued) templates default database, 230–233 for databases, 1727–1730 for forms, 897–899 for tables, 180 templates for databases, 1727–1730 temporary variables in macros, 1219 text expressions, 563–565 unique identifiers, 1762–1763 update queries, 711–713 USysRibbons tables, 1667–1671 VBA callbacks, 1691–1692 web databases, 291–296 web forms. See simple web forms web macros, 1254–1258 web queries, 695–700 web reports, 1077–1083, 1083–1086 web tables in Datasheet view. See Datasheet view simple, 297–300 using Application Parts, 300–304 using Data Type Parts, 304–306 Criteria row in query parameters, 660 looking for single values, 556 looking for values in multiple rows, 559 Crosstab button, 658 crosstab queries about, 652–653 Access database language for, 1774 creating simple, 653–658 in Access databases, 1774 partitioning data in, 658–660 Currency data type about, 190 converting to, 264 formatting properties, 866–869 selecting, 192 Visual Basic, 1475 Currency web data type about, 312 format property settings, 925–926 Current Database category in Access Options dialog box about, 113–114 assigning web forms for Access Services, 1289–1290 Check For Truncated Number Fields check box, 1075 compacting databases, 286 creating macros to run when database opens, 1201–1202 enabling Windows themes in forms, 951–952 keeping users out of Design and Layout views, 887 limiting returned records, 618 propagating changes in tables, 239 setting table design options, 227 web message box title, 1257
custom categories and groups about, 78 creating categories, 83–84 creating groups, 84–87 creating object shortcuts in groups, 87–91 display order rules, 86 dragging and dropping objects into groups, 90 hiding and renaming object shortcuts, 93–96 hiding groups in categories, 91–93 unhiding object shortcuts, 97–99 viewing categories in Navigation pane, 101 Custom Dictionaries, 116 Customize Ribbon category in Access Options dialog box, 63–65, 69, 119–120, 897 customizing Application Parts, 300–304, 1728 colors, 816–817 automatically setting, 882 gridlines, 883 in themes, 933–934 special effects and, 860–862 email messages, 506–507 fonts, 862–865, 935–936 forms adding lines, 857–858 adding scroll bars, 876 adding smart tags, 879–881 adjusting fonts, 862–864 allowing different views, 887 changing control defaults, 897 controlling changes to, 890 defining pop-up and/or modal forms, 888–889 defining templates, 897–899 defining window controls, 891 drawing rectangles, 858–859 enabling and locking controls, 876–877 examining alignment and size of controls, 843–844 lining up controls, 852–856 other client form properties, 892–896 other control properties, 882–885 setting border style, 891–892 setting tab order, 877–878 sizing controls, 844–849, 853 “Snapping” controls to grid, 850–852 specifying format for Date/Time, 872–875 specifying format for numbers and currency, 866–869 specifying format for text, 869–872 specifying format for Yes/No fields, 874–875 using colors and special effects, 860–862 help with common typing mistakes, 116 modules (VB), 1459–1461 Navigation pane display objects, 73–74 display order, 102
display view for users, 96 lists of objects, 93 number of databases above Info Tab, 29 query properties about, 663–664 applying to dynamically linked tables, 673–674 controlling output, 664–665 defining subdatasheets, 669–673 Record Locks property, 673 using Orientation property, 674 working with unique records and values, 665–668 Quick Access Toolbar, 39–47 Ribbon, 63–69 exporting customizations, 69 Ribbon, using XML about, 1665–1666 building, 1671–1679 creating USysRibbons table, 1667–1671 loading, 1679–1682 Visual Basic Editor, 1459 web forms about, 899–900 adding gridlines, 918–921 adding spaces with control padding, 921–922 control layouts and control anchoring in, 901–903 creating titles, 922–923 formatting column of controls, 909–910 inserting rows and columns, 914–916 lining of controls, 903–905 moving controls to different sections, 923–925 moving controls within layouts, 905–908 removing control layouts, 911–912 resizing controls, 910–911 setting control properties, 925–926 setting form properties, 927–928 Shared Resources feature, 938–944 splitting and merging cells, 912–914 using themes, 928–937 using web-compatible controls, 916–918 custom queries, providing by forms, 1619 Cut command for moving records, 601 using to unlink tables, 492
D DAO (Data Access Objects) about, 1497–1498 common objects with ADODB and ADOX, 1504 fetching ODBC databases, 447 manipulating data types using, 1516–1519 recordsets, working with, 1512–1516 support for, 1385 using FindFirst method, 1638 using in Access architecture, 1497–1501
data access pages (DAPs) 1403
DAPs (data access pages), 127 data. See also databases analysis, 1754–1756 changing form, 776–777 checking for duplicate names, 1605–1607 checking for overlapping data, 1611–1613 cutting, 601 deleting data and testing for related records, 1607–1608 deleting data in forms, 776 delimited, 472–473 importing, 472–473 duplicate data in forms, 773 event properties for changing data, 1172–1173 exporting, 1823–1829 finding records across date spans, 637–638 fixed-width data importing, 473–474 importing about, 452–453 keyboard shortcuts for entering, 766–767 linking. See linking files maintaining special unique values, 1610–1611 moving to database software, 15–17 normalization of. See normalization of data randomly load data complex procedure, 1553–1568 replacing, 600 searching for and filtering in Datasheet view, 612–619 searching form, 777–779 selecting before changing, 599–600 selecting from single tables about, 548–551 entering selection criteria. See selection criteria, single table setting field properties, 553–555 specifying fields, 551–552 selection automating, 1615–1619 providing custom queries by forms, 1619–1627 sorting form data, 780–783 in Datasheet view, 608–610 in queries, 583–585 storing dates and times, 556–557 validating using macros, 1239–1245 using preset values, 1247–1251 verifying prerequisites, 1608–1610 viewing on forms, 763–764 vs. information, 1751 Data Access Objects (DAO), 447. See also DAO (Data Access Objects) use in Access architecture, 1497–1501 data access pages (DAPs), 127
1404 data attributes, changing
data attributes, changing about, 261 data lengths, 266–267 data types, 262–266 dealing with conversion errors, 267–268 data bar rules, 981, 982, 983 conditional formatting rules, troubleshooting, 1150 database applications, designing analyzing tasks, 1749–1751 application design strategy, 1747 capturing point-in-time data, 1771–1772 concepts for about, 1757 efficient relationships, 1768–1769 problems with waste, 1757–1760 rules for table design, 1760–1768 creating report snapshot data, 1772 data analysis, 1754–1757 fundamentals of, 1743–1747 improving performance of critical tasks, 1770 organizing tasks, 1753–1754 selecting data, 1751–1753 Database Documenter, 233–234 database files importing about, 452–453 dbase files, 453–457 SQL tables, 456–459 vs. linking, 451–452 opening in exclusive or shared mode, 521 database objects. See also objects description of macro actions, 1854–1856 Visual Basic procedures and, 1500 Database Properties dialog box, 29 databases about, 4–7 backing up, 239–242 compacting, 285–286 creating execute-only, 1732–1733 creating new, 168–175, 230–233 creating new web, 291–296 creating templates, 1727–1730 enabling an untrusted database, 49–51 encrypting, 1737–1738 exploring desktop. See desktop databases exporting to, 1823–1824 importing Access objects, 459–462 secured files, 462 in Access, 125 ODBC, exporting to, 1827 packaging and signing, 1739–1742 setting startup properties, 1706–1708 using copying to move, 245
Database Splitter Wizard, 1717–1720 Database Tools tab, 61–62 Database window, 71, 73. See also Navigation pane data control about, 6 data sharing and, 12–13 data definition about, 6 and storage, 7–9 data entry operations macro actions, 1851 Data Execution Prevention (DEP) mode, settings for, 54–55 data import/export macro actions, 1852–1854 data lengths, changing, 266–267 data macros, 361–442 debugging, 438–441 design facility, overview, 364–369 sharing logic, 442–443 understanding recursion, 441–442 uses of, 362–364 working with after events, 398–410 After Delete, 409–411 After Insert, 398–403 After Update, 404–408 working with before Before Change events. See Before Change events working with before events, 369–398 Before Delete, 396–398 data manipulation, 6, 9–12 Data Mode argument, 1202, 1244, 1275, 1866 Data Services option, troubleshooting, 1367 Datasheet category in Access Options dialog box, 114–115 Datasheet forms resizing and moving columns, 1308 using in web browsers, 1306–1309 Datasheet view changing data adding new records, 596–599 copying and replacing data, 600–602 deleting rows, 602–603 replacing data, 600 selecting before, 599–600 understanding record indicators, 596 creating calculated fields, 319–327 creating web tables in about, 306–308 creating calculated fields, 319–327 defining field validation rules, 327–331 defining web fields, 307–311 setting field properties, 315–318 understanding web data types, 311–315 filtering data, 613–619 keyboard options, setting, 597–599 keyboard shortcuts entering data, 597 for scrolling, 591
selecting data, 592 setting keyboard options, 597 opening tables, 133 Query window in about, 141 checking field properties, 554 setting field properties, 553 working with subdatasheets, 592–595 saving Filter By property in, 337 searching for data, 612–613 setting field properties in, 553 sorting data, 608–611 table windows in, 137–138 using subforms in, 962 working with hyperlinks, 603–607 Data Source dialog box, creating data source using, 448 data sources linking ODBC databases, creating, 448–451 Data Type Parts, 182–186, 1731–1732 data types Attachment about, 8–9, 191 selecting, 193 Attachment web about, 312 using, 314 AutoNumber about, 190 converting to, 264 duplicate data in forms and, 774 in web tables, 315 selecting, 192 Boolean, Visual Basic, 1475 Byte, Visual Basic, 1475 Calculated about, 191 selecting, 193 vs. calculated expressions, 563 Calculated web about, 312 as display values for Lookup fields, 345 using, 314, 319–327 changing, 262–266 CHAR[ACTER] SQL, 459 Choice, creating in SharePoint list, 341 Currency about, 190 converting to, 264 formatting properties, 866–869 selecting, 192 Currency web about, 312 format property settings, 925–926 DATE SQL, 459
data types 1405
Date/Time about, 190 converting to, 264 formatting properties, 872–874 troubleshooting setting defined default value for, 1596 understanding, 192 Date/Time SharePoint, 313 Date/Time web about, 312 format property settings, 926 using, 313 Date, Visual Basic, 1476 Decimal, Visual Basic, 1475 description of VB, 1475–1476 DOUBLE SQL, 459 Double, Visual Basic, 1475 field, 188, 190–193, 266 FLOAT SQL, 459 Hyperlink about, 191, 603–604 activating hyperlinks, 604–605 converting to, 263 editing hyperlinks, 607 fixing email, 1594 inserting new hyperlinks, 605–606 selecting, 192 Hyperlink web about, 312 using, 314 IMAGE SQL, 459 Integer, Visual Basic, 1475 INT SQL, 459 LongLong, Visual Basic, 1475, 1579–1580 LongPtr, Visual Basic, 1475, 1576–1577 Long, Visual Basic, 1475 Lookup & Relationship web, 312 manipulating, using DAO, 1516–1519 Memo about, 190 converting to, 262 Memo web, 312 Number about, 190 converting to, 263 formatting properties, 866–869 selecting, 191 Number web about, 312 format property settings, 925–926 Object, Visual Basic, 1476 OLE Object about, 190 selecting, 192 REAL SQL, 459
1406 data types
data types (continued) Single, Visual Basic, 1475 SMALLINT SQL, 459 String, Visual Basic, 1475 testing, 1474 Text about, 190 converting to, 262 selecting, 191 TEXT SQL, 459 Text web about, 312 using, 313 TIME SQL, 459 TIMESTAMP SQL, 459 TINYINT SQL, 459 User-defined, Visual Basic, 1476 VARCHAR SQL, 459 Variant, Visual Basic, 1476 web, 311–315 Yes/No about, 190 limitations of, 265 using, 312, 313 DateAdd (interval, amount, date) function, 581 Date And Time dialog box, 799, 1102–1103, 1130 date and time functions, 581 Date data type, Visual Basic, 1476 DateDiff function in arithmetic expressions, 566–568 in Expression Builder, 574–580 Date() function, 581, 1129 DatePart (interval, date) function, 581 DATE SQL data type, 459 Date/Time data type about, 190 converting to, 264 formatting properties, 872–874 troubleshooting setting defined default value for, 1596 understanding, 192 Date/Time functions, 1833 Date/Time SharePoint data type, 313 Date/Time web data type about, 312 format property settings, 926 using, 313 date values, formatting, 201 Day(dates) function, 581 dBase files accessing, 9, 454 as IN clause source, 1787–1788 exporting long field names to, 1825 exporting spreadsheets to, 1824–1825
importing, 453–456 linking, 481–482 linking to, 487–488 troubleshooting ODBC file sources, 458 DBEngine (Access Database Engine) about, 1494, 1496 DAO hierarchy and, 1498–1501 debugging tools (Visual Basic) breakpoints (stopping points) setting, 1463–1464, 1469 using, 1466 examining procedure call sequences, 1473–1474 using Immediate window, 1464–1469 using Watch window, 1469–1472 Decimal data types, Visual Basic, 1475 Declare statements, 1575–1576, 1578 declaring arrays within procedures, 1489 constants and variables, 1477–1478 data type for arguments, 1485–1486, 1528 new subroutines, 1527–1528 new VB functions, 1525–1526 static arrays, 1492 Default Database Folder box, 113 Default Value field property, 316 delete action queries deleting groups of rows, 725–730 using with Before Delete, 396 Delete command, 244 Delete Rule button, 982 DELETE statement, 1815–1816 deleting data in forms, 776 embedded macros, 1215–1216 fields, 260–261 groups of rows, 725–730 in update queries, 704–710 named data macros, 418–419 records in InfoPath, 526 rows in Datasheet view, 602 tables, 244–245 delimited data fixing errors caused by, 479 setting up the import, 472–473 DEP (Data Execution Prevention) mode, 54–55 Description argument, 439 Description property for table fields, 188 for web fields, 309 Design view creating tables in, 186–187 customizing forms in adjusting layout of controls, 849–850 enabling Snap To Grid, 850–852
examining alignment and size of controls, 843–844 lining up controls, 852–856 sizing controls, 844–849, 853 fixing errors from importing text files, 479 keeping users of, 887 Query window in about, 139–141 changing size of fonts for, 678 clearing design grid, 552 creating web queries, 697, 698 designing expressions, 699 opening new window, 947 opening query property sheet, 663, 670 selecting all fields, 805 selecting data for single table, 549–550 selecting fields for single table, 551–552 specifying field names, 582–583 using inner joins, 624–625 using keyboard for moving between Windows, 257 report windows in, 149–152 setting field properties in, 193–199 table properties in, 212–215 table windows in, 134–136 desktop applications creating shortcuts, 1733–1737 designing for client-server, 1716–1717 desktop databases. See also accdb files opening, 128–132 using Database Splitter Wizard, 1717–1720 using linked tables, 1716, 1719–1724 detail sections, in reports, 1028–1030 dialog boxes Access About, 38 Access Options configuring Name AutoCorrect options, 227–229 customizing look using, 110 modifying global settings by way of. See Access Options dialog box opening to customize Ribbon, 64 Show Property Update Options Buttons, 229 Show Table Names option, 623 Tabbed Documents settings, 111 Attachments, 751–752, 770 Browse, 771 Choose Builder, 1214 Color Picker, choosing theme colors, 928 Colors, 862 Color setting changing background color for reports, 1116 Conditional Formatting Rules Manager, 979–985, 1146–1148 Database Properties, 29 Data Source, 448
dialog boxes 1407
Date And Time, 799, 1102–1103, 1130 Documenter, 233–234 Edit Relationships, 221–222 Enter Table Properties, 336 Enter Validation Message, 334–335 Export - dBase File, 1824 Export - Excel Spreadsheet, 1824 Expression Builder, 321–325 File Download, 1314 File New Database, 171–172 File Open importing dBase files, 454 linking dBase files, 488 Find And Replace FindNextRecord macro actions and, 1856 FindRecord macro actions and, 1857 replacing data, 600 Search box vs., 779 searching for data, 612–613, 777–779 Get External Data - Access Database, 484–486 Get External Data - dBASE File importing dBase files, 453 linking dBase files, 487–488 Get External Data - Excel spreadsheet, 488–489 Get External Data - ODBC Database, 448, 457, 490 Insert Picture, 799 Join Properties changing properties for queries, 635 defining links on multiple tables, 625 Manage Attachments, 798 Microsoft Access, 771 Microsoft Office Genuine Advantage confirmation, 172–173 Microsoft Office Security Options, 52 Modify Button, 43–44 Navigation Options exploring, 80–82 hiding custom groups, 91–92 New Formatting Rule, 982 Open database files in exclusive mode, 521, 1737 database files in shared mode, 521 finding and opening existing database files, 25 Options customizing VBE, 1459 modifying settings for debugging VB code, 1461 setting custom colors for code elements, 1460 using Option Explicit statements, 1477 Page Numbers, 1131 Page Setup, 1118, 1148 Personalization setting color for 3-D objects, 791 Print, 33 Privacy Options, 21–23
1408 dialog boxes
dialog boxes (continued) Properties changing Hidden property, 98 changing PivotTable field captions, 689–690 customizing query properties, 664 defining properties for printers, 1042 in Navigation pane, 94 modifying shortcut targets, 1734 running programs in compatibility mode, 1737 Publish Failed, 1298 References selecting Access database engine object library, 1497 selecting ActiveX Data Objects Library, 1504 Rename changing name of custom tabs, 65 Resolve Conflicts, 1340 Save As, 178 server login, 1827 Show Table adding fields lists, 954 building report queries, 1046 creating web queries, 697 defining Subdatasheets, 669 making SQL default option, 677 opening database for first time, 216 seeing defining relationships, 222 selecting tables or queries, 548–550 Single Step, 1861 SQL Server Login displaying for SQL data source, 490 using Trusted Connection in, 1827 Subform Linker, 966–967 Trust Center, 52–55 VBE Options. See Options dialog box WCF Connection, 1359 Windows Choose File, 752 Windows Color and Appearance, 791 Workflows, 1861 Workflow Tasks, 1861 Zoom, 803, 1055–1056, 1298 Dialog Box Launchers, 57 Dictionaries, Custom, 116 Dim statement, 1480–1483 Display control lookup property, 278 DISTINCTROW function, 1801 DoCmd object, 1549–1550 Documenter dialog box, 233–234 documents word processing defining contents, 7 import/export data, 9 RDBMS vs., 12
Document Window Options section in Access Options dialog box, 110–111 dollar sign ($), as character in format strings, 868, 870 Do...Loop statement, 1539–1540 Double data types, Visual Basic, 1475 double left arrow () button, in Available Fields list, 345 DOUBLE SQL data type, 459 drag and drop fields in Query window, 551 Draw application OLE Object data type and, 192 drawing tools, 857–859 duplicate contact table names, 1605–1607 rows in databases, 1801, 1808 rows in queries eliminating, 680 in append queries, 730 preventing, 665
E Edit Relationships dialog box, 221–222 E-, e-, generating scientific notation, 868 email collection wizard for HTML forms choosing recipients, 508–510 choosing users type of form, 497 creating HTML form, 495–496 customizing email messages, 506–507 identifying recipients’ email addresses, 504–505 instructing recipient to click Reply, 507 methods of entering email addresses, 503–504 previewing messages, 510 processing replies, 500–503 seeing all the fields in the email collection wizard, 500 selecting fields on the form, 498–500 using InfoPath forms choosing fields in the email form, 517–518 choosing recipients, 522–523 choosing users type of form, 516–517 processing replies, 518 selecting recipients’ email addresses, 519 specifying subject line, 520–521 EmailDatabaseObject, 1852 E-mail Messages Wizard, 1852 emails. See also email collection wizard collecting data via, 493 embedded blanks, 1776
embedding linked pivot chart, 998–999 macros. See also Invoice Audit Web form creating, 1212–1215 deleting, 1215–1216 editing, 1209–1212 objects and reports, 1033–1035 PivotCharts to client reports, 1161–1163 subforms, 964–968 subforms in client reports, 1157–1160 Enable AutoJoin, 624 encrypting databases, 1737–1738 endless loops, causes of, 1175 enterprise web services, 1348 Enter Table Properties dialog box, 336 Enter Validation Message dialog box, 334–335 Enum statement, 1483–1485 equal sign (=) in field validation expressions, 327 meaning of, 328 equi-join queries, 622, 634 Error Description argument, 379, 380, 383–384 Error Number argument, 379, 383 errors analyzing publish errors, 1297–1298 using named data macros, 420–425 clearing MacroError object, 1226 conversion errors, dealing with, 267–268 # Error avoiding, 1135 correcting, 489 fixing caused by importing delimited data, 479 using imported spreadsheets, 468–470 using imported text files, 479–480 trapping event properties for, 1185 in Invoice Audit Web form, 1278–1279 in macros, 1219–1225 using RaiseError data action, 378–380 Error Trapping (Visual Basic), 1461 event processing about events in Windows, 1167–1168 about form and report events, 1169–1170 event properties for changing data, 1172–1174 for detecting changes in PivotTables and PivotCharts, 1181–1184 for detecting filters applied to forms and reports, 1177 for detecting focus changes, 1175–1177 for detecting timer expiration, 1185 for opening and closing forms and reports, 1170–1171 for printing, 1184–1185
Expression Builder 1409
for trapping errors, 1185 for trapping keyboard and mouse events, 1178–1181 event sequencing and form editing, 1185–1188 Event statement, 1485–1486 examine all error codes complex procedure (VB), 1568–1574 Excel 64-bit versions of Office 2010 and, 1387 as output option, 153 defining smart tags, 879 exporting data to Access about, 462–463 as temporary table, 464 fixing errors, 468–471 preparing spreadsheet, 463–464 exporting to data, 9, 1319, 1824–1825 PivotTables, 688 importing web reports, 1306 keeping prior versions, 1383 linking to, 488–489 list of user interface control identifiers, 1676 OLE Object data type and, 192 organizing data in, 168 programming language for, 1452 similarities to Pivot Tables, 681 switching to databases from, 16 themes in, 930 troubleshooting ODBC file sources, 458 viewing exported web reports, 1306 exclamation point (!) forces left-alignment, 868 forces placeholders to fill left to right, 870 separating table and field names with, 575, 576 using, 1507–1508 using in lists, 328 EXISTS predicate, 1778–1779 Export BDC Model button, 1365 Export commands, 61 Export - dBase File dialog box, 1824 Export - Excel Spreadsheet dialog box, 1824 Export Text Wizard, 1826 Expression arguments AskEdit Submacro, 1244 in web-supported macro actions, 1867 SetLocalVar action, 428 SetReturnVar data action, 432 SetStateAndZip Submacro, 1248 SyncWeddingAndCity, 1236 Expression Builder about, 572–573 adding DateDiff function, 574–580 creating embedded macros, 1213 moving ScreenTips, 574 using exclamation mark by, 576
1410 Expression Builder dialog box
Expression Builder dialog box, 321–325 expressions about using, 562–563 adding parentheses (), 572 arithmetic, 566–571 operator precedence, 568–569 operators used in, 566 using DateDiff function, 566–568 complex, 572–580 conditional expressions in macros, 1207–1209 creating text expressions, 563–565 date and time functions, 581 IsClient limitations of functionality, 1282 using web, 1281 referencing table fields, 711 SQL using parentheses ( ) in, 1780 using brackets, 1209 using date, 722 External Data tab, 60–61
F fetching information, using ADO, 447 Number and Description properties, 1221 field data types, 188, 190–193, 266 field lists in queries, assigning alias names, 715–716 selecting all fields in, 805 using with Controls group, 800–801 field properties checking, 554 on general tab, 193–199 setting, 553–555 Field row field names, 564 fields adding to web reports, 1091–1095 changing default data types, 266 changing names of, 247–251 copying, 257–260 deleting, 260–261 editing joined, 628 importance of sequence of field definitions, 252 inserting, 255–257 in web tables choosing names, 311 defining, 307–311 renaming, 299 moving, 251–255 referring to names of, 210 selecting, 551–552 selecting multiple using keyboard, 807
specifying names of, 582–583 true/false fields choosing controls, 833–835 updating with select queries, 680–681 yes/no fields choosing types of controls, 833–835 Field Size field property, 316 field validation expressions, 327 field validation rules checking, 586–587 defining, 201–203 feedback on failures, 1302 in web databases, 327–331 Record Not Saved dialog displayed, 1303 violations of, 731 File Download dialog box, 1314 File New Database dialog box, 171–172 File Open dialog box importing dBase files, 454 linking dBase files, 488 file system functions, 1836–1837 File tab on Backstage view changing default data types for fields, 266 Filter argument, 1855 Filter By Group, commands, 74 property, 336–337 Filter By Form command, 782 filtering and searching for data in Datasheet view, 612–619 form data, 780–782 filter macro actions, 1856–1858 Filter Name argument, 1202 Filter table property, 212 Find And Replace dialog box FindNextRecord macro actions and, 1856 FindRecord macro actions and, 1857 replacing data, 600 Search box vs., 779 searching for data, 612–613, 777–779 Find commands, 59 Finder methods, 1363 FindNextRecord macro action, 1856 FindRecord macro action, 1857 Find Unmatched Query Wizard, 641–642, 643 First function, 647, 1135 fixed-width data, importing, 473–474 file, defining import specification for, 480 fixing errors importing spreadsheets, 468–471 importing text files, 479–480 FLOAT SQL data type, 459 Font Color button, 909
Font group buttons, 810–811 fonts changing font size for Query windows, 678 customizing, 862–865, 935–936 in code editing, 1460 size, increasing in Expression Builder, 324 footer/header group buttons, 799 footers, in reports, 1028–1030 For Each...Next statement, 1541–1542 foreign keys, 1768 joining relationships, 624 Format field property, 316 Format Painter button, 810 formatting adding scroll bars, 876 Application Parts Forms, 836–837 columns of controls on web forms, 909–910 combo boxes, 978 conditional client forms, 978–985 controls in forms, 811–812 date values, 201 fonts, 810–811 options, quick access to web forms, 919 property settings, 991–992 about, 865–866 for Currency data types, 866–869 for date/time data types, 872–874 for Number data types, 866–869 for Text data types, 869–872 specifying both input mask setting and, 875 text boxes, 978 text strings values, 201 web reports, 1102–1105 year values, 866 Form Design button, 969 form events, 1169–1170 form modules (Visual Basic) about, 1454–1455 editing, 1458 Form Name argument, 1202, 1244, 1866 Form/Report Design View, 844, 898 forms about, 126, 142–143 about key design terms using, 792 ActiveX objects, 753–756 adding filters, 780–782 adding records, 768–775 adding scroll bars, 876 adding smart tags, 879–881 advanced form design. See advanced form design building Allow Layout View property, 818 checking design results, 817–818 formatting controls, 811–812 formatting fonts, 810–811
forms 1411
input form, 806–818 modifying fields, 826–828 moving and sizing controls, 808–810 property sheets and form sections, 801–806 record sources, 792–793 setting form properties, 815–816 setting label properties, 814 setting text box properties, 813–814 using Application Parts Forms, 835–839 using design tools, 789–793 using field lists with Control group, 800–801, 805 using Form Wizard, 823–826 using Quick Create commands, 819–823 building custom ribbons, 1671–1679 changing captions, 1270 changing data, 776–777 changing name of default form, 898 check boxes in, 746, 833–835 choosing width and height, 791 colors and special effects, 860 combo boxes. See also combo boxes about, 748–749 as controls in, 829–833 formatting, 978 conditional formatting in, 978–985 continuous, 741 controls for client, 881–886 controls group buttons, 795–799 formatting control using, 811–812 locking, 800 controls in about, 745 adjusting layout of, 849–850 aligning, 852–856 attachment control, 751–753 changing defaults, 897 check boxes, 746, 833–835 command buttons, 756–757 enabling Snap To Grid, 850–852 image, 754 list boxes, 829–830 moving, 855 moving and sizing controls, 808–810 navigation controls. See navigation controls option buttons, 746, 833 option groups, 746, 976–978 resizing using arrows, 853 resizing using Auto Resize property, 856 selecting multiple controls, 844 Size To Fit command, 845–847 sizing, 808–810 tab controls, 749–750, 985 toggle buttons, 746, 833–835 using multiple data bar rules, 982 web browser controls, 759–760, 1014–1018
1412 forms
forms (continued) customizing colors, 816–817 fonts, 862–865 customizing in Design view adjusting layout of controls, 849–850 aligning controls, 852–856 enabling Snap To Grid, 850–852 sizing controls, 844–849 deleting data, 776 displaying images, 938–944 drawing tools in, 857–859 duplicate data, 773–774 editing and event sequencing, 1185–1188 enabling and locking controls, 876–877 establishing standard design on, 897–899 event properties for detecting filters applied to forms, 1177 for opening and closing forms, 1170–1171 footers, 739 formatting properties about, 865–866 for Currency data types, 866–869 for date/time data types, 872–874 for Number data type, 866–869 for Text data types, 869–872 group, 60 header/footer group buttons, 799 headers, 739–740 linking using filters, 1631–1632 list boxes in, 747–748 macro actions in, 156–158 modal, 744–745, 888–889, 891 moving around on, 763–764 multiple-page client forms, 992–996 multiple-page forms, 740–741 multiple-table query, 946–952 object-oriented programming and, 785–789 opening secondary forms, 1231–1235 option buttons, 746, 833–835 PivotCharts as client forms, 996–1000 as forms, 761–763 PivotTables as, 761–763 pop-up, 743–744, 888–889 printing, 783–784 referencing objects in macros, 1229–1230 searching for data, 777–779 section details, 739 property sheets and, 801–806 setting color for 3-D objects, 791
setting properties allowing users to change views, 887 controlling updates, 890 preventing user from opening control menu, 891 properties on All tab, 892–896 setting border styles, 891–892 setting navigation options, 888 setting tab order, 877–878 sorting data, 780–783 special effects and colors, 860–862 Split, 742 subforms about, 742–743, 952–953 creating Main Form, 969–972 designing first level, 962–963 designing innermost, 956–962 embedding, 964–968 rules for referencing, 1231 sizing controls, 965 specifying main source, 968 specifying source, 954–956 using subdatasheets, 973–976 synchronizing two related forms, 1235–1239 synchronizing using class events, 1635–1638 tabbing on multiple page, 1613–1615 testing status information between linked forms, 1245–1247 toggle buttons, 746, 833–835 triggering data tasks, 1639–1643 typing data into forms using keyboard shortcuts, 766–767 unbound object frame, 754 uses of, 737–738, 1023 using, 972 using themes, 928–937, 951–952 viewing data on, 763–764 web building. See web forms limitations of, 763 working in layout view, 899–900 windows in Design view, 143–145 in Form view, 147–148 in Layout view, 146–147 Forms/Report Design View, 1214 Form view, 147–148 Form Wizard building many-to-one form, 948–952 creating forms, 823–826 designing subforms, 957–961 modifying forms created by, 826–828 For...Next statement, 1540–1541 forward slash (/), dividing numeric expressions with, 566
FoxPro databases, 9, 13, 14 indexes, 223 FROM clause, 675, 1782–1785 FullName index, 224–225 functions Access Services, 1838 aggregate description of, 647 description of SQL, 1837 using in calculated values, 1135 using in desktop applications (accdb) files, 1780 API, Type statement and, 1492 arithmetic, 1831–1832 Avg description of, 647, 1837 using in reports, 1135 conversion, 1832–1833 Count, 647, 1135, 1837 Date(), 581, 1129 DateAdd(interval, amount, date), 581 DateDiff in arithmetic expressions, 566–568 in Expression Builder, 574–580 DatePart(interval, date), 581 date/time, 1833 Day(date), 581 file system, 1836–1837 First, 647, 1135 GetAllSettings, 1836 Hour(date, 581 IIF, 211 IsArray, 1476, 1834 IsCurrentWebUserinGroup, 1325 keyboard shortcuts to jump to, 1597 Last, 647, 1135 logic, 1834 Max, 647, 1135, 1837 MessageBox about, 1197–1198 displaying when creating macros, 1213–1214 vs. MsgBox, 1198, 1243–1244 Min, 647, 1135, 1837 Month(date), 581 MsgBox options settings, 1243 return values, 1244 vs. MessageBox, 1198, 1243–1244 ObjPtr, 1578–1579 pointer valued, 1578–1579 SQL aggregate, 1780, 1837
greater than sign (>) 1413
StDev, 1135, 1837 StDevP, 1837 string, 1834–1836 StrPtr, 1578–1579 Sum, 647, 1135, 1837 Total, 647 user interface system, 1836–1837 Var, 647, 1135 VarP, 1837 VarPtr, 1578–1579 Visual Basic declaring new functions, 1525 declaring new subroutines, 1527 queries using, 127 web-compatible, 1838–1840 Weekday(date), 581 Year(date), 581 Function statements in middle of procedures, 1459 using, 1525–1527
G GetAllSettings function, 1836 Get External Data - Access Database dialog box, 484–486 Get External Data - dBASE File dialog box importing dBase files, 453–454 linking dBase files, 487–488 Get External Data - Excel Spreadsheet dialog box, 488–489 Get External Data - ODBC Database dialog box, 448, 457, 490 Get External Data - SharePoint Site wizard, 532–534, 536–537 global settings in Access Options dialog box, modifying about, 112–113 Add-Ins category, 121–122 Client Settings category, 118 Current Database category, 113–114 Customize Ribbon category, 119–120 Datasheet category, 114–115 Language category, 117–118 Object Designers category, 115–116 Proofing category, 116 Quick Access Toolbar category, 120 Trust Center category, 122 Go To argument, 1220, 1221, 1224, 1225 statement, 1543 grand totals, creating, 1137–1138 greater than or equal to sign (>=), meaning of, 328 greater than sign (>) to display all characters in uppercase, 870 to indicate positive numeric values, 327
1414 gridlines
gridlines adding in web forms, 918–921 adding to web reports, 1100–1102 Gridlines command, 919, 1100–1101 GROUP BY clause, 675, 1785–1786 Group constructs, using, 373–374 grouping criteria, defining in complex reports, 1111–1114 grouping information, in reports, 1050–1059 grouping options, understanding, 1113–1114 groups, custom about, 78–80 creating groups, 84–87 creating object shortcuts, 87–91 display order rules for, 86 dragging and dropping objects into groups, 90 hiding and renaming object shortcuts, 93–96 hiding groups in categories, 91–93 unhiding object shortcuts, 97–99 groups, in reports, 1028–1030 Group, Sort, And Total pane, 1051–1059 Group & Sort button, 1089
H HasModule property, setting to no, 1455 HAVING clause, 675, 1786–1787 header/footer group buttons, 799 headers, in reports, 1028–1030 Help tab, in Backstage view, 37–39 hiding duplicate values, 1138–1141 Home tab, exploring, 58–59 Hotmail, Outlook automatically processing replies from, 513 Hour(date) function, 581 HTML forms automatic processing replies by Outlook, 513–514 collecting data via. See email collection wizard filling out, 510–513 look up values in, 513 managing data collection messages, 529 replying to data collection messages, 530 resending data collection messages, 530–531 HTML (Hypertext Markup Language) linking name of file using, 314 vs. XML, 1350 HTML tags, formatting the Rich Text, 512 hybrid applications, 289 Hyperlink button, Insert, 795 Hyperlink data type about, 191, 603–604 activating hyperlinks, 604–605 converting to, 263
editing hyperlinks, 607 fixing email, 1594–1595 inserting new hyperlinks, 605–606 selecting, 192 Hyperlink web data type about, 312 checking before publishing on SharePoint server, 314 using, 314
I ID field automatically created, 315 ID numbers changing after publishing web databases, 1296–1297 internal unique, 227 If...Then...Else statement, 1543–1544 IIF function, 211 Image button, 798 Image button, Insert, 799 image control, 754 images sharing across forms and reports, 938–944 working with linked photos, 1602–1604 IMAGE SQL data type, 459 Immediate window, using, 1464–1469 Import/Export customizations button, 69 importing Access object, 459–462 database files about, 452–453 dBase files, 453–456 modifying tables, 481 SQL tables, 456–459 vs. linking database files, 451–452 spreadsheet data, 464–468 about, 462–463 preparing, 463–464 to temporary table, 464 text files, 474–479 about, 471 delimited data, 472–473 fixed-width data, 473–474 fixing errors, 479–480 Import & Link group commands, 61 importing text data using, 474–475 linking to SharePoint lists using, 536 import procedures creating, 539–540 saving, 540–542
Import Spreadsheet Wizard fixing errors, 469–471 importing spreadsheets, 465–468 Import Text Wizard defining import specification, 480 using, 475–479 Import Wizard, 542, 1853 IN clause, 1787–1788 Increase/Decrease Decimals field property, 316 Indexed field property, 317 indexes, adding table about, 222–223 multiple-field, 224–226 number of indexes supported by SharePoint lists, 349 single-field, 223–224 InfoPath forms collecting data using. See email collection wizard filling out, 523–527 managing data collection messages, 529 manually processing replies, 527–529 replying to data collection messages, 530 resending data collection messages, 530–531 information vs. data, 1751 Info tab, 285 of backstage view, 27–29 inner joins, 622–630 about, 622–623 creating queries, 623–626 matching relationships, 624 running queries, 626–627 troubleshooting using correct tables, 623 using query data, 628–629 IN operator description of, 561–562 meaning of, 328 IN predicate, 1788–1789 input masks defining, 204–207 inputting both settings for formatting and, 875 Input Mask Wizard, 205–207 Insert ActiveX Control button, 794, 799 Insert Chart button, 796 Insert Hyperlink button, 795 Insert Image button, 799 Insert Or Remove Page Break button, 796 Insert Rows command above selected field rows, 255–256 in Indexes window, 225 INSERT statement (append query), 1816–1818 instances, 5
joins 1415
Integer data type, Visual Basic, 1475 IntelliSense options, displaying or hiding, 323 internal ID numbers, 227 International Organization for Standardization (ISO), 445, 1350 Internet. See web interval settings for DateDiff function, 567 INT SQL data type, 459 Invoice Audit Web form from macros about, 1266 calling named data macros, 1271–1275 tracking error messages, 1278–1279 using BrowseTo for browsing web forms and web reports, 1275–1279 using return variables, 1271–1275 IsArray function, 1476, 1834 IsClient expression limitations of functionality, 1282 using web, 1281 IsCurrentWebUserinGroup function, 1325 IS NOT NULL operator, 328 ISO (International Organization for Standardization), 445, 1350 Italic button, 810 Item argument, 1236, 1244, 1248
J Join Properties dialog box changing properties for queries, 635 defining links on multiple tables, 625 joins about, 5 editing fields in tables, 628 equi-join, 622, 634 inner joins, 622–630 about, 622–623 creating queries, 623 matching relationships, 624 running queries, 626–627 using query data, 628–629 matching relationships, 624 outer joins, 634–641 between tables, 220 building simple, 634–636 solving complex to unmatched problems, 636–641 self join relationships in web databases, 345 troubleshooting using correct tables, 623 unions, 674 using tables related by more than one field, 625
1416 keyboard
K keyboard commands display or hide IntelliSense options, 323 for moving data in Datasheet view, 590–592 for moving fields, 253 moving between windows, 257 setting keyboard options in Datasheet view, 597 options setting, 597–599 shortcuts duplicating logic on macro design surface, 390 ensuring lines are straight, 858 entering data in Datasheet view, 597 for combo boxes, 767 for deleting rows, 602 for list boxes, 767 for moving rows, 601 for opening Immediate window, 1464 for selecting fields, 551 jumping to functions and procedures, 1597 moving controls in web forms, 908 moving controls in web reports, 1082 selecting multiple fields, 807 typing data into forms, 766–767 trapping, 1178–1180 keywords, avoiding in selection criterion, 556
L Label button, 795 label properties, setting, 814 Label Wizard, 1077 Language category in Access Options dialog box, 117–118 LAN, linking name of file to, 314 Last function, 647, 1135 Layout view building web reports adding color to report sections, 1092 adding fields, 1091–1095 adding grouping and sorting, 1089–1091 adding totals to records, 1098–1100 counting pages, 1100 formatting report, 1102–1105 using gridlines, 1100–1102 working with controls. See controls in web form creating web reports completing reports, 1083–1086 modifying reports, 1077–1083 disabling, 1705–1706 form windows in, 146–147 keeping users out of, 887 opening forms and seeing controls, 1331 report windows in, 154–155 web forms in, 899–900
less than or equal to sign () button, in Available Fields list, 345 Single Step dialog box, 1861 Size To Fit command, 845–847 SMALLINT SQL data type, 459 smart tags adding, 879–881 assigning to control with data, 880 Smart Tag Software Development Kit (SDK), 879 snapshot data, creating report, 1772 Snap To Grid enabling, 850–852 vs. To Grid, 851 Sort & filter commands, 58 sorting criteria, defining in complex reports, 1111–1113 sorting data applying multiple sorts in reverse order, 609 importance of specifying sort criteria, 585 in Datasheet view, 608–611 in queries, 583–585 on forms, 780–783 troubleshooting sorting criteria, 648 sorting information, in reports, 1050–1059 Soundex codes, 1605–1606 Source Connect Str query property, 673 Source Database query property, 673 Special Effect options, 812 special effects, colors and, 860–862 Split Form view, 742
spreadsheet data. See also Excel defining data, 7 exporting data, 9, 1824–1825 exporting data to Access about, 462–463 fixing errors, 468–471 preparing, 463–464 to temporary table, 464 linking to, 488–489 organizing, 168 switching to databases from, 16 SQL aggregate functions, 1780, 1837 SQL Server creating data source, 449–451 importing from, 456–459 linking files to, 490 moving tables to, 62 security for linking databases, 482 settings for web queries, 700–701 SQL and, 446, 674 SQL Server 2008, downloading, 161 SQL Server Configuration Manager, 490 SQL Server Desktop Engine (MSDE), 6 SQL Server Express Edition downloading, 161 installing, 456 SQL Server Login dialog box displaying for SQL data source, 490 using Trusted Connection in, 1827 SQL Server Reporting Services 2008, installing, 1306 SQL Server version 7.0, connecting project files to, 161 SQL Server wizard, Create A New Data Source To, 450–451 SQL (Structured Query Language) about, 445–446 action queries DELETE statement, 1815–1816 INSERT statement (append query), 1816–1818 SELECT... INTO statement (make-table query), 1819–1820 UPDATE statement, 1820–1822 aggregate functions, 1780, 1837 ANSI SQL Access support for, 674 DISTINCTROW equipment, 1801 referencing output-column-name, 1781 defining a query in, 626 SELECT queries about, 1774 BETWEEN predicate, 1775–1776 building, 675–679 clauses, 675 Column-Name, 1776–1777 comparison predicate, 1777–1778
EXISTS predicate, 1778–1779 expressions, 1779–1782 FROM clause, 675, 1782–1785 GROUP BY clause, 675, 1785–1786 HAVING clause, 675, 1786–1787 IN clause, 1787–1788 IN predicate, 1788–1789 LIKE predicate, 1790–1791 limitations to updating data, 680 literal strings in, 1780 NULL predicate, 1791–1792 ORDER BY clause, 1792–1794 PARAMETERS declaration, 1794–1795 quantified predicate, 1796 search condition, 1797–1799 SELECT clause, 675 SELECT statements, 1799–1806 subquery, 1806–1810 TRANSFORM statement, 1810–1811 UNION query operator, 1811–1813 WHERE clause, 675, 1813–1814 wildcard characters for strings, 1790 specifying column-names, 1780–1781 tables importing, 456–459 linking files to, 490 naming columns, 1780–1781 SQL View command, 445–446 Static statement, 1491–1492 StDevP function, 1837 StDev (standard deviation) function, 647, 1135, 1837 string concatenation, in web databases, 327 String data type, Visual Basic, 1475 string functions, 1834–1836 strings creating constants, 563 formatting text strings values, 201 wildcard characters for, 1790 zero-length strings, 199–200 StrPtr function, 1578–1579 Subdatasheet Expanded table property, 214 Subdatasheet Height table property, 214 Subdatasheet Name table property, 213 subdatasheets defining, 669–673 working in Datasheet view with, 592–595 Subform Linker dialog box, 966–967 subforms about, 742–743, 952–953 creating Main Form, 969–972 creating subdatasheet, 973–976 designing first level, 962–963
Table Analyzer Wizard 1431
designing innermost, 956–962 editing from subform controls, 971 embedding, 964–968 rules for referencing, 1231 sizing controls, 965 specifying main source, 968 specifying source, 954–956 Subform/Subreport button, 798 submacros RunMacro action within objects creating, 1205 using AskEdit, 1244–1245 using OnError macro action, 1220–1221 using RunMacro action to call message, 1262 working with, 1204–1207 subquery, 1806–1810 subreports rules for referencing, 1231 using in forms, 972 using in reports, 1030–1033 building client reports from, 1155–1160 embedding, 1151 understanding, 1152–1155 Subreport/Subform button, 798 subroutines, 1539 Sub statements in middle of procedures, 1459 using, 1527–1529 suggestions to improve Access, submitting, 37 Sum function, 647, 1135, 1837 Super Video Graphics Array (SVGA) for Print Preview, 1027 SVGA (Super Video Graphics Array) for Print Preview, 1027 Sync All command, 1332–1333 synchronization conflicts, resolving, 1335–1337 SyncWeddingAndCity arguments, 1236 System Button Face, 861 system commands macro actions, 1861–1862
T Tabbed Documents setting, 111, 136 tabbing on multiple page forms, 1613–1615 tab character, using between fields, 472–473 Tab Control button, 795 tab controls about, 749–750 formatting properties, 991–992 setting order of, 877–878 troubleshooting seeing multiple rows of tabs, 992 working with, 985–990 Table Analyzer Wizard looking at lookup properties, 275–280 using, 270–275
1432 table design
table design changing about, 237–238 backing up databases, 239–242 changing data attributes. See data attributes checking object dependencies, 242–244 copying fields, 257–260 deleting fields, 260–261 deleting tables, 244–245 field names, 247–251 field properties, 268–269 inserting fields, 255–257 looking at lookup properties, 275–280 moving fields, 251–255 renaming tables, 245–247 reversing changes, 269–270 working with multi-value lookup fields, 280–286 compacting databases, 285–286 for the web. See web tables, designing in Access, 168 setting options, 226–229, 266 using Table Analyzer Wizard, 270–275 tables about, 125, 531 ActiveX objects in, database limitations, 235 adding indexes about, 222–223 multiple-field, 224–226 single-field, 223–224 append queries, inserting data using, 721–725 backing up, 240–242 building queries from single entering selection criteria, 555–562 selecting data, 548–551 setting field properties, 553–555 sorting data, 583, 583–585 specifying field names, 582–583 specifying fields, 551–552 specifying sort criteria, 585 using Expression Builder, 572–580 using expressions, 562–572 changing names on, 177–178 creating in Design view, 186–187 simple, 176–178 using Application Parts feature, 178–182 using Data Type Parts feature, 182–186 creating links, 1769 Datasheet view opening in, 133 defining fields about, 187–190 choosing names, 189–190
data types, 190–193 setting field properties, 193–199 validation rules for, 201–203 defining relationships about, 215–217 between two tables, 217–220 on multiple fields, 220–222 deleting, 244–245 design options, 226–229 editing fields in joined, 628 fields changing names, 247–251 copying, 257–260 deleting, 260–261 importance of sequence of field definitions, 252 inserting, 255–257 moving, 251–255 properties, 268–269 finding records across date spans, 637–638 foreign keys, 1768 group, 60 input masks defining, 204–207 joins outer, 220 limiting returned records, 618 linking files to. See linking files make-table queries creating, 714–718 running, 719–720 move to SQL Server wizards, 62 one-to-many relationships, 1769 one-to-one relationships, 1769 other properties in Design view Filter property, 212 Link Child Fields property, 214 Link Master Fields property, 214 setting Subdatasheet table properties in applications, 214–215 Subdatasheet properties, 213 primary keys, 1762–1763 changing, 283–285 defining, 208 on web databases, 335 printing definitions, 233–234 propagating changes in tables, 239 properties of dynamically linked, 673–674 renaming, 245–247 reversing changes, 269–270 rules of good table design, 1768 selecting all fields, 552
selecting data from multiple choosing correct table in query designer, 623 creating inner joins, 622–630 solving complex problems with queries, 630–634 SQL linking files to, 490 naming columns, 1780–1781 SQL importing, 456–459 troubleshooting extra rows in lower half of screen, 138 maximize/minimize buttons, 136 unlinking linked tables, 492 viewing Tables collection, 1469 windows in Datasheet view, 137–138 in Design view, 134–136 yes/no fields, 833–835 Tables And Related Views category, 75–78, 82 Table Templates, 180 table validation rules checking, 588–589 defining, 209–211 feedback on failures, 1302 in web bases, 332–335 Record Not Saved dialog displayed, 1303 violations of, 731 tabs. See also tab controls adding built-in groups to, 1676–1679 All, in the property sheet, 892–896 Backstage view File, changing default data types for fields, 266 Help, 37–39 Info, 29 New, 31–33 Print, 33 Recent, 29–31 Save & Publish, 34–37 Create, 59–60 Database Tools, 61–62 External Data, 60–61 Home, 58–59 Info, 285 templates changing name of report templates, 898 creating in forms, 897–899 creating new database default, 230–233 creating new databases using, 169–173, 180, 1727–1730 creating new web databases, 291–294 group, 60 instantiating Access Services, 1342 web, 1019 temporary variables, using, 1216–1219 TestCity Submacro arguments, 1241
trapping errors 1433
testing data types, 1474 for related records one deleting records, 1607 validation rule changes, 268 validation rules, 586–589 Text Box button, 795 text boxes, formatting, 978 text box properties, setting, 813–814 Text data type, 869–872 about, 190 converting to, 262 selecting, 191 text expressions, 563–565 text files exporting to, 1825–1826 importing about, 471–472 delimited data, 472–473 fixed-width data, 473–474 fixing errors, 479–480 maximum text data length, 481 linking to, 488–489 Text Formatting commands, 59 TEXT SQL data type, 459 text strings values concatenating, 1140 enclosing in quotation marks (“ “), 327 formatting, 201 Text web data type about, 312 using, 313 themes, using, 928–937 This Database node, 1260 timeout messages, 1311 TIME SQL data type, 459 TIMESTAMP SQL data type, 459 TINYINT SQL data type, 459 Title argument, 1198, 1213 toggle button, 746, 797, 833–835 top-down database design, 1747 total functions, 647 totaling information, in reports, 1050–1059 totals building crosstab, 652–660 selecting records from groups, 650–652 Total functions, 647 within groups, 645–650 Totals button, 645 TRANSFORM statement, 1810–1811 trapping errors event properties for, 1185 in Invoice Audit Web form, 1278–1279 in macros, 1219–1225
1434 trapping errors (VB)
trapping errors (VB), 1551–1553 troubleshooting action queries, 730–732 calendar control, 1601 choosing correct table in query designer, 623 connecting to server using trusted authentication, 491 data services option on ribbon, 1367 displaying more than one value in crosstabs, 655 dragging forms in Layout view, 1006 extra rows in lower half of tables, 138 ID values of lookup fields in web reports, 1086 imported SharePoint list doesn’t include all records, 535 ODBC file sources, 458 restoring records from Recycle Bin in Access Services, 1322 seeing all the fields in the email collection wizard, 500 seeing complete list of macros, 1198 seeing controls in Layout view, 1331 seeing events and property sheet window, 1261 seeing multiple rows of tabs, 992 seeing web browser control listed in controls group, 1016 setting defined default value for date/time field, 1596 sorting criteria, 648 viewing web forms or web reports in browsers, 1265 web browser control display, 760 true/false fields, choosing controls, 833–835 Trust Center about, 48 dialog box, 52–55 enabling a not trust database, 49–51 macros that are not trusted and, 1226–1227 Trust Center category in Access Options dialog box, 52, 55, 122–123 Trust Center dialog box, 52–55 trusted authentication, troubleshooting connection to server using, 491 Trusted Documents, 53 Trusted Locations about, 53 defining, 55–57 in corporate network environment, 55 Trusted Publishers, 52–53 Trustworthy Computing initiative, 47–48 Type argument, 1198, 1213 type coercion issues, avoiding, 1282–1284 Type statement, 1492–1493 typing mistakes, help with, 116, 885
U Unassigned Objects group, 84, 86–87 unbound controls, using in reports, 1135 unbound object frame, 754 Unbound Object Frame button, 797 Underline button, 810
Undo command, 244, 245, 259 Unicode Compression property, 197 union queries, 674 UNION query operator, 1811–1813 Unique field property, 317 Universal Naming Convention (UNC), linking name of file to LAN, 314 unlinking linked tables, 492 Unrelated Objects category, 76, 82 unsafe macro actions, 1227 Up arrow button, 390 Update Parameters link, updating query using, 1263 update queries converting select query to, 706–707 creating, using multiple tables or queries, 711–713 deleting groups of rows, 725–730 generic queries, 713 running, 707–709 updating multiple fields, 709–711 UPDATE statement, 1820–1822 Update To row, 707 URLs, finding, 1300 Use Control Wizards button, 798, 829, 916 user-defined data type, Visual Basic, 1476 user interface macros description of macro actions, 1864–1865 referencing local variables, 1274 user interface system functions, 1836–1837 user permission levels, checking SharePoint, 1279–1280 U.S. National Archives and Records Administration (NARA), 1605–1606 USysRibbons table creating, 1667–1671 defining for .adp files, 1681
V validating data by presetting values, 1247–1251 using macros, 1239–1245 Validation Rule field property, 317, 318 validation rules about, 8 checking changes to, 268, 770, 1817 comparison symbols in, 202 feedback on failures, 1302 field checking, 586–587 defining, 196, 201–203 in web databases defining field validation rules, 327–331 defining table validation rules, 332–335 Record Not Saved dialog displayed, 1303 setting control, 886 specifying, 199
table defining, 209–211 testing rule changes, 586–589 testing changes, 586–589 for characters, 203 using LIKE operator to test, 329 violations of, 731 Validation Text field property, 317, 318 Value argument, 1244, 1267–1268 value list lookup field, 341 VARCHAR SQL data type, 459 Var function, 647, 1135, 1837 variables referencing local, 1274 variables (VB) about, 1474 data types, 1475 declaring public or private, 1477–1478 naming conventions for, 1480 statements to define Dim, 1480–1483 Event, 1485–1486 Private, 1486–1488 Public, 1488–1489 ReDim, 1489–1490 Static, 1491–1492 Type, 1492–1493 using temporary, 1216–1219 Variant data type, Visual Basic, 1476 VarP function, 1837 VarPtr function, 1578–1579 VBA7 language updates, 1579–1580 VBA (Visual Basic for Applications) changing ribbon tab focus, 1704–1705 creating callbacks, 1691–1692 VBE Options dialog box. See Options dialog box View argument, 1202, 1227, 1244, 1855, 1857 View commands, 58 Views allowing users to change, 887 Backstage view about, 27–29 closing, 39 Help tab, 37–39 Info tab, 29 New tab, 31–33 Print tab, 33 Recent tab, 29–31 Save & Publish tab, 34–37 Security Warning on, 50 calendar view of SharePoint list data, creating, 1322 Datasheet view. See Datasheet view
Visual Basic (VB) 1435
Design view. See Design view Layout view. See Layout view Navigation pane sorting, 99–101 Report view about, 1035–1039 report windows in, 155–156 Split Form, 742 SQL view building a query, 675–679 learning, 675 types of queries, 674 updating data, 680 Vista. See Windows Vista Visual Basic Editor (VBE) about, 1455–1461 applying options to new databases, 232 building Smart tags, 879 object list box, 1458 opening, 62, 159 procedure list box, 1458 viewing Visual Basic code, 1456 Visual Basic for Applications (VBA) changing ribbon tab focus, 1704–1705 creating callbacks, 1691–1692 Visual Basic functions declaring new functions, 1525–1526 declaring new subroutines, 1527–1528 event properties running for changing data, 1172–1174 for detecting changes in PivotTables and PivotCharts, 1181–1184 for detecting filters applied to forms and reports, 1177 for detecting focus changes, 1175–1177 for detecting timer expiration, 1185 for opening and closing forms and reports, 1170–1171 for printing, 1184–1185 for trapping errors, 1185 for trapping keyboard and mouse events, 1178–1181 queries using, 127 Visual Basic (VB) 64-bit Access applications about, 1574–1575 LongLong data types, 1475, 1579–1580 LongPtr data types, 1475, 1576–1577 LongPtr type coercion, 1578–1579 PtrSafe attributes, 1577 setting registry key to test upper memory, 1576 supporting previous versions of Access, 1577–1578 understanding pointer value functions, 1578–1579 using Declare statements, 1575–1576 VBA7 language updates, 1579–1580 ActiveX in. See individual headings under ActiveX
1436 Visual Basic (VB)
Visual Basic (VB) (continued) architecture ADO (ActiveX Data Objects), 1502–1504 DAO (Data Access Objects) model, 1497–1501 arrays conversion function, 1832 declaring static, 1492 declaring within procedures, 1489 determining Variants as, 1476 dimensions, 1481 ParamArray argument, 1526 passing, 1486 two-dimensional, 1836 using in example code, 1565 assigning object variables, 1509–1512 assisting data entry filling in data, 1585–1590 fixing email hyperlinks, 1594–1595 handling NotInList event, 1590–1594 providing graphical calendars, 1595–1602 working with linked photos, 1602–1604 automating complex tasks linking related tasks, 1643–1649 triggering data tasks, 1639–1643 automating data selection filtering list with another, 1628–1631 providing custom queries by forms, 1619–1627 selecting from summary lists, 1627–1628 working with multiple-selection list boxes, 1615–1619 automating reports, 1649–1658 ByRef keyword, 1486 calling named data macros, 1658–1661 commands executing, 1464–1469 menu, 1549–1551 compiling, 1713–1714 constants about, 1474 Const statement, 1479 data types, 1475–1476 declaring, 1477, 1478 Enum statement, 1483–1485 ReDim statement, 1489–1490 controlling flow of statements Call statement, 1538–1539 For Each...Next statement, 1541–1542 For...Next statement, 1540–1541 Go To statement, 1543 If...Then...Else statement, 1543–1544 RaiseEvent statement, 1545 Select Case statement, 1545–1547 While...Wend statement, 1547–1548 With...End statement, 1548–1549 counters, 1541
data types, 1475–1476 debugging tools breakpoints (stopping points), setting and using, 1466, 1469 examining procedure call sequences, 1473–1474 setting a breakpoint (stopping point), 1463–1464 using Immediate window, 1464–1469 using Watch window, 1469–1472 Declare statements, 1575–1576, 1578 Do...Loop statement, 1539–1540 form modules, 1454–1455 functions. See Visual Basic functions Function statements, 1525–1527 linking related data linking forms and reports using filters, 1631–1635 synchronizing forms using class events, 1635–1638 looking for, 1188 loops, 1542 macro actions. See macro actions macros, referencing, 1509 modules about, 1452–1455 creating new procedures, 1458–1459 customizing, 1459–1461 declaring private or public variables in, 1477 understanding class. See class modules (VB) object methods manipulating data types using DAO, 1516–1519 working with ADO recordsets, 1520–1524 working with DAO recordsets, 1512–1516 Option Explicit statements, using, 1477 procedures, 128, 1500 declaring private variables in, 1477 running public, 1466 randomly load data complex procedure, 1553–1568 referencing collections, objects, and properties, 1505–1509 report modules, 1454–1455 routines, coding in modules, 158–160 Sub statements, 1527–1528 tabbing on multiple page forms, 1613–1615 trapping errors, 1551–1553 troubleshooting window, 1464 using, 1584–1585 using with .accde files, 1580–1581 validating complex data checking for duplicate names, 1605–1607 checking for overlapping data, 1611–1613 maintaining unique values, 1610–1611 testing for related records, 1607–1608 verifying prerequisites, 1608–1610 variables about, 1474 declaring public or private, 1477–1478 Dim statement, 1480–1483
Event statement, 1485–1486 naming conventions for, 1480 Private statements, 1486–1488 Public statements, 1488–1489 ReDim statement, 1489–1490 Static statement, 1491–1492 Type statement, 1492–1493 using temporary, 1216–1218 viewing code, 1456 Visual Studio building Smart tags, 879 creating BDC model definition files, 1352–1353
W Watch window (Visual Basic), using, 1469–1472 WCF Connection dialog box, 1359 web compatible functions, 1838–1840 creating Application Parts Forms for, 838 creating queries for, 695–700 display forms assigning startup form, 1289–1290 macro actions, 1255, 1866–1868 macros creating, 1254–1258 creating embedded, 1258–1260 linking web macro objects, 1258 message box title, 1257 publishing Access Services applications to, 157 publishing databases to, 17–19, 18 web browser buttons, 32 Web Browser Control button, 795, 1016 web browser controls, 759–760 using, 1014–1019 web browsers downloading web applications, 1314 viewing web forms or web reports using, 1265 working with applications in about, 1299 hiding a repositioning Web Report Toolbar, 1305 understanding session management, 1311–1312 using Datasheet forms, 1306–1309 using web forms, 1299–1304 using web reports, 1304–1306 viewing application settings, 1312 waiting for server processing, 1309–1310 working with columns in Datasheet forms, 1308 Web Compatibility Checker tool, 351–359, 1292, 1333 web databases about, 289 creating lookup fields in web databases, 337 defining field validation rules in, 327–331 defining primary key, 335 defining table validation rules in, 332–335
web forms 1437
publishing to web about, 1290–1296 analyzing publish errors, 1297–1298 backing up original database, 1293 compiling web objects on servers, 1295 converting embedded images to shared images, 1292 creating Access Applications folder, 1294 self join relationships, 345 setting field properties for, 315–318 using in Access published changing web applications, 1330–1335 instantiating Access Services template, 1342–1345 re-enabling prompt, 1328 resolving synchronization conflicts, 1335–1337 saving application as local database, 1341–1342 working offline, 1337–1341 using Web Compatibility Checker, 351–359 viewing relationships, 351 web forms adding gridlines, 918–921 allow space on right edge for controls, 916 changing caption property, 1270 changing control padding, 921–922 combo boxes, 917 control anchoring about, 901–903 control layouts about, 901–903 creating label controls, 918 lining up, 903–905 moving controls within, 905–908 removing in client forms, 911–912 controls formatting columns of, 909–910 moving to different sections, 923–925 resizing, 910–911 selecting all controls in column, 910 using SetProperty action, 1266–1270, 1282 using web-compatible, 916–918 working with events, 1260–1261 creating titles, 922–923 filtering drop-down list in Navigation Target Name property, 1005 format property settings for Date/Time data type, 926 for Number and Currency data types, 925–926 inserting columns, 914–915 inserting rows, 915 limitations of, 763 page break controls in, 993 passing parameters, 1261–1265 seeing events and property sheet window, 1261 setting properties, 927–928 splitting and merging cells, 912–914, 1094
1438 web forms
web forms (continued) using BrowseTo for browsing, 1275–1279 using in web browsers, 1299–1304 using navigation controls, 1003–1014 using subreports, 1031 Visual Basic and, 1453 web forms aligning, 903–905 working in layout view, 899–900 Web Linked Lists commands, 61 web reports building in Layout view adding color to report sections, 1092 adding fields, 1091–1095 adding grouping, 1089–1091 adding sorting, 1089–1091 adding totals to records, 1098–1100 counting pages, 1100 formatting report, 1102–1105 using gridlines, 1100–1102 controls in moving to different sections, 1095 resizing in Layout view, 1096 creating using Report command in Layout view completing report, 1083–1086 modifying Report command report, 1077–1083 dragging forms and records to Macro design surface, 1263 dragging to Macro design surface, 1263 limitations of, 1105–1106 passing parameters, 1261–1265 printing exported, 1306 supporting subreports, 1151 troubleshooting ID values of lookup fields, 1086 using BrowseTo for browsing, 1275–1279 using in web browsers, 1304–1306 viewing exported web reports, 1306 using web browsers, 1265 yes/no fields in, 1065 Web Report Toolbar hiding a repositioning, 1305 web services, 1347–1349 websites mashup, 1347 setting permissions, 1315–1318 web-supported macro actions, 1866–1868 web tables, designing about, 287 choosing table names, 300 creating new databases using templates, 291–296 creating tables simple, 297–300 using Application Parts, 300–304
using Datasheet view. See Datasheet view using Data Type Parts, 304–306 data types, 311–315 defining primary key, 335 defining table validation rules, 332–335 fields choosing names, 311 renaming, 299 lookup fields in. See lookup fields number of fields allowed, 315 using Create Relationship Wizard, 301–304 using Web Compatibility Checker, 351–360 web templates, 1019 Weekday(date) function, 581 WHERE clause, 675, 1813–1815 Where Condition argument as web-supported argument, 1866 BrowseTo macro action, 1275 empty values in, 1237 LookupRecord data block, 394 OpenForm macro action, 1202, 1233 OpenReport macro action, 1855 While...Wend statement, 1547–1548 wildcard characters ACE/JET, 1522 ANSI, 1522 for strings, 1790 LIKE, 203 Window Color and Appearance dialog box, 791 WindowHide command, 1708 Window Mode argument, 1202–1203, 1244, 1866 Windows 7 forms with themes like, 951–952 opening access for the first time in, 22 User Account Control, 232 Windows API Declarations and Constants for Visual Basic, 1578 Windows authentication, 1827 Windows Choose File dialog box, 752 Windows commands, 59 Windows event-driven applications, 1167–1169 windows management macro actions, 1866 Windows RegOpenKeyA API, 1575 Windows Vista forms with themes like, 951–952 User Account Control, 232 With...End statement, 1548–1549 WithEvents keyword, using, 1481 Wizard Decide option, 272 Wizards Chart Insert Chart button, 796 Combo Box, 798, 829–832
XML 1439
Command Button, 798 Create A New Data Source To SQL Server, 450–451 Create Relationship, 301–304 Create Shortcut, 1734–1735 Database Splitter, 1717–1720 email collection, for HTML forms choosing recipients, 508–510 choosing users type of form, 497 creating HTML form, 495–496 customizing email messages, 506–507 identifying recipients email addresses, 504–505 instructing recipient to click Reply, 507 methods of entering email addresses, 503–504 previewing messages, 510 processing replies, 500–502 seeing all fields in the email collection wizard, 500 selecting fields on the form, 498–500 email collection, for InfoPath forms choosing fields in the email form, 517–518 choosing recipients, 522–523 choosing users type of form, 516–517 processing replies, 518 selecting recipients email addresses, 519 specifying subject line, 520–521 E-mail Messages, 1852 Export, 1853 Export Text, 1826 Find Unmatched Query, 641–642, 643 Form building many-to-one form, 948–952 creating forms, 823–826 designing subforms, 957–961 modifying forms created by, 826–828 Get External Data - SharePoint Site, 532–534, 536–537 Import, 542, 1853 Import Spreadsheet fixing errors, 469–471 importing spreadsheets, 465–468 Import Text defining import specification, 480 using, 475–479 Input Mask, 205–207 Label, 1077 Link Spreadsheet, 489 Link Text, 489 List Box, 798 Lookup about, 275–276 creating Lookup fields in web database using, 338–341 creating relationships using Lookup fields, 342–343 defining Restrict Delete relationships using, 344–349 Microsoft Word Mail Merge, 1826, 1854 Package Solution, 1725
Query creating queries for Web, 697 using, 641–644 Report about, 1069 laying out client reports, 1109–1111 limitations for web reports, 1077 setting Long Data, 1129 specifying options, 1069–1074 viewing results, 1074–1075 Table Analyzer looking at Lookup properties, 275–280 using, 270–275 Word as output option, 153 keeping prior versions, 1383 OLE Object data type and, 192 programming language for, 1452 themes in, 930 viewing exported web reports, 1306 word processing documents defining contents, 7 export/import data, 9 RDBMS vs., 12 Workflows dialog box, 1861 Workflows Tasks dialog box, 1861 Work Offline command, 1338 World Wide Web. See also web linking URL on, 314
X XML Backstage view attributes, 1700–1701 Backstage view controls, 1701–1703 creating custom ribbons with about, 1665–1666 building, 1671–1679 creating USysRibbons table, 1667–1671 loading, 1679–1682 displaying ribbon errors, 1674 exporting BCS Entity to, 1365–1366 in BDC definition files, 1352–1355 using, 1350–1351 using ribbon attributes adding options to Backstage view, 1697–1703 creating Quick Access Toolbar, 1703 hiding options and Backstage view, 1696–1697 loading images into custom controls, 1695–1696 RibbonX attributes, 1683–1685 RibbonX controls, 1685–1687 setting ribbon tab focus, 1704–1705 updating elements, 1692–1694
1440 Year(date) function
Y
Z
Year(date) function, 581 year values, formatting, 866 Yes/No data type about, 190 limitations of, 265 using, 312, 313 yes/no fields choosing types of controls, 833–835 in web reports, 1065 specifying format for, 874–875
zero-length strings, 199–200 Zoom control, in Print Preview, 153 Zoom dialog box, 803, 1055–1056, 1298 Zoom window opening, 563 using to enter expressions, 564
About the Authors Jeff Conrad started working with Access when he saw a need at his full-time position for a database solution. He bought a book on Access (should have been one of John’s books) and began teaching himself how to use the program to solve his business’s needs. He immediately became hooked on the power and ease of working with Access long after John had written several books on the program. Jeff found a home in the Microsoft Access newsgroups asking questions as he was learning the ins and outs of Access and database development. He now enjoys giving back to a community that helped him when he was first learning how to use Access. He has been an active participant for many years in the Access newsgroups, where he is best known as the Access Junkie. Jeff also was awarded Microsoft’s Most Valuable Professional award from 2005 to 2007 for his continual involvement with the online Access community. He maintains a website with a wealth of information and resource links for those needing guidance with Access (http:// www.AccessJunkie.com). He co-authored Microsoft Office Access 2007 Inside Out with John Viescas. Jeff is currently employed by Microsoft as a Software Design Engineer in Test working with the Access development team. John Viescas has been working with database systems for most of his career. He began by designing and building a database application for a magazine and paperback book distributing company in Illinois in 1968. He went on to build large database application systems for El Paso Natural Gas Company in his hometown in the early 1970s. From there, he went to Applied Data Research in Dallas, where he managed the development of database and data dictionary systems for mainframe computers. Before forming his own company in 1993, he helped market and support NonStop SQL for Tandem Computers in California. Somewhere along the way (would you believe 1991?), he got involved in the early testing of a new Microsoft product that was code-named “Cirrus.” The first edition of Running Microsoft Access was published in 1992. Since then, he has written four more editions of Running, co-authored the best-selling SQL Queries for Mere Mortals, wrote Building Microsoft Access Applications, and is pleased to be writing about Access from the “Inside Out” for this book. If you hang out on the Web, you can find him answering questions about Access in the newsgroups. John has been named a Microsoft MVP every year since 1993 for his continuing help to Access users’ community. You can reach John via his website at http://www.viescas.com.
What do you think of this book? We want to hear from you! To participate in a brief online survey, please visit:
microsoft.com/learning/booksurvey
Tell us how well this book meets your needs—what works effectively, and what we can do better. Your feedback will help us continually improve our books and learning resources for you. Thank you in advance for your input!
Stay in touch! To subscribe to the Microsoft Press® Book Connection Newsletter—for news on upcoming books, events, and special offers—please visit: microsoft.com/learning/books/newsletter
Part 8
Automating an Access Application Using Visual Basic
n this chapter, you’ll learn how to create, edit, and test Microsoft Visual Basic code in your Microsoft Access 2010 applications. The chapter covers the following major topics:
●●
The Microsoft Visual Basic Editor (VBE) and its debugging tools
●●
Variables and constants and how to declare them
●●
The primary object models defined in Access—the Access model, the Data Access Objects (DAO) model, and the ActiveX Data Objects (ADO) model. You’ll need to understand these models to be able to manipulate objects such as forms, form controls, and recordsets in your code.
●●
Visual Basic procedural statements:
●●
●●
Function and Sub statements
●●
Property Get, Property Let, and Property Set (for use in class modules) statements
●●
Flow-control statements, including Call, Do, For, If, and Select Case
●●
DoCmd and RunCommand statements
●●
On Error statements
A walkthrough of some example code you’ll find in the sample databases
If you’re new to Visual Basic, you might want to read through the chapter from beginning to end, but keep in mind that the large section in the middle of the chapter on procedural statements is designed to be used primarily as a reference. If you’re already familiar with Visual Basic, you might want to review the sections on the VBE and the object models, and then use the rest of the chapter as reference material.
Note You can find many of the code examples from this chapter in the modExamples module in the Contacts.accdb and Housing.accdb sample databases on the companion CD.
The Visual Basic Development Environment In Access for Windows 95 (version 7.0), Visual Basic replaced the Access Basic programming language included with versions 1 and 2 of Access. The two languages are very similar because both Visual Basic and Access Basic evolved from a common design created before either product existed. (It’s called Visual Basic because it was the first version of Basic designed specifically for the Windows graphical environment.) In recent years, Visual Basic has become the common programming language for Microsoft Office applications, including Access, Microsoft Excel, Microsoft Word, and Microsoft PowerPoint. Some of the Office 2010 system products (including Word 2010 and Excel 2010) can work with an even newer variant of Visual Basic—VB.NET—but Access 2010 does not. Having a common programming language across applications provides several advantages. You have to learn only one programming language, and you can easily share objects across applications by using Visual Basic with object automation. Access 2010 uses the VBE common to all Office applications and to the Visual Basic programming product. The VBE provides color-coded syntax, an Object Browser, and other features. It also provides excellent tools for testing and confirming the proper execution of the code you write.
Modules You save all Visual Basic code in your database in modules. Access 2010 provides two ways to create a module: as a module object or as part of a client form or client report object.
The Visual Basic Development Environment 1453
You cannot create a module as part of a web form or web report object in a web database. You can, however, create module objects and modules as part of client forms and client reports in a web database. Web objects do not support using Visual Basic so for the purposes of the discussions in this chapter, you can assume we are always referring to client forms and client reports.
Module Objects You can view the module objects in your database by clicking the top of the Navigation pane and then clicking Object Type under Navigate To Category. Click the Navigation Pane menu again, and click Modules under Filter By Group. Figure 24-1 shows the standard and class modules in the Conrad Systems Contacts sample database—Contacts.accdb. (We also right-clicked the top of the Navigation pane, clicked View By on the shortcut menu, and then Details on the submenu so you can see the descriptions we’ve attached to all the modules.) You should use module objects to define procedures that you need to call from queries or from several forms or reports in your application. You can call a public procedure defined in a module from anywhere in your application.
Figure 24-1 To see all the modules in your database, click Modules under Filter By Group on the Navigation Pane menu when you have Navigate To Category set to Object Type. On the Create tab, in the Macros & Code group, click the Module command to create a new standard module.
To create a new module, click the Module or Class Module command in the Macros & Code group on the Create tab, also shown in Figure 24-1. When you click Module, Access creates a new standard module. You use a standard module to define procedures that you can call from anywhere in your application. It’s a good idea to name modules based on their purpose. For example, you might name a module that contains procedures to perform custom calculations for queries modQueryFunctions, and you might name a module containing procedures to work directly with Windows functions modWindowsAPIFunctions. Advanced developers might want to create a special type of module object called a class module. A class module is a specification for a user-defined object in your application, and the Visual Basic procedures you create in a class module define the properties and methods that your object supports. You create a new class module by clicking Class Module. You’ll learn more about objects, methods, properties, and class modules later in this chapter.
Form and Report Modules To make it easy to create Visual Basic procedures that respond to events on client forms or client reports, Access 2010 supports a class module associated with each form or report. (You can design forms and reports that do not have a related class module.) A module associated with a form or report is also a class module that allows you to respond to events defined for the form or report as well as define extended properties and methods of the form or report. Within a form or report class module, you can create specially named event procedures to respond to Access-defined events, private procedures that you can call only from within the scope of the class module, and public procedures that you can call as methods of the class. See “Collections, Objects, Properties, and Methods,” on page 1494, for more information about objects and methods. You can edit the module for a form or a report by opening the form or report in Design view and then clicking the View Code button in the Tools group on the Design contextual tab (located under Form Design Tools). As you’ll learn later, you can also open a form or a report by setting an object equal to a new instance of the form or report’s class module. Using form and report modules offers three main advantages over module objects: ●●
All the code you need to automate a form or a report resides with that form or report. You don’t have to remember the name of a separate form-related or reportrelated module object.
The Visual Basic Development Environment 1455
●●
Access loads module objects into memory when you first reference any procedure or variable in the module and leaves them loaded so long as the database is open. Access loads the code for a form or a report only when the form or the report is opened. Access unloads a form or a report class module when the object is closed; therefore, form and report modules consume memory only when you’re using the form or the report to which they are attached.
●●
If you export a form or report, all the code in the form or report module is exported with it.
However, form and report modules have one disadvantage: Because the code must be loaded each time you open the form or report, a form or report with a large supporting module opens noticeably more slowly than one that has little or no code. In addition, saving a form or report design can take longer if you have also opened the associated module and changed any of the code. One enhancement that first appeared in Access 97 (version 8.0)—the addition of the HasModule property—helps Access load forms and reports that have no code more rapidly. Access automatically sets this property to Yes if you try to view the code for a form or report, even if you don’t define any event procedures. If HasModule is No, Access doesn’t bother to look for an associated Visual Basic module, so the form or report loads more quickly.
!
CAUTION
If you set the HasModule property to No in the property window, Access deletes the code module associated with the form or report. However, Access warns you and gives you a chance to change your mind if you set the HasModule property to No in error.
The Visual Basic Editor Window When you open a module in Design view, Access 2010 opens the VBE and asks the editor to display your code. Open the Conrad Systems Contacts (Contacts.accdb) sample database if you haven’t already, view the Modules list in the Navigation pane, and then either rightclick the modExamples object and click Design View on the shortcut menu or double-click the modExamples object to see the code for this module opened in the VBE, as shown in Figure 24-2. Notice that the VBE in Access 2010 uses the older menu and toolbar technology from releases of Access before Access 2007, not the ribbon used in the main Access window.
Return to Microsoft Access window Insert a new module or procedure
Chapter 24
Pause execution Run procedure
Properties window Project Explorer window
Halt execution and reset Design mode Open Project Explorer window Open Properties window Open Object Browser Object list Procedure list
Immediate window
Code window
Locals window
Figure 24-2 Use the VBE to view and edit all Visual Basic code in your database.
What you see on your screen might differ from Figure 24-2, particularly if you have opened the VBE previously and moved some windows around. In the upper-left corner of the figure, you can see the Visual Basic Project Explorer window docked in the workspace. (Click Project Explorer on the View menu or press Ctrl+R to see this window if it’s not visible.) In this window, you can discover all module objects and form and report class modules saved
The Visual Basic Development Environment 1457
in the database. You can double-click any module to open it in the Code window, which you can see maximized in the upper-right corner. Docked in the lower-left corner is the Properties window. (Click Properties Window on the View menu or press F4 to see this window if it’s not visible.) When you have a form or report that has a Visual Basic module open in Design view in Access, you can click that object in the Project Explorer to see all its properties. If you modify a property in the Properties window, you’re changing it in Access. To open a form or report that is not open, you can select it in the Project Explorer and then click Object on the View menu. In the lower-right corner, you can see the Locals window docked. (Click Locals Window on the View menu to see this window if it’s not visible.) As you will see later, this window allows you to instantly see the values of any active variables or objects when you pause execution in a procedure. In the lower center, you can see the Immediate window docked. (Click Immediate Window on the View menu or press Ctrl+G to see this window if it’s not visible.) It’s called the Immediate window because you can type any valid Visual Basic statement and press Enter to execute the statement immediately. You can also use a special “what is” command character (?) to find out the value of an expression or variable. For example, you can type ?5*20 and press Enter, and Visual Basic responds with the answer on the following line: 100. You can undock any window by grabbing its title bar and dragging it away from its docked position on the edge toward the center of the screen. You can also undock a window by right-clicking anywhere in the window and clearing the Dockable property. As you will see later, you can set the Dockable property of any window by clicking Options on the Tools menu. When a window is set as Dockable but not docked along an edge, it becomes a pop-up window that floats on top of other windows—similar to the way an Access form works when its Pop Up property is set to Yes, as you learned in Chapter 14, “Customizing a Form.” When you make any window not Dockable, it shares the space occupied by the Code window. You cannot set the Code window as Dockable. The Code window always appears in the part of the workspace that is not occupied by docked windows. You can maximize the Code window to fill this remaining space, as shown in Figure 24-2. You can also click the Restore button for this window and open multiple overlaid Code windows for different modules within the Code window space.
At the top of the Code window, just below the toolbar, you can see two list boxes: Chapter 24
●●
Object list box When you’re editing a form or report class module, open this list on the left to select the form or the report, a section on the form or the report, or any control on the form or the report that can generate an event. The Procedure list box then shows the available event procedures for the selected object. Select General to view the Declarations section of the module, where you can set options or declare variables shared by multiple procedures. In a form or a report class module, General is also where you’ll see any procedures you have coded that do not respond to events. When you’re editing a standard module object, this list displays only the General option. In a class module object, you can choose General or Class.
●●
Procedure list box Open this list on the right to select a procedure in the module and display that procedure in the Code window. When you’re editing a form or report module, this list shows the available event procedures for the selected object and displays in bold type the event procedures that you have coded and attached to the form or the report. When you’re editing a module object, the list displays in alphabetic order all the procedures you coded in the module. In a class module when you have selected Class in the Object list box, you can choose the special Initialize or Terminate procedures for the class.
In Figure 24-2, we dragged the divider bar at the top of the scroll bar on the right of the Code window downward to open two edit windows. We clicked in the lower window and then clicked ShowTables in the Procedure list box. You might find a split window very handy when you’re tracing calls from one procedure to another. The Procedure list box always shows you the name of the procedure that currently has the focus. In the Code window, you can use the arrow keys to move horizontally and vertically. When you enter a new line of code and press Enter, Visual Basic optionally verifies the syntax of the line and warns you of any problems it finds. If you want to create a new procedure in a module, you can type either a Function statement, a Sub statement, or a Property statement on any blank line above or below an existing procedure and then press Enter; click anywhere in the module and click the arrow to the right of the Insert button on the toolbar and then click Procedure; or click Procedure on the Insert menu. (For details about the Function and Sub statements, see “Functions and Subroutines,” on page 1525. For details about the Property statement, see “Understanding Class Modules,” on page 1529.) Visual Basic creates a new procedure for you (it does not embed the new procedure in the procedure you were editing) and inserts an End Function, End Sub, or
The Visual Basic Development Environment 1459
End Property statement. When you create a new procedure using the Insert button or the Insert menu, Visual Basic opens a dialog box where you can enter the name of the new procedure, select the type of the procedure (Sub, Function, or Property), and select the scope of the procedure (Public or Private). To help you organize your procedures, Visual Basic inserts the new procedure in alphabetical order within the existing procedures.
!
CAUTION
If you type a Function, Sub, or Property statement in the middle of an existing procedure, Visual Basic accepts the statement if it’s syntactically correct, but your project won’t compile because you cannot place a Function, Sub, or Property procedure inside another Function, Sub, or Property procedure.
If you’re working in a form or report module, you can select an object in the object list box and then open the Procedure list box to see all the available events for that object. An event name displayed in bold type means you have created a procedure to handle that event. Select an event whose name isn’t displayed in bold type to create a procedure to handle that event. Visual Basic provides many options that you can set to customize how you work with modules. Click Options on the Tools menu, and then click the Editor tab to see the settings for these options, as shown in Figure 24-3.
Figure 24-3 You can customize the VBE by using the settings on the Editor tab in the Options dialog box.
On the Editor tab, some important options to consider are Auto Syntax Check, to check the syntax of lines of code as you enter them; and Require Variable Declaration, which forces you to declare all your variables. (Require Variable Declaration is not selected by default— you’ll see later why it’s important to select it.) If you want to see required and optional parameters as you type complex function calls, select the Auto List Members check box. Auto Quick Info provides drop-down lists where appropriate built-in constants are available to complete parameters in function or subroutine calls. When you’re debugging code, Auto Data Tips lets you discover the current value of a variable by pausing your mouse pointer on any usage of the variable in your code. Drag-And-Drop Text Editing allows you to highlight code and drag it to a new location. Default To Full Module View shows all your code for multiple procedures in a module in a single scrollable view. If you clear that check box, you will see only one procedure at a time and must page up or down or select a different procedure in the Procedure list box to move to a different part of the module. When you’re in full module view, selecting the Procedure Separator check box asks Visual Basic to draw a line between procedures to make it easy to see where one procedure ends and another begins. Selecting the Auto Indent check box asks Visual Basic to leave you at the same indent as the previous line of code when you press the Enter key to insert a new line. We wrote all of the sample code you’ll see in this book and in the sample databases with indents to make it easy to see related lines of code within a loop or an If…Then…Else construct. You can set the Tab Width to any value from 1 through 32. This setting tells Visual Basic how many spaces you want to indent when you press the Tab key while writing code. On the Editor Format tab of the Options dialog box, you can set custom colors for various types of code elements and also choose a display font. We recommend using a monospaced font such as Courier New for all code editing. On the General tab, shown in Figure 24-4, you can set some important options that dictate how Visual Basic acts as you enter new code and as you debug your code. You can ignore all the settings under Form Grid Settings because they apply to forms designed in Visual Basic, not Access.
The Visual Basic Development Environment 1461
Chapter 24
Figure 24-4 You can modify settings to help you debug your code on the General tab in the Options dialog box.
If your code has halted, in many cases you can enter new code or correct problems in code before continuing to test. Some changes you make, however, will force Visual Basic to reset rather than let you continue to run from the halted point. If you select the Notify Before State Loss check box, Visual Basic will warn you before allowing you to make code changes that would cause it to reset. In the Error Trapping section, you can select one of three ways to tell Visual Basic how to deal with errors. As you’ll discover later in this chapter, you can write statements in your code to attempt to catch errors. If you think you have a problem in your error-trapping code, you can select Break On All Errors. With this setting, Visual Basic ignores all error trapping and halts execution on any error. If you have written class modules that can be called from other modules, to catch an untrapped error that occurs within a class module, choose Break In Class Module to halt on the statement within the class module that failed. (We recommend this setting for most testing.) If you choose Break On Unhandled Errors, and an untrapped error occurs within a class module, Visual Basic halts at the statement that invoked the class module. The last two important options on this tab are Compile On Demand and Background Compile. With the Compile On Demand check box selected, Visual Basic compiles any previously uncompiled new code whenever you run that code directly or run a procedure that calls that code. Background Compile lets Visual Basic use spare CPU cycles to compile new code as you are working in other areas. Finally, on the Docking tab, you can specify whether the Immediate window, Locals window, Watch window, Project Explorer, Properties window, or Object Browser can be docked. We will take a look at the Immediate window and Watch window in the next section. You can use the Object Browser to discover all the supported properties and methods of any object or function defined in Access, Visual Basic, or your database application.
Understanding the Relationship Between Access and Visual Basic
Access 2010 and Visual Basic work as two separate but interlinked products in your Access application. Access handles the storage of the Visual Basic project (both the source code and the compiled code) in your desktop database (.accdb or .mdb) or project (.adp) file, and it calls Visual Basic to manage the editing and execution of your code. Because Access tightly links your forms and reports with class modules stored in the Visual Basic project, some complex synchronization must happen between the two products. For example, when you open a form module and enter a new event procedure in the Visual Basic Code window, Access must set the appropriate event property to [Event Procedure] so that both the form and the code are correctly linked. Likewise, when you delete all the code in an event procedure, Access must clear the related form or control property. Therefore, when you open a form or report module from the VBE window, you’ll notice that Access also opens the related form or report object in the Access window. When Access first began using Visual Basic (instead of Access Basic) in version 7 (Access for Windows 95), it was possible to end up with a corrupted Visual Basic project or corrupted form or report object if you weren’t careful to always compile and save both the code and the form or report definition at the same time when you made changes to either. It was particularly easy to encounter corruption if multiple developers had the database open at the same time. This corruption most often occurred when Access failed to merge a changed module back into the Visual Basic project when the developer saved changes. Microsoft greatly improved the reliability of this process when it switched in version 9 (Access 2000) to saving the entire Visual Basic project whenever you save a change. However, this change means that two developers can no longer have the same database open and be working in the code at the same time. This also means that your Access file can grow rapidly if you’re making frequent changes to the code and saving your changes. When you’re making multiple changes in an Access application, we recommend that you always compile your project when you have finished changing a section of code. (Click Compile on the Debug menu in the VBE.) You should also save all at once multiple objects that you have changed by clicking the Save button in the VBE window and always responding Yes to the Save dialog box message that Access shows you when you have multiple changed objects open.
The Visual Basic Development Environment 1463
You might have noticed that the debugging tools for data macros and user interface macros are limited. You can’t do much more than run user interface macros in Single Step mode to try to find the source of an error. The debugging tools for Visual Basic are significantly more extensive. The following sections describe many of the tools available in Visual Basic. You might want to scan these sections first and then return after you have learned more about the Visual Basic language and have begun writing procedures that you need to debug.
Setting Breakpoints If you still have the modExamples module open, scroll down until you can see the entire ShowTables function, as shown in Figure 24-5. This sample function examines all the table definitions in the current database and displays the table name, the names of any indexes defined for the table, and the names of columns in each index by printing to a special object called Debug (another name for the Immediate window).
Figure 24-5 You can set a breakpoint in a Visual Basic module to help you debug your code.
One of the most common ways to test particularly complex code is to open the module you want to examine, set a stopping point in the code (called a breakpoint), and then run the code. Visual Basic halts before executing the statement on the line where you set the breakpoint. As you’ll soon see, when Visual Basic stops at a breakpoint, you can examine all sorts of information to help you clean up potential problems. While a procedure is stopped, you can look at the values in variables—including all object variables you might have defined. In addition, you can also change the value of variables, single-step through the code, reset the code, or restart at a different statement. To set a breakpoint, click anywhere on the line of code where you want Visual Basic execution to halt and either click the Toggle Breakpoint button on the Debug toolbar (open this toolbar by right-clicking any toolbar and clicking Debug on the shortcut menu), click Toggle Breakpoint on the Debug menu, or press F9 to set or clear a breakpoint. When a breakpoint is active, Access highlights the line of code (in red by default) where the breakpoint is established and displays a dot on the selection bar to the left of the line of code. Note that you can set as many breakpoints as you like, anywhere in any module. After you set a breakpoint, the breakpoint stays active until you close the current database, specifically clear the breakpoint, or click Clear All Breakpoints on the Debug menu (or press Ctrl+Shift+F9). In the example shown in Figure 24-5, we set a breakpoint to halt the procedure at the bottom of the loop that examines each table. When you run the procedure later, you’ll see that Visual Basic will halt on this statement just before it executes the statement. Note that you can right-click the toolbar at the top of the VBE window and then click Debug to see the floating Debug toolbar shown in Figure 24-5.
Using the Immediate Window “Action central” for all troubleshooting in Visual Basic is a special edit window called the Immediate window. You can open the Immediate window while editing a module by clicking the Immediate Window button on the Debug toolbar or clicking Immediate Window on the View menu. Even when you do not have a Visual Basic module open, you can open the Immediate window from anywhere in Access by pressing Ctrl+G. Executing Visual Basic Commands in the Immediate Window In the Immediate window (shown in Figure 24-2), you can type any valid Visual Basic command and press Enter to have it executed immediately. You can also execute a procedure by typing the procedure name followed by any parameter values required by the procedure. You can ask Visual Basic to evaluate any expression by typing a question mark character (sometimes called the “what is” character) followed by the expression. Access displays the result of the evaluation on the line below. You might want to experiment by typing ?(5 * 4) / 10. You will see the answer 2 on the line below.
The Visual Basic Development Environment 1465
Because you can type any valid Visual Basic statement, you can enter an assignment statement (the name of a variable, an equals sign, and the value you want to assign to the variable) to set a variable that you might have forgotten to set correctly in your code. For example, there’s a public variable (you’ll learn more about variables later in this chapter) called gintDontShowCompanyList that the Conrad Systems Contacts sample application uses to save whether the current user wants to see the Select Companies pop-up window when clicking Companies on the main switchboard. Some users may prefer to go directly to the Companies/Organizations form that edits all companies rather than select or filter the list. If you have been running the Conrad Systems Contacts application, you can find out the current value of the string by typing ?gintDontShowCompanyList
Visual Basic displays the value of this variable, which should be either 0 or –1. You can set the value of this string to False (0) by typing gintDontShowCompanyList = 0
You can verify the value of the variable you just set by typing ?gintDontShowCompanyList
If you assigned 0 to the variable, you should see that value echoed in the Immediate window. To have a sense of the power of what you’re doing, go to the Database window in Access by clicking the View Microsoft Access button on the left end of the toolbar in the VBE window. Open the frmMain form in Form view. Click Companies to find out whether the Select Companies form or the Companies/Organizations form opens. If you go directly to the Select Companies form, then gintDontShowCompanyList must be False (0). Close the form that opens. Now, go back to the VBE window. (An easy way to do this is to use the Windows Alt+Tab feature.) In the Visual Basic Immediate window, set the value to True by entering in the Immediate window gintDontShowCompanyList = True
Go back to the main switchboard and click Companies again. Because you set the public variable to True, you should go directly to the Companies/Organizations form. Now that you have the form open to edit companies, you can set a filter directly from the Immediate window. Go back to that window and enter the expression Forms!frmCompanies.Filter = "[StateOrProvince] = 'PA'"
If you want, you can ask what the filter property is to see if it is set correctly. Note that nothing has happened yet to the form. Next, turn on the form’s FilterOn property by entering Forms!frmCompanies.FilterOn = True
Return to the form, and you should now see the form filtered down to two rows—all the companies in the state of Pennsylvania. If you want to try another example, return to the Immediate window and enter Forms!frmCompanies.Section(0).Backcolor = 255
The background of Section(0), the detail area of the form, should now appear red. Note that none of these changes affect the design of the form. You can close the form, and the next time you open it, the form will have a normal background color, and the records won’t be filtered. Close the forms you have open to continue with the next section. Using Breakpoints You saw earlier how to set a breakpoint within a module procedure. To see how a breakpoint works, open the modExamples module in the VBE window, find the ShowTables function, and be sure you have set a breakpoint on the Next tbl statement, as shown in Figure 24-6. Because the ShowTables procedure is a function that might return a value, you have to ask Visual Basic to evaluate the function to run it. The function doesn’t require any parameters, so you don’t need to supply any. To run the function, type ?ShowTables() in the Immediate window, as shown in Figure 24-6, and press Enter.
Note You can also ask Visual Basic to run any public procedure by clicking in the procedure and clicking the Run button on either the Standard or Debug toolbar.
The Visual Basic Development Environment 1467
Chapter 24
Figure 24-6 You can execute a module function from the Immediate window.
Visual Basic runs the function you requested. Because you set a breakpoint, the code stops on the statement with the breakpoint, as shown in Figure 24-7. The first table in the database is actually a linked table (an Excel spreadsheet), so you won’t see any output. Click the Continue button on the toolbar to run through the loop a second time to display the first table. Note that we clicked Locals Window on the View menu to reveal the Locals window that you can see across the bottom of Figure 24-7. (We undocked the Immediate window so you can see more of the Locals window.) In the Locals window, Visual Basic shows you all the active variables. You can, for example, click the plus sign (+) next to the word cat (a variable set to the currently opened database catalog) to browse through all the property settings for the database and all the objects within the database. You can click on the tbl variable to explore the columns and properties in the table. See “Collections, Objects, Properties, and Methods,” on page 1494, for details about all the objects you see in the “tree” under the database catalog.
The Immediate window displays the output of three Debug.Print statements within the function you’re running, as also shown in Figure 24-7.
Figure 24-7 When your Visual Basic code stops at a breakpoint, you can use the Locals window to examine variable and object values.
The first line shows the name of the first table (Errorlog) that the function found in the database. The second (indented) line shows the name of the index for that table. The third line shows the name of the one column in the index. If you want to see the results of executing the next loop in the code (examining the next table object in the catalog), click the Continue button on the toolbar. If you want to run the code a single statement at a time, click Step Into or Step Over on the Debug menu or open the Debug toolbar and click the Step Into or Step Over button. Step Into and Step Over work the same unless you’re about to execute a statement that calls another procedure. If the next statement calls another procedure, Step Into literally steps into the called procedure so that you can step through the code in the called procedure one line at a time. Step Over calls the procedure without halting and stops at the next statement in the current procedure. When you are finished studying the loop in the ShowTables function, be sure to click the Reset button on the toolbar to halt code execution.
The Visual Basic Development Environment 1469
The Tables collection in the catalog includes tables, linked tables, system tables, and queries. Because the ShowTables procedure only looks for tables, you will need to loop through the code several times until the procedure finds the next object that defines a table. You should quickly find the ErrorLog, ErrTable, and ErrTableSample tables, but the code must then loop through all the queries and linked tables (more than 40 of them) before finding the SwitchboardDriver table.
Working with the Watch Window Sometimes setting a breakpoint isn’t enough to catch an error. You might have a variable that you know is being changed somewhere by your code (perhaps incorrectly). By using the Watch window, you can examine a variable as your code runs, ask Visual Basic to halt when an expression that uses the variable becomes true, or ask Visual Basic to halt when the variable changes. An interesting set of variables in the Conrad Systems Contacts sample database are gintDontShowCompanyList, gintDontShowContactList, and gintDontShowInvoiceList (all defined in the modGlobals module). When any of these variables are set to True, the main switchboard bypasses the intermediate list/search form for companies, contacts, and invoices, respectively. You played with one of these variables earlier, but it would be interesting to trap when these are set or reset.
!
CAUTION
There are a couple of known issues with setting breakpoints in Access 2010. First, code will not halt if you have cleared the Use Access Special Keys check box in the Application Options section of the Current Database category of the Access Options dialog box (click the File tab on the Backstage view and then click Options). Second, the Break When Value Is True and Break When Value Changes options in the Add Watch dialog box will not work if the value or expression you’re watching is changed in a form or report module that is not already open in the VBE. For this example to work, the form modules for frmMain, frmSignon, and frmUsers must be open. You can verify that these modules are open by opening the Windows menu in the VBE window. The Contacts. accdb sample file should have modules open, but these modules might not be open in your copy if you have closed them and compiled and saved the project. You can find these modules in the Project Explorer window. Open the list of objects in the Microsoft Class Objects category and then double-click the form modules that you need to open them.
To set a watch for when the value changes, open the Watch window by clicking it on the View menu, right-click in the Watch window, and click Add Watch on the shortcut menu. You can also click Add Watch on the Debug menu. You should see the Add Watch dialog box, as shown in Figure 24-8.
Figure 24-8 You can set a watch for when a variable’s value changes.
In the Expression box, enter the name of the variable you want the code to watch. In this case, you want to watch when the gintDontShowContactList variable changes. You don’t know where the variable is set, so set the Procedure and Module selections to (All Procedures) and (All Modules), respectively. Under Watch Type, select the Break When Value Changes option, and click OK to set the watch. Go to the Immediate window and set gintDontShowContactList to True by entering gintDontShowContactList = True and pressing Enter. Now return to the Navigation pane and start the application by opening the frmSplash form. (Code in the Load event of this form hides the Navigation pane and then opens the Conrad Systems Contacts Sign On form.) Because you set a watch to halt when gintDontShowContactList changes, the code execution should halt in the module for the frmSignOn form, as shown in Figure 24-9.
The Visual Basic Development Environment 1471
Chapter 24
Figure 24-9 Visual Basic code halts immediately after a watch variable has changed.
Note that the code halts at the statement immediately after the one that reset the watched variable. If you didn’t set the variable to True before you started the application, Visual Basic won’t halt because the value won’t be changing. Click Continue (or press F5) to let the code continue executing. Return to the Access window, and in the Conrad Systems Contacts Sign On dialog box, select my name (Jeff Conrad), type password in the Password text box, and press Enter or click Sign On. The dialog box will close, and the main switchboard form opens. In the main switchboard, click Users to open the user edit form. The first record should be my record unless you’ve created other users. Select the Don’t Show Contact List check box in my record and click Save. The procedure halts again, as shown in Figure 24-10.
Chapter 24 Figure 24-10 The gintDontShowContactList variable is set to the value of a form control.
It appears that this code is setting the gintDontShowContactList variable to some value on the user edit form. (As you’ll learn later, Me is a shorthand way to reference the form object where your code is running, so Me.DontShowContactList references a control on the form.) Click Continue again to let the code finish execution. Return to the Access window and click the Close button on the Users form to return to the main switchboard. (The Users form might be showing behind the main switchboard form.) If you open frmUsers in Design view (you can’t do this while the procedure is still halted) and examine the names of the check box controls on the form, you’ll find that the check box you selected is named DontShowContactList. When the code behind frmUsers detects a change to the options for the currently signed-on user, it makes sure the option variables in modGlobals get changed as well. Be sure to close the frmUsers form when you’re finished looking at it.
The Visual Basic Development Environment 1473
Examining the Procedure Call Sequence (Call Stack) After stopping code that you’re trying to debug, it’s useful sometimes to find out what started the current sequence of code execution and what procedures have been called by Visual Basic. For this example, you can continue with the watch on the gintDontShowContactList variable. You should now be at the main switchboard form (frmMain) in the application. Click Exit to close the application and return to the Navigation pane. (You’ll see a prompt asking you if you’re sure you want to exit—click Yes. You might also see a prompt offering to back up the data file—click No.) The code should halt again at the Close event of the frmMain form. Click the Call Stack button on the toolbar or click Call Stack on the View menu to see the call sequence shown in Figure 24-11.
Figure 24-11 When your code is halted, you can see the chain of code executed to the point of the halt in the Call Stack dialog box.
The Call Stack dialog box shows the procedures that have executed, with the most recent procedure at the top of the list, and the first procedure at the bottom. You can see that the code started executing in the cmdExit_Click procedure of the frmMain form. This happens to be the Visual Basic event procedure that runs when you click Exit. If you click that line and then click Show, you should see the cmdExit_Click procedure in the module for the frmMain form (the switchboard) with the cursor on the line that executes the DoCmd. Close command to close the form. This line calls the Access built-in Close command (the you see in the call stack list), which in turn triggered the Close event procedure for the form. It’s the Close event procedure code that sets the gintDontShowContactList variable back to False (0). Be sure that the Call Stack dialog box is closed and click Continue on the toolbar to let the code finish running.
Note Be sure to delete the watch after you are finished seeing how it works by right-clicking it in the Watch window and clicking Delete on the shortcut menu.
Variables and Constants In addition to using Visual Basic code to work with the controls on any open forms or reports (as you can with user interface macros), you can declare and use named variables in Visual Basic code for storing values temporarily, calculating a result, or manipulating any of the objects in your database. To create a value available anywhere in your code, you can define a global variable, as you can find in the modGlobals module in the Conrad Systems Contacts sample database. Another way to store data in Visual Basic is with a constant. A constant is a data object with a fixed value that you cannot change while your application is running. You’ve already encountered some of the built-in constants in Access 2010—Null, True, and False. Visual Basic also has a large number of intrinsic constants—built-in constants that have meaningful names—that you can use to test for data types and other attributes or that you can use as fixed arguments in functions and expressions. You can view the list of intrinsic constants by searching for the Visual Basic Constants topic in Help. You can also declare your own constant values to use in code that you write. In the following sections, you’ll learn about using variables to store and calculate data and to work with database objects.
Variables and Constants 1475
Visual Basic supports data types for variables and constants that are similar to the data types you use to define fields in tables. It also allows you to define a variable that is a pointer to an object (such as a form or a recordset). The data types are described in Table 24-1. Table 24-1 Visual Basic Data Types
Data Type
Size
Data-Typing Can Contain Character
Boolean
2 bytes
(none)
True (–1) or False (0)
Byte
1 byte
(none)
Binary data ranging in value from 0 through 255
Integer
2 bytes
%
Integers from –32,768 through 32,767
Long
4 bytes
&
Integers from –2,147,483,648 through 2,147,483,647
LongLong
8 bytes
^
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (Valid on 64-bit platforms only.)
LongPtr
4 bytes on 32-bit systems and 8 bytes on 64-bit systems
(none)
–2,147,483,648 to 2,147,483,647 on 32-bit systems –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 on 64-bit systems
Single
4 bytes
!
Floating-point (imprecise) numbers from approximately –3.4 × 1038 through 3.4 × 1038
Double
8 bytes
#
Floating-point (imprecise) numbers from approximately –1.79 × 10308 through 1.79 × 10308
Currency
8 bytes
@
A scaled integer with four decimal places from –922,337,203,685,477.5808 through 922,337,203,685,477.5807
Decimal
14 bytes
(none)
A precise number with up to 29 digits and up to 28 decimal places from –79.228 × 1027 to 79.228 × 1027 (Visual Basic in Access supports the Decimal data type only as a type within the Variant data type.)
String
10 bytes plus 2 bytes per character
$
Any text or binary string up to approximately 2 billion bytes in length, including text, hyperlinks, memo data, and “chunks” from an ActiveX object; a fixed-length string can be up to 65,400 characters long
Date/time values ranging from January 1, 100, to December 31, 9999
Object
4 bytes
(none)
A pointer to an object—you can also define a variable that contains a specific type of object, such as the Database object
Variant
16 bytes (none) through approximately 2 billion bytes
Any data, including Empty, Null, and date/ time data (Use the VarType function to determine the current data type of the data in the variable. A Variant can also contain an array of Variants. Use the andto determine whether a Variant is an array.)
Userdefined
Depends on elements defined
Any number of variables of any of the above data types
(none)
You can implicitly define the data type of a variable by appending a data-typing character, as noted in Table 24-1, the first time you use the variable. For example, a variable named MyInt% is an integer variable. If you do not explicitly declare a data variable that you reference in your code and do not supply a data-typing character, Visual Basic assigns the Variant data type to the variable. (See “Declaring Constants and Variables,” on page 1479, to learn how to explicitly declare data variables.) Note that although the Variant data type is the most flexible (and, in fact, is the data type for all controls on forms and reports), it is also the least efficient because Visual Basic must do extra work to determine the current data type of the data in the variable before working with it in your code. Variant is also the only data type that can contain the Null value. The Object data type lets you define variables that can contain a pointer to an object. See “Collections, Objects, Properties, and Methods,” on page 1494, for details about objects that you can work with in Visual Basic. You can declare a variable as the generic Object data type, or you can specify that a variable contains a specific type of object. The major object types are AccessObject, Application, Catalog, Column, Command, Connection, Container, Control, Database, Document, Error, Field, Form, Group, Index, Key, Parameter, Procedure, Property, QueryDef, Recordset, Relation, Report, Table, TableDef, User, View, and Workspace.
Variables and Constants 1477
Using Option Explicit Is a Good Idea
You can request that Visual Basic generate all new modules with an Option Explicit statement by selecting the Require Variable Declaration check box on the Editor tab of the Options dialog box, as shown in Figure 24-3. If you set this option, Visual Basic includes an Option Explicit statement in the Declarations section of every new module. This helps you avoid errors that can occur when you use a variable in your code that you haven’t properly declared in a Dim, Public, Static, or Type statement or as part of the parameter list in a Function statement or a Sub statement. (See “Functions and Subroutines,” on page 1525.) When you specify this option in a module, Visual Basic flags any undeclared variables it finds when you ask it to compile your code. Using an Option Explicit statement helps you find variables that you might have misspelled when you entered your code.
Variable and Constant Scope The scope of a variable or a constant determines whether the variable or the constant is known to only one procedure, all procedures in a module, or all procedures in your database. You can create variables or constants that can be used by any procedure in your database (public scope). You can also create variables or constants that apply only to the procedures in a module or only to a single procedure (private scope). A variable declared inside a procedure is always private to that procedure (available only within the procedure). A variable declared in the Declarations section of a module can be private (available only to the procedures in the module) or public. You can pass values from one procedure to another using a parameter list, but the values might be held in variables having different names in the two procedures. See the sections on the Function, Sub, and Call statements later in this chapter. To declare a public variable, use the Public statement in the Declarations section of a standard module or a class module. All modules attached to forms or reports are class modules. To declare a public constant, use the Public keyword with a Const statement in the Declarations section of a standard module. You cannot declare a public constant in a class module. To declare a variable or a constant that all procedures in a module can reference, define that variable or constant in the Declarations section of the module. (A variable defined in a Declarations section is private to the module unless you use the Public statement.) To declare a variable or a constant used only in a particular procedure, define that variable or constant as part of the procedure.
Visual Basic in Access 2010 allows you to use the same name for variables or constants in different module objects or at different levels of scope. In addition, you can declare constants and public variables in form and report modules as well as public variables and constants in standard modules. (You can declare a constant in a form or report module, but it cannot be public.) To use the same name for public variables and constants in different module objects or form or report modules, specify the name of the module to which it belongs when you refer to it. For example, you can declare a public variable named intX in a module object with the name modMyModule and then declare another public variable named intX in a second module object, named modMyOtherModule. If you want to reference the intX variable in modMyModule from a procedure in modMyOtherModule (or any module other than modMyModule), you must use the following code: modMyModule.intX
You can also declare variables or constants with the same name at different levels of scope within a module object or a form or report module. For example, you can declare a public variable named intX and then declare a local variable named intX within a procedure. (You can’t declare a public variable within a procedure.) References to intX within the procedure refer to the local variable, while references to intX outside the procedure refer to the public variable. To refer to the public variable from within the procedure, qualify it with the name of the module, just as you would refer to a public variable from within a different module. Declaring a public variable in a form or report module can be useful for variables that are logically associated with a particular form or report but that you might also want to use elsewhere. Like the looser naming restrictions, however, this feature can sometimes create confusion. In general, it’s still a good idea to keep common public variables and constants in standard modules and to give public variables and constants names that are unique across all variable names in your application.
Note For information on the syntax conventions used in the remainder of this chapter, refer to “Syntax Conventions,” in the “Conventions Used in This Book” section at the beginning of this book.
Declaring Constants and Variables 1479
The following sections show the syntax of the statements you can use to define constants and variables in your modules and procedures.
Const Statement Use a Const statement to define a constant.
Notes Include the Public keyword in the Declarations section of a standard module to define a constant that is available to all procedures in all modules in your database. Include the Private keyword to declare constants that are available only within the module where the declaration is made. Constants are private by default, and a constant defined within a procedure is always private. You cannot define a Public constant in a class module. (All constants in a class module are private.) Valid datatype entries can be Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String, or Variant. You cannot declare a constant as an object. Use a separate As datatype clause for each constant being declared. If you don’t declare a type, Visual Basic assigns the data type that is most appropriate for the expression provided. (You should always explicitly declare the data type of your constants.) The item cannot include variables, user-defined functions, or Visual Basic built-in functions (such as Chr). You can include simple literals and other previously defined constants.
Example To define the constant PI to be available to all procedures in all modules, enter the following in the Declarations section of any standard module: Public Const PI As Double = 3.14159
It’s a good idea to give all variable names you create a prefix notation that indicates the data type of the variable, particularly if you create complex procedures. This helps ensure that you aren’t attempting to assign or calculate incompatible data types. (For example, the names will make it obvious that you’re creating a potential error if you try to assign the contents of a long integer variable to an integer variable.) It also helps ensure that you pass variables of the correct data type to procedures. Finally, including a prefix helps ensure that you do not create a variable name that is the same as an Access or Visual Basic reserved word. The following table suggests data type prefixes that you can use for many of the most common data types.
Data Type
Prefix
Data Type
Prefix
Boolean
bol
Document
doc
Byte
byt
Field
fld
Currency
cur
Form
frm
Double
dbl
Index
idx
Integer
int
Key
key
Long
lng
Parameter
prm
Single
sgl
Procedure
prc
String
str
Property
prp
User-defined (using the Type statement)
usr
QueryDef
qdf
Variant
var
Recordset
rst
Catalog
cat
Report
rpt
Column
col
Table
tbl
Command
cmd
TableDef
tbl
Connection
cn
View
vew
Control
ctl
Workspace
wks
Database
db
Dim Statement Use a Dim statement in the Declarations section of a module to declare a variable or a variable array that can be used in all procedures in the module. Use a Dim statement within a procedure to declare a variable used only in that procedure.
Declaring Constants and Variables 1481
Dim {[WithEvents] variablename [([],... )] [As [New] datatype]},...
where is [lowerbound To ] upperbound
Notes If you do not include an specification but you do include the parentheses, you must include a ReDim statement in eac procedure that uses the array to dynamically allocate the array at run time. You can define an array with as many as 60 dimensions. If you do not include a lowerbound value in an specification, the default lower bound is 0. You can reset the default lower bound to 1 by including an Option Base 1 statement in the module Declarations section. The lowerbound and upperbound values must be integers, and upperbound must be greater than or equal to lowerbound. The number of members of an array is limited only by the amount of memory on your computer. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. You can also declare a userdefined variable structure using the Type statement and then use the user type name as a data type. You should always explicitly declare the data type of your variables. If you do not include the As datatype clause, Visual Basic assigns the Variant data type. Use the New keyword to indicate that a declared object variable is a new instance of an object that doesn’t have to be set before you use it. You can use the New keyword only with object variables to create a new instance of that class of object without requiring a Set statement. You can’t use New to declare dependent objects. If you do not use the New keyword, you cannot reference the object or any of its properties or methods until you set the variable to an object using a Set statement. Use the WithEvents keyword to indicate an object variable within a class module that responds to events triggered by an ActiveX object. Form and report modules that respond to events on the related form and report objects are class modules. You can also define custom class modules to create custom objects. If you use the WithEvents keyword, you cannot use the New keyword.
Visual Basic initializes declared variables at compile time. Numeric variables are initialized to zero (0), variant variables are initialized to empty, variable-length string variables are initialized as zero-length strings, and fixed-length string variables are filled with American National Standards Institute (ANSI) zeros (Chr(0)). If you use a Dim statement within a procedure to declare variables, Visual Basic reinitializes the variables each time you run the procedure.
Examples To declare a variable named intMyInteger as an integer, enter the following: Dim intMyInteger As Integer
To declare a variable named dbMyDatabase as a database object, enter the following: Dim dbMyDatabase As Database
To declare an array named strMyString that contains fixed-length strings that are 20 characters long and contains 50 entries from 51 through 100, enter the following: Dim strMyString(51 To 100) As String * 20
To declare a database variable, a new table variable, and two new field variables for the table; set up the objects; and append the new table to the Tabledefs collection, enter the following: Public Sub NewTableExample() Dim db As DAO.Database Dim tdf As New DAO.TableDef, _ fld1 As New DAO.Field, _ fld2 As New DAO.Field ' Initialize the table name tdf.Name = "MyTable" ' Set the name of the first field fld1.Name = "MyField1" ' Set its data type fld1.Type = dbLong ' Append the first field to the Fields ' collection of the table tdf.Fields.Append fld1 ' Set up the second field fld2.Name = "MyField2" fld2.Type = dbText fld2.Size = 20 ' Append the second field to the table
Declaring Constants and Variables 1483
tdf.Fields.Append fld2 ' Establish an object on the current database Set db = CurrentDb ' Create a new table by appending tdf to ' the Tabledefs collection of the database db.TableDefs.Append tdf End Sub
See “Collections, Objects, Properties, and Methods,” on page 1494, for details about working with DAO objects. See “Functions and Subroutines,” on page 1525, for details about the Sub statement.
To declare an object variable to respond to events in another class module, enter the following: Option Explicit Dim WithEvents objOtherClass As MyClass Sub LoadClass () Set objOtherClass = New MyClass End Sub Sub objOtherClass_Signal(ByVal strMsg As string) MsgBox "MyClass Signal event sent this " & _ "message: " & strMsg End Sub
In class module MyClass, enter the following: Option Explicit Public Event Signal(ByVal strMsg As String) Public Sub RaiseSignal(ByVal strText As String) RaiseEvent Signal(strText) End Sub
In any other module, execute the following statement: MyClass.RaiseSignal "Hello"
Enum Statement Use an Enum statement in a module Declarations section to assign long integer values to named members of an enumeration. You can use an enumeration name as a restricted Long data type.
[Public | Private] Enum enumerationname [= ] ... End Enum
Notes Enumerations are constant values that you cannot change when your code is running. Include the Public keyword to define an enumeration that is available to all procedures in all modules in your database. Include the Private keyword to declare an enumeration that is available only within the module where the declaration is made. Enumerations are public by default. You must declare at least one member within an enumeration. If you do not provide a assignment, Visual Basic adds 1 to the previous value or assigns 0 if the member is the first member of the enumeration. The cannot include variables, user-defined functions, or Visual Basic built-in functions (such as CLng). You can include simple literals and other previously defined constants or enumerations. Enumerations are most useful as a replacement for the Long data type in a Function or Sub statement. When you call the function or sub procedure in code, you can use one of the enumeration names in place of a variable, constant, or literal. If you select the Auto List Members option (see Figure 24-3), Visual Basic displays the available names in a drop-down list as you type the sub or function call in your code.
Example To declare a public enumeration for days of the week and use the enumeration in a procedure, enter the following: Option Explicit Public Enum DaysOfWeek Sunday = 1 Monday Tuesday Wednesday Thursday Friday Saturday End Enum
Declaring Constants and Variables 1485
Public Function NextDate(lngDay As DaysOfWeek) As Date ' This function returns the next date ' that matches the day of week requested Dim intThisDay As Integer, datDate As Date ' Get today datDate = Date ' Figure out today's day of week intThisDay = WeekDay(datDate) ' Calculate next day depending on ' whether date requested is higher or lower If intThisDay < lngDay Then NextDate = datDate + (lngDay – intThisDay) Else NextDate = datDate + (lngDay + 7) – intThisDay End If End Function
You can test the function from the Immediate window by entering the following: ?NextDate(Monday)
Event Statement Use the Event statement in the Declarations section of a class module to declare an event that can be raised within the module. In another module, you can define an object variable using the WithEvents keyword, set the variable to an instance of this class module, and then code procedures that respond to the events declared and triggered within this class module.
Syntax [Public] Event eventname ([])
where is {[ByVal | ByRef] argumentname [As datatype]},...
Notes An Event must be public, which makes the event available to all other procedures in all modules. If you want, you can include the Public keyword when coding this statement. You should declare the data type of any arguments in the event’s argument list. Note that the names of the variables passed by the triggering procedure can be different from the names of the variables known by this event. If you use the ByVal keyword to declare an
argument, Visual Basic passes a copy of the argument to your event. Any change you make to a ByVal argument does not change the original variable in the triggering procedure. If you use the ByRef keyword, Visual Basic passes the actual memory address of the variable, allowing the event to change the variable’s value in the triggering procedure. (If the argument passed by the triggering procedure is an expression, Visual Basic treats it as if you had declared it by using ByVal.) Visual Basic always passes arrays by reference (ByRef).
Example To declare an event that can be triggered from other modules, enter the following in the class module MyClass: Option Explicit Public Event Signal(ByVal strMsg As String) Public Sub RaiseSignal(ByVal strText As String) RaiseEvent Signal(strText) End Sub
To respond to the event from another module, enter the following: Option Explicit Dim WithEvents objOtherClass As MyClass Sub LoadClass () Set objOtherClass = New MyClass End Sub Sub objOtherClass_Signal(ByVal strMsg As string) MsgBox "MyClass Signal event sent this " & _ "message: " & strMsg End Sub
To trigger the event in any other module, execute the following: MyClass.RaiseSignal "Hello"
Private Statement Use a Private statement in the Declarations section of a standard module or a class module to declare variables that you can use in any procedure within the module. Procedures in other modules cannot reference these variables.
Notes If you do not include an specification but you do include the parentheses, you must include a ReDim statement in each procedure that uses the array to dynamically allocate the array at run time. You can define an array with up to 60 dimensions. If you do not include a lowerbound value in an specification, the default lower bound is 0. You can reset the default lower bound to 1 by including an Option Base 1 statement in the module Declarations section. The lowerbound and upperbound values must be integers, and upperbound must be greater than or equal to lowerbound. The number of members of an array is limited only by the amount of memory on your computer. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. You can also declare a userdefined variable structure using the Type statement and then use the user type name as a data type. You should always explicitly declare the data type of your variables. If you do not include the As datatype clause, Visual Basic assigns the Variant data type. Use the New keyword to indicate that a declared object variable is a new instance of an object that doesn’t have to be set before you use it. You can use the New keyword only with object variables to create a new instance of that class of object without requiring a Set statement. You can’t use New to declare dependent objects. If you do not use the New keyword, you cannot reference the object or any of its properties or methods until you set the variable to an object using a Set statement. Use the WithEvents keyword to indicate an object variable within a class module that responds to events triggered by an ActiveX object. Form and report modules that respond to events on the related form and report objects are class modules. You can also define custom class modules to create custom objects. If you use the WithEvents keyword, you cannot use the New keyword.
Visual Basic initializes declared variables at compile time. Numeric variables are initialized to zero (0), variant variables are initialized to empty, variable-length string variables are initialized as zero-length strings, and fixed-length string variables are filled with ANSI zeros (Chr(0)).
Example To declare a long variable named lngMyNumber that can be used in any procedure within this module, enter the following: Private lngMyNumber As Long
Public Statement Use a Public statement in the Declarations section of a standard module or a class module to declare variables that you can use in any procedure anywhere in your database.
Syntax Public {[WithEvents] variablename [([],... )] [As [New] datatype]},...
where is [lowerbound To ] upperbound
Notes If you do not include an specification but you do include the parentheses, you must include a ReDim statement in each procedure that uses the array to dynamically allocate the array at run time. You can define an array with up to 60 dimensions. If you do not include a lowerbound value in an specification, the default lower bound is 0. You can reset the default lower bound to 1 by including an Option Base 1 statement in the module Declarations section. The lowerbound and upperbound values must be integers, and upperbound must be greater than or equal to lowerbound. The number of members of an array is limited only by the amount of memory on your computer. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. Note, however, that you cannot declare a Public fixed-length string within a class module. You can also declare a userdefined variable structure using the Type statement and then use the user type name as a data type. You should always explicitly declare the data type of your variables. If you do not include the As datatype clause, Visual Basic assigns the Variant data type.
Declaring Constants and Variables 1489
Use the New keyword to indicate that a declared object variable is a new instance of an object that doesn’t have to be set before you use it. You can use the New keyword only with object variables to create a new instance of that class of object without requiring a Set statement. You can’t use New to declare dependent objects. If you do not use the New keyword, you cannot reference the object or any of its properties or methods until you set the variable to an object using a Set statement. Use the WithEvents keyword to indicate an object variable within a class module that responds to events triggered by an ActiveX object. Form and report modules that respond to events on the related form and report objects are class modules. You can also define custom class modules to create custom objects. If you use the WithEvents keyword, you cannot use the New keyword. Visual Basic initializes declared variables at compile time. Numeric variables are initialized to zero (0), variant variables are initialized to empty, variable-length string variables are initialized as zero-length strings, and fixed-length string variables are filled with ANSI zeros (Chr(0)).
Example To declare a long variable named lngMyNumber that can be used in any procedure in the database, enter the following: Public lngMyNumber As Long
ReDim Statement Use a ReDim statement to dynamically declare an array within a procedure or to redimension a declared array within a procedure at run time.
Notes If you’re dynamically allocating an array that you previously defined with no specification in a Dim, Public, or Private statement, your array can have up to 60 dimensions. You cannot dynamically reallocate an array that you previously defined with
an specification in a Dim, Public, or Private statement. If you declare the array only within a procedure, your array can have up to 60 dimensions. If you do not include a lowerbound value in an specification, the default lower bound is 0. You can reset the default lower bound to 1 by including an Option Base 1 statement in the module Declarations section. The lowerbound and upperbound values must be integers, and upperbound must be greater than or equal to lowerbound. The number of members of an array is limited only by the amount of memory on your computer. If you previously specified dimensions in a Public, Private, or Dim statement or in another ReDim statement within the same procedure, you cannot change the number of dimensions. Include the Preserve keyword to ask Visual Basic not to reinitialize existing values in the array. When you use Preserve, you can change the bounds of only the last dimension in the array. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. You can also declare a userdefined variable structure using the Type statement and then use the user type name as a data type. You should always explicitly declare the data type of your variables. If you do not include the As datatype clause, Visual Basic assigns the Variant data type. You cannot change the data type of an array that you previously declared with a Dim, Public, or Private statement. After you establish the number of dimensions for an array that has module or global scope, you cannot change the number of its dimensions using a ReDim statement. Visual Basic initializes declared variables at compile time. Numeric variables are initialized to zero (0), variant variables are initialized to empty, variable-length string variables are initialized as zero-length strings, and fixed-length string variables are filled with ANSI zeros (Chr(0)). When you use the Preserve keyword, Visual Basic initializes only additional variables in the array. If you use a ReDim statement within a procedure to both declare and allocate an array (and you have not previously defined the array with a Dim, Public, or Private statement), Visual Basic reinitializes the array each time you run the procedure.
Example To dynamically allocate an array named strProductNames that contains 20 strings, each with a fixed length of 25, enter the following: ReDim strProductNames(20) As String * 25
Declaring Constants and Variables 1491
Use a Static statement within a procedure to declare a variable used only in that procedure and that Visual Basic does not reinitialize while the module containing the procedure is open. Visual Basic opens all standard and class modules (objects you can see in the Modules list in the Navigation pane) when you open the database containing those objects. Visual Basic keeps form or report class modules open only while the form or the report is open.
Notes If you do not include an specification but you do include the parentheses, you must include a ReDim statement in each procedure that uses the array to dynamically allocate the array at run time. You can define an array with up to 60 dimensions. If you do not include a lowerbound value in an specification, the default lower bound is 0. You can reset the default lower bound to 1 by including an Option Base 1 statement in the module Declarations section. The lowerbound and upperbound values must be integers, and upperbound must be greater than or equal to lowerbound. The number of members of an array is limited only by the amount of memory on your computer. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described in this chapter. You can also declare a user-defined variable structure using the Type statement and then use the user type name as a data type. You should always explicitly declare the data type of your variables. If you do not include the As datatype clause, Visual Basic assigns the Variant data type. Use the New keyword to indicate that a declared object variable is a new instance of an object that doesn’t have to be set before you use it. You can use the New keyword only with object variables to create a new instance of that class of object without requiring a Set statement. You can’t use New to declare dependent objects. If you do not use the New keyword, you cannot reference the object or any of its properties or methods until you set the variable to an object using a Set statement.
Visual Basic initializes declared variables at compile time. Numeric variables are initialized to zero (0), variant variables are initialized to empty, variable-length string variables are initialized as zero-length strings, and fixed-length string variables are filled with ANSI zeros (Chr(0)).
Examples To declare a static variable named intMyInteger as an integer, enter the following: Static intMyInteger As Integer
To declare a static array named strMyString that contains fixed-length strings that are 20 characters long and contains 50 entries from 51 through 100, enter the following: Static strMyString(51 To 100) As String * 20
Type Statement Use a Type statement in a Declarations section to create a user-defined data structure containing one or more variables.
Syntax [Public | Private] Type typename {variablename [({},...)] As datatype} ... End Type
where is [lowerbound To ] upperbound
Notes A Type statement is most useful for declaring sets of variables that can be passed to procedures, including Windows application programming interface (API) functions, as a single variable. You can also use the Type statement to declare a record structure. After you declare a user-defined data structure, you can use typename in any subsequent Dim, Public, Private, or Static statement to create a variable of that type. You can reference variables in a user-defined data structure variable by entering the variable name, a period, and the name of the variable within the structure. (See the second part of the example that follows.)
Declaring Constants and Variables 1493
Include the Public keyword to declare a user-defined type that is available to all procedures in all modules in your database. Include the Private keyword to declare a user-defined type that is available only within the module in which the declaration is made. You must enter each variablename entry on a new line. You must indicate the end of your user-defined data structure using an End Type statement. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. You can also declare a userdefined variable structure using the Type statement and then use the user type name as a data type. You should always explicitly declare the data type of your variables. If you do not include the As datatype clause, Visual Basic assigns the Variant data type. If you do not include an specification but you do include the parentheses, you must include a ReDim statement in each procedure that uses the array to dynamically allocate the array at run time in any variable that you declare as this Type. You can define an array with as many as 60 dimensions. If you do not include a lowerbound value in an specification, the default lower bound is 0. You can reset the default lower bound to 1 by including an Option Base 1 statement in the module Declarations section. The lowerbound and upperbound values must be integers, and upperbound must be greater than or equal to lowerbound. The number of members of an array is limited only by the amount of memory on your computer. Note that a Type declaration does not reserve any memory. Visual Basic allocates the memory required by the Type statement when you use typename as a data type in a Dim, Public, Private, or Static statement.
Example To define a user type structure named MyRecord containing a long integer and three string fields, declare a variable named usrContacts using that user type, and then set the first string to “Jones”, first enter the following: Type MyRecord lngID As Long strLast As String strFirst As String strMid As String End Type
Then, within a procedure, enter the following: Dim usrContacts As MyRecord usrContacts.strLast = "Jones"
Collections, Objects, Properties, and Methods Chapter 24
You’ve already dealt with two of the main collections supported by Access 2010—Forms and Reports. The Forms collection contains all the form objects that are open in your application, and the Reports collection contains all the open report objects. As you’ll learn in more detail later in this section, collections, objects, properties, and methods are organized in several object model hierarchies. An object has properties, which describe the object, and methods, which are actions that you can ask the object to execute. For example, a Form object has a Name property (the name of the form) and a Requery method (to ask the form to requery its record source). Many objects also have collections that define sets of other objects within the object. For example, a Form object has a Controls collection, which is the set of all control objects (text boxes, labels, and so on) defined on the form. You don’t need a thorough understanding of collections, objects, properties, and methods to perform most application tasks. It’s useful, however, for you to know how Access and Visual Basic organize these items so that you can better understand how Access works. If you want to study advanced code examples available in the many sample databases that you can download from public forums, you’ll need to understand collections, objects, properties, and methods and how to correctly reference them.
The Access Application Architecture An Access 2010 desktop application (.accdb or .mdb) has two major components—the application engine, which controls the programming and the user interface, and the Access Database Engine (DBEngine), which controls the storage of data and the definition of all the objects in your database. An Access project (.adp) also uses the application engine, but it depends on its Connection object to define a link to the Microsoft SQL Server database that contains the tables, views, functions, and stored procedures used by the application. As you’ll see in the next section, Visual Basic supports two distinct object models (Data Access Objects–DAO, and ActiveX Data Objects–ADO) for manipulating objects stored by the database engine. Figure 24-12 shows the application architecture of Access.
Collections, Objects, Properties, and Methods 1495
Chapter 24
Figure 24-12 You can explore objects in the Access application architecture from the Application object.
When you open a database, the application engine loads the appropriate object collections from the database and application files to enable it to list the names of all the tables, queries, views, database diagrams, stored procedures, forms, reports, macros, and modules to display in the Navigation pane. The application engine establishes the top-level Application object, which contains a Forms collection (all the open forms), a Reports collection (all the open reports), a Modules collection (all the open modules, including form and report modules), and a References collection (all Visual Basic library references). Each form and report, in turn, contains a Controls collection (all of the controls on the form or report). Among some of the more interesting properties of the Application object is the ADOConnectString property that contains the information you can use to connect to this database from another database.
Note For backward compatibility with earlier versions and database files in the .mdb format, the Access object architecture continues to support obsolete collections, objects, and properties. For example, the Application object continues to support a CommandBars collection to allow you to manipulate any custom menus or toolbars that might have been defined using Access 2003 or earlier.
The Application object also contains two special objects, the Screen object and the DoCmd object. The Screen object has six very useful properties: ActiveForm, ActiveReport, ActiveDatasheet, ActiveControl, PreviousControl, and MousePointer. Without knowing the actual names, you can reference the control (if any) that currently has the focus, the datasheet (if any) that has the focus, the form (if any) that has the focus, the report (if any) that has the focus, or the name of the control that previously had the focus. You can use the MousePointer property to examine the current status of the mouse pointer (arrow, I-beam, hourglass, and so on) and set the pointer. (Additional details about referencing properties of objects appear later in this chapter.) The DoCmd object lets you execute most macro actions within Visual Basic. For more information, see “Running Macro Actions and Menu Commands,” on page 1549. If your application is an Access desktop database (.accdb), the DBEngine object under the Application object connects you to the Access Database Engine (ACE) to manipulate its objects using the DAO model.
Collections, Objects, Properties, and Methods 1497
Two properties allow you to directly find out the names of all objects stored in your database without having to call the database engine. In an Access desktop database (.accdb), you can find out the names of all your tables and queries via the CurrentData property. In an Access project file (.adp) that is connected to SQL Server, you also can learn the names of database diagrams, stored procedures, functions, and views via this same property. In either type of Access file, you can discover the names of all your forms, reports, macros, and modules via the CurrentProject property. Finally, the FullName property of the CurrentProject object tells you the full path and file name of your application file, and the Name property tells you the file name only.
The DAO Architecture The first (and older) of the two models you can use to fetch data and examine or create new data objects is the DAO model. This model is best suited for use within Access desktop applications (.accdb and .mdb) because it provides objects, methods, and properties specifically tailored to the way Access and the ACE work together. To use this model, you must ask Visual Basic to load a reference to the Microsoft Office 14.0 Access Database Engine Object Library. To verify that your project includes this reference, open any module in Design view and click References on the Tools menu. If you don’t see the check box for this library selected at the top of the References dialog box, scroll down the alphabetical list until you find the library, select its check box, and click OK to add the reference. Access 2010 creates this reference for you in any new database that you create.
INSIDE OUT
Is the Rumor That “DAO Is Dead” Really True?
Absolutely not! First, you need to know a bit of history. Beginning with version 9 (Access 2000), the Access development team introduced ADO to make it easier to work with SQL Server or other server databases as the data store for Access applications. ADO was touted as the “new direction” for data engine object models because it was designed to be more generic to work with different databases. Access 2000 also introduced the project file format (.adp) that lets you create an Access application linked directly to a database in SQL Server. Both Access 2000 and Access XP (2002) provided a default reference to the ADO library in new database, and you had to add the DAO library if you wanted to use it. Microsoft also declared DAO “stable” (read: no new enhancements) and began distributing the Access JET database engine as part of Microsoft Data Access Components (MDAC) that you install with your operating system—Microsoft Windows 98, Windows 2000, Windows XP, Windows Vista, or Windows 7. And so, the developer community began to think that DAO was “dead.”
But DAO in many cases really works better if you’re building a desktop application. DAO gives you direct access not only to all your table and query definitions but also forms, reports, macros, and modules. Also, the record source for all forms and reports creates a DAO recordset, so it doesn’t make sense to try to use the entirely different ADO recordset object in your code. As of Access 2002, you can assign a recordset object you open in code directly to the Recordset property of a form. But if you’re using an ADO recordset, features that you expect to work—such as updating across a join or autolookup when you set a foreign key—don’t work correctly. In short, DAO was designed to work best with Access desktop applications. When Microsoft stopped providing DAO as a default reference in new databases, many in the developer community pointed out to Microsoft that this really wasn’t a good idea for desktop applications. Microsoft listened to its users and changed the default library back to DAO in Access 2003. However, the Access development team couldn’t plan any major enhancements because the JET engine had become part of Windows. For Access 2007, the development team created its own new version of the JET engine—now called the ACE. ACE includes the new features to support the Attachment and the Calculated data types, as well as multi-value fields, and it also supports all the features of the old JET engine, but uses an enhanced version of DAO. So no, DAO is not dead—it in a sense has been reborn in the new database engine for Access 2007 and Access 2010.
The Application object’s DBEngine property serves as a bridge between the application engine and the Access Database Engine. The DBEngine property represents the DBEngine object, which is the top-level object in the DAO hierarchy. Figure 24-13 shows you a diagram of the hierarchy of collections defined in the DAO model.
Collections, Objects, Properties, and Methods 1499
Chapter 24
Figure 24-13 The DAO model is specifically designed to manipulate data objects in an Access desktop database.
The DBEngine object controls all the database objects in your database through a hierarchy of collections, objects, and properties. When you open an Access database, the DBEngine object first establishes a Workspaces collection and a default Workspace object (the first object in the Workspaces collection). If you are opening a secured database created in the prior version format (.mdb, .mde) and your workgroup is secured, Access prompts you for a password and a user ID so that the DBEngine can create a User object in the Users collection and a Group object in the Groups collection within the default workspace. If your workgroup is not secured, the DBEngine signs you in as a default user called Admin.
Finally, the DBEngine creates a Database object within the Databases collection of the default Workspace object. If your prior version format file is secured, the DBEngine uses the current User and/or Group object information to determine whether you’re authorized to access any of the objects within the database. After the DBEngine creates a Database object, the application engine determines whether the database contains any potentially untrustworthy objects. Any database containing tables, queries, macros, or Visual Basic code is deemed potentially untrustworthy. If the database is signed with a certificate that you have accepted as trustworthy or the database resides in a trusted location, the application engine enables all code. If the database is not trusted, the application engine displays a security warning message and provides the option to enable the content in the database. Next, the application engine checks the database’s application options to find out whether to open a display form, load an application icon, and display a title or to use one or more of the other application options. You can set these options when you have your database open by clicking the File tab on the Backstage view, clicking Options, and clicking the Current Database category in the Access Options dialog box. After checking the application options, the application engine checks to see whether a macro group named Autoexec exists in the database. If it finds Autoexec, the application engine runs this macro. In versions 1 and 2 of Access, you’d often use the Autoexec macro to open a startup form and run startup routines. In Access 2010, however, you should use the application options to specify a display form, and then use the event procedures or embedded macros of the startup form to run your startup routines. See Chapter 26, “The Finishing Touches,” on the companion CD, for details on creating startup properties and custom ribbons.
You can code Visual Basic procedures that can create additional Database objects in the Databases collection by opening additional .accdb files. Each open Database object has a Containers collection that the DBEngine uses to store the definition (using the Documents collection) of all your tables, queries, forms, reports, macros, and modules.
Collections, Objects, Properties, and Methods 1501
You can use the TableDefs collection to examine and modify existing tables. You can also create new TableDef objects within this collection. Each TableDef object within the TableDefs collection has a Fields collection that describes all the fields in the table, and an Indexes collection (with a Fields collection for each Index object) that describes any indexes that you created on the table. Likewise, the Relations collection contains Relation objects that describe how tables are related and what integrity rules apply between tables, and each Relation object has a Fields collection that describes the fields that participate in the relation. The QueryDefs collection contains QueryDef objects that describe all the queries in your database. You can modify existing queries or create new ones. Each QueryDef object has a Parameters collection for any parameters required to run the query and a Fields collection that describes the Fields returned by the query. Finally, the Recordsets collection contains a Recordset object for each open recordset in your database, and the Fields collection of each Recordset object tells you the Fields in the recordset. To reference any object within the DAO model, you can always start with the DBEngine object. If you want to work in the current database, that Database object is always the first database in the Databases collection of the first Workspace object. For example: Dim dbMyDB As DAO.Database Set dbMyDB = DBEngine.Workspaces(0).Databases(0)
Access also provides a handy shortcut object to the current database called CurrentDb. Therefore, you can also establish a pointer to the current database as follows: Set dbMyDB = CurrentDb
Note In one of the examples at the end of this chapter, you’ll learn how to create a new TableDef object and then open a Recordset object on the new table to insert rows. You can find code examples in the Conrad Systems Contacts application that manipulate objects using both DAO and ADO.
With Access 2000, Microsoft introduced a more generic set of data engine object models to provide references not only to objects stored by the ACE but also to data objects stored in other database products such as SQL Server. These models are called the ADO architecture. With Access 97 (version 8.0), you could download the Microsoft Data Access Components from the Microsoft website to be able to use the ADO model. Access 2000 and Access XP (2002) provided direct support for ADO with built-in libraries and direct references to key objects in the model from the Access Application object. As noted earlier, Access 2003, Access 2007, and Access 2010 provide a default reference to the DAO library, not ADO. Because these models are designed to provide a common set of objects across any data engine that supports the ADO, they do not necessarily support all the features you can find in the DAO architecture that was specifically designed for the ACE. For this reason, if you are designing an application that will always run with the ACE, you are better off using the DAO model. If, however, you expect that your application might one day “upsize” to an ActiveX data engine such as SQL Server, you should consider using the ADO architecture as much as possible. If you create your Access application as an Access project (.adp) linked to SQL Server, you should use only the ADO models. Figure 24-14 shows you the two major models available in the ADO architecture. The basic ActiveX Data Objects (ADODB) model lets you open and manipulate recordsets via the Recordset object and execute action or parameter queries via the Command object. The ADO Extensions for DDL and Security (ADOX) model allows you to create, open, and manipulate tables, views (non-parameter unordered queries), and procedures (action queries, parameter queries, ordered queries, functions, triggers, or procedures) within the data engine Catalog object (the object that describes the definition of objects in your database). You can also examine and define Users and Groups collections defined in the Catalog object with ADOX.
Collections, Objects, Properties, and Methods 1503
Chapter 24
Figure 24-14 The ADODB and ADOX models provide another way to work with the data and objects in your database.
To use the ADODB model, you must instruct Visual Basic to load a reference to the Microsoft ActiveX Data Objects Library. For objects in the ADOX model, you need the Microsoft ADO Extensions for DDL and Security Library. (You should normally find only one version on your computer. If you find multiple versions in the list, select the latest one.) To verify that your project includes these references, open any module in Design view and click References on the Tools menu. If you don’t see the check boxes for these libraries selected at the top of the References dialog box, scroll down the alphabetical list until you find the library you need, select its check box, and click OK to add the reference. Access 2010 does not automatically create a reference to the ADODB library for you in any new database that you create. Note that there are some objects in common between DAO, ADODB, and ADOX. If you use multiple models in an application, you must be careful to qualify object declarations. For example, a Recordset object type in the DAO model is DAO.Recordset, whereas a Recordset in the ADODB model is ADODB.Recordset. You cannot freely interchange a DAO recordset with an ADODB recordset—they are completely different objects. The link to ADODB and ADOX is via the CurrentProject.Connection property. After you open an ADODB.Connection object, you can work with other collections, objects, and properties within the ADODB model. Likewise, by establishing an ADOX.Catalog object and setting its Connection property, you can work with any collection, object, or property within the ADOX model. For all objects within either ADODB or ADOX, you must first establish a base object (connection or catalog, respectively). For example: Dim cn As ADODB.Connection, rst As New ADODB.Recordset Set cn = CurrentProject.Connection rst.Open = "tblContacts", cn
or Dim catThisDB As New ADOX.Catalog, tbl As ADOX.Table Set catThisDB.ActiveConnection = CurrentProject.Connection Set tbl = catThisDB.Tables("tblContacts")
Note One of the extensive examples at the end of this chapter uses ADO exclusively to manipulate recordsets in the Conrad Systems Contacts sample database.
Collections, Objects, Properties, and Methods 1505
In Chapter 23, “Using Business Connectivity Services,” you were introduced to the most common way to reference objects in the Forms and Reports collections, controls on open forms and reports, and properties of controls. There are two alternative ways to reference an object within a collection. The three ways to reference an object within a collection are as follows: ●●
CollectionName![Object Name] This is the method you used in Chapter 20, “Automating a Client Application Using Macros,” and Chapter 21, “Automating a Web Application Using Macros.” For example: Forms![frmContacts].
●●
CollectionName("Object Name") This method is similar to the first method but uses a string constant (or a string variable) to supply the object name. For example: Forms("frmContacts") and Forms(strFormName).
●●
CollectionName(RelativeObjectNumber) Visual Basic numbers objects within most collections from zero (0) to CollectionName.Count minus 1. You can determine the number of open forms by referring to the Count property of the Forms collection. For example: Forms.Count. You can refer to the second open form in the Forms collection as Forms(1).
Forms and Reports are relatively simple because they are top-level collections within the application engine. As you saw in Figure 24-13, when you reference a collection or an object maintained by the DBEngine, the hierarchy of collections and objects is quite complex. If you want to find out the number of Workspace objects that exist in the Workspaces collection, for example, you need to reference the Count property of the Workspaces collection like this: DBEngine.Workspaces.Count
(You can create additional workspaces from Visual Basic code.) Using the third technique described earlier to reference an object, you can reference the default (first) Workspace object by entering the following: DBEngine.Workspaces(0)
Likewise, you can refer to the currently open database in a desktop application (.accdb) by entering the following: DBEngine.Workspaces(0).Databases(0)
When you want to refer to an object that exists in an object’s default (or only) collection (see Figures 22-13 and 22-14), you do not need to include the collection name. Therefore, because the Databases collection is the default collection for the Workspaces collection, you can also refer to the currently open database by entering the following: DBEngine.Workspaces(0)(0)
As you can see, even with this shorthand syntax, object names can become quite cumbersome if you want to refer, for example, to a particular field within an index definition for a table within the current database in the default Workspace object—or a column within an index definition for a table within the current catalog. For example, using this full syntax, you can reference the name of the first field in the tblContacts table in Contacts.accdb like this: DBEngine(0)(0).TableDefs("tblContacts").Fields(0).Name
(Whew!) If for no other reason, object variables are quite handy to help minimize name complexity. In particular, you can reduce name complexity by using an object variable to represent the current database. When you set the variable to the current database, you can call the CurrentDb function rather than use the database’s full qualifier. For example, you can declare a Database object variable, set it to the current database by using the CurrentDb function, and then use the Database object variable name as a starting point to reference the TableDefs, QueryDefs, and Recordsets collections that it contains. (See “Assigning an Object Variable—Set Statement,” on page 1509, for the syntax of the Set statement.) Likewise, if you are going to work extensively with fields in a TableDef object or columns in a Table object, you are better off establishing an object variable that points directly to the TableDef or Table object. For example, you can simplify the complex expression to reference the name of the first field in the tblContacts table in Contacts.accdb like this: Dim db As DAO.Database, tdf As DAO.TableDef Set db = CurrentDb Set tdf = db.Tabledefs![tblContacts] Debug.Print tdf.Fields(0).Name
Collections, Objects, Properties, and Methods 1507
INSIDE OUT
Should I Use CurrentDb or DBEngine.Workspaces(0). Databases(0)?
When you use DBEngine.Workspaces(0).Databases(0) (or DBEngine(0)(0)) to set a database object, Visual Basic establishes a pointer to the current database. You can have only one object variable set to the actual copy of the current database, and you must never close this copy. A safer technique is to set your database variable using the CurrentDb function. Using this technique opens a new database object that is based on the same database as the current one. You can have as many copies of the current database as you like, and you can close them when you finish using them. When you use CurrentDb to establish a pointer to your database, Visual Basic refreshes all the collections and keeps them current. If you want to ensure that the collections are current (for example, to be aware of any added or deleted tables or queries), you must refresh the collections yourself when you use DBEngine(0)(0). The one small advantage to DBEngine(0)(0) is that it is more efficient because it does not refresh all collections when you establish a pointer to it.
When to Use “!” and “.” You’ve probably noticed that a complex, fully qualified name of an object or a property in Access 2010 or Visual Basic contains exclamation points (!) and periods (.) that separate the parts of the name. Use an exclamation point preceding a name when the name refers to an object that is in the preceding object or collection of objects. A name following an exclamation point is generally the name of an object you created (such as a form or a table). Names following an exclamation point must be enclosed in brackets ([ ]) if they contain embedded blank spaces or a special character, such as an underscore (_). You must also enclose the name of an object you created in brackets if the name is also an Access or SQL reserved word. For example, most objects have a Name property—if you name a control or field “Name,” you must use brackets when you reference your object. To make this distinction clear, you might want to get into the habit of always enclosing in brackets names that follow an exclamation point, even though brackets are not required for names that don’t use blank spaces or special characters. Access automatically inserts brackets around names in property sheets, design grids, and action arguments.
Use a period preceding a name that refers to a collection name, a property name, or the name of a method that you can perform against the preceding object. (Names following a period should never contain blank spaces.) In other words, use a period when the following name is of the preceding name (as in the TableDefs collection of the Databases(0) object, the Count property of the TableDefs collection, or the MoveLast method of the DAO Recordset object). This distinction is particularly important when referencing something that has the same name as the name of a property. For example, the reference DBEngine.Workspaces(0).Databases(0).TableDefs(18).Name
refers to the name of the 19th TableDef object in the current database. In the Contacts. accdb database, if you use Debug.Print or the Immediate window to display this reference, Visual Basic returns the value tblCompanies. However, the reference DBEngine.Workspaces(0).Databases(0).TableDefs(18)![Name]
refers to the contents of a field called Name (if one exists) in the 19th TableDef object in the current database. In the Conrad Systems Contacts database, this reference returns an error because there is no Name field in the tblCompanies table.
INSIDE OUT
What About Me?
If you spend some time looking at any of the code behind forms and reports in the sample databases, you’ll notice many references such as Me.Name or Me.ProductName. Whenever you write code in a form or report module, you’ll likely need to reference some of the controls on the form or report or some of the properties of the form or report. You already know that you can reference an open form by using, for example, Forms![frmProducts]
and to reference a control on the open frmProducts form, you could use Forms![frmProducts]![ProductName]
Rather than type the collection name (Forms) and the form name (frmProducts) each time, you can use a shortcut—Me. This special keyword is a reference to the object where your code is running. Also, when Access opens a form, it loads the names of all controls you defined on the form as properties of the form—which are also properties of the Me object. (It also does the same for controls on open reports.) Therefore, you can reference the ProductName control in code behind the frmProducts form by entering Me.ProductName
This can certainly make entering code faster. Also, because Me is an object, your code executes more quickly.
Collections, Objects, Properties, and Methods 1509
INSIDE OUT
Is It Possible to Reference in Visual Basic Variables Created by Macros?
You bet! As you learned in Chapter 20, you can use SetTempVar, RemoveTempVar, and RemoveAllTempVars actions to create, modify, and inspect values that you can pass from one macro to another. If you create an application that uses both macros and Visual Basic, you can also create, modify, and inspect these variables by using the TempVars collection. Unlike most collections in Access where you must first create an object before you can reference it, you can both create and set a macro temporary variable by simply assigning a value to a name in the TempVars collection. For example, to create and set a temporary variable called MyTempVar, use the following: TempVars!MyTempVar = "Value to pass to a macro"
Temporary variables are the Variant data type, so you assign a string, a number, or a date/time value to a member of the TempVars collection. To delete a temporary variable, use the Removemethod as follows: TempVars.Remove MyTempVar
To remove all temporary variables, use the RemoveAll method as follows: TempVars.RemoveAll
However, be careful. If you reference a temporary variable that does not exist yet, you won’t get any error. If you misspell a temporary variable name, Access temporarily creates the variable and returns the value Null.
Assigning an Object Variable—Set Statement Use the Set statement to assign an object or object reference to an object variable.
Syntax Set objectvariablename = [New] objectreference
Notes As noted earlier, you can use object variables to simplify name references. Also, using an object variable is less time-consuming than using a fully qualified name. At run time, Visual Basic must always parse a qualified name to first determine the type of object and then determine which object or property you want. If you use an object variable, you have already defined the type of object and established a direct pointer to it, so Visual Basic can quickly go to that object. This is especially important if you plan to reference, for example,
many controls on a form. If you create a form variable first and then assign the variable to point to the form, referencing controls on the form via the form variable is much simpler and faster than using a fully qualified name for each control. You must first declare objectvariablename using a Dim, Private, Public, or Static statement. The object types you can declare include AccessObject, Application, ADOX.Catalog, ADOX.Column, ADODB.Command, ADOX.Command, ADODB.Connection, DAO.Container, Control, DAO.Database, DAO.Document, ADODB.Error, DAO.Error, ADODB.Field, DAO. Field, DAO.Field2, Form, ADOX.Group, DAO.Group, ADOX.Index, DAO.Index, ADOX.Key, ADODB.Parameter, DAO.Parameter, ADOX.Procedure, ADODB.Property, ADOX.Property, DAO.Property, DAO.QueryDef, ADODB.Recordset, DAO.Recordset, DAO.Recordset2, DAO. Relation, Report, ADOX.Table, DAO.TableDef, ADOX.User, DAO.User, ADOX.View, and DAO. Workspace object. You can also declare a variable as the generic Object data type and set it to any object (similar to the Variant data type). In addition, you can declare a variable as an instance of the class defined by a class module. The object type must be compatible with the object type of objectreference. You can use another object variable in an objectreference statement to qualify an object at a lower level. (See the examples that follow.) You can also use an object method to create a new object in a collection and assign that object to an object variable. For example, it’s common to use the OpenRecordset method of a QueryDef or TableDef object to create a new Recordset object. See the example in the next section, “Object Methods.” An object variable is a reference to an object, not a copy of the object. You can assign more than one object variable to point to the same object and change a property of the object. When you do that, all variables referencing the object will reflect the change as well. The one exception is that several Recordset variables can refer to the same recordset, but each can have its own Bookmark property pointing to different rows in the recordset. If you want to create a new instance of an object, include the New keyword.
Examples To create a variable reference to the current database, enter the following: Dim dbMyDB As DAO.Database Set dbMyDB = CurrentDb
To create a variable reference to the tblContacts table in the current database using the dbMyDB variable defined earlier, enter the following: Dim tblMyTable As DAO.TableDef Set tblMyTable = dbMyDB![tblContacts]
Collections, Objects, Properties, and Methods 1511
Notice that you do not need to explicitly reference the TableDefs collection of the database, as in dbMyDB.TableDefs![tblContacts] or dbMyDB.TableDefs("tblContacts"), because TableDefs is the default collection of the database. Visual Basic assumes that [tblContacts] refers to the name of an object in the default collection of the database. To create a variable reference to the Notes field in the tblContacts table using the tblMyTable variable defined earlier, enter the following: Dim fldMyField As DAO.Field Set fldMyField = tblMyTable![Notes]
Again, you do not need to include a specific reference to the Fields collection of the TableDef object, as in tblMyTable.Fields![Notes], because Fields is the default collection. To create a variable reference to the catalog for the current database, enter the following: Dim catThisDB As New ADOX.Catalog catThisDB.ActiveConnection = CurrentProject.Connection
Note that you must use the New keyword because there’s no way to open an existing catalog without first establishing a connection to it. You open a catalog by declaring it as a new object and assigning a Connection object to its ActiveConnection property. The example earlier takes advantage of the existence of the Application.CurrentProject.Connection property rather than first setting a Connection object. If you already have another Catalog object open, you can create a copy of it by using Dim catCopy As ADOX.Catalog Set catCopy = catThisDB
To create a variable reference to the tblContacts table in the current database using the catThisDB variable defined earlier, enter the following: Dim tblMyTable As ADOX.Table Set tblMyTable = catThisDB![tblContacts]
Notice that you do not need to explicitly reference the Tables collection of the database, as in catThisDB.Tables![ tblContacts] or catThisDB.Tables("tblContacts"), because Tables is the default collection of the catalog. Visual Basic assumes that [tblContacts] refers to the name of an object in the default collection of the catalog. To create a variable reference to the Notes column in the tblContacts table using the tblMyTable variable defined earlier, enter the following: Dim colMyColumn As ADOX.Column Set colMyColumn = tblMyTable![Notes]
Again, you do not need to explicitly reference the Columns collection of the Table object, as in tblMyTable.Columns![Notes], because the Columns collection is the default collection of a Table object.
Object Methods When you want to apply an action to an object in your database (such as open a query as a recordset or go to the next row in a recordset), you apply a method of either the object or an object variable that you have assigned to point to the object. In some cases, you’ll use a method to create a new object. Many methods accept parameters that you can use to further refine how the method acts on the object. For example, you can tell the DAO OpenRecordset method whether you’re opening a recordset on a local table, a dynaset (a querybased recordset), or a read-only snapshot. Visual Basic supports many different object methods—far more than there’s room to properly document in this book. Perhaps one of the most useful groups of methods is the group you can use to create a recordset and then read, update, insert, and delete rows in the recordset.
Working with DAO Recordsets To create a recordset, you must first declare a Recordset object variable. Then open the recordset using the DAO OpenRecordset method of the current database (specifying a table name, a query name, or an SQL statement to create the recordset) or the OpenRecordset method of a DAO.QueryDef, DAO.TableDef, or other DAO.Recordset object. (As you’ll learn in “Working with ADO Recordsets,” on page 1520, if you’re working in ADO, you use the Open method of a New ADODB.Recordset object.) In DAO, you can specify options to indicate whether you’re opening the recordset as a local table (which means you can use the Seek method to quickly locate rows based on a match with an available index), as a dynaset, or as a read-only snapshot. For updateable recordsets, you can also specify that you want to deny other updates, deny other reads, open a read-only recordset, open the recordset for append only, or open a read-only forward scroll recordset (which allows you to move only forward through the records and only once). The syntax to use the OpenRecordset method of a Database object is as follows: Set RecordSetObject = DatabaseObject.OpenRecordset(source, [type], [options], [lockoptions])
RecordSetObject is a variable you have declared as DAO.Recordset, and DatabaseObject is a variable you have declared as DAO.Database. Source is a string variable or literal containing the name of a table, the name of a query, or a valid SQL statement. Table 24-2 describes the settings you can supply for type, options, and lockoptions.
Collections, Objects, Properties, and Methods 1513
Setting
Description
Type (Select one)
dbOpenTable
Returns a table recordset. You can use this option only when source is a table local to the database described by the Database object. Source cannot be a linked table. You can establish a current index in a table recordset and use the Seek method to find rows using the index. If you do not specify a type, OpenRecordset returns a table if source is a local table name.
dbOpenDynaset
Returns a dynaset recordset. Source can be a local table, a linked table, a query, or an SQL statement. You can use the Find methods to search for rows in a dynaset recordset. If you do not specify a type, OpenRecordset returns a dynaset if source is a linked table, a query, or an SQL statement.
dbOpenSnapshot
Returns a read-only snapshot recordset. You won’t see any changes made by other users after you open the recordset. You can use the Find methods to search for rows in a snapshot recordset.
dbOpenForwardOnly Returns a read-only snapshot recordset that you can move forward through only once. You can use the MoveNext method to access successive rows. Options (You can select multiple options, placing a plus sign between option names to add them together)
dbAppendOnly
Returns a table or dynaset recordset that allows inserting new rows only. You can use this option only with the dbOpenTable and dbOpenDynaset types.
dbSeeChanges
Asks Access to generate a run-time error in your code if another user changes data while you are editing it in the recordset.
dbDenyWrite
Prevents other users from modifying or inserting records while your recordset is open.
dbDenyRead
Prevents other users from reading records in your open recordset.
dbInconsistent
Allows you to make changes to all fields in a multiple table recordset (based on a query or an SQL statement), including changes that would be inconsistent with any join defined in the query. For example, you could change the customer identifier field (foreign key) of an orders table so that it no longer matches the primary key in an included customers table–unless referential integrity constraints otherwise prevent you from doing so. You cannot include both dbInconsistent and dbConsistent.
dbConsistent
Allows you to only make changes in a multiple table recordset (based on a query or an SQL statement) that are consistent with the join definitions in the query. For example, you cannot change the customer identifier field (foreign key) of an orders table so that its value does not match the value of any customer row in the query. You cannot include both dbInconsistent and dbConsistent.
Asks Access to lock a row as soon as you place the row in an editable state by executing an Edit method. This is the default if you do not specify a lock option.
dbOptimistic
Asks Access to not attempt to lock a row until you try to write it to the database with an Update method. This generates a run-time error if another user has changed the row after you executed the Edit method.
For example, to declare a recordset for the tblFacilities table in the Housing Reservations (Housing.accdb) database and open the recordset as a table so that you can use its indexes, enter the following: Dim dbHousing As DAO.Database Dim rcdFacilities As DAO.RecordSet Set dbHousing = CurrentDb Set rcdFacilities = dbHousing.OpenRecordSet("tblFacilities", _ dbOpenTable)
To open the qryContactProducts query in the Conrad Systems Contacts database (Contacts. accdb) as a dynaset, enter the following: Dim dbContacts As DAO.Database Dim rcdContactProducts As DAO.RecordSet Set dbContacts = CurrentDb Set rcdContactProducts = _ dbContacts.OpenRecordSet("qryContactProducts")
(Note that opening a recordset as a dynaset is the default when the source is a query.)
Note Any table recordset or dynaset recordset based on a table is updateable. When you ask Access to open a dynaset on a table, Access internally builds a query that selects all columns from the table. A dynaset recordset based on a query will be updateable if the query is updateable. See “Limitations on Using Select Queries to Update Data,” on page 680, for details.
After you open a recordset, you can use one of the Move methods to move to a specific record. Use recordset.MoveFirst to move to the first row in the recordset. Other Move methods include MoveLast, MoveNext, and MovePrevious. If you want to move to a specific row in a dynaset recordset, use one of the Find methods. You must supply a string variable
Collections, Objects, Properties, and Methods 1515
containing the criteria for finding the records you want. The criteria string looks exactly like a WHERE clause in SQL, but without the WHERE keyword. (See Article 2, “Understanding SQL,” on the companion CD, for more details.) For example, to find the first row in the qryContactProducts query’s recordset whose SoldPrice field is greater than $200, enter the following: rcdContactProducts.FindFirst "SoldPrice > 200"
To delete a row in an updateable recordset, move to the row you want to delete and then use the Delete method. For example, to delete the first row in the qryContactProducts query’s recordset that hasn’t been invoiced yet (the Invoiced field is false), enter the following: Dim dbContacts As DAO.Database Dim rcdContactProducts As DAO.RecordSet Set dbContacts = CurrentDb Set rcdContactProducts = _ dbContacts.OpenRecordSet("qryContactProducts") rcdContactProducts.FindFirst "Invoiced = 0" ' Test the recordset NoMatch property for "not found" If Not rcdContactProducts.NoMatch Then rcdContactProducts.Delete End If
If you want to update rows in a recordset, move to the first row you want to update and then use the Edit method to lock the row and make it updateable. You can then refer to any of the fields in the row by name to change their values. Use the Update method on the recordset to save your changes before moving to another row. If you do not use the Update method before you move to a new row or close the recordset, the database discards your changes. For example, to increase by 10 percent the SoldPrice entry of the first row in the rcdContactProducts query’s recordset whose SoldPrice value is greater than $200, enter the following: Dim dbContacts As DAO.Database Dim rcdContactProducts As DAO.RecordSet Set dbContacts = CurrentDb Set rcdContactProducts = _ dbContacts.OpenRecordSet("qryContactProducts") rcdContactProducts.FindFirst "SoldPrice > 200" ' Test the recordset NoMatch property for "not found" If Not rcdContactProducts.NoMatch Then rcdContactProducts.Edit rcdContactProducts![SoldPrice] = _ rcdContactProducts![SoldPrice] * 1.1 rcdContactProducts.Update End If
To insert a new row in a recordset, use the AddNew method to start a new row. Set the values of all required fields in the row, and then use the Update method to save the new row. For example, to insert a new company in the Conrad Systems Contacts tblCompanies table, enter the following: Dim dbContacts As DAO.Database Dim rcdCompanies As DAO.RecordSet Set dbContacts = CurrentDb Set rcdCompanies = _ dbContacts.OpenRecordSet("tblCompanies") rcdCompanies.AddNew rcdCompanies![CompanyName] = "Winthrop Brewing Co." rcdCompanies![Address] = "155 Riverside Ave." rcdCompanies![City] = "Winthrop" rcdCompanies![StateOrProvince] = "WA" rcdCompanies![PostalCode] = "98862" rcdCompanies![PhoneNumber] = "(509) 555-8100" rcdCompanies.Update
Note that because all the main data tables in Contacts.accdb are linked tables, rcdCompanies is a dynaset recordset, not a table recordset. If you want to position the recordset on the newly created record, you could add an rcdCompanies.Bookmark=rcdCompanies.LastModified line at the end of the preceding code example.
Manipulating Complex Data Types Using DAO Access 2010 supports complex data types—the Attachment data type or any field defined as multi-value. A complex data type lets you store multiple values or objects in a field within a single record. Access 20107 accomplishes this by building hidden tables that contain one row per multiple value stored. You can manipulate these rows in a recordset in code, but only using DAO. To work with data in a complex data type field, you must first open a recordset on the table containing the field. You can either open the table directly or open a query that includes the table and its complex field(s). The secret to dealing with complex fields is the Value property of the field in the recordset returns a DAO.Recordset2 object. Therefore, you can set a declared DAO.Recordset2 variable to the Value property to open a recordset on the hidden table. You can manipulate this recordset exactly as you can any other DAO recordset, including using the Find, Move, Edit, AddNew, Update, and Delete methods. When the complex field is a multi-value field, the recordset returned from the Value property of the parent field contains a single field called Value. You’ll find one row per multiple value stored in the complex field. When the complex field is an Attachment data type,
Collections, Objects, Properties, and Methods 1517
the recordset returned from the Value property of the parent field contains three fields— FileData, FileName, and FileType. The FileData field in an attachment complex recordset supports one method, LoadFromFile, that lets you insert the complex Object Linking and Embedding (OLE) data into the record by supplying a file location and name. The tblContacts table in the Contacts sample database contains both a multi-value field (ContactType) and an attachment field (Photo). In the modExamples module in the Contacts.accdb database, you can find the following code, which displays in the Immediate window the values from both fields for all contact records: Public Sub ListContactComplex() ' An example of listing all the complex values in the Contacts table Dim db As DAO.Database, rst As DAO.Recordset, rstComplex As DAO.Recordset2 Dim fld As DAO.Field2 ' Point to this database Set db = CurrentDb ' Open a recordset on tblContacts Set rst = db.OpenRecordset("SELECT * FROM tblContacts") ' Loop through all the records Do Until rst.EOF ' Dump out the ID and name Debug.Print rst!ContactID, rst!LastName, rst!FirstName ' Get the contact type complex field Set rstComplex = rst!ContactType.Value ' Loop through them all Do Until rstComplex.EOF ' Dump out each value Debug.Print " ", "Contact Type: ", rstComplex!Value ' Get the next rstComplex.MoveNext Loop ' Get the Photo Attachment recordset Set rstComplex = rst!Photo.Value ' Loop though them all Do Until rstComplex.EOF ' Dump out the data Debug.Print " ", "Photo FileName: ", rstComplex!FileName, _ " File Type: ", rstComplex!FileType ' Get the next rstComplex.MoveNext Loop ' Get the next contact rst.MoveNext Loop ' Close out rst.Close Set rst = Nothing Set rstComplex = Nothing Set db = Nothing End Sub
If you want to find the record for John Viescas and add the Trainer value to the ContactType field, use the following code: Public Sub AddContactTypeViescas() Dim db As DAO.Database, rst As DAO.Recordset, rstComplex As DAO.Recordset2 ' Set a pointer to the current database Set db = CurrentDb ' Open the contacts table Set rst = db.OpenRecordset("tblContacts", dbOpenDynaset) ' Find the record for Viescas rst.FindFirst "LastName = 'Viescas'" ' Make sure we found it If Not rst.NoMatch Then ' Put parent record in Edit rst.Edit ' Get the ContactType recordset Set rstComplex = rst!ContactType.Value ' Add a new row rstComplex.AddNew ' Insert the new value rstComplex.Value = "Trainer" ' Save the new value rstComplex.Update ' Now save the parent rst.Update End If ' Close out rst.Close Set rst = Nothing Set rstComplex = Nothing Set db = Nothing
To find the contact record for John Viescas, check for the Trainer value in the ContactType field, and delete it if it exists, use the following code: Public Sub DeleteTrainerFromViescas() Dim db As DAO.Database, rst As DAO.Recordset, rstComplex As DAO.Recordset2 ' Set a pointer to the current database Set db = CurrentDb ' Open the contacts table Set rst = db.OpenRecordset("tblContacts", dbOpenDynaset) ' Find the record for Viescas rst.FindFirst "LastName = 'Viescas'" ' Make sure we found it If Not rst.NoMatch Then ' Get the ContactType recordset Set rstComplex = rst!ContactType.Value ' See if Trainer exists rstComplex.FindFirst "Value = 'Trainer '" ' If it exists,
Collections, Objects, Properties, and Methods 1519
If Not rstComplex.NoMatch Then ' Delete it rstComplex.Delete End If End If ' Close out rst.Close Set rst = Nothing Set rstComplex = Nothing Set db = Nothing
To check whether the Photo field for contact Jeff Conrad contains a file named JeffConrad. docx and add it if it does not, use the following code: Public Sub AddDocumentToConradPhotoField() Dim db As DAO.Database, rst As DAO.Recordset, rstComplex As DAO.Recordset2 ' Set a pointer to the current database Set db = CurrentDb ' Open the contacts table Set rst = db.OpenRecordset("tblContacts", dbOpenDynaset) ' Find the record for Conrad rst.FindFirst "LastName = 'Conrad'" ' Make sure we found it If Not rst.NoMatch Then ' Get the Photo recordset Set rstComplex = rst!Photo.Value ' See if the JeffConrad.docx file exists rstComplex.FindFirst "FileName = 'JeffConrad.docx'" ' If it does not exist, If rstComplex.NoMatch Then ' Put parent record in Edit rst.Edit ' Start a new attachment record rstComplex.Addnew ' Load the file rstComplex!FileData.LoadFromFile _ "C:\Microsoft Press\Access 2010 Inside Out\Documents\Jeff Conrad.docx" ' Save the new row rstComplex.Update ' Save the parent row rst.Update End If End If ' Close out rst.Close Set rst = Nothing Set rstComplex = Nothing Set db = Nothing
Recordsets in ADO offer many of the same capabilities and options as recordsets in DAO, but the terminology is somewhat different. Because you will most often use ADO with data stored in a server database such as SQL Server, the options for an ADO recordset are geared toward server-based data. For example, ADO uses the term cursor to refer to the set of rows returned by the server. Fundamentally, a cursor is a pointer to each row you need to work with in code. Depending on the options you choose (and the options supported by the particular database server), a cursor might also be read-only, updateable, or forward-only. A cursor might also be able to reflect changes made by other users of the database (a keyset or dynamic cursor), or it might present only a snapshot of the data (a static cursor). To open an ADO recordset, you must use the Open method of a new ADO Recordset object. The syntax to use the Open method of a Recordset object is as follows: RecordSetObject.Open [source], [connection], [cursortype], [locktype], [options]
RecordSetObject is a variable you have declared as a New ADO.Recordset. Source is a Command object, a string variable, or string literal containing the name of a table, the name of a view (the SQL Server term for a query), the name of a stored procedure, the name of a function that returns a table, or a valid SQL statement. A stored procedure might be a parameter query or a query that specifies the sorting of rows from a table or view. A function might also accept parameters. If you supply a Command object as the source, you do not need to supply a connection (you define the connection in the Command object). Otherwise, connection must be the name of a Connection object that points to the target database. Table 24-3 describes the settings you can supply for cursortype, lockoptions, and options. Table 24-3 RecordSetObject.Open Parameter Settings
Setting
Description
CursorType (Select one)
adOpenForwardOnly
Returns a read-only snapshot cursor (recordset) that you can move forward through only once. You can use the MoveNext method to access successive rows. If you do not supply a CursorType setting, adOpenForwardOnly is the default.
adOpenKeyset
Returns a Keyset cursor. This is roughly analogous to a DAO dynaset. If you are using ADO to open a recordset against a source in an Access .accdb file, you should use this option to obtain a recordset that behaves most like a DAO recordset. In this type of cursor, you will see changes to rows made by other users, but you will not see new rows added by other users after you have opened the cursor.
Collections, Objects, Properties, and Methods 1521
Setting
Description
adOpenDynamic
Returns a dynamic cursor. This type of cursor lets you see not only changes made by other users, but also added rows. Note, however, that certain key properties you might depend on in a DAO recordset such as RecordCount might not exist or might always be zero.
adOpenStatic
Returns a read-only snapshot cursor. You won’t be able to see changes made by other users after you’ve opened the cursor.
LockType (Select one)
adLockReadOnly
Provides no locks. The cursor is read-only. If you do not provide a lock setting, this is the default.
adLockPessimistic
Asks the target database to lock a row as soon as you place the row in an editable state by executing an Edit method.
adLockOptimistic
Asks the target database not to attempt to lock a row until you try to write it to the database with an Update method. This generates a run-time error in your code if another user has changed the row after you executed the Edit method. You should use this option when accessing rows in an Access .accdb file.
Options (You can combine one Cmd setting with one Async setting with a plus sign)
adCmdText
Indicates that source is an SQL statement.
adCmdTable
Indicates that source is a table name (or a query name in a desktop database). In DAO, this is analogous to opening a dynaset recordset on a table.
adCmdTableDirect
Indicates that source is a table name. This is analogous to a DAO dbOpenTable.
adCmdStoredProc
Indicates that source is a stored procedure. In DAO, this is analogous to opening a dynaset on a sorted query.
adAsyncFetch
After fetching the initial rows to populate the cursor, additional fetching occurs in the background. If you try to access a row that has not been fetched yet, your code will wait until the row is fetched.
adAsyncFetchNonBlocking After fetching the initial rows to populate the cursor, additional fetching occurs in the background. If you try to access a row that has not been fetched yet, your code will receive an end-of-file indication.
For example, to declare a recordset for the tblFacilities table in the Housing Reservation database (Housing.accdb) and open the recordset as a table so you can use its indexes, enter the following: Dim cnThisConnect As ADODB.Connection Dim rcdFacilities As New ADODB.RecordSet Dim rcdBooks As New ADODB.Recordset Set cnThisConnect = CurrentProject.Connection rcdFacilities.Index = "PrimaryKey" rcdBooks.Open "tblFacilities", cnThisConnect, adOpenKeyset, _ adLockOptimistic, adCmdTableDirect
Note that you must establish the index you want to use before you open the recordset. (If you want to try this in the Housing Reservation database, Housing.accdb, you’ll need to add a reference to the Microsoft ActiveX Data Objects Library.) To open the qryContactProducts query in the Conrad Systems Contacts database as a keyset, enter the following: Dim cnThisConnect As ADODB.Connection Dim rcdContactProducts As New ADODB.RecordSet Set cnThisConnect = CurrentProject.Connection rcdContactProducts.Open "qryContactProducts", _ cnThisConnect, adOpenKeyset, adLockOptimistic, _ adCmdTable
After you open a recordset, you can use one of the Move methods to move to a specific record. Use recordset.MoveFirst to move to the first row in the recordset. Other Move methods include MoveLast, MoveNext, and MovePrevious. If you want to search for a specific row in the recordset, use the Find method or set the recordset’s Filter property. Unlike the Find methods in DAO, the Find method in ADO is limited to a single simple test on a column in the form " ". Note that to search for a Null value, you must say: "[SomeColumn] = Null", not "[SomeColumn] Is Null" as you would in DAO. Also, can be only , =, , =, or LIKE. Note that if you want to use the LIKE keyword, you can use either the ANSI wildcards "%" and "_" or the Access ACE/JET wildcards "*" and "?", but the wildcard can appear only at the end of the string. If you want to search for rows using a more complex filter, you must assign a string variable or an expression containing the criteria for finding the records you want to the Filter property of the recordset. This limits the rows in the recordset to only those that meet the filter criteria. The criteria string must be made of the simple comparisons that you can use with Find, but you can include multiple comparisons with the AND or OR Boolean operator.
Collections, Objects, Properties, and Methods 1523
For example, to find the first row in the qryContactProducts query’s recordset whose SoldPrice field is greater than $200, enter the following: rcdContactProducts.MoveFirst rcdContactProducts.Find "SoldPrice > 200" ' EOF property will be true if nothing found If Not rcdContactProducts.EOF Then ' Found a record!
To find all rows in qryContactProducts where the product was sold after November 1, 2010, and SoldPrice is greater than $200, enter the following: rcdContactProducts.Filter = & "DateSold > #11/1/2010# AND SoldPrice > 200" ' EOF property will be true if filter produces no rows If Not rcdODetails.EOF Then ' Found some rows!
To delete a row in a keyset, simply move to the row you want to delete and then use the Delete method. For example, to delete the first row in the qryContactProducts query’s recordset that hasn’t been invoiced yet (the Invoiced field is false), enter the following: Dim cnThisConnect As ADODB.Connection Dim rcdContactProducts As New ADODB.RecordSet Set cnThisConnect = CurrentProject.Connection rcdContactProducts.Open "qryContactProducts", _ cnThisConnect, adOpenKeyset, adLockOptimistic, _ adCmdTable rcdContactProducts.MoveFirst rcdContactProducts.Find "Invoiced = 0" ' Test the recordset EOF property for "not found" If Not rcdContactProducts.EOF Then rcdContactProducts.Delete End If
Note that in this example, if tblContactRelatedProducts includes related records, Access prevents the deletion. If you want to update rows in a recordset, move to the first row you want to update. You can refer to any of the updateable fields in the row by name to change their values. You can use the Update method on the recordset to explicitly save your changes before moving to another row. ADO automatically saves your changed row when you move to a new row. If you need to discard an update, you must use the CancelUpdate method of the recordset object.
For example, to increase by 10 percent the SoldPrice entry of the first row in the rcdContactProducts query’s recordset whose SoldPrice value is greater than $200, enter the following: Public Sub UpdateFirstSoldPrice10Percent() Dim cnThisConnect As ADODB.Connection Dim rcdContactProducts As New ADODB.RecordSet Set cnThisConnect = CurrentProject.Connection rcdContactProducts.Open "qryContactProducts", _ cnThisConnect, adOpenKeyset, adLockOptimistic, _ adCmdTable rcdContactProducts.Filter = "SoldPrice > 200" ' Test the recordset EOF property for "not found" If Not rcdContactProducts.EOF Then rcdContactProducts![SoldPrice] = _ rcdContactProducts![SoldPrice] * 1.1 rcdContactProducts.Update rcdContactProducts.MoveNext End If
To insert a new row in a recordset, use the AddNew method to start a new row. Set the values of all required fields in the row and then use the Update method to save the new row. For example, to insert a new company in the Conrad Systems Contacts tblCompanies table, enter the following: Dim cnThisConnect As ADODB.Connection Dim rcdCompanies As New ADODB.RecordSet Set cnThisConnect = CurrentProject.Connection rcdCompanies.Open "tblCompanies", cnThisConnect, _ adOpenKeyset, adLockOptimistic, adCmdTable rcdCompanies.AddNew rcdCompanies![CompanyName] = "Winthrop Brewing Co." rcdCompanies![Address] = "155 Riverside Ave." rcdCompanies![City] = "Winthrop" rcdCompanies![StateOrProvince] = "WA" rcdCompanies![PostalCode] = "98862" rcdCompanies![PhoneNumber] = "(509) 555-8100" rcdCompanies.Update
Other Uses for Object Methods As you’ll learn later in this chapter in more detail, you must use a method of the DoCmd object to execute the equivalent of most macro actions within Visual Basic. You must use the RunCommand method of either the Application or DoCmd object to execute commands you can find on any of the Access menus.
Functions and Subroutines 1525
You can also define a public function or subroutine (see the next section) within the module associated with a Form or Report object and execute that procedure as a method of the form or report. If your public procedure is a function, you must assign the result of the execution of the method to a variable of the appropriate type. If the public procedure is a subroutine, you can execute the form or report object method as a Visual Basic statement. For more information about object methods, find the topic about the object of interest in Help, and then click the Methods hyperlink.
Functions and Subroutines You can create two types of procedures in Visual Basic—functions and subroutines—which are also known as Function procedures and Sub procedures. (As you’ll learn in “Understanding Class Modules,” on page 1529, class modules also support a special type of function, Property Get, and special subroutines, Property Let and Property Set, that let you manage properties of the class.) Each type of procedure can accept parameters—data variables that you pass to the procedure that can determine how the procedure operates. Functions can return a single data value, but subroutines cannot. In addition, you can execute a public function from anywhere in Access, including from expressions in queries and from macros. You can execute a subroutine only from a function, from another subroutine, or as an event procedure in a form or a report.
Function Statement Use a Function statement to declare a new function, the parameters it accepts, the variable type it returns, and the code that performs the function procedure.
Syntax [Public | Private | Friend] [Static] Function functionname ([]) [As datatype] [] [functionname = ] [Exit Function] [] [functionname = ] End Function
where is {[Optional][ByVal | ByRef][ParamArray] argumentname[()] [As datatype][= default]},...
Use the Public keyword to make this function available to all other procedures in all modules. Use the Private keyword to make this function available only to other procedures in the same module. When you declare a function as private in a module, you cannot call that function from a query or a macro or from a function in another module. Use the Friend keyword in a class module to declare a function that is public to all other code in your application but is not visible to outside code that activates your project via automation. Include the Static keyword to preserve the value of all variables declared within the procedure, whether explicitly or implicitly, so long as the module containing the procedure is open. This is the same as using the Static statement (discussed earlier in this chapter) to explicitly declare all variables created in this function. You can use a type declaration character at the end of the functionname entry or use the As datatype clause to declare the data type returned by this function. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. If you do not declare a data type, Visual Basic assumes that the function returns a variant result. You can set the return value in code by assigning an expression of a compatible data type to the function name. You should declare the data type of any arguments in the function’s parameter list. Note that the names of the variables passed by the calling procedure can be different from the names of the variables known by this procedure. If you use the ByVal keyword to declare an argument, Visual Basic passes a copy of the argument to your function. Any change you make to a ByVal argument does not change the original variable in the calling procedure. If you use the ByRef keyword, Visual Basic passes the actual memory address of the variable, allowing the procedure to change the variable’s value in the calling procedure. (If the argument passed by the calling procedure is an expression, Visual Basic treats it as if you had declared it by using ByVal.) Visual Basic always passes arrays by reference (using ByRef). Use the Optional keyword to declare an argument that isn’t required. All optional arguments must be the Variant data type. If you declare an optional argument, all arguments that follow in the argument list must also be declared as optional. You can specify a default value only for optional parameters. Use the IsMissing built-in function to test for the absence of optional parameters. You can also use the ParamArray argument to declare an array of optional elements of the Variant data type. When you call the function, you can then pass it an arbitrary number of arguments. The ParamArray argument must be the last argument in the argument list. Use the Exit Function statement anywhere in your function to clear any error conditions and exit your function normally, returning to the calling procedure. If Visual Basic runs your
Functions and Subroutines 1527
code until it encounters the End Function statement, control is passed to the calling procedure, but any errors are not cleared. If this function causes an error and terminates with the End Function statement, Visual Basic passes the error to the calling procedure. See “Trapping Errors,” on page 1551, for details.
Example To create a function named MyFunction that accepts an integer argument and a string argument and returns a double value, enter the following: Function MyFunction (intArg1 As Integer, strArg2 As _ String) As Double If strArg2 = "Square" Then MyFunction = intArg1 * intArg1 Else MyFunction = Sqr(intArg1) End If End Function
Sub Statement Use a Sub statement to declare a new subroutine, the parameters it accepts, and the code in the subroutine.
Syntax [Public | Private | Friend] [Static] Sub subroutinename ([]) [ ] [Exit Sub] [ ] End Sub
where is {[Optional][ByVal | ByRef][ParamArray] argumentname[()] [As datatype][ = default]},...
Notes Use the Public keyword to make this subroutine available to all other procedures in all modules. Use the Private keyword to make this procedure available only to other procedures in the same module. When you declare a sub as private in a module, you cannot call that sub from a function or sub in another module. Use the Friend keyword in a class module to declare a sub that is public to all other code in your application but is not visible to outside code that activates your project via automation.
Include the Static keyword to preserve the value of all variables declared within the procedure, whether explicitly or implicitly, so long as the module containing the procedure is open. This is the same as using the Static statement (discussed earlier in this chapter) to explicitly declare all variables created in this subroutine. You should declare the data type of all arguments that the subroutine accepts in its argument list. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. Note that the names of the variables passed by the calling procedure can be different from the names of the variables as known by this procedure. If you use the ByVal keyword to declare an argument, Visual Basic passes a copy of the argument to your subroutine. Any change you make to a ByVal argument does not change the original variable in the calling procedure. If you use the ByRef keyword, Visual Basic passes the actual memory address of the variable, allowing the procedure to change the variable’s value in the calling procedure. (If the argument passed by the calling procedure is an expression, Visual Basic treats it as if you had declared it by using ByVal.) Visual Basic always passes arrays by reference (using ByRef). Use the Optional keyword to declare an argument that isn’t required. All optional arguments must be the Variant data type. If you declare an optional argument, all arguments that follow in the argument list must also be declared optional. You can specify a default value only for optional parameters. Use the IsMissing built-in function to test for the absence of optional parameters. You can also use the ParamArray argument to declare an array of optional elements of the Variant data type. When you call the subroutine, you can then pass it an arbitrary number of arguments. The ParamArray argument must be the last argument in the argument list. Use the Exit Sub statement anywhere in your subroutine to clear any error conditions and exit your subroutine normally, returning to the calling procedure. If Visual Basic runs your code until it encounters the End Sub statement, control is passed to the calling procedure but any errors are not cleared. If this subroutine causes an error and terminates with the End Sub statement, Visual Basic passes the error to the calling procedure. See “Trapping Errors,” on page 1551, for details.
Example To create a subroutine named MySub that accepts two string arguments but can modify only the second argument, enter the following: Sub MySub (ByVal strArg1 As String, ByRef strArg2 _ As String) End Sub
Understanding Class Modules 1529
Whenever you create event procedures behind a form or report, you’re creating a class module. A class module is the specification for a user-defined object in your database, and the code you write in the module defines the methods and properties of the object. Of course, forms and reports already have dozens of methods and properties already defined by Access, but you can create extended properties and methods when you write code in the class module attached to a form or report. You can also create a class module as an independent object by clicking the Class Module button in the Macros & Code group on the Create tab or by clicking Class Module on the Insert menu in the VBE. In the Conrad Systems Contacts sample database (Contacts.accdb), you can find a class module called ComDlg that provides a simple way to call the Open File dialog box in Windows from your Visual Basic code. As previously discussed, you define a method in a class module by declaring a procedure (either a function or a sub) public. When you create an active instance of the object defined by the class module, either by opening it or by setting it to an object variable, you can execute the public functions or subs you have defined by referencing the function or sub name as a method of the object. For example, when the frmContacts form is open, you can execute the cmdCancel_Click sub by referencing it as a method of the form’s class. (The cmdCancel_Click sub is public in all forms in the sample database so that the Exit button on the main switchboard can use it to command the form to clear edits and close itself.) The name of any form’s class is in the form Form_formname, so you execute this method in your code like this: Form_frmContacts.cmdCancel_Click
When you create a class module that you see in the Modules list in the Navigation pane, you can create a special sub that Visual Basic runs whenever code in your application creates a new instance of the object defined by your class. For example, you can create a private Class_Initialize sub to run code that sets up your object whenever other code in your application creates a new instance of your class object. You might use this event to open recordsets or initialize variables required by the object. You can also create a private Class_ Terminate sub to run code that cleans up any variables or objects (perhaps closing open recordsets) when your object goes out of scope or the code that created an instance of your object sets it to Nothing. (Your object goes out of scope if a procedure activates your class by setting it to a nonstatic local object variable and then the procedure exits.)
Although you can define properties of a class by declaring public variables in the Declarations section of the class module, you can also define specific procedures to handle fetching and setting properties. When you do this, you can write special processing code that runs whenever a caller fetches or sets one of the properties defined by these procedures. To create special property processing procedures in a class module, you need to write Property Get, Property Let, and Property Set procedures as described in the following sections.
Property Get Use a Property Get procedure to return a property value for the object defined by your class module. When other code in your application attempts to fetch the value of this property of your object, Visual Basic executes your Property Get procedure to return the value. Your code can return a data value or an object.
where is {[Optional][ByVal | ByRef][ParamArray] argumentname[()] [As datatype][= default]},...
Notes Use the Public keyword to make this property available to all other procedures in all modules. Use the Private keyword to make this property available only to other procedures in the same module. When you declare a property as private in a class module, you cannot reference that property from another module. Use the Friend keyword to declare a property that is public to all other code in your application but is not visible to outside code that activates your project via automation. Include the Static keyword to preserve the value of all variables declared within the property procedure, whether explicitly or implicitly, so long as the module containing the procedure is open. This is the same as using the Static statement (discussed earlier in this chapter) to explicitly declare all variables created in this property procedure.
Understanding Class Modules 1531
You can use a type declaration character at the end of the propertyname entry or use the As datatype clause to declare the data type returned by this property. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. If you do not declare a data type, Visual Basic assumes that the property returns a variant result. The data type of the returned value must match the data type of the propvalue variable you declare in any companion Property Let or Property Set procedure. You can set the return value in code by assigning an expression of a compatible data type to the property name. You should declare the data type of all arguments in the property procedure’s parameter list. Note that the names of the variables passed by the calling procedure can be different from the names of the variables known by this procedure. If you use the ByVal keyword to declare an argument, Visual Basic passes a copy of the argument to your procedure. Any change you make to a ByVal argument does not change the original variable in the calling procedure. If you use the ByRef keyword, Visual Basic passes the actual memory address of the variable, allowing the procedure to change the variable’s value in the calling procedure. (If the argument passed by the calling procedure is an expression, Visual Basic treats it as if you had declared it by using ByVal.) Visual Basic always passes arrays by reference (using ByRef). Use the Optional keyword to declare an argument that isn’t required. All optional arguments must be the Variant data type. If you declare an optional argument, all arguments that follow in the argument list must also be declared as optional. You can specify a default value only for optional parameters. Use the IsMissing built-in function to test for the absence of optional parameters. You can also use the ParamArray argument to declare an array of optional elements of the Variant data type. When you attempt to access this property in an object set to the class, you can then pass it an arbitrary number of arguments. The ParamArray argument must be the last argument in the argument list. Use the Exit Property statement anywhere in your property procedure to clear any error conditions and exit your procedure normally, returning to the calling procedure. If Visual Basic runs your code until it encounters the End Property statement, control is passed to the calling procedure but any errors are not cleared. If this procedure causes an error and terminates with the End Property statement, Visual Basic passes the error to the calling procedure. See “Trapping Errors,” on page 1551, for details.
To declare a Filename property as a string and return it from a variable defined in the Declarations section of your class module, enter the following: Option Explicit Dim strFileName As String Property Get Filename() As String ' Return the saved file name as a property Filename = strFilename End Property
You can see an example of Property Get in the ComDlg class where we added similar code. To establish a new instance of the object defined by the ComDlg class module and then fetch its Filename property, enter the following in a function or sub: Dim clsDialog As New ComDlg, strFile As String With clsDialog ' Set the title of the dialog box .DialogTitle = "Locate Conrad Systems Contacts Data File" ' Set the default file name .FileName = "ContactsData.accdb" ' .. and start directory .Directory = CurrentProject.Path ' .. and file extension .Extension = "accdb" ' .. but show all accdb files just in case .Filter = "Conrad Systems File (*.accdb)|*.accdb" ' Default directory is where this file is located .Directory = CurrentProject.Path ' Tell the common dialog that the file and path must exist .ExistFlags = FileMustExist + PathMustExist ' If the ShowOpen method returns True If .ShowOpen Then ' Then fetch the Filename property strFile = .FileName Else Err.Raise 3999 End If End With
Property Let Use a Property Let procedure to define code that executes when the calling code attempts to assign a value to a data property of the object defined by your class module. You cannot define both a Property Let and a Property Set procedure for the same property.
[Static] Property Let propertyname [As datatype]) ] ]
where is {[Optional][ByVal | ByRef][ParamArray] argumentname[()] [As datatype][ = default]},...
Notes Use the Public keyword to make this property available to all other procedures in all modules. Use the Private keyword to make this property available only to other procedures in the same module. When you declare a property as private in a class module, you cannot reference the property from another module. Use the Friend keyword to declare a property that is public to all other code in your application but is not visible to outside code that activates your project via automation. Include the Static keyword to preserve the value of all variables declared within the property procedure, whether explicitly or implicitly, so long as the module containing the procedure is open. This is the same as using the Static statement (discussed earlier in this chapter) to explicitly declare all variables created in this property procedure. You should declare the data type of all arguments in the property procedure’s parameter list. Valid datatype entries are Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, or one of the object types described earlier in this chapter. Note that the names of the variables passed by the calling procedure can be different from the names of the variables as known by this procedure. Also, the names and data types of the arguments must exactly match the arguments declared for the companion Property Get procedure. If you use the ByVal keyword to declare an argument, Visual Basic passes a copy of the argument to your property procedure. Any change you make to a ByVal argument does not change the original variable in the calling procedure. If you use the ByRef keyword, Visual Basic passes the actual memory address of the variable, allowing the procedure to change the variable’s value in the calling procedure. (If the argument passed by the calling procedure is an expression, Visual Basic treats it as if you had declared it by using ByVal.) Visual Basic always passes arrays by reference (using ByRef).
Use the Optional keyword to declare an argument that isn’t required. All optional arguments must be the Variant data type. If you declare an optional argument, all arguments that follow in the argument list must also be declared as optional. You can specify a default value only for optional parameters. Use the IsMissing built-in function to test for the absence of optional parameters. You can also use the ParamArray argument to declare an array of optional elements of the Variant data type. When you attempt to assign a value to this property in an object set to the class, you can then pass it an arbitrary number of arguments. The ParamArray argument must be the last argument in the argument list. You must always declare at least one parameter, propvalue, to be the variable that contains the value that the calling code wants to assign to your property. This is the value or expression that appears on the right side of the assignment statement executed in the calling code. If you declare a data type, it must match the data type declared by the companion Property Get procedure. Also, when you declare a data type, the caller receives a data type mismatch error if the assignment statement attempts to pass an incorrect data type. You cannot modify this value, but you can evaluate it and save it as a value to be returned later by your Property Get procedure. Use the Exit Property statement anywhere in your property procedure to clear any error conditions and exit your procedure normally, returning to the calling procedure. If Visual Basic runs your code until it encounters the End Property statement, control is passed to the calling procedure, but errors are not cleared. If this procedure causes an error and terminates with the End Property statement, Visual Basic passes the error to the calling procedure. See “Trapping Errors,” on page 1551, for details.
Examples To declare a FileName property, accept a value from a caller, and save the value in a variable defined in the Declarations section of your class module, enter the following: Option Explicit Dim strFileName As String Property Let FileName(strFile) If Len(strFile) = "A" And strFirst = "G" And strFirst = "O" And strFirst | =}
Notes If the matches a in a Case clause, Visual Basic executes the statements that follow that clause. If the is a single expression, the must equal the for the statements following that clause to execute. If the contains a To keyword, the first expression must be less than the second expression (either in numeric value if the expressions are numbers or in collating sequence if the expressions are strings) and the must be between the first expression and the second expression. If the contains the Is keyword, the evaluation of expression must be true. If more than one Case clause matches the , Visual Basic executes only the set of statements following the first Case clause that matches. You can include a block of statements following a Case Else clause that Visual Basic executes if none of the previous Case clauses matches the . You can nest another Select Case statement within the statements following a Case clause.
Controlling the Flow of Statements 1547
To assign an integer value to a variable, depending on whether a string begins with a letter from A through F, from G through N, or from O through Z, enter the following: Dim strMyString As String, intVal As Integer Select Case UCase$(Mid$(strMyString, 1, 1)) Case "A" To "F" intVal = 1 Case "G" To "N" intVal = 2 Case "O" To "Z" intVal = 3 Case Else intVal = 0 End Select
Stop Statement Use a Stop statement to suspend execution of your procedure.
Syntax Stop
Notes A Stop statement has the same effect as setting a breakpoint on a statement. You can use the Visual Basic debugging tools, such as the Step Into and the Step Over buttons and the Debug window, to evaluate the status of your procedure after Visual Basic halts on a Stop statement. You should not use the Stop statement in a production application.
While…Wend Statement Use a While…Wend statement to continuously execute a block of statements so long as a condition is true.
A While…Wend statement is similar to a Do…Loop statement with a While clause, except that you can use an Exit Do statement to exit from a Do loop. Visual Basic provides no similar Exit clause for a While loop. The is an expression that Visual Basic can evaluate to True (nonzero) or False (0 or Null). Execution continues so long as the is true.
Example To read all the rows in the tblCompanies table until you reach the end of the recordset, enter the following in a function or sub: Dim dbContacts As DAO.Database Dim rcdCompanies As DAO.RecordSet Set dbContacts = CurrentDb Set rcdCompanies = dbContacts.OpenRecordSet("tblCompanies") While Not rcdCompanies.EOF rcdCompanies.MoveNext Wend
With…End Statement Use a With statement to simplify references to complex objects in code. You can establish a base object using a With statement and then use a shorthand notation to refer to objects, collections, properties, or methods on that object until you terminate the With statement. When you plan to reference an object many times within a block of code, using With also improves execution speed.
Syntax With [] End With
Example To use shorthand notation on a recordset object to add a new row to a table, enter the following: Dim rcd As DAO.Recordset, db As DAO.Database Set db = CurrentDb Set rcd = db.OpenRecordset("MyTable", _ dbOpenDynaset, dbAppendOnly) With rcd
Running Macro Actions and Menu Commands 1549
' Start a new record .Addnew ' Set the field values ![FieldOne] = "1" ![FieldTwo] = "John" ![FieldThree] = "Viescas" .Update .Close End With
To write the same code without the With, you would have to say: Dim rcd As DAO.Recordset, db As DAO.Database Set db = CurrentDb Set rcd = db.OpenRecordset("MyTable", _ dbOpenDynaset, dbAppendOnly) ' Start a new record rcd.Addnew ' Set the field values rcd![FieldOne] = "1" rcd![FieldTwo] = "John" rcd![FieldThree] = "Viescas" rcd.Update rcd.Close
Running Macro Actions and Menu Commands From within Visual Basic, you can execute most of the macro actions that Access provides and any of the built-in menu commands. Only a few of the macro actions have direct Visual Basic equivalents. To execute a macro action or menu command, use the methods of the DoCmd object, described next.
DoCmd Object Use the methods of the DoCmd object to execute a macro action or menu command from within a Visual Basic procedure.
Syntax DoCmd.actionmethod [actionargument],...
Notes Some of the macro actions you’ll commonly execute from Visual Basic include ApplyFilter, Close, FindNext and FindRecord (for searching the recordset of the current form and immediately displaying the result), Hourglass, Maximize, Minimize, MoveSize, OpenForm,
OpenQuery (to run a query that you don’t need to modify), OpenReport, and RunCommand. Although you can run the Echo, GoToControl, GoToPage, RepaintObject, and Requery actions from Visual Basic using a method of the DoCmd object, it’s more efficient to use the Echo, SetFocus, GoToPage, Repaint, and Requery methods of the object to which the method applies.
Examples To open a form named frmCompanies in Form view for data entry, enter the following: DoCmd.OpenForm "frmCompanies", acNormal, , , acAdd
To close a form named frmContacts, enter the following: DoCmd.Close acForm, "frmContacts"
Executing an Access Command To execute an Access command (one of the commands you can find on the ribbon), use the RunCommand method of either the DoCmd or Application object and supply a single action argument that is the numeric code for the command.
Syntax [DoCmd.]RunCommand [actionargument],...
Notes You can also use one of many built-in constants for actionargument to reference the command you want. When you use RunCommand, you can leave out the DoCmd or Application object if you want.
Examples To execute the Save command from the Records group on the Home tab, enter the following: RunCommand acCmdSaveRecord
To switch an open form to PivotChart view (execute the PivotChart View command in the Views group on the Home tab), enter the following: RunCommand acCmdPivotChartView
Trapping Errors 1551
To open the Find window while the focus is on a form (execute the Find command in the Find group on the Home tab), enter the following: RunCommand acCmdFind
Note Visual Basic provides built-in constants for many of the macro action and RunCommand parameters. For more information, search for “Microsoft Access Constants” and “RunCommand Method” in Help.
Actions with Visual Basic Equivalents A few macro actions cannot be executed from a Visual Basic procedure. All but one of these actions, however, have equivalent statements in Visual Basic, as shown in Table 24-4. Table 24-4 Visual Basic Equivalents for Macro Actions
Macro Action
Visual Basic Equivalent
AddMenu
No equivalent
MessageBox
MsgBox statement or function
RunApplication*
Shell function
RunCode
Call subroutine
SendKeys
SendKeys statement
SetValue
Variable assignment (=)
StopAllMacros
Stop or End statement
StopMacro
Exit Sub or Exit Function statement
* Database must be Trusted to execute this action.
Trapping Errors One of the most powerful features of Visual Basic is its ability to trap all errors, analyze them, and take corrective action. In a well-designed production application, the user should never see any of the default error messages or encounter a code halt when an error occurs. Also, setting an error trap is often the best way to test certain conditions. For example, to find out if a query exists, your code can set an error trap and then attempt to reference the query object. In an application with hundreds of queries, using an error trap can also be faster than looping through all QueryDef objects. To enable error trapping, you use an On Error statement.
Use an On Error statement to enable error trapping, establish the procedure to handle error trapping (the error handler), skip past any errors, or turn off error trapping.
Syntax On Error {GoTo lineID | Resume Next | GoTo 0}
Notes Use a GoTo lineID clause to establish a code block in your procedure that handles any error. The lineID can be a line number or a label. Use a Resume Next clause to trap errors but skip over any statement that causes an error. You can call the Err function in a statement immediately following the statement that you suspect might have caused an error to see whether an error occurred. Err returns 0 if no error has occurred. Use a GoTo 0 statement to turn off error trapping for the current procedure. If an error occurs, Visual Basic passes the error to the error routine in the calling procedure or opens an error dialog box if there is no previous error routine. In your error handling statements, you can examine the built-in Err variable (the error number associated with the error) to determine the exact nature of the error. You can use the Error function to examine the text of the message associated with the error. If you use line numbers with your statements, you can use the built-in Erl function to determine the line number of the statement that caused the error. After taking corrective action, use a Resume statement to retry execution of the statement that caused the error. Use a Resume Next statement to continue execution at the statement immediately following the statement that caused the error. Use a Resume statement with a statement label to restart execution at the indicated label name or number. You can also use an Exit Function or Exit Sub statement to reset the error condition and return to the calling procedure.
Examples To trap errors but continue execution with the next statement, enter the following: On Error Resume Next
To trap errors and execute the statements that follow the MyError: label when an error occurs, enter the following: On Error GoTo MyError
Some Complex Visual Basic Examples 1553
On Error GoTo 0
If you create and run the following function with zero as the second argument, such as MyErrExample(3,0), the function will trigger an error by attempting to divide by zero, trap the error, display the error in an error handling section, and then exit gracefully: Public Function MyErrExample(intA As Integer, intB As Integer) As Integer ' Set an error trap On Error GoTo Trap_Error ' The following causes an error if intB is zero MyErrExample = intA / intB ExitNice: Exit Function Trap_Error: MsgBox "Something bad happened: " & Err & ", " & Error Resume ExitNice End Function
Some Complex Visual Basic Examples A good way to learn Visual Basic techniques is to study complex code that has been developed and tested by someone else. In the Conrad Systems Contacts and Housing Reservations sample databases, you can find dozens of examples of complex Visual Basic code that perform various tasks. The following sections describe two of the more interesting ones in detail.
A Procedure to Randomly Load Data You’ve probably noticed a lot of sample data in both the Conrad Systems Contacts and the Housing Reservations databases. No, we didn’t sit at our keyboards for hours entering sample data! Instead, we built a Visual Basic procedure that accepts some parameters entered on a form. In both databases, the form to load sample data is saved as zfrmLoadData. If you open this form in Contacts.accdb from the Navigation pane, you’ll see that you use it to enter a beginning date, a number of days (max 365), a number of companies to load (max 25), a maximum number of contacts per company (max 10), and a maximum number of events per contact (max 25). You can also select the check box to delete all existing data before randomly loading new data. (The zfrmLoadData form in the Housing Reservations database offers some slightly different options.) Figure 24-15 shows this form with the values we used to load the Conrad Systems Contacts database.
Chapter 24
To turn off error trapping in the current procedure, enter the following:
Chapter 24 Figure 24-15 The zfrmLoadData form in the Conrad Systems Contacts sample database makes it easy to load sample data.
As you might expect, when you click Load!, our procedure examines the values entered and loads some sample data into tblCompanies, tblContacts, tblCompanyContacts, tblContactEvents, and tblContactProducts. The code picks random company names from ztblCompanies (a table containing a list of fictitious company names) and random person names from ztblPeople (a table containing names of Microsoft employees who have agreed to allow their names to be used in sample data). It also chooses random ZIP codes (and cities, counties, and states) from tlkpZips (a table containing U.S. ZIP codes, city names, state names, county names, and telephone area codes as of December 2002 that we licensed from CD Light, LLC—http://www.zipinfo.com). Figure 24-16 shows you the design of the query used in the code to pick random person names.
Figure 24-16 This query returns person names in a random sequence.
The query creates a numeric value to pass to the Rnd (random) function by grabbing the first character of the LastName field and then calculating the ASCII code value. The Rnd function returns some floating-point random value less than 1 but greater than or equal to zero. Asking the query to sort on this random number results in a random list of values each time you run the query.
Some Complex Visual Basic Examples 1555
If you open zqryRandomNames in Datasheet view, the RandNum column won’t appear to be sorted correctly. In fact, the values change as you scroll through the data or resize the datasheet window. The database engine actually calls the Rnd function on a first pass through the data to perform the sort. Because the function depends on a value of one of the columns (LastName), Access assumes that other users might be changing this column—and therefore, the calculated result—as you view the data. Access calls the Rnd function again each time it refreshes the data display, so the actual values you see aren’t the ones that the query originally used to sort the data.
If you want to run this code, you should either pick a date starting after January 24, 2011, or select the option to delete all existing records first. You can find the code in the cmdLoad_Click event procedure that runs when you click the Load button on the zfrmLoadData form. We’ve added line numbers to some of the lines in this code listing in the book so that you can follow along with the line-by-line explanations in Table 24-5, which follows the listing. Because the code loads data into both a multivalue field and an attachment field in the tblContacts table, it uses the DAO object model exclusively. (You cannot manipulate multi-value or attachment fields using the ADO object model.) 1 Private Sub cmdLoad_Click() 2 ' Code to load a random set of companies, ' contacts, events, and products ' Database variable 3 Dim db As DAO.Database ' Table delete list (if starting over) Dim rstDel As DAO.Recordset ' Company recordset; Contact recordset (insert only) Dim rstCo As DAO.Recordset, rstCn As DAO.Recordset ' Photo (attachment) and ContactType (multi-value) recordset Dim rstComplex As DAO.Recordset2 ' CompanyContact recordset, ContactEvent recordset (insert only) Dim rstCoCn As DAO.Recordset, rstCnEv As DAO.Recordset ' A random selection of zips Dim rstZipRandom As DAO.Recordset ' ..and company names Dim rstCoRandom As DAO.Recordset ' .. and people names Dim rstPRandom As DAO.Recordset ' A recordset to pick "close" zip codes for contacts Dim rstZipClose As DAO.Recordset ' A recordset to pick contact events Dim rstEvents As DAO.Recordset ' Place to generate Picture Path
4 Dim strPicPath As String ' Places for path to backend database and folder Dim strBackEndPath As String, strBackEndFolder As String ' Place to generate a safe "compact to" name Dim strNewDb As String ' Places to save values from the form controls Dim datBeginDate As Date, intNumDays As Integer Dim intNumCompanies As Integer, intNumContacts As Integer Dim intNumEvents As Integer ' Lists of street names and types 5 Dim strStreetNames(1 To 9) As String, strStreetTypes(1 To 5) As String ' As string of digits for street addresses and area codes Const strDigits As String = "1234567890" ' List of Person Titles by gender Dim strMTitles(1 To 6) As String, strFTitles(1 To 7) As String ' Place to put male and female picture file names Dim strMPicture() As String, intMPicCount As Integer Dim strFPicture() As String, intFPicCount As Integer ' Some working variables Dim intI As Integer, intJ As Integer, intK As Integer Dim intL As Integer, intM As Integer, intR As Integer Dim varRtn As Variant, intDefault As Integer Dim datCurrentDate As Date, datCurrentTime As Date ' Variables to assemble Company and Contact records Dim strCompanyName As String, strCoAddress As String Dim strAreaCode As String, strPAddress As String Dim strThisPhone As String, strThisFax As String Dim strWebsite As String Dim lngThisCompany As Long Dim lngThisContact As Long, strProducts As String ' Set up to bail if something funny happens (it shouldn't) 6 On Error GoTo BailOut ' Initialize Streets 7 strStreetNames(1) = "Main" strStreetNames(2) = "Central" strStreetNames(3) = "Willow" strStreetNames(4) = "Church" strStreetNames(5) = "Lincoln" strStreetNames(6) = "1st" strStreetNames(7) = "2nd" strStreetNames(8) = "3rd" strStreetNames(9) = "4th" strStreetTypes(1) = "Street" strStreetTypes(2) = "Avenue" strStreetTypes(3) = "Drive" strStreetTypes(4) = "Parkway" strStreetTypes(5) = "Boulevard" ' Initialize person titles strMTitles(1) = "Mr." strMTitles(2) = "Dr." strMTitles(3) = "Mr." strMTitles(4) = "Mr."
Some Complex Visual Basic Examples 1557
8 9
10
11
12
13 14
15 16 17
18
strMTitles(5) = "Mr." strMTitles(6) = "Mr." strFTitles(1) = "Mrs." strFTitles(2) = "Dr." strFTitles(3) = "Ms." strFTitles(4) = "Mrs." strFTitles(5) = "Ms." strFTitles(6) = "Mrs." strFTitles(7) = "Ms." ' Search for male picture names (should be in Current Path\Pictures) strPicPath = Dir(CurrentProject.Path & "\Pictures\PersonM*.bmp") ' Loop until Dir returns nothing (end of list or not found) Do Until (strPicPath = "") ' Add 1 to the count intMPicCount = intMPicCount + 1 ' Extend the file name array ReDim Preserve strMPicture(1 To intMPicCount) ' Add the file name to the array strMPicture(intMPicCount) = strPicPath ' Get next one strPicPath = Dir Loop ' Search for female picture names (should be in Current Path\Pictures) strPicPath = Dir(CurrentProject.Path & "\Pictures\PersonF*.bmp") ' Loop until Dir returns nothing (end of list or not found) Do Until (strPicPath = "") ' Add 1 to the count intFPicCount = intFPicCount + 1 ' Extend the file name array ReDim Preserve strFPicture(1 To intFPicCount) ' Add the file name to the array strFPicture(intFPicCount) = strPicPath ' Get next one strPicPath = Dir Loop ' Capture values from the form datBeginDate = CDate(Me.BeginDate) intNumDays = Me.NumDays intNumCompanies = Me.NumCompanies intNumContacts = Me.NumContacts intNumEvents = Me.NumEvents ' Open the current database Set db = CurrentDb ' Do they want to delete old rows? If (Me.chkDelete = -1) Then ' Verify it If vbYes = MsgBox("Are you SURE you want to delete " & _ "all existing rows? " & vbCrLf & vbCrLf & _ "(This will also compact the data file.)", _ vbQuestion + vbYesNo + vbDefaultButton2, gstrAppTitle) Then ' Open the table that tells us the safe delete sequence Set rstDel = db.OpenRecordset("SELECT * FROM " & _
"ztblDeleteSeq ORDER BY Sequence", _ dbOpenSnapshot, dbForwardOnly) ' Loop through them all Do Until rstDel.EOF ' Check for tblContacts If rstDel!TableName = "tblContacts" Then ' Can't just delete all rows in the linked table - must do one at a time ' Open a recordset on tblContacts Set rstCn = db.OpenRecordset("tblContacts", dbOpenDynaset) ' Loop through them all Do Until rstCn.EOF ' Put it in edit mode rstCn.Edit ' Get the first complex field's recordset (ContactType) Set rstComplex = rstCn!ContactType.Value ' Loop and delete them all Do Until rstComplex.EOF ' Delete it rstComplex.Delete ' Get the next rstComplex.MoveNext Loop ' Get the second complex field's recordset (Photo) Set rstComplex = rstCn!Photo.Value ' Loop and delete them all Do Until rstComplex.EOF ' Delete it rstComplex.Delete ' Get the next rstComplex.MoveNext Loop ' Save the row with the deleted complex data rstCn.Update ' Now finally delete the contact rstCn.Delete ' Get the next one rstCn.MoveNext Loop ' Clear the objects Set rstComplex = Nothing rstCn.Close Set rstCn = Nothing Else ' Execute a delete db.Execute "DELETE * FROM " & rstDel!TableName, _ dbFailOnError End If ' Go to the next row rstDel.MoveNext Loop ' Figure out the path to the backend data strBackEndPath = Mid(db.TableDefs("tblContacts").Connect, 11)
Some Complex Visual Basic Examples 1559
22
23
24
25 26 27 28
29 30
31
32 33
34 35
' Figure out the backend folder strBackEndFolder = Left(strBackEndPath, _ InStrRev(strBackEndPath, "\")) ' Calculate a "compact to" database name strNewDb = "TempContact" & Format(Now, "hhnnss") & ".accdb" ' Compact the database into a new name DBEngine.CompactDatabase strBackEndPath, _ strBackEndFolder & strNewDb ' Delete the old one Kill strBackEndPath ' Rename the new Name strBackEndFolder & strNewDb As strBackEndPath Else ' Turn off the delete flag – changed mind Me.chkDelete = 0 End If End If ' Initialize the randomizer on system clock Randomize ' Open all output recordsets Set rstCo = db.OpenRecordset("tblCompanies", dbOpenDynaset) Set rstCn = db.OpenRecordset("tblContacts", dbOpenDynaset) Set rstCoCn = db.OpenRecordset("tblCompanyContacts", dbOpenDynaset) Set rstCnEv = db.OpenRecordset("tblContactEvents", dbOpenDynaset) ' Open the random recordsets Set rstZipRandom = db.OpenRecordset("zqryRandomZips", dbOpenDynaset) Set rstCoRandom = db.OpenRecordset("zqryRandomCompanies", dbOpenDynaset) Set rstPRandom = db.OpenRecordset("zqryRandomNames", dbOpenDynaset) ' Open the Events/products list Set rstEvents = db.OpenRecordset("zqryEventsProducts", dbOpenDynaset) ' Move to the end to get full recordcount rstEvents.MoveLast ' Turn on the hourglass DoCmd.Hourglass True ' Initialize the status bar varRtn = SysCmd(acSysCmdInitMeter, "Creating Companies...", _ intNumCompanies) ' Outer loop to add Companies For intI = 1 To intNumCompanies ' Start a new company record rstCo.AddNew ' Clear the saved website strWebsite = "" ' Grab the next random "company" name strCompanyName = rstCoRandom!CompanyName ' .. and the website rstCo!Website = rstCoRandom!CompanyName & "#" & _ rstCoRandom!Web & "##" & rstCoRandom!CompanyName & " Website" strWebsite = rstCo!Website rstCo!CompanyName = strCompanyName ' Generate a random street number intR = Int((7 * Rnd) + 1)
strCoAddress = Mid(strDigits, intR, 4) ' Now pick a random street name intR = Int((9 * Rnd) + 1) strCoAddress = strCoAddress & " " & strStreetNames(intR) ' and street type intR = Int((5 * Rnd) + 1) strCoAddress = strCoAddress & " " & strStreetTypes(intR) rstCo!Address = strCoAddress ' Fill in random values from the zip code table rstCo!City = rstZipRandom!City rstCo!County = rstZipRandom!County rstCo!StateOrProvince = rstZipRandom!State rstCo!PostalCode = rstZipRandom!ZipCode ' Generate a random Area Code intR = Int((8 * Rnd) + 1) strAreaCode = Mid(strDigits, intR, 3) ' Generate a random phone number (0100 - 0148) intR = Int((48 * Rnd) + 1) + 100 strThisPhone = strAreaCode & "555" & Format(intR, "0000") rstCo!PhoneNumber = strThisPhone ' Add 1 for the fax number strThisFax = strAreaCode & "555" & Format(intR + 1, "0000") rstCo!FaxNumber = strThisFax ' Save the new Company ID lngThisCompany = rstCo!CompanyID ' .. and save the new Company rstCo.Update ' Now, do some contacts for this company ' - calc a random number of contacts intJ = Int((intNumContacts * Rnd) + 1) ' Set up the recordset of Zips "close" to the Work Zip Set rstZipClose = db.OpenRecordset("SELECT * FROM tlkpZips " & _ "WHERE ZipCode BETWEEN '" & _ Format(CLng(rstZipRandom!ZipCode) - 5, "00000") & _ "' AND '" & Format(CLng(rstZipRandom!ZipCode) + 5, "00000") & _ "'", dbOpenDyanaset) ' Move to last row to get accurate count rstZipClose.MoveLast ' Make the first contact the company default intDefault = True ' Loop to add contacts For intK = 1 To intJ ' Start a new record rstCn.AddNew ' Put in the name info from the random people record rstCn!LastName = rstPRandom!LastName rstCn!FirstName = rstPRandom!FirstName rstCn!MiddleInit = rstPRandom!MiddleInit rstCn!Suffix = rstPRandom!Suffix ' Select title and picture based on gender of person If rstPRandom!Sex = "f" Then ' Pick a random female title and picture
Some Complex Visual Basic Examples 1561
44
45 46
47
intR = Int((7 * Rnd) + 1) rstCn!Title = strFTitles(intR) ' Make sure we have some picture file names If intFPicCount 0 Then ' Pick a random file name intR = Int((intFPicCount * Rnd) + 1) strPicPath = strFPicture(intR) ' Don't reuse it For intL = intR To intFPicCount – 1 strFPicture(intL) = strFPicture(intL + 1) Next intL intFPicCount = intFPicCount - 1 Else ' Set empty picture name strPicPath = "" End If Else ' Pick a random male title and picture intR = Int((6 * Rnd) + 1) rstCn!Title = strMTitles(intR) ' Make sure we have some picture file names If intMPicCount 0 Then ' Pick a random file name intR = Int((intMPicCount * Rnd) + 1) strPicPath = strMPicture(intR) ' Don't reuse it For intL = intR To intMPicCount – 1 strMPicture(intL) = strMPicture(intL + 1) Next intL intMPicCount = intMPicCount - 1 Else ' Set empty picture name strPicPath = "" End If End If ' Set contact type to "Customer" – complex data type Set rstComplex = rstCn!ContactType.Value rstComplex.AddNew rstComplex!Value = "Customer" rstComplex.Update ' Copy the company website rstCn!Website = strWebsite ' Set up a dummy email rstCn!EmailName = rstPRandom!FirstName & " " & _ rstPRandom!LastName & "#mailto:" & Left(rstPRandom!FirstName, 1) & _ rstPRandom!LastName & "@" _ & Mid(rstCoRandom!Web, Instr(rstCoRandom!Web, "http://www.") + 11) ' Strip off the trailing "/" rstCn!EmailName = Left(rstCn!EmailName, Len(rstCn!EmailName) – 1) ' Pick a random birth date between Jan 1, 1940 and Dec 31, 1979 ' There are 14,610 days between these dates intR = Int((14610 * Rnd) + 1)
rstCn!BirthDate = #12/31/1939# + Int((14610 * Rnd) + 1) ' Set Default Address to 'work' rstCn!DefaultAddress = 1 ' Copy work address from Company rstCn!WorkAddress = strCoAddress rstCn!WorkCity = rstZipRandom!City rstCn!WorkStateOrProvince = rstZipRandom!State rstCn!WorkPostalCode = rstZipRandom!ZipCode rstCn!WorkPhone = strThisPhone rstCn!WorkFaxNumber = strThisFax ' Generate a random street number for home address intR = Int((7 * Rnd) + 1) strPAddress = Mid(strDigits, intR, 4) ' Now pick a random street name intR = Int((9 * Rnd) + 1) strPAddress = strPAddress & " " & strStreetNames(intR) ' and street type intR = Int((5 * Rnd) + 1) strPAddress = strPAddress & " " & strStreetTypes(intR) rstCn!HomeAddress = strPAddress ' Position to a "close" random zip intR = rstZipClose.RecordCount intR = Int(intR * Rnd) rstZipClose.MoveFirst If intR > 0 Then rstZipClose.Move intR rstCn!HomeCity = rstZipClose!City rstCn!HomeStateOrProvince = rstZipClose!State rstCn!HomePostalCode = rstZipClose!ZipCode ' Generate a random phone number (0150 - 0198) intR = Int((48 * Rnd) + 1) + 149 rstCn!HomePhone = strAreaCode & "555" & Format(intR, "0000") ' Add 1 for the fax number rstCn!MobilePhone = strAreaCode & "555" & Format(intR + 1, "0000") ' Save the new contact ID lngThisContact = rstCn!ContactID ' If got a random photo name, load it If strPicPath "" Then ' Open the special photo editing recordset Set rstComplex = rstCn!Photo.Value rstComplex.Addnew rstComplex!FileData.LoadFromFile _ (CurrentProject.Path & "\Pictures\" & strPicPath) rstComplex.Update End If ' Finally, save the row rstCn.Update ' Insert linking CompanyContact record rstCoCn.AddNew ' Set the Company ID rstCoCn!CompanyID = lngThisCompany ' Set the Contact ID rstCoCn!ContactID = lngThisContact
Some Complex Visual Basic Examples 1563
53
54
55 56
57
58
59
60
' Make this the default company for the contact rstCoCn!DefaultForContact = True ' Set default for company - 1st contact will be the default rstCoCn!DefaultForCompany = intDefault ' Reset intDefault after first time through intDefault = False ' Save the linking row rstCoCn.Update ' Now, do some contacts events for this contact ' - calc a random number of events intM = Int((intNumEvents * Rnd) + 1) ' Clear the Products sold string strProducts = "" ' Loop to add some events For intL = 1 To intM ' Start a new row rstCnEv.AddNew ' Set the Contact ID rstCnEv!ContactID = lngThisContact ' Calculate a random number of days intR = Int(intNumDays * Rnd) datCurrentDate = datBeginDate + intR ' Calculate a random time between 8am and 8pm (no seconds) datCurrentTime = CDate(Format(((0.5 * Rnd) + 0.3333), "hh:nn")) ' Set the contact date/time rstCnEv!ContactDateTime = datCurrentDate + datCurrentTime TryAgain: ' Position to a random event intR = rstEvents.RecordCount intR = Int(intR * Rnd) rstEvents.MoveFirst If intR > 0 Then rstEvents.Move intR ' If a product sale event, If (rstEvents!ContactEventProductSold = True) Then ' Can't sell the same product twice to the same contact If InStr(strProducts, _ Format(rstEvents!ContactEventProductID, "00")) 0 Then ' ooops. Loop back to pick a different event GoTo TryAgain End If End If ' Set the Event Type rstCnEv!ContactEventTypeID = rstEvents!ContactEventTypeID ' Set the follow-up rstCnEv!ContactFollowUp = rstEvents!ContactEventRequiresFollowUp ' Set the follow-up date If (rstEvents!ContactEventRequiresFollowUp = True) Then rstCnEv!ContactFollowUpDate = datCurrentDate + _ rstEvents!ContactEventFollowUpDays End If ' Save the record rstCnEv.Update
' If this event is a product sale, If (rstEvents!ContactEventProductSold = True) Then ' Call the routine to also add a product record! varRtn = Add_Product(lngThisCompany, lngThisContact, _ rstEvents!ContactEventProductID, datCurrentDate) ' Add the product to the products sold string strProducts = strProducts & " " & _ Format(rstEvents!ContactEventProductID, "00") End If ' Loop to do more events Next intL ' Move to the next random person record rstPRandom.MoveNext ' and loop to do more contacts Next intK rstZipClose.Close Set rstZipClose = Nothing ' Move to the next random zip record rstZipRandom.MoveNext ' Update the status bar varRtn = SysCmd(acSysCmdUpdateMeter, intI) ' Move to the next Company row rstCoRandom.MoveNext ' Loop until done Next intI ' Clear the status bar varRtn = SysCmd(acSysCmdClearStatus) ' Done with error trapping, too On Error GoTo 0 ' Be nice and close everything up rstCo.Close rstCn.Close rstCoCn.Close rstCnEv.Close rstZipRandom.Close rstCoRandom.Close ' Finally, generate invoices for most records if all deleted If (Me.chkDelete = -1) Then intI = Do_Invoices() End If ' Turn off the hourglass DoCmd.Hourglass False MsgBox "Done!", vbExclamation, gstrAppTitle DoCmd.Close acForm, Me.Name Done: Set rstCo = Nothing Set rstCn = Nothing Set rstCoCn = Nothing Set rstCnEv = Nothing Set rstZipRandom = Nothing Set rstCoRandom = Nothing Set rstComplex = Nothing
Some Complex Visual Basic Examples 1565
Set db = Nothing Exit Sub 72 BailOut: MsgBox "Unexpected error: " & Err & ", " & Error ' Turn off the hourglass DoCmd.Hourglass False varRtn = SysCmd(acSysCmdClearStatus) Resume Done 73 End Sub
Table 24-5 lists the statement line numbers and explains the code on key lines in the preceding Visual Basic code example. Table 24-5 Explanation of Example Code to Load Random Data
Line
Explanation
1
Declare the beginning of the subroutine. The subroutine has no arguments.
2
You can begin a comment anywhere on a statement line by preceding the comment with a single quotation mark. You can also create a comment statement using the Rem statement.
3
Declare local variables for a DAO Database object and all the DAO Recordset objects used in this code.
4
Beginning of the declarations of all local variables. You should always explicitly define variables in your code.
5
This procedure uses several arrays in which it stores street names, street types, male person titles, female person titles, and the paths to male and female pictures. Code later in the procedure randomly chooses values from these arrays.
6
Set an error trap; the BailOut label is at line 71.
7
Code to initialize the arrays begins here. Note that separate arrays handle male and female titles.
8
Use the Dir function to find available male picture names in the Pictures subfolder under the location of the current database. Note that if you move the sample database, this code won’t find any pictures to load. When Dir finds a matching file, it returns the file name as a string. The code subsequently calls Dir with no arguments inside the following loop to ask for the next picture.
9
Begin a loop to load male pictures, and keep looping until the picture file name is an empty string (Dir found no more files).
10
Note the use of ReDim Preserve to dynamically expand the existing file name array for male pictures without losing any entries already stored.
11
End of the loop started at statement number 9.
12
This loop finds all the female pictures available and loads them into the array that holds picture file names for females.
The next several lines of code capture the values from the form. Validation rules in the form controls make sure that the data is valid.
15
Initialize the Database object.
16
Check to see if you selected the option to delete all existing rows.
17
Use the MsgBox function to verify that you really want to delete existing data.
18
The ztblDeleteSeq table contains the table names in a correct sequence for deletes from the bottom up so that this code doesn’t violate any referential integrity rules. Note that the recordset is opened as a forward-only snapshot for efficiency.
19
Start a loop to process all the table names in ztblDeleteSeq. If tblContacts needs to be deleted, loop through each contact record individually and delete all complex data from the ContactType and Photo fields. Delete each contact record after complex data finishes the deletions.
20
Use the Execute method of the Database object to run the DELETE SQL commands on remaining tables.
21
Figure out the path to the linked data file by examining the Connect property of one of the linked tables.
22
Extract the folder name of the data file using the Left and InStrRev functions.
23
Use the CompactDatabase method of the DBEngine object to compact the data file into a new one—TempContacthhmmss.accdb—where hhmmss is the current time to avoid conflicts.
24
Use the Kill command to delete the old file and the Name command to rename the compacted temp copy.
25
Terminate the If statement on line 17.
26
Terminate the If statement on line 16.
27
Initialize the randomizer so that all random recordsets are always different.
28
Open all the recordsets needed in this code.
29
Turn the mouse pointer into an hourglass to let you know the transaction is under way and might take a while. You could also set the Screen.MousePointer property to 11 (busy).
30
The SysCmd utility function provides various useful options such as finding out the current directory for msaccess.exe (the Access main program), and the current version of Access. It also has options to display messages and a progress meter on the status bar. This code calls SysCmd to initialize the progress meter you see as the code loads the data.
31
Start the main loop to load company data.
32
Save the company name from the random recordset in a local variable.
33
Generate the website hyperlink from the company name and the Web field.
34
Set the company name in the new company record.
Some Complex Visual Basic Examples 1567
Line
Explanation
35
The next several lines of code use the Rnd function to randomly generate a fourdigit street address and randomly choose a street name and street type from the arrays loaded earlier.
36
Grab the city, county, state, and ZIP code from the current row in the random ZIP Code query.
37
Use Rnd again to generate a fake phone area code and phone and fax numbers.
38
The primary key of tblCompanies is an AutoNumber field. Access automatically generates the next number as soon as you update any field in a new record. This code saves the new company ID to use in related records and writes the company record with the Update method.
39
Calculate a random number of contacts to load for the new company based on the maximum you specified in the form.
40
Open a recordset that chooses the ZIP codes that are five higher or lower than the random ZIP code for the company. (It makes sense that the employees of the company live nearby.)
41
Start the loop to add contacts for this company.
42
Update the new contacts record with a random name plucked from the random person names query.
43
The records in the ztblPeople table have a gender field to help choose an appropriate title and picture for the contact. The statements following this If statement load female data, and the statements following the Else statement on line 44 load male data.
44
This Else statement matches the If on line 43. Statements following this choose male data.
45
This End If closes the If on line 43.
46
The ContactType field is a multi-value field, so it must open a recordset on the field’s Value property even though we’re specifying only one value.
47
Finish generating fields for the contacts record, including the website copied from the company, a fake e-mail name, and a random birth date and addresses.
48
Choose a random ZIP code for the contact near the company ZIP code from the recordset opened on line 40. Also generate phone and fax numbers.
49
The primary key for tblContacts is also an AutoNumber field, so save the new value to use to generate related records and save the new contact.
50
If the code found a good picture file name earlier (male or female), then the following code adds that picture to the record.
51
Photo is an attachment field that works similarly to multi-value fields in code. The code opens a recordset and uses the LoadFromFile method to insert the picture using its file path.
52
Create the linking record in tblCompanyContacts from the saved CompanyID and ContactID. The first contact created is always the default contact for the company.
53
Calculate a random number of events to load for this contact.
Start the loop to add contact events. The following several lines calculate a random contact date and time within the range you specified on the form.
55
Code at line 58 goes here if the random product picked was already sold to this contact.
56
Choose a random event.
57
If the random event is a product sale, verify that this product isn’t already sold to this contact. A product can be sold to a contact only once.
58
The code loops back up to line 55 to choose another event if this is a duplicate product.
59
Finish updating the fields in the new contact event record.
60
Save the new contact event.
61
If the event was a product sale, call the Add_Product function that’s also in this form module to add a row to tblContactProducts. This code passes the company ID, contact ID, product ID, and the date of the event to the function. It also saves the product ID to be sure it isn’t sold again to this contact.
62
This Next statement closes the loop started on line 54.
63
Move to the next random person record.
64
Loop back up to line 41.
65
Close the recordset of ZIP codes close to the company ZIP code.
66
Get the next random ZIP code for the next company.
67
Update the status bar to indicate you’re done with another company.
68
Loop back up to line 31.
69
Clear the status bar and close all recordsets.
70
Clear the hourglass set on line 29. Also issue the final MsgBox confirming that all data is now loaded. Finally, close this form and exit.
71
Set all recordsets to nothing and exit the subroutine.
72
Any trapped error comes here. This code simply displays the error, clears the mouse pointer and the status bar, and exits. (If you don’t reset the mouse pointer and clear the status bar, Access won’t do it for you.)
73
End of the subroutine.
A Procedure to Examine All Error Codes In the Housing Reservations database (Housing.accdb), we created a function that dynamically creates a new table and then inserts into the table (using DAO) a complete list of all the error codes used by Access and the text of the error message associated with each error code. You can find a partial list of the error codes in Help, but the table in the Housing Reservations sample database provides the best way to see a list of all the error codes. You
Some Complex Visual Basic Examples 1569
might find this table useful as you begin to create your own Visual Basic procedures and set error trapping in them.
Note You can find the ADO equivalent of this example in the modExamples module in the Conrad Systems Contacts sample database.
The name of the function is CreateErrTable, and you can find it in the modExamples module. The function statements are listed next. You can execute this function by entering the following in the Immediate window: ?CreateErrTable
The sample database contains the ErrTable table, so the code will ask you if you want to delete and rebuild the table. You should click Yes to run the code. Again, we’ve added line numbers to some of the lines in this code listing so that you can follow along with the lineby-line explanations in Table 24-6, which follows the listing. 1 Function CreateErrTable() ' This function creates a table containing a list of ' all the valid Access application error codes ' You can find the ADO version of this procedure in Contacts.accdb 2 ' Declare variables used in this function 3 Dim dbMyDatabase As DAO.Database, tblErrTable As DAO.TableDef, _ fldMyField As DAO.Field, idxPKey As DAO.Index 4 Dim rcdErrRecSet As DAO.Recordset, lngErrCode As Long, _ intMsgRtn As Integer 5 Dim varReturnVal As Variant, varErrString As Variant, _ ws As DAO.Workspace ' Create Errors table with Error Code and Error String fields ' Initialize the MyDatabase database variable ' to the current database 6 Set dbMyDatabase = CurrentDb 7 Set ws = DBEngine.Workspaces(0) ' Trap error if table doesn't exist ' Skip to next statement if an error occurs 8 On Error Resume Next 9 Set rcdErrRecSet = dbMyDatabase.OpenRecordset("ErrTable") 10 Select Case Err ' See whether error was raised 11 Case 0 ' No error - table must already exist 12 On Error GoTo 0 ' Turn off error trapping 13 intMsgRtn = MsgBox("ErrTable already " & _ "exists. Do you want to delete and " & _ "rebuild all rows?", vbQuestion + vbYesNo, _ "Access 2010 Inside Out") 14 If intMsgRtn = vbYes Then
' Reply was YES—delete rows and rebuild ' Run quick SQL to delete rows dbMyDatabase.Execute_ "DELETE * FROM ErrTable;", dbFailOnError Else ' Reply was NO—done rcdErrRecSet.Close ' Close the table Exit Function ' And exit End If Case 3011, 3078 ' Couldn't find table, ' so build it On Error GoTo 0 ' Turn off error trapping ' Create a new table to contain error rows Set tblErrTable = _ dbMyDatabase.CreateTableDef("ErrTable") ' Create a field in ErrTable to contain the ' error code Set fldMyField = tblErrTable.CreateField( _ "ErrorCode", DB_LONG) ' Append "ErrorCode" field to the fields ' collection in the new table definition tblErrTable.Fields.Append fldMyField ' Create a field in ErrTable for the error ' description Set fldMyField = _ tblErrTable.CreateField("ErrorString", _ DB_MEMO) ' Append the "ErrorString" field to the fields ' collection in the new table definition tblErrTable.Fields.Append fldMyField ' Append the new table to the TableDefs ' collection in the current database dbMyDatabase.TableDefs.Append tblErrTable ' Set text field width to 5" (7200 twips) ' (calls sub procedure) SetFieldProperty _ tblErrTable![ErrorString], _ "ColumnWidth", DB_INTEGER, 7200 ' Create a Primary Key Set idxPKey = tblErrTable.CreateIndex("PrimaryKey") ' Create and append the field to the index fields collection idxPKey.Fields.Append idxPKey.CreateField("ErrorCode") ' Make it the Primary Key idxPKey.Primary = True ' Create the index tblErrTable.Indexes.Append idxPKey ' Set recordset to Errors Table recordset Set rcdErrRecSet = _ dbMyDatabase.OpenRecordset("ErrTable") Case Else ' Can't identify the error—write message ' and bail MsgBox "Unknown error in CreateErrTable " & _
Some Complex Visual Basic Examples 1571
35 36 37
38 39
40 41
42 43
44 45 46 47 48 49 50
51 52 53 54 55
56
Err & ", " & Error$(Err), 16 Exit Function End Select ' Initialize progress meter on the status bar varReturnVal = SysCmd(acSysCmdInitMeter, _ "Building Error Table", 32767) ' Turn on hourglass to show this might take ' a while DoCmd.Hourglass True ' Start a transaction to make it go fast ws.BeginTrans ' Loop through Microsoft Access error codes, ' skipping codes that generate ' "Application-defined or object-define error" ' message. For lngErrCode = 1 To 32767 varErrString = AccessError(lngErrCode) If IsNothing(varErrString) Or _ varErrString = "Application-defined or object-defined error" Then ' If AccessError returned nothing, then try Error varErrString = Error(lngErrCode) End If If Not IsNothing(varErrString) Then If varErrString "Application-" & _ "defined or object-defined error" Then ' Add each error code and string to ' Errors table rcdErrRecSet.AddNew rcdErrRecSet("ErrorCode") = lngErrCode ' Put the message text in the record rcdErrRecSet("ErrorString") = varErrString rcdErrRecSet.Update End If End If ' Update the status meter varReturnVal = SysCmd(acSysCmdUpdateMeter, _ lngErrCode) ' Process next error code Next lngErrCode ' Commit all added rows ws.CommitTrans ' Close recordset. rcdErrRecSet.Close ' Turn off the hourglass — we're done DoCmd.Hourglass False ' And reset the status bar varReturnVal = SysCmd(acSysCmdClearStatus) ' Select new table in the Navigation pane ' to refresh the list DoCmd.SelectObject acTable, "ErrTable", True ' Open a confirmation dialog box
Table 24-6 lists the statement line numbers and explains the code on each line in the preceding Visual Basic code example. Table 24-6 Explanation of Example Code to Examine Error Codes
Line
Explanation
1
Declare the beginning of the function. The function has no arguments.
2
You can begin a comment anywhere on a statement line by preceding the comment with a single quotation mark. You can also create a comment statement using the Rem statement.
3
Declare local variables for a Database object, a TableDef object, a Field object, and an Index object.
4
Declare local variables for a Recordset object, a Long Integer, and an Integer.
5
Declare local variables for a Variant that is used to accept the return value from the SysCmd function, a Variant that is used to accept the error string returned by the AccessError function, and a Workspace object.
6
Initialize the Database object variable by setting it to the current database.
7
Initialize the Workspace object by setting it to the current workspace.
8
Enable error trapping but execute the next statement if an error occurs.
9
Initialize the Recordset object variable by attempting to open the ErrTable table. If the table does not exist, this generates an error.
10
Call the Err function to see whether an error occurred. The following Case statements check the particular error values that interest you.
11
The first Case statement tests for an Err value of 0, indicating that no error occurred. If no error occurred, the table already existed and opened successfully.
12
Turn off error trapping because you don’t expect any more errors.
13
Use the MsgBox function to ask whether you want to clear and rebuild all rows in the existing table. The vbQuestion intrinsic constant asks MsgBox to display the question icon, and the vbYesNo intrinsic constant requests Yes and No buttons (instead of the default OK button). The statement assigns the value returned by MsgBox so that you can test it on the next line.
14
If you click Yes, MsgBox returns the value of the intrinsic constant vbYes. (vbYes happens to be the integer value 6, but the constant name is easier to remember than the number.)
15
Run a simple SQL statement to delete all the rows in the error table.
16
Else clause that goes with the If statement on line 14.
17
Close the table if the table exists and you clicked the No button on line 13.
18
Exit the function.
19
End If statement that goes with the If statement on line 14.
Some Complex Visual Basic Examples 1573
Line
Explanation
20
Second Case statement. Error codes 3011 and 3078 are both “object not found.”
21
Turn off error trapping because you don’t expect any more errors.
22
Use the CreateTableDef method on the database to start a new table definition. This is the same as clicking the Table Design button in the Tables group on the Create tab on the ribbon.
23
Use the CreateField method on the new table to create the first field object—a long integer (the intrinsic constant DB_LONG) named ErrorCode.
24
Append the first new field to the Fields collection of the new Table object.
25
Use the CreateField method to create the second field—a memo field named ErrorString.
26
Append the second new field to the Fields collection of the new Table object.
27
Save the new table definition by appending it to the TableDefs collection of the Database object. If you were to halt the code at this point and repaint the Navigation pane, you would find the new ErrTable listed.
28
Call the SetFieldProperty subroutine in this module to set the column width of the ErrorString field to 7200 twips (5 inches). This ensures that you can see more of the error text when you open the table in Datasheet view.
29
Use the CreateIndex method of the TableDef to begin building an index.
30
Create a single field and append it to the Fields collection of the index. The following statement sets the Primary property of the index to True to indicate that this will be the primary key.
31
Save the new primary key index by appending it to the Indexes collection of the TableDef.
32
Open a recordset by using the OpenRecordset method on the table.
33
This Case statement traps all other errors.
34
Show a message box with the error number and the error message.
35
Exit the function after an unknown error.
36
End Select statement that completes the Select Case statement on line 10.
37
Call the SysCmd function to place a “building table” message on the status bar and initialize a progress meter. The CreateErrTable function will look at 32,767 different error codes.
38
Turn the mouse pointer into an hourglass to indicate that this procedure will take a few seconds.
39
Use the BeginTrans method of the Workspace object to start a transaction. Statements within a transaction are treated as a single unit. Changes to data are saved only if the transaction completes success fully with a CommitTrans method. Using transactions when you’re updating records can speed performance by reducing disk access.
40
Start a For loop to check each error code from 1 through 32,767.
Assign the error text returned by the AccessError function to the variable varErrString. If the string is empty or returned “Application-defined or objectdefined error,” try calling the Error function to get the text of the message.
42
Call the IsNothing function in the modUtility module of the sample database to test whether the text returned is blank. You don’t want blank rows, so don’t add a row if the AccessError function for the current error code returns a blank string.
43
Lots of error codes are defined as “Application-defined or object-defined error.” You don’t want any of these, so this statement adds a row only if the AccessError function for the current error code doesn’t return this string.
44
Use the AddNew method to start a new row in the table.
45
Set the ErrorCode field equal to the current error code.
46
Save the text of the message in the ErrorString field. Because we defined the field as a memo, we don’t need to worry about the length of the text.
47
Use the Update method to save the new row.
48
End If statement that completes the If statement on line 43.
49
End If statement that completes the If statement on line 42.
50
After handling each error code, update the progress meter on the status bar to show how far you’ve gotten.
51
Next statement that completes the For loop begun on line 40. Visual Basic increments lngErrCode by 1 and executes the For loop again until lngErrCode is greater than 32,767.
52
CommitTrans method that completes the transaction begun on line 39.
53
After looping through all possible error codes, close the recordset.
54
Change the mouse pointer back to normal.
55
Clear the status bar.
56
Put the focus on the ErrTable table in the Navigation pane.
57
Display a message box confirming that the function has completed.
58
End of the function.
Working with 64-Bit Access Visual Basic for Applications With the creation of 64-bit versions of the Office 2010 applications, Microsoft has introduced a new 64-bit version of Visual Basic. In general, your Visual Basic code runs without modification with 64-bit Visual Basic. However, there are a few issues and opportunities when using 64-bit Visual Basic. For any programming language, the biggest source of issues when moving between different-sized architectures is the size of pointers. As you learned earlier in this chapter, pointers are variables that hold memory addresses. When you are working on 32-bit systems, these pointers are 32-bit variables; and on 64-bit systems, they are 64-bit variables.
Working with 64-Bit Access Visual Basic for Applications 1575
One of the great things about Visual Basic is that pointers are managed on behalf of programmers, relieving them of the tedium of managing pointers themselves. Still, there are situations in which a programmer needs to manage a pointer manually, in particular when interacting with the Windows API. Prior to Office 2010, Visual Basic had no official pointer data type. Moving to 64-bit with Access 2010 has both advantages and disadvantages. The advantage is that since there are no pointers, most existing Visual Basic code in your applications works just fine with 64-bit Access without any modifications. None of the data types in Visual Basic change their size when moving to 64-bit; in particular, a Long is still 32 bits. The disadvantage is that although “officially” there was no pointer data type, some Visual Basic code used Long variables to hold memory addresses as an “unofficial” pointer. Microsoft, in fact, promoted this behavior for making calls to the Windows operating system. Since Long variables did not increase in size when moving to 64-bit, executing code that stored pointers in Long variables will result in unexpected behavior for your applications— even possibly crashing. So what does this mean to you as an Access developer? This means that you need to identify all the places where a pointer could enter or exit Visual Basic and modify them. These include: ●●
Declare statements
●●
VarPtr functions
●●
StrPtr functions
●●
ObjPtr functions
Thankfully, the 64-bit Visual Basic compiler helps identify these situations.
Using Declare Statements The Visual Basic Declare statement is commonly used to access Windows APIs, although it can also be used to call any DLL entry point. For example, the following Declare statement sets up a call to the Windows RegOpenKeyA API for opening a Windows registry key: Declare Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As Long, ByVal SubKey As String, _ NewKey As Long) As Long
The Key and NewKey parameters above are Windows handles—a handle is a pointer. When you run the statement on 32-bit computers running Windows, Key and NewKey are 32-bit values and fit nicely into a Long variable. This method of coding is precisely what was done for years.
When you are using a 64-bit version of Office 2010, however, pointers and handles are 64-bit values. The big problem here is that the Long variable in Visual Basic is still 32 bits. Using our example here, consider what happens with NewKey, which is filled in by the API call. If Visual Basic allocates only 32 bits to hold NewKey and Windows thinks this is a 64-bit quantity, Windows overwrites the adjacent memory to NewKey, resulting in undefined behavior, including possibly crashing Visual Basic. For this reason, Visual Basic blocks this Declare statement from running on 64-bit Visual Basic until you properly update the statement.
INSIDE OUT
Setting a Registry Key to Test Upper Memory
You can set a registry key on your computer to force Windows to use memory allocations into the upper 32 bits of memory to help find instances in your application code where a Long was not properly upgraded to a LongPtr. You can find more information about this registry setting at the following page on Microsoft’s website: http://www. microsoft.com/whdc/system/platform/server/PAE/PAEdrv.mspx.
Using LongPtr Data Types Before we update the Declare statement, let’s recall what got us into this situation: lack of an official pointer data type and the subsequent overloading of Long to be the unofficial pointer data type. If Visual Basic had a pointer data type from the beginning, we could have written that Declare statement properly so that it runs correctly on both 32-bit and 64-bit versions of Visual Basic. In Office 2010, Microsoft introduces a new data type for Visual Basic to fill this role as the official pointer data type—LongPtr. With 32-bit Visual Basic, LongPtr is a 32-bit quantity; and with 64-bit Microsoft Visual Basic for Applications (VBA), LongPtr is a 64-bit quantity. Now, we can rewrite the previous Declare statement, which will work with both 32-bit and 64-bit Visual Basic, as follows: Declare Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As LongPtr, ByVal SubKey As String, _ NewKey As LongPtr) As Long
Working with 64-Bit Access Visual Basic for Applications 1577
You’ll also need to update any Long sized pointers in User Defined Types (UDTs) that are passed to and from Declare procedures. Here’s an example with the Windows process information structure: Type PROCESS_INFORMATION hProcess As LongPtr hThread As LongPtr dwProcessId As Long dwThreadId As Long End Type
You need to remember that all Windows handlers are pointers and therefore need to be accordingly increased in size in your code. You can use LongPtr to hold and pass handles.
Using PtrSafe Attributes As you’re following along, you might be noticing that we have another problem: How can Visual Basic tell if a Declare statement’s parameters and return value have been properly updated to handle pointers and are safe to use with both 32-bit and 64-bit Visual Basic? The answer, of course, is that it cannot. There are many Declare statements that quite legitimately pass or return Long values that are not pointers. To address this issue, Microsoft introduced a new attribute for Declare statements called PtrSafe. This attribute tells Visual Basic that the Declare statement you’re writing is safe to run with both 32-bit and 64-bit Visual Basic and that all pointer-sized values are properly handled. Without the PtrSafe attribute, 64-bit Visual Basic does not compile Declare statements. To maintain backward compatibility, 32-bit Visual Basic continues to compile Declare statements without the PtrSafe attribute. So, using the example we’ve been working through previously, the Declare statement is as follows: Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As LongPtr, ByVal SubKey As String, _ NewKey As LongPtr) As Long
Microsoft recommends that all new Declare statements use LongPtr and PtrSafe.
Supporting Older Versions of Access If you develop Access applications in Access 2010 for users with previous versions of Access, you still need to address one more issue. Versions of Visual Basic before Access 2010 do not understand the new data types and attributes and therefore generate errors. If the Visual Basic code you write for Access 2010 needs to run in previous versions of Access, then you must wrap the code in the new #If VBA7 construct and include the older format as well.
This new conditional compilation variable VBA7 is defined only for Visual Basic included with Access 2010. Using the example Declare statement we’ve been working on previously, you can write your code like the following: #If VBA7 Then Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As LongPtr, ByVal SubKey As String, _ NewKey As LongPtr) As Long #Else Declare Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As Long, ByVal SubKey As String, _ NewKey As Long) As Long #End If
Note that there is also a Win64 conditional compilation variable, which can be useful if the Declare statement has other differences besides pointer size between 32-bit and 64-bit platforms. You write your code, in this case, like the following: #If WIN64 Then Declare PtrSafe Function WindowFromPoint Lib "user32" Alias _ "WindowFromPoint"(ByVal Point As LongLong) As LongPtr #Else Declare PtrSafe Function WindowFromPoint Lib "user32" Alias _ "WindowFromPoint"(ByVal xPoint As Long, ByVal yPoint As Long) As LongPtr #End If
Many Access developers create Visual Basic code in their applications using Declare statements based on a text file called Windows API Declarations and Constants for Visual Basic—Win32API.txt—supplied by Microsoft. The Win32API.txt file includes around 1,500 examples of the most common Windows API calls. For Office 2010, Microsoft updated this reference file to include information about the new LongPtr data type and PtrSafe attribute, as outlined earlier. You can download this new reference file, called Win32API_PtrSafe.txt, from Microsoft’s website at the following location: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=035b 72a5-eef9-4baf-8dbc-63fbd2dd982b
Understanding Pointer Valued Functions and LongPtr Type Coercion VarPtr, StrPtr, and ObjPtr are functions that return pointers to Visual Basic variables. You can use these functions to pass pointers to APIs, for example. In 32-bit Visual Basic, these functions return Long values as they always have, but when you use 64-bit VBA, these functions return LongPtr values. Although this seems correct on the surface, this can pose a problem with an unexpected result. Consider, for example, the following code:
Working with 64-Bit Access Visual Basic for Applications 1579
Dim L as Long Dim X as Long L = VarPtr(X)
When you use 32-bit Visual Basic with the code sample here, your code should execute properly because L is a Long (32-bit) and VarPtr returns a Long (32-bit). However, if you use this code sample with 64-bit Visual Basic, L is a Long (32-bit), but VarPtr is a LongPtr (64-bit). In this case, we are assigning a possibly large value into a smaller variable. In most cases, Visual Basic handles this kind of conversion at run time. If the return value from VarPtr fits in 32 bits, then Visual Basic silently does the downsizing and you won’t see a runtime error. Because pointer values are unpredictable, however, you might never encounter a run-time error while developing the application, and end users might only sporadically see a run-time error. These types of errors are hard to reproduce and very difficult to debug. To help alleviate this potential issue, 64-bit Visual Basic does not allow a LongPtr to be implicitly converted into a Long, even if the value being converted fits in the smaller variable. A LongPtr value can be explicitly converted by using the CLong() function.
Using LongLong Data Types Besides LongPtr, Access 2010 Visual Basic includes another new data type called LongLong. The LongLong data type can hold an 8-byte signed integer value. The LongLong data type is useful when you are interacting with APIs on a computer running 64-bit Windows that consume or return 64-bit values. The LongLong data type is available only with the 64-bit version of Visual Basic. If you to use the LongLong data type in a 32-bit version of Access 2010, you’ll receive a compile error. Table 24-7 shows a summary of the VBA7 language updates. Table 24-7 Summary of VBA7 Language Updates
Name
Type
Description
PtrSafe
Keyword
Asserts that a Declare statement is targeted for 64-bit systems. This is required on 64-bit systems.
LongPtr
Data Type
Type alias that maps to Long on 32-bit systems or LongLong on 64-bit systems.
LongLong
Data Type
8 byte data type that is available only on 64-bit systems. Supports integer numbers in the range of –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. LongLong is a valid declared type only on 64-bit systems. In addition, you cannot implicitly convert a LongLong to a smaller type. For example, you cannot assign a LongLong data type to a Long. Explicit coercions are allowed, so in the previous example, you could apply CLng to a LongLong and assign the result to a Long on 64-bit platforms.
LongLong Explicitly declares a literal value as a LongLong. This is type-declara- required to declare a LongLong literal that is larger than tion character the maximum Long value. If you don’t explicitly declare the value, Access converts it to a Double.
CLngPtr
Type conversion function
Converts a simple expression to a LongPtr. This is valid on 64-bit platforms only.
CLngLng
Type conversion function
Converts a simple expression to a LongLong data type. This is valid on 64-bit platforms only.
vbLongLong
VarType constant
Constant used with the VarType function. Note that there is no vbLongPtr, since LongPtr is a mapping to Long and LongLong and therefore is not really a separate type.
DefLngPtr
DefType statement
Sets the default data type for a range of variables as LongPtr.
DefLngLng
DefType statement
Sets the default data type for a range of variables as LongLong.
Working with .MDE and .ACCDE files in 64-Bit Environments As you’ll learn in Chapter 27, “Distributing Your Application,” on the companion CD, .mde and .accde files are execute-only Access databases in which the Visual Basic source code (the text that the developer edits) is removed. The binary executable form of the Visual Basic project remains, however, which allows Visual Basic to continue executing in these databases. Without the source code, the Visual Basic project cannot be read or modified by another developer. Many Access developers use this feature included in Access to help protect their intellectual property. Unfortunately, the binary executable form of Visual Basic is not compatible between 32-bit and 64-bit versions of Visual Basic. Normally, this is not a problem when you are using an .mdb or .accdb database; Visual Basic is designed to recompile from source code if it finds the binary executable form stored within the database is the wrong type. For .mde and .accde databases, however, this presents a problem because .mde and .accde files have no source code. As a result, .mde and .accde databases created with 32-bit Access 2010 can only be used with 32-bit versions of Access, and .mde and .accde databases created with 64-bit Access 2010 can only be used with 64-bit versions of Access. If you are distributing an application that needs to be run with both 32-bit and 64-bit versions of Access, you must create and distribute separate 32-bit and 64-bit .mde and .accde databases.
Working with 64-Bit Access Visual Basic for Applications 1581
The controls in the MSComCtl and MSComCtl2 libraries were not ported to 64-bit in Office 2010. You cannot use any of the following controls in a 64-bit environment of Office 2010: ●●
MSComCtl Control Library: TabStrip, Toolbar, StatusBar, ProgressBar, TreeView, ListView, ImageList, Slider, and ImageComboBox
●●
MSComCt2 Control Library: Animation, UpDown, MonthView, DateTimePicker, and FlatScrollBar
You should now have a basic understanding of how to create functions and subroutines using Visual Basic. In Chapter 25, you’ll enhance what you’ve learned as you study major parts of the Conrad Systems Contacts, Housing Reservations, and Wedding List applications.
ow that you’ve learned the fundamentals of using Microsoft Visual Basic, it’s time to put this knowledge into practice. In this chapter, you’ll learn how to create the Visual Basic code you need to automate many common tasks.
You can find dozens of examples of automation in the Conrad Systems Contacts, Housing Reservations, Back Office Software System, and Wedding List sample databases. As you explore the databases, whenever you see something interesting, open the form or report in Design view and take a look at the Visual Basic code behind the form or report. This chapter walks you through a few of the more interesting examples in these databases.
Note You can find the code explained in this chapter in the Conrad Systems Contacts (Contacts.accdb), Housing Reservations (Housing.accdb), and Wedding List (WeddingList.accdb) sample applications on the companion CD.
Why Aren’t We Using Macros? Although you can certainly use user interface macros to automate applications, macros have certain limitations. For example, as you might have noticed when examining the list of available events in Chapter 19, “Understanding Event Processing,” many events require or return parameters that can be passed to or read from a Visual Basic procedure but not a macro. And as you saw in Chapter 20, “Automating a Client Application Using Macros,” and Chapter 21, “Automating a Web Application Using Macros,” the debugging facilities for macros are not as robust as for Visual Basic.
1583
1584 Chapter 25 Automating Your Application with Visual Basic
When to Use Macros Chapter 25
Use macros in your application in any of the following circumstances: ●●
You are working with a web database.
●●
Your application consists of only a few forms and reports.
●●
You need to build a simple application that is automated using only trusted macro actions so that the application can run in an untrusted environment.
●●
Your application might be used by users unfamiliar with Visual Basic who will want to understand how your application is constructed and possibly modify or enhance it.
●●
You’re developing an application prototype, and you want to rapidly automate a few features to demonstrate your design. However, once you understand Visual Basic, automating a demonstration application is just as easy using event procedures.
●●
You don’t need to evaluate or set parameters passed by certain events, such as AfterDelConfirm, ApplyFilter, BeforeDelConfirm, Error, Filter, KeyDown, KeyPress, KeyUp, MouseDown, MouseMove, MouseUp, NotInList, and Updated.
●●
You don’t need to open and work with recordsets or other objects.
When to Use Visual Basic Although user interface macros can be useful and are necessary when working with web forms, a number of tasks cannot be carried out with macros, and there are others that are better implemented using a Visual Basic procedure. Use a Visual Basic procedure instead of a macro in any of the following circumstances: ●●
You need complex error handling in your application.
●●
You want to define a new function.
●●
You need to handle events that pass parameters or accept return values (other than Cancel).
●●
You need to create new objects (tables, queries, forms, or reports) in your database from application code.
Assisting Data Entry 1585
●●
Your application needs to interact with another Windows-based program via ActiveX automation.
●●
You want to be able to directly call Windows application programming interface (API) functions.
●●
You want to define application code that is common across several applications in a library.
●●
You want to be able to open and work with data in a recordset on a record-by-record basis.
●●
You need to use some of the native facilities of the relational database management system that handles your attached tables (such as Microsoft SQL Server procedures or data definition facilities).
●●
You want maximum performance in your application. Because modules are compiled, they execute slightly faster than macros. You’ll probably notice a difference only on slower processors.
●●
You are writing a complicated application that will be difficult to debug.
Assisting Data Entry You can do a lot to help make sure the user of your application enters correct data by using data macros and by defining default values, input masks, and validation rules. But what can you do if the default values come from a related table? How can you assist a user who needs to enter a value that’s not in the row source of a combo box? How do you make the display text in a hyperlink more readable? Is there a way you can make it easier for your user to pick dates and times? And how do you help the user edit linked picture files? You can find the answers to these questions in the following sections.
Filling In Related Data The tblContactProducts table in the Conrad Systems Contacts database (Contacts.accdb) has a SoldPrice field that reflects the actual sales price at the time of a sale. The tblProducts table has a UnitPrice field that contains the normal selling price of the product. When the user is working in the Contacts form (frmContacts) and wants to sell a new product, you don’t want the user to have to look up the current product price before entering it into the record.
Chapter 25
1586 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
You learned in Chapter 15, “Advanced Form Design,” how to build a form with subforms nested two levels to edit contacts, the default company for each contact, and the products sold to that company and registered to the current contact. However, if you open frmContacts in the Contacts.accdb sample database and click the Products tab, as shown in Figure 25-1, you’ll notice that there doesn’t appear to be any linking company data between contacts and the products sold. (The subform to display contact products isn’t nested inside another subform to show the companies for the current contact.) Again, the user shouldn’t have to look up the default company ID for the current contact before selling a product. Note that in Figure 25-1, we navigated to the fourth contact record.
Figure 25-1 Selling a product to a contact involves filling in the price and the default company.
As you can see, a combo box on the subform (fsubContactProducts) helps the user choose the product to sell. Part of the secret to setting the price (the SoldPrice field in tblContactProducts) automatically is in the row source query for the combo box, qlkpProductsForContacts, as shown in Figure 25-2.
Assisting Data Entry 1587
Chapter 25
Figure 25-2 The qlkpProductsForContacts query is the row source for the Product combo box on fsubContactProducts.
You certainly need the ProductID field for the new record in tblContactProducts. Displaying the ProductName field in the combo box is more meaningful than showing the ProductID number, and, as you can see in Figure 25-1, the list in the combo box also shows you the CategoryDescription and whether the product is a trial version. But why did we include the UnitPrice, TrialExpire, and PreRequisite columns in the query’s design grid? As it turns out, you can retrieve any of these fields from the current row in the combo box by referencing the combo box Column property. (You’ll see later in this chapter, in “Validating Complex Data” on page 1604, that other code behind the form uses the additional fields to make sure the contact already owns any prerequisite product.) You can see the simple line of code that copies the UnitPrice field by opening the Visual Basic module behind the fsubContactProducts form. Go to the Navigation pane, select the fsubContactProducts form, right-click the form and click Design View on the menu, and then click the View Code button in the Tools group on the Design tab. In the Visual Basic Editor (VBE) Code window, scroll down until you find the cmbProductID_AfterUpdate procedure. The code is as follows: Private Sub cmbProductID_AfterUpdate() ' Grab the default price from the hidden 5th column Me.SoldPrice = Me.cmbProductID.Column(4) End Sub
Notice that you use an index number to fetch the column you want and that the index starts at zero. You can reference the fifth column in the query (UnitPrice) by asking for the Column(4) property of the combo box. Notice also that the code uses the Me shortcut object to reference the form object where this code is running. Therefore, every time you
1588 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
pick a different product, the After Update event occurs for the ProductID combo box, and this code fills in the related price automatically. Close the fSubContactProducts form before continuing with the next section. If you open the frmContacts form in Design view, select the fsubContactProducts form on the Products tab, and examine the Link Child Fields and Link Master Fields properties, you’ll find that the two forms are linked on ContactID. However, the tblContactProducts table also needs a CompanyID field in its primary key. Code in the module for the fsubContactProducts form handles fetching the default CompanyID for the current contact, so you don’t need an intermediary subform that would clutter the form design. If you still have the module for the fsubContactProducts form open in the VBE window, you can find the code in the Form_BeforeInsert procedure. The code is as follows: Private Sub Form_BeforeInsert(Cancel As Integer) Dim varCompanyID As Variant ' First, disallow insert if nothing in outer form If IsNothing(Me.Parent.ContactID) Then MsgBox "You must define the contact information on a new row before "attempting to sell a product", vbCritical, gstrAppTitle Cancel = True Exit Sub End If ' Try to lookup this contact's Company ID varCompanyID = DLookup("CompanyID", "qryContactDefaultCompany", _ "(ContactID = " & Me.Parent.ContactID.Value & ")") If IsNothing(varCompanyID) Then ' If not found, then disallow product sale MsgBox "You cannot sell a product to a Contact that does not have a "related Company that is marked as the default for this Contact." " Press Esc to clear your edits and click on the Companies tab " "to define the default Company for this Contact.", vbCritical, _ gstrAppTitle Cancel = True Else ' Assign the company ID behind the scenes Me.CompanyID = varCompanyID End If End Sub
" & _
" & _ & _ & _
This procedure executes whenever the user sets any value on a new row in the subform. First, it makes sure that the outer form has a valid ContactID. Next, the code uses the DLookup domain function to attempt to fetch the default company ID for the current contact. The query includes a filter to return only the rows from tblCompanyContacts where the DefaultForContact field is True. If the function returns a valid value, the code sets the required CompanyID field automatically. If it can’t find a CompanyID, the code uses the MsgBox statement to tell the user about the error.
Assisting Data Entry 1589
The IsNothing function that you see used in code throughout all the sample applications is not a built-in Visual Basic function. This function tests the value you pass to it for “nothing”—Null, zero, or a zero-length string. You can find this function in the modUtility standard module in all the sample databases.
INSIDE OUT
Understanding the Useful Domain Functions
Quite frequently in code, in a query, or in the control source of a control on a form or report, you might need to look up a single value from one of the tables or queries in your database. Although you can certainly go to the trouble of defining and opening a recordset in code, Microsoft Access provides a set of functions, called domain functions, that can provide the value you need with a single function call. The available functions are as follows:
Function Name
Description
DFirst, DLast
Return a random value from the specified domain (the table or query that’s the record source)
DLookup
Looks up a value in the specified domain
DMax
Returns the highest (Max) value in the specified domain
DMin
Returns the lowest (Min) value in the specified domain
DStDev, DstDevP Return the standard deviation of a population sample or a population of the specified domain DSum
Returns the sum of an expression from a domain
DVar, DVarP
Return the variance of a population sample or a population of the specified domain
The syntax to call a domain function is as follows: (, [, ])
where is the name of one of the functions in the preceding list; is a string literal or name of a string variable containing the name of a field or an expression using fields from the specified domain; is a string literal or name of a string variable containing the name of a table or query in your database;
Chapter 25
Note
1590 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
is a string literal or name of a string variable containing a Boolean comparison expression to filter the records in the domain Note that when a domain function finds no records, the returned value is a Null, so you should always assign the result to a Variant data type variable. When you construct a criteria expression, you must enclose string literals in quotes and date/time literals in the # character. (If you use double quotes to delimit the criteria string literal, then use single quotes around literals inside the string, and vice versa.) For example, to find the lowest work postal code value for all contacts where the contact type is customer and the birth date is before January 1, 1970, enter: DMin("WorkPostalCode", "tblContacts", "[ContactType] = 'customer' And Format([BirthDate], 'mm/dd/yyyy') < #01/01/1970#")
Handling the NotInList Event In almost every data entry form you’ll ever build, you’ll need to provide a way for the user to set the foreign key of the edited record on the many side of a relationship to point back to the correct one side record—for example, to set the ProductID field in the tblContactProducts table when selling a product on the Products tab of the frmContacts form. But what if the user needs to create a new product? Should the user have to open the form to edit products first to create the new product before selling it? The answer is a resounding no, but you must write code in the NotInList event of the combo box to handle new values and provide a way to create new rows in the tblProducts table. Figure 25-3 shows you what happens when the user tries to type a product name that’s not already in the tblProducts table. In this case, the customer wants to purchase a two-year support contract instead of the already available one-year product. You can see that something has intercepted the new product name to confirm that the user wants to add the new product.
Assisting Data Entry 1591
Chapter 25
Figure 25-3 When you enter a product that isn’t defined in the database, the application asks if you want to add the new product.
First, the combo box has been defined with its Limit To List property set to Yes. Second, there’s an event procedure defined to handle the NotInList event of the combo box, and it is this code that’s asking whether the user wants to add a product. If the user clicks Yes to confirm adding this product, the event procedure opens the frmProductAdd form in Dialog mode to let the user enter the new data, as shown in Figure 25-4. Opening a form in Dialog mode forces the user to respond before the application resumes execution. The code that opens this form passes the product name entered and the product type that the user selected before entering a new product name. The user can fill in the price and other details. The user can also click Cancel to avoid saving the record and close the form. If the user clicks Save, the form saves the new product record and closes to allow the code in the NotInList event procedure to continue.
Figure 25-4 The frmProductAdd form lets you define the details for the new product.
1592 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
To see how this works, open the fsubContactProducts form in Design view, select the cmbProductID combo box control from the Selection Type combo box on the Property Sheet window, find the On Not In List event property in the Properties window, and click Build to open the code. (We had you select the combo box from the Property Sheet window because the ProductName text box control overlays the cmbProductID combo box control on the form design grid.) The code for the procedure is shown here: Private Sub cmbProductID_NotInList(NewData As String, Response As Integer) Dim strType As String, strWhere As String ' User has typed in a product name that doesn't exist strType = NewData ' Set up the test predicate strWhere = "[ProductName] = """ & strType & """" ' Ask if they want to add this product If vbYes = MsgBox("Product " & NewData & " is not defined. " & _ "Do you want to add this Product?", vbYesNo + vbQuestion + _ vbDefaultButton2, gstrAppTitle) Then ' Yup. Open the product add form and pass it the new name ' - and the pre-selected Category DoCmd.OpenForm "frmProductAdd", DataMode:=acFormAdd, _ WindowMode:=acDialog, _ OpenArgs:=strType & ";" & Me.cmbCategoryDescription ' Verify that the product really got added If IsNull(DLookup("ProductID", "tblProducts", strWhere)) Then ' Nope. MsgBox "You failed to add a Product that matched what you entered." & _ " Please try again.", vbInformation, gstrAppTitle ' Tell Access to continue - we trapped the error Response = acDataErrContinue Else ' Product added OK - tell Access so that combo gets requeried Response = acDataErrAdded End If Else ' Don't want to add - let Access display normal error Response = acDataErrDisplay End If End Sub
As you can see, Access passes two parameters to the NotInList event. The first parameter (NewData) contains the string you typed in the combo box. You can set the value of the second parameter (Response) before you exit the sub procedure to tell Access what you want to do. You wouldn’t have access to these parameters in a macro, so you can see that this event requires a Visual Basic procedure to handle it properly. The procedure first creates the criteria string that it uses later to verify that the user saved the product. Next, the procedure uses the MsgBox function to ask whether the user wants to add this product to the database (the result shown in Figure 25-3). If you’ve ever looked at the MsgBox function Help topic, you know that the second parameter is a number that’s
Assisting Data Entry 1593
the sum of all the options you want. Fortunately, Visual Basic provides named constants for these options, so you don’t have to remember the number codes. In this case, the procedure asks for a question mark icon (vbQuestion) and for the Yes and No buttons (vbYesNo) to be displayed. It also specifies that the default button is the second button (vbDefaultButton2)— the No button—just in case the user quickly presses Enter upon seeing the message. If the user clicks Yes in the message box, the procedure uses DoCmd.OpenForm to open the frmProductAdd form in Dialog mode and passes it the product name entered and the product type selected by setting the form’s OpenArgs property. Note that the use of the named parameter syntax in the call to DoCmd.OpenForm makes it easy to set the parameters you want. You must open the form in Dialog mode. If you don’t, your code continues to run while the form opens. Whenever a dialog box form is open, Visual Basic code execution stops until the dialog box closes, which is critical in this case because you need the record to be saved or canceled before you can continue with other tests. After the frmProductAdd form closes, the next statement calls the DLookup function to verify that the product really was added to the database. If the code can’t find a new matching product name (the user either changed the product name in the add form or clicked Cancel), it uses the MsgBox statement to inform the user of the problem and sets a return value in the Response parameter to tell Access that the value hasn’t been added but that Access can continue without issuing its own error message (acDataErrContinue). If the matching product name now exists (indicating the user clicked Save on the frmProductAdd form), the code tells Access that the new product now exists (acDataErrAdded). Access re-queries the combo box and attempts a new match. Finally, if the user clicks No in the message box shown in Figure 25-3, the procedure sets Response to acDataErrDisplay to tell Access to display its normal error message. The other critical piece of code is in the Load event for the frmProductAdd form. The code is as follows: Private Sub Form_Load() Dim intI As Integer If Not IsNothing(Me.OpenArgs) Then ' If called from "not in list", Openargs should have ' Product Name; Category Description ' Look for the semi-colon separating the two intI = InStr(Me.OpenArgs, ";") ' If not found, then all we have is a product name If intI = 0 Then Me.ProductName = Me.OpenArgs Else ' If called from fsubContactProducts, ' .. have category only If intI > 1 Then ' Have a product name - grab it Me.ProductName = Left(Me.OpenArgs, intI - 1)
Chapter 25
1594 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
End If Me.CategoryDescription = Mid(Me.OpenArgs, intI + 1) ' lock the category Me.CategoryDescription.Locked = True Me.CategoryDescription.Enabled = False ' .. and clear the tool tip Me.CategoryDescription.ControlTipText = "" End If End If End Sub
If you remember, the cmbProductID NotInList event procedure passes the original string that the user entered and selected the product type (the CategoryDescription field) as the OpenArgs parameter to the OpenForm method. This sets the OpenArgs property of the form being opened. The OpenArgs property should contain the new product name, a semicolon, and the selected product type, so the Form_Load procedure parses the product name and product type by using the InStr function to look for the semicolon. (The InStr function returns the offset into the string in the first parameter where it finds the string specified in the second parameter, and it returns 0 if it doesn’t find the search string.) The code then uses the two values it finds to set the ProductName and CategoryDescription fields. Also, when the code finds a category description, it locks that combo box so that the user can’t change it to something other than what was selected on the new product row in the original form.
Fixing an E-Mail Hyperlink As you learned in Chapter 9, “Creating and Working with Simple Queries,” one of the easiest ways to enter a hyperlink is to use the Insert Hyperlink feature. However, you can also type the hyperlink address directly into the field in a datasheet or form. Remember that a hyperlink field can contain up to four parts: display text, hyperlink address, bookmark, and ScreenTip text. If a user simply enters an e-mail address into a hyperlink field, Access 2010 recognizes the format, adds the mailto: protocol, and uses what the user typed as the display text. For example, if the user enters [email protected]
Rather than repeat the e-mail address as the display text, the result might look better if the display text is the person’s name rather than a repeat of the e-mail address. One of the forms that has an e-mail address is the frmContacts form in the Conrad Systems Contacts application. You can find the code that examines and attempts to fix the address in the AfterUpdate event procedure for the EmailName text box. (If the user enters some valid protocol other than http:// or mailto:, this code won’t fix it.) The code is as follows:
Assisting Data Entry 1595
Private Sub EmailName_AfterUpdate() ' If you just type in an email name: [email protected] ' Access changes it to: [email protected]#mailto:[email protected]# ' This code replaces the display field with the user name Dim intI As Integer ' Don't do anything if email is empty If IsNothing(Me.EmailName) Then Exit Sub ' Fix up http:// if it's there ' This was an old bug in 2003 and earlier, but fixed in Access 2007 Me.EmailName = Replace(Me.EmailName, "http://", "mailto:") ' Now look for the first "#" that delimits the hyperlink display name intI = InStr(Me.EmailName, "#") ' And put the person name there instead if found If intI > 0 Then Me.EmailName = (Me.FirstName + " ") & Me.LastName & _ Mid(Me.EmailName, intI) End If End Sub
If the user clears the EmailName text box, the code doesn’t do anything. If there’s something in the text box, the code uses the Replace function to search for an incorrect http:// and replace it with the correct mailto: protocol identifier. As you know, a hyperlink field can contain text that is displayed instead of the hyperlink, a # character delimiter, and the actual hyperlink address. The code uses the InStr function to check for the presence of the delimiter. (The InStr function returns the offset into the string in the first parameter where it finds the string specified in the second parameter.) If the code finds the delimiter, it replaces the contents of the field with the person’s first and last name as display text followed by the text starting with the # delimiter. (The Mid function called with no length specification—the optional third parameter—returns all characters starting at the specified offset.)
Note In Access 2003 and earlier, when you typed an e-mail address without the mailto: protocol prefix into a hyperlink field, Access would store the hyperlink with the http:// protocol prefix in error. This bug was fixed in Access 2007, but the preceding code will fix that problem if you use it in the earlier versions of the software.
Providing a Graphical Calendar You can always provide an input mask to help a user enter a date and time value correctly, but an input mask can be awkward—always requiring, for example, that the user type a two-digit month. An input mask also can conflict with any default value that you might want to assign. It’s much more helpful if the user can choose the date using a graphical calendar.
Chapter 25
1596 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
Access 2010 provides a Show Date Picker property for text boxes. You can set this property to For Dates to instruct Access to display a calendar icon next to the control when it contains a date/time value and has the focus. The user can click the button to pop open a graphical calendar to select a date value. But Show Date Picker isn’t available for controls other than the text box control, and the date picker lets the user enter only a date, not a date and time. You also are restricted to moving backward and forward one month at a time using the left and right arrow keys on the date picker, so if you need to enter a date that is many months away from the current date, such as a birth date, you’ll have to click the arrow keys many times to reach the correct month and year. Both the Conrad Systems Contacts and the Housing Reservations sample applications provide sample calendar forms and code you can use to set a date/time value in any control. The two applications have a calendar form—frmCalendar—that uses Visual Basic code to “draw” the calendar on a form using an option group and toggle button controls. This calendar form provides an option to enter a time as well as select a date.
Troubleshooting Why isn’t Access setting my defined default value for a date/time field? Did you also define an Input Mask property? If so, then that’s your problem. A date/ time field is actually a floating-point number, but Access always converts and displays the character value in table and query datasheets and forms and reports. When you define an Input Mask property, any Default Value setting must match the restrictions imposed by the input mask. If the value violates the restrictions, Access won’t use the default value. When you assign a default value to a date/time field, you typically use the Date or Now built-in functions. These functions return a valid date/time floatingpoint value—which probably won’t match your input mask restrictions. To have Access use the default value, you must format it to match your input mask. For example, if your input mask is 90/00/0000\ 00:00, then you should set the Default Value property of the field or control to =Format(Now(), "mm/dd/yyyy hh:nn"). This forces Access to return a string value as the default that matches your input mask.
This graphical facility is available in the sample applications wherever you see a small command button next to a control containing a date or date/time field on a form. Click the button to open the calendar and set the value. One control that uses our custom calendar form is the ContactDateTime control on the Events tab of the frmContacts form. You can see the calendar open in Figure 25-5.
Assisting Data Entry 1597
Chapter 25
Figure 25-5 Click the calendar command button next to the ContactDateTime control on the Events tab of the frmContacts form to open a graphical form to select the date and enter the time.
The code in the Click event of this command button calls a public function to open the form and pass it the related control that should receive the resulting date value. You can find the code shown here in the module for the fsubContactEvents form: Private Sub cmdContactTimeCal_Click() Dim varReturn As Variant ' Clicked the calendar icon asking for graphical help ' Put the focus on the control to be updated Me.ContactDateTime.SetFocus ' Call the get a date/time function varReturn = GetDate(Me.ContactDateTime, False) End Sub
INSIDE OUT
Use Keyboard Shortcuts to Jump to Procedures and Functions
If you highlight the function call, GetDate in our previous example, and then press Shift+F2, Access takes you directly to that function in the modCalendar module.
When the user clicks the command button, Access moves the focus to it. The code moves the focus back to the date field to be edited and calls the public function where the real action happens. You can find the code for the function GetDate in the modCalendar module; the code is also listed here:
1598 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
Option Compare Database Option Explicit Public Function GetDate(ctl As control, _ Optional intDateOnly As Integer = 0) As Integer '----------------------------------------------------------' Inputs: A Control object containing a date/time value ' Optional "date only" (no time value) flag ' Outputs: Sets the Control to the value returned by frmCalendar ' Created By: JLV 09/05/01 ' Last Revised: JLV 09/05/01 '----------------------------------------------------------Dim varDateTime As Variant Dim strDateTime As String Dim frm As Form ' Error trap just in case On Error GoTo Error_Date ' First, validate the kind of control passed Select Case ctl.ControlType ' Text box, combo box, and list box are OK Case acTextBox, acListBox, acComboBox Case Else GetDate = False Exit Function End Select ' If the control has no value If IsNothing(ctl.Value) Then If intDateOnly Then ' Set default date varDateTime = Date Else ' .. or default date and time varDateTime = Now End If Else ' Otherwise, pick up the current value varDateTime = ctl.Value ' Make sure it's a date/time If vbDate varType(varDateTime) Then GetDate = False Exit Function End If End If ' Turn the date and time into a string ' to pass to the form strDateTime = Format(varDateTime, "mm/dd/yyyy hh:nn") ' Make sure we don't have an old copy of ' frmCalendar hanging around If IsFormLoaded("frmCalendar") Then DoCmd.Close acForm, "frmCalendar" End If ' Open the calendar as a dialog so this code waits, ' and pass the date/time value
Assisting Data Entry 1599
DoCmd.OpenForm "frmCalendar", WindowMode:=acDialog, _ OpenArgs:=strDateTime & "," & intDateOnly ' If the form is gone, user canceled the update If Not IsFormLoaded("frmCalendar") Then Exit Function ' Get a pointer to the now-hidden form Set frm = Forms!frmCalendar ' Grab the date part off the hidden text box strDateTime = Format(frm.ctlCalendar.Value, "dd-mmm-yyyy") If Not intDateOnly Then ' If looking for date and time, ' also grab the hour and minute strDateTime = strDateTime & " " & frm.txtHour & _ ":" & frm.txtMinute End If ' Stuff the returned value back in the caller's control ctl.Value = DateValue(strDateTime) + TimeValue(strDateTime) ' Close the calendar form to clean up DoCmd.Close acForm, "frmCalendar" GetDate = True Exit_Date: Exit Function Error_Date: ' This code is pretty simple and does check for ' a usable control type, ' .. so this should never happen. ' But if it does, log it... ErrorLog "GetDate", Err, Error GetDate = False Resume Exit_Date End Function
The function begins by setting an error trap that executes the code at the Error_Date label if anything goes wrong. The function accepts two arguments—ctlToUpdate and intDateOnly. Access uses the ctlToUpdate argument to examine the control type and control value passed into the function. Access uses the optional intDateOnly argument to indicate whether the control needs a date and time or a date only. The function checks to see if the control passed in is a text box, combo box, or list box. If the control matches one of these control types, the function continues; otherwise, the function exists. The function then checks the value of the control passed in. If there is no value in the control, Access assigns the current date to the variant varDateTime or the current date and time, depending upon the value of the intDateOnly argument. If the control has a value, the function assigns the current value of the control to the variant and also verifies the value is a valid date and time. Next, the function converts the variant value to a string and checks to see if the frmCalendar form is open. If the function finds the calendar form currently open, the function closes it, and then reopens the form in Dialog mode. In the OpenForm call to frmCalendar, the function passes in the string value of the date and time and the intDateOnly value as OpenArgs parameters.
Chapter 25
1600 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
After the user clicks either the Save or Cancel button on the frmCalendar form, this function continues executing. If the user cancels the update by clicking the cmdCancel command button on the frmCalendar form, the function exits. If the user clicks the cmdSave command button on the frmCalendar form, the function grabs the selected date and time information off the form, sets the calling control’s value to the date and time data, closes the frmCalendar form, and then exits. The final pieces of code that make all of this work are in the module behind the frmCalendar form. The code in the Load event of the form is listed here: Private Sub Form_Load() ' Establish an initial value for the date If IsNothing(Me.OpenArgs) Then varDate = Date Else ' Should have date, time, and "DateOnly" ' indicator in OpenArgs: ' mm/dd/yyyy hh:mm,-1 varDate = Left(Me.OpenArgs, 10) Me.txtHour = Mid(Me.OpenArgs, 12, 2) Me.txtMinute = Mid(Me.OpenArgs, 15, 2) ' If "date only" If Right(Me.OpenArgs, 2) = "-1" Then ' Hide some stuff Me.txtHour.Visible = False Me.txtMinute.Visible = False Me.lblColon.Visible = False Me.lblTimeInstruct.Visible = False Me.SetFocus ' .. and resize my window DoCmd.MoveSize , , , 4295 End If End If ' Initialize the month selector Me.cmbMonth = Month(varDate) ' Initialize the year selector Me.cmbYear = Year(varDate) ' Call the common calendar draw routine SetDays ' Place the date/time value in a hidden control ' The calling routine fetches it from here Me.ctlCalendar = varDate ' Highlight the correct day box in the calendar Me.optCalendar = Day(varDate) End Sub
Assisting Data Entry 1601
This code first checks to see if any OpenArgs parameters are passed into the form. If no OpenArgs parameters are passed in, the code assigns the current date to a variant called varDate. If there are OpenArgs parameters passed in, the code parses out the OpenArgs elements for the date and possible time portion. If the optional intDateOnly variable from the GetDate function is True (the control needs only a date value, not a date and time value), the form shrinks to hide those text boxes. Because the event date/time field needs a time value, this parameter is False, so you should be able to see the hour and minute text boxes. The final parts of the code set up the calendar from control elements to match either the value already in the control or the system date and time. (Note that the code calls a SetDays procedure included in the form’s class module to set up the various from controls.) After the setup code for the calendar form controls completes, the form waits until the user enters a value and clicks Save or decides not to change the value by clicking Cancel. The code for the two procedures that respond to the command buttons are as follows: Public Sub cmdCancel_Click() ' Closing doesn't pass the value back DoCmd.Close acForm, Me.Name End Sub Private Sub cmdSave_Click() ' Hiding this dialog lets the calling code in GetDate continue Me.Visible = False End Sub
Clicking the Cancel button (cmdCancel_Click) simply closes the form without changing any value in the control passed to the form. The code that saves the value that the user selects on the graphical calendar is in the GetDate module. To save the value, the click event for the cmdSave command button simply hides the frmCalendar form.
Troubleshooting Why can’t I find the ActiveX Calendar Control in Access 2010? In Access 2010, Microsoft removed the ActiveX Calendar Control that shipped with many past versions of Access. If you want to show a graphical calendar to your users when they need to select a date, you’ll need to use the newer, built-in Date Picker control included with Access or create your own calendar form using Visual Basic, as we have in the Conrad Systems Contacts and the Housing Reservations sample applications.
Chapter 25
1602 Chapter 25 Automating Your Application with Visual Basic
Working with Linked Photos Chapter 25
Although you can certainly store and display photos in an Access application using the OLE Object data type, if your application needs to handle hundreds or thousands of photos, you could easily exceed the 2-GB file size limit for an .accdb file. You can also use the Attachment data type for your photos to store them more efficiently, but you still might run into file size limitations if you need to store many photos. The alternative method is to store the pictures as files and save the picture path as a text field in your tables. The good news is the image control in Access 2010 lets you specify a Control Source property. When this property points to a field containing a folder and file location as a text string, the image control will load the photo for you from that location. However, you should still provide features in your forms to help users to easily edit the file location information. The Housing Reservations database (Housing.accdb) is designed to use this functionality. Open the Housing.accdb sample database and then open the frmEmployeesPlain form, as shown in Figure 25-6. The employee picture you see on the frmEmployees and frmEmployeesPlain forms is fetched by the image control from the path stored in the Photo field of the table.
Figure 25-6 The image control loads the photo on the Employees form from a picture path.
Notice that the user cannot see the contents of the Photo field that contains the picture path information. However, we’ve provided two command buttons to make it easy for the user to edit or delete the photo path information.
Assisting Data Entry 1603
Clearing the file name saved in the record is the easy part, so let’s look at that first. Behind the Delete button that you can see on the frmEmployeesPlain form, you can find the following code: Private Sub cmdDelete_Click() ' User asked to remove the picture ' Clear photo Me.txtPhoto = Null ' Set the message Me.lblMsg.Caption = "Click Add to create a photo for this employee." ' Put focus in a safe place Me.FirstName.SetFocus End Sub
When the user clicks the command button asking to delete the photo, the code sets the photo path to Null and displays the informative label. Setting the Photo field to Null causes the mage control to remove the image. Because the background of the image control is transparent, the label control hidden behind it shows through, displaying an informative message. The tricky part is to provide the user with a way to enter the picture path to add or update a picture in a record. Although you could certainly use the InputBox function to ask the user for the path, it’s much more professional to call the Open File dialog box in Windows so that the user can navigate to the desired picture using familiar tools. The bad news is calling any procedure in Windows is complex and usually involves setting up parameter structures and a special declaration of the external function. The good news is the Microsoft Office 2010 system includes a special FileDialog object that greatly simplifies this process. You need to add a reference to the Microsoft Office library to make it easy to use this object—to do this, from the VBE window, choose References from the Tools menu and be sure the Microsoft Office 14.0 Object Library is selected. After you do this, you can include code using the FileDialog object to load a picture path. You can find the following code behind the Click event of the Add button (cmdAdd) in the frmEmployeesPlain form: Private Sub cmdAdd_Click() ' User asked to add a new photo Dim strPath As String ' Grab a copy of the Office file dialog With Application.FileDialog(msoFileDialogFilePicker) ' Select only one file .AllowMultiSelect = False ' Set the dialog title .Title = "Locate the Employee picture file" ' Set the button caption .ButtonName = "Choose" ' Make sure the filter list is clear
Chapter 25
Deleting and Updating an Image Path
1604 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
.Filters.Clear ' Add two filters .Filters.Add "JPEGs", "*.jpg" .Filters.Add "Bitmaps", "*.bmp" ' Set the filter index to 2 .FilterIndex = 2 ' Set the initial path name .InitialFileName = CurrentProject.Path & "\Pictures" ' Show files as thumbnails .InitialView = msoFileDialogViewThumbnail ' Show the dialog and test the return If .Show = 0 Then ' Didn't pick a file - bail Exit Sub End If ' Should be only one filename - grab it strPath = Trim(.SelectedItems(1)) ' Set an error trap On Error Resume Next ' Set the image Me.txtPhoto = strPath ' Set the message in case Image control couldn't find it Me.lblMsg.Caption = "Failed to load the picture you selected." & _ " Click Add to try again." End With ' Put focus in a safe place Me.FirstName.SetFocus End Sub
The code establishes a pointer to the FileDialog object using a With statement, sets the various properties of the object (including the allowed file extensions and the initial path), and then uses the Show method to display the Open File dialog box. Setting the Photo field causes the image control to load the new picture, but the code also sets the message hidden behind the image control just in case the image control had a problem loading the file.
Validating Complex Data Although you can certainly take advantage of the Input Mask property and the field and table Validation Rule properties, your application often has additional business rules that you can enforce only by adding code behind the forms you provide to edit the data or by using data macros at the data level. The following examples show you how several of the business rules in the Conrad Systems Contacts and Housing Reservations applications are enforced with Visual Basic code.
Validating Complex Data 1605
When you design a table, you should attempt toone identify some combination of fields that will be unique across all records to use as your primary key. However, when you create a table to store information about people, you usually create an artificial number as the primary key of the table because you would need to combine many fields to ensure a unique value. Even when you attempt to construct a primary key from first name, last name, address, postal code, and phone number, you still can’t guarantee a unique value across all rows. Using an artificial primary key doesn’t mean you should abandon all efforts to identify potentially duplicate rows. Code in the frmContacts form in the Conrad Systems Contacts application (Contacts.accdb) checks the last name the user enters for a new record and issues a warning message if it finds any close names. For example, if the user creates a new record and enters a last name like “Viscas” (assuming John’s record is still in the table), code behind the form’s BeforeUpdate event detects the similar name and issues the warning shown in Figure 25-7.
Figure 25-7 The application warns you about a potential duplicate name in the contacts table.
The code searches for potential duplicates by comparing the Soundex codes of the last names. The formula for generating a Soundex code for a name was created by the U.S. National Archives and Records Administration (NARA). Soundex examines the letters by sound and produces a four-character code. When the codes for two names match, it’s
Chapter 25
Checking for Possible Duplicate Names
1606 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
likely that the names are very similar and sound alike. Therefore, by using Soundex, the error-checking code not only finds existing contacts with exactly the same last name but also other contacts whose name might be the same but one or both might be slightly misspelled. Access 2010 doesn’t provide a built-in Soundex function (SQL Server does), but it’s easy to create a simple Visual Basic procedure to generate the code for a name. You can find a Soundex function in the modUtility module in both the Conrad Systems Contacts and Housing Reservations sample databases. You can find the code that checks for a potential duplicate name in the BeforeUpdate event procedure of the frmContacts form. The code is as follows: Private Sub Form_BeforeUpdate(Cancel As Integer) Dim rst As DAO.Recordset, strNames As String ' If on a new row, If (Me.NewRecord = True) Then ' Check for similar name If Not IsNothing(Me.LastName) Then ' Open a recordset to look for similar names Set rst = CurrentDb.OpenRecordset("SELECT LastName, FirstName FROM " & _ "tblContacts WHERE Soundex([LastName]) = '" & _ Soundex(Me.LastName) & "'") ' If got some similar names, collect them for the message Do Until rst.EOF strNames = strNames & rst!LastName & ", " & rst!FirstName & vbCrLf rst.MoveNext Loop ' Done with the recordset rst.Close Set rst = Nothing ' See if we got some similar names If Len(strNames) > 0 Then ' Yup, issue warning If vbNo = MsgBox("CSD Contacts found contacts with similar " & _ "last names already saved in the database: " & vbCrLf & vbCrLf & _ strNames & vbCrLf & _ "Are you sure this contact is not a duplicate?", _ vbQuestion + vbYesNo + vbDefaultButton2, gstrAppTitle) Then ' Cancel the save Cancel = True End If End If End If End If End Sub
The code checks only when the user is about to save a new row. It opens a recordset to fetch any other contact records where the Soundex code of the last name matches the last name about to be saved. It includes all names it finds in the warning message so that
Validating Complex Data 1607
the user can verify that the new contact is not a duplicate. If the user decides not to save the record, the code sets the Cancel parameter to True to tell Access not to save the new contact.
Testing for Related Records When Deleting a Record You certainly can and should define relationships between your tables and ask Access to enforce referential integrity to prevent saving unrelated records or deleting a record that still has related records in other tables. In most cases, you do not want to activate the cascade delete feature to automatically delete related records. However, Access displays a message “The record cannot be deleted or changed because ‘tblXYZ’ contains related records” whenever the user tries to delete a record that has dependent records in other tables. You can do your own testing in code behind your forms in the Delete event and give the user a message that more clearly identifies the problem. For example, here’s the code in the Delete event procedure of the frmContacts form in the Conrad Systems Contacts application: Private Sub Form_Delete(Cancel As Integer) Dim db As DAO.Database, qd As DAO.QueryDef, rst As DAO.Recordset Dim varRelate As Variant ' Check for related child rows ' Get a pointer to this database Set db = CurrentDb ' Open the test query Set qd = db.QueryDefs("qryCheckRelateContact") ' Set the contact parameter qd!ContactNo = Me.ContactID ' Open a recordset on the related rows Set rst = qd.OpenRecordset() ' If we got rows, then can't delete If Not rst.EOF Then varRelate = Null ' Loop to build the informative error message rst.MoveFirst Do Until rst.EOF ' Grab all the table names varRelate = (varRelate + ", ") & rst!TableName rst.MoveNext Loop MsgBox "You cannot delete this Contact because you have " & _ "related rows in " & _ varRelate & _ ". Delete these records first, and then delete the Contact.", _ vbOKOnly + vbCritical, gstrAppTitle ' close all objects rst.Close qd.Close Set rst = Nothing
Chapter 25
1608 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
Set qd = Nothing Set db = Nothing ' Cancel the delete Cancel = True Exit Sub End If ' No related rows - clean up objects rst.Close qd.Close Set rst = Nothing Set qd = Nothing Set db = Nothing ' No related rows, so OK to ask if they want to delete! If vbNo = MsgBox("Are you sure you want to delete Contact " & _ Me.txtFullName & "?", _ vbQuestion + vbYesNo + vbDefaultButton2, gstrAppTitle) Then Cancel = True End If End Sub
The code uses a special UNION parameter query, qryCheckRelateContact, that attempts to fetch related rows from tblCompanyContacts, tblCompanies (the ReferredBy field), tblContactEvents, and tblContactProducts, and returns the name(s) of the table(s) that have any related rows. When the code finds rows returned by the query, it formats a message containing names more meaningful to the user, and it includes all the tables that the user must clear to be able to delete the contact. The standard Access error message lists only the first related table that Access finds. Even when the check for related records finds no problems, the code also gives the user a chance to decide not to delete the contact after all.
Verifying a Prerequisite In some applications, it makes sense to save a certain type of record only if prerequisite records exist. For example, in a school or seminar registration application, the user might need to verify that the person enrolling has successfully completed prerequisite courses. In the Conrad Systems Contacts application, it doesn’t make sense to sell support for a product that the contact doesn’t own. It’s not possible to ask Access to perform this sort of test in a validation rule, so you must write code or create a data macro to enforce this business rule. Figure 25-8 shows you the message the user sees when trying to sell support for a product that the contact doesn’t own. This message also appears if the user attempts to sell the special upgrade to a multi-user product and the contact doesn’t already own the prerequisite single-user product.
Validating Complex Data 1609
Chapter 25
Figure 25-8 Special business rule code won’t let you sell a product with a missing prerequisite.
The code that enforces this business rule is in the BeforeUpdate event procedure of the fsubContactProducts form. The code is as follows: Private Sub Form_BeforeUpdate(Cancel As Integer) Dim lngPreReq As Long, strPreReqName As String ' Check for prerequisite If Not IsNothing(Me.cmbProductID.Column(6)) Then ' Try to lookup the prerequisite for the contact lngPreReq = CLng(Me.cmbProductID.Column(6)) If IsNull(DLookup("ProductID", "tblContactProducts", _ "ProductID = " & lngPreReq & " And ContactID = " & _ Me.Parent.ContactID)) Then ' Get the name of the prerequisite strPreReqName = DLookup("ProductName", "tblProducts", _ "ProductID = " & lngPreReq) ' Display error MsgBox "This contact must own prerequisite product " & strPreReqName & _ " before you can sell this product.", vbCritical, gstrAppTitle ' Cancel the edit Cancel = True End If End If End Sub
Remember, from Figure 25-2, that the query providing the row source for the cmbProductID combo box includes any prerequisite product ID in its seventh column. When the code finds a prerequisite, it uses the DLookup function to verify that the current contact already owns the required product. If not, then the code looks up the name of the product,
1610 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
includes it in an error message displayed to the user, and disallows saving the product by setting the Cancel parameter to True. This enforces the business rule and makes it crystal clear to the user what corrective action is necessary.
Maintaining a Special Unique Value When two subjects have a many-to-many relationship in your database, you must define a linking table to create the relationship. (See Article 1, “Designing Your Database Application,” on the companion CD, for details about designing tables to support a many-to-many relationship.) You will often add fields in the linking table to further clarify the relationship between a row in one of the related tables and the matching row in another. Figure 25-9 shows you the table in the Conrad Systems Contacts application that defines the link between companies and contacts.
Figure 25-9 The tblCompanyContacts table defines the many-to-many relationship between companies and contacts.
Two special yes/no fields in this table identify which company is the default for a contact and which contact is the default for a company. However, a contact can’t have two or more default companies. Likewise, it doesn’t make sense for a company to have more than one default contact. To verify this type of special unique value constraint, you can add business rules in code behind the forms you provide to the user to edit this data.
Validating Complex Data 1611
You can find the code that ensures that there is only one default company for each contact in code behind the fsubContactCompanies form in the Conrad Systems Contacts sample application (Contacts.accdb). The code is in the BeforeUpdate event procedure for the DefaultForContact control on the form. The code is as follows: Private Sub DefaultForContact_BeforeUpdate(Cancel As Integer) ' Disallow update if there's no Company ID yet If IsNothing(Me.CompanyID) Then MsgBox "You must select a Company / Organization before" & _ " you can set Default.", _ vbCritical, gstrAppTitle Cancel = True Exit Sub End If ' Make sure there's only one default ' Check only if setting Default = True If (Me.DefaultForContact = True) Then ' Try to lookup another contact set Default If Not IsNothing(DLookup("ContactID", "tblCompanyContacts", _ "ContactID = " & Me.Parent.ContactID & _ " AND CompanyID " & Me.CompanyID & _ " AND DefaultForContact = True")) Then ' ooops... MsgBox "You have designated another Company as the" & _ " Default for this Contact." & _ " You must remove that designation before you" & _ " can mark this Company as the Default.", _ vbCritical, gstrAppTitle Cancel = True End If End If End Sub
First, the code verifies that the user has chosen a company for this record. (The Link Child Fields and Link Master Fields properties of the subform control provide the ContactID.) Next, if the user is attempting to mark this company as the default for the contact, the code uses the DLookup function to see if any other record exists (in the tblCompanyContacts table for the current contact) that is also marked as the default. If it finds such a duplicate record, it warns the user and sets the Cancel parameter to True to prevent saving the change to the control. You’ll find similar code in the fsubCompanyContacts form that makes sure only one contact is the primary for any company.
Checking for Overlapping Data When you build an application that tracks the scheduling of events or reservations that can span a period of time, you most likely need to make sure that a new event or reservation doesn’t overlap with an existing one. This can be a bit tricky, especially when the records you’re checking have start and end dates or times.
Chapter 25
1612 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
Of course, the Housing Reservations application (Housing.accdb) must make sure that an employee doesn’t enter an overlapping reservation request. To see how this works, open the sample database and then open the frmSplash form to start the application. Choose any employee name you like from the combo box in the sign-on dialog box (Jack Richins is a good choice), type password as the password, and click Sign On. On the main switchboard, click Reservation Requests. If you see the Edit Reservation Requests dialog box (because you happened to sign on as a manager), click Edit All. The Reservation Requests form won’t let you enter a reservation start date in the past. Click in the blank new row in the list of reservation requests, enter a reservation request for next week for a span of several days, and save the row. (Remember, you can click the Calendar buttons that appear next to the date fields when the focus is on the field to help you choose dates.) Enter another request that overlaps the reservation you just created either at the beginning, the end, or across the middle of the reservation you just entered. Try to save the row, and you should see a warning message similar to the one in Figure 25-10.
Figure 25-10 The Housing Reservations application displays a warning when you attempt to save an overlapping reservation request.
If you click No, the code cancels your save and returns you to the record to fix it. Notice that you can click Yes to save the duplicate—the application allows this because an employee might intend to reserve two or more rooms on the same or overlapping dates. The code that performs this check in the BeforeUpdate event of the fsubReservationRequests form is as follows (note that this code is near the end of the BeforeUpdate event code):
Controlling Tabbing on a Multiple-Page Form 1613
Dim varNum As Variant ' Check for overlap with existing request ' Try to grab RequestID - will be Null on unsaved row varNum = Me.RequestID If IsNull(varNum) Then varNum = 0 ' Set dummy value If Not IsNull(DLookup("RequestID", "tblReservationRequests", _ "(EmployeeNumber = " & _ Me.Parent.EmployeeNumber & ") AND (CheckInDate < #" & _ Format(Me.CheckOutDate, "mm/dd/yyyy") & _ "#) AND (CheckOutDate > #" & _ Format(Me.CheckInDate, "mm/dd/yyyy") & "#) AND (RequestID " & _ varNum & ")")) Then If vbNo = MsgBox("You already have a room request " & _ "that overlaps the dates you have " & _ "requested. Are you sure you want to make this request?", _ vbQuestion + vbYesNo + vbDefaultButton2, gstrAppTitle) Then Cancel = True Exit Sub End If End If
The code uses the DLookup function to see if another reservation exists (but a different request ID) for the same employee with dates that overlap. The criteria asks for any record that has a check-in date earlier than the requested checkout date (an employee can legitimately check out and then check back in on the same date) and a checkout date that is later than the requested check-in date. You might be tempted to build more complex criteria that checks all combinations of reservations that overlap into the start of the requested period, overlap into the end of the requested period, span the entire requested period, or are contained wholly within the requested period, but the two simple tests are all you need.
Controlling Tabbing on a Multiple-Page Form In Chapter 15, you learned how to create a multiple-page form as one way to handle displaying more data than will fit on one page of a form on your computer screen. You also learned how to control simple tabbing on the form by setting the form’s Cycle property to Current Page. One disadvantage of this approach is you can no longer use Tab or Shift+Tab to move to other pages or other records. You must use the Page Up and Page Down keys or the record selector buttons to do that. You can set the Cycle property to All Records to restore this capability, but some strange things happen if you don’t add code to handle page alignment. To see what happens, open the frmXmplContactsPages form in the Conrad Systems Contacts sample database (Contacts.accdb) from the Navigation pane. Press Page Down to move to the Home Address field for the first contact. Next, press Shift+Tab once (back tab). Your screen should look something like Figure 25-11.
Chapter 25
1614 Chapter 25 Automating Your Application with Visual Basic
Chapter 25 Figure 25-11 The form page doesn’t align correctly when you back-tab from the Home Address field in frmXmplContactsPages.
If you leave the Cycle property set to All Records or Current Record, tabbing across page boundaries causes misalignment unless you add some code to fix it. What happens is that Access moves the form display only far enough to show the control you just tabbed to. (In this example, you’re tabbing to the Notes text box control.) Open the sample frmContactsPages form that has the code to fix this problem and try the same exercise. You should discover that Shift+Tab places you in the Notes field, but the form scrolls up to show you the entire first page. To allow tabbing across a page boundary while providing correct page alignment, you need event procedures in the Enter event for the first and last controls that can receive the focus on each page. If you examine the code behind the frmContactsPages form, you’ll find these four procedures: Private Sub ContactID_Enter() ' If tabbing forward into this field from previous record ' align page 1 Me.GoToPage 1 End Sub Private Sub HomeAddress_Enter() ' If tabbing forward into this field, align page 2 Me.GoToPage 2 End Sub Private Sub Notes_Enter() On Error Resume Next ' If tabbing backward into the last control on page 1, align it Me.GoToPage 1 End Sub
Automating Data Selection 1615
Private Sub Photo_Enter() On Error Resume Next ' If tabbing backward into the last control on page 2, align it Me.GoToPage 2 End Sub
This is arguably some of the simplest example code in any of the sample databases, but this attention to detail will make the users of your application very happy.
Note The code also executes when you tab backward into the ContactID or HomeAddress controls or forward into the Notes or Photo control, or you can click in any of the controls. Access realizes that the form is already on the page requested in each case, so it does nothing.
Automating Data Selection One of the most common tasks to automate in a database application is filtering data. Particularly when a database contains thousands of records, users will rarely need to work with more than a few records at a time. If your edit forms always display all the records, performance can suffer greatly. So it’s a good idea to enable the user to easily specify a subset of records. This section examines four ways to do this.
Working with a Multiple-Selection List Box You work with list boxes all the time in Windows and in Access. For example, the file list in Windows Explorer is a list box, the Access 2010 Navigation pane is a list box, and the list of properties on any tab in the property sheet is a list box. In the property list box, you can select only one property from the list at a time. If you click a different property, the previous object is no longer selected—this is a simple list box. In Windows Explorer, you can select one file, select multiple noncontiguous files by holding down the Ctrl key and clicking, or select a range of files by holding down the Shift key and clicking—this is a multipleselection list box. Suppose you’re using the Conrad Systems Contacts application (Contacts.accdb) and you’re interested in looking at the details for several contacts at one time but will rarely want to look at the entire list. Start the application by opening the frmSplash form, select John Viescas as the User Name, and click Sign On (no password required). Click the Contacts button on the main switchboard form, and the application opens the Select Contacts form (frmContactList). As shown in Figure 25-12, the frmContactList form contains a multipleselection list box.
Chapter 25
1616 Chapter 25 Automating Your Application with Visual Basic
Note Chapter 25
You won’t see the Select Contacts dialog box if the Don’t Show Contact List option is selected in John’s user profile. If the Contacts form opens when you click the Contacts button on the main switchboard, close the form and click Users. Clear the Don’t Show Contact List option in John’s profile, save the record, and close the form. You should now see the Select Contacts dialog box when you click the Contacts button on the main switchboard.
Figure 25-12 You can select multiple contact records to edit in the frmContactList form.
In this list box, the contacts are shown in alphabetic order by last name, and the list is bound to the ContactID field in the underlying table. You can edit any single contact by simply double-clicking the person’s name. You can move the highlight up or down by using the arrow keys. You can also type the first letter of a contact’s last name to jump to the next contact whose last name begins with that letter. You can hold down the Shift key and use the arrow keys to extend the selection to multiple names. Finally, you can hold down either the Shift key or the Ctrl key and use the mouse to select multiple names.
Automating Data Selection 1617
Figure 25-12 shows three contacts selected using the Ctrl key and the mouse. When you click Edit, the application opens the frmContacts form with only the records you selected. As shown in Figure 25-13, the caption to the right of the Record Number box indicates that there are three available records and that the recordset is filtered.
Figure 25-13 After you select the records you want to edit in the frmContactList, the application opens the frmContacts form displaying only those records.
To see how this works, you need to go behind the scenes of the frmContactList form. Click Exit on the main switchboard form to return to the Navigation pane. (Click Yes in the message box that asks “Are you sure you want to exit?” and click No if the application offers to create a backup for you.) Select frmContactList, and open the form in Design view, as shown in Figure 25-14. Click the list box control, and open its property sheet to see how the list box is defined. The list box uses two columns from the qlkpContacts query, hiding the ContactID (the primary key that will provide a fast lookup) in the first column and displaying the contact name in the second column. The key to this list box is that its Multi Select property is set to Extended. Using the Extended setting gives you the full Ctrl+click or Shift+click features that you see in most list boxes in Windows. The default for this property is None, which lets you select only one value at a time. You can set it to Simple if you want to select or clear multiple values using the mouse or the spacebar.
Chapter 25
1618 Chapter 25 Automating Your Application with Visual Basic
Chapter 25 Figure 25-14 The multiple-selection list box on the frmContactList form has its Multi Select property set to Extended.
If you scroll down to the Event properties, you’ll find an event procedure defined for On Dbl Click. The code for this event procedure (which is called when you double-click an item in the list box) runs only the cmdSome_Click procedure. Right-click the cmdSome command button (the one whose caption says Edit), and choose Build Event from the shortcut menu to jump to the cmdSome_Click procedure that does all the work, as shown here: Private Sub cmdSome_Click() Dim strWhere As String, varItem As Variant ' Request to edit items selected in the list box ' If no items selected, then nothing to do If Me!lstCName.ItemsSelected.Count = 0 Then Exit Sub ' Loop through the items selected collection For Each varItem In Me!lstCName.ItemsSelected ' Grab the ContactID column for each selected item strWhere = strWhere & Me!lstCName.Column(0, varItem) & "," Next varItem ' Throw away the extra comma on the "IN" string strWhere = Left$(strWhere, Len(strWhere) - 1) ' Open the contacts form filtered on the selected contacts strWhere = "[ContactID] IN (" & strWhere & ") And (Inactive = False)" DoCmd.OpenForm FormName:="frmContacts", WhereCondition:=strWhere DoCmd.Close acForm, Me.Name End Sub
Automating Data Selection 1619
When you set the Multi Select property of a list box to something other than None, you can examine the control’s ItemsSelected collection to determine what (if anything) is selected. In the cmdSome_Click procedure, the Visual Basic code first checks the Count property of the control’s ItemsSelected collection to determine whether anything is selected. If the Count is 0, there’s nothing to do, so the procedure exits. The ItemsSelected collection is composed of variant values, each of which provides an index to a highlighted item in the list box. The For Each loop asks Visual Basic to loop through all the available variant values in the collection, one at a time. Within the loop, the code uses the value of the variant to retrieve the Contact ID from the list. List boxes also have a Column property, and you can reference all the values in the list by using a statement such as Me.ListBoxName.Column(ColumnNum, RowNum)
where ListBoxName is the name of your list box control, ColumnNum is the relative column number (the first column is 0, the second is 1, and so on), and RowNum is the relative row number (also starting at 0). The variant values in the ItemsSelected collection return the relative row number. This Visual Basic code uses column 0 and the values in the ItemsSelected collection to append each selected ContactID to a string variable, separated by commas. You’ll recall from studying the IN predicate in Chapter 9 that a list of values separated by commas is ideal for an IN clause. After retrieving all the ContactID numbers, the next statement removes the trailing comma from the string. The final Where clause includes an additional criterion to display only active contacts. The DoCmd.OpenForm command uses the resulting string to create a filter clause as it opens the form. Finally, the code closes the frmContactList form. (Me.Name is the name of the current form.)
Providing a Custom Query By Form Suppose you want to do a more complex search on the frmContacts form—using criteria such as contact type, company, or products owned rather than simply using contact name. You could teach your users how to use the Filter By Form features to build the search, or you could use Filter By Form to easily construct multiple OR criteria on simple tests. But if you want to find, for example, all contacts who own the Single User edition or whom you contacted between certain dates, there’s no way to construct this request using standard filtering features. The reason for this is that when you define a filter for a subform (such as the Events subform in frmContacts) using Filter By Form, you’re filtering only the subform rows. You’re not finding contacts who have only a matching subform row.
Chapter 25
1620 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
The only solution, then, is to provide a custom Query By Form that provides options to search on all the important fields and then build the Where clause to solve the search problem using Visual Basic code. To start, open the Conrad Systems Contacts application. (If you have exited to the Navigation pane, you can start the application by opening frmSplash.) Sign on, click the Contacts button on the main switchboard form, and then click the Search button in the Select Contacts dialog box. You should see the fdlgContactSearch form, as shown in Figure 25-15.
Figure 25-15 You can design a custom Query By Form to perform a complex search.
Try selecting contacts whose last name begins with the letter M, whom you contacted between September 1, 2010, and December 15, 2010, and who own the BO$$ Single User product (from the Owns Product drop-down list). When you click Search, you should see the frmContacts form open and display two contacts. To see how this works, you need to explore the design of the fdlgContactSearch form. Switch to the Navigation pane (by pressing F11), and open the form in Design view. You should see a window like Figure 25-16. Notice that the form is not bound to any record source. The controls must be unbound so they can accept any criteria values that a user might enter.
Automating Data Selection 1621
Chapter 25
Figure 25-16 When you look at the fdlgContactSearch form in Design view, you can see that it has no record source.
The bulk of the work happens when you click Search. The code for the event procedure for the Click event of the Search button is shown here: Private Sub cmdSearch_Click() Dim varWhere As Variant, varDateSearch As Variant Dim rst As DAO.Recordset ' Initialize to Null varWhere = Null varDateSearch = Null ' First, validate the dates ' If there's something in Contact Date From If Not IsNothing(Me.txtContactFrom) Then ' First, make sure it's a valid date If Not IsDate(Format(Me.txtContactFrom, "mm/dd/yyyy")) Then ' Nope, warn them and bail MsgBox "The value in Contact From is not a valid date.", _ vbCritical, gstrAppTitle Exit Sub End If ' Now see if they specified a "to" date If Not IsNothing(Me.txtContactTo) Then ' First, make sure it's a valid date If Not IsDate(Format(Me.txtContactTo, "mm/dd/yyyy")) Then ' Nope, warn them and bail MsgBox "The value in Contact To is not a valid date.", _ vbCritical, gstrAppTitle Exit Sub
1622 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
End If ' Got two dates, now make sure "to" is >= "from" If Format(Me.txtContactTo, "mm/dd/yyyy") < _ Format(Me.txtContactFrom, "mm/dd/yyyy") Then MsgBox "Contact To date must be greater than " & _ "or equal to Contact From date.", _ vbCritical, gstrAppTitle Exit Sub End If End If Else ' No "from" but did they specify a "to"? If Not IsNothing(Me.txtContactTo) Then ' Make sure it's a valid date If Not IsDate(Format(Me.txtContactTo, "mm/dd/yyyy")) Then ' Nope, warn them and bail MsgBox "The value in Contact To is not a valid date.", _ vbCritical, gstrAppTitle Exit Sub End If End If End If ' If there's something in Follow-up Date From If Not IsNothing(Me.txtFollowUpFrom) Then ' First, make sure it's a valid date If Not IsDate(Format(Me.txtFollowUpFrom, "mm/dd/yyyy")) Then ' Nope, warn them and bail MsgBox "The value in Follow-up From is not a valid date.", _ vbCritical, gstrAppTitle Exit Sub End If ' Now see if they specified a "to" date If Not IsNothing(Me.txtFollowUpTo) Then ' First, make sure it's a valid date If Not IsDate(Format(Me.txtFollowUpTo, "mm/dd/yyyy")) Then ' Nope, warn them and bail MsgBox "The value in Follow-up To is not a valid date.", _ vbCritical, gstrAppTitle Exit Sub End If ' Got two dates, now make sure "to" is >= "from" If Format(Me.txtFollowUpTo, "mm/dd/yyyy") < _ Format(Me.txtFollowUpFrom, "mm/dd/yyyy") Then MsgBox "Follow-up To date must be greater than " & _ "or equal to Follow-up From date.", _ vbCritical, gstrAppTitle Exit Sub End If End If Else ' No "from" but did they specify a "to"? If Not IsNothing(Me.txtFollowUpTo) Then ' Make sure it's a valid date
Automating Data Selection 1623
If Not IsDate(Format(Me.txtFollowUpTo, "mm/dd/yyyy")) Then ' Nope, warn them and bail MsgBox "The value in Follow-up To is not a valid date.", _ vbCritical, gstrAppTitle Exit Sub End If End If End If ' OK, start building the filter ' If specified a contact type value If Not IsNothing(Me.cmbContactType) Then ' .. build the predicate varWhere = "(ContactType.Value = '" & Me.cmbContactType & "')" End If ' Do Last Name next If Not IsNothing(Me.txtLastName) Then ' .. build the predicate ' Note: taking advantage of Null propagation ' so we don't have to test for any previous predicate varWhere = (varWhere + " AND ") & "([LastName] LIKE '" & _ Me.txtLastName & "*')" End If ' Do First Name next If Not IsNothing(Me.txtFirstName) Then ' .. build the predicate varWhere = (varWhere + " AND ") & "([FirstName] LIKE '" & _ Me.txtFirstName & "*')" End If ' Do Company next If Not IsNothing(Me.cmbCompanyID) Then ' .. build the predicate ' Must use a subquery here because the value is in a linking table... varWhere = (varWhere + " AND ") & _ "([ContactID] IN (SELECT ContactID FROM tblCompanyContacts " & _ "WHERE tblCompanyContacts.CompanyID = " & Me.cmbCompanyID & "))" End If ' Do City next If Not IsNothing(Me.txtCity) Then ' .. build the predicate ' Test for both Work and Home city varWhere = (varWhere + " AND ") & "(([WorkCity] LIKE '" & _ Me.txtCity & "*')" & _ " OR ([HomeCity] LIKE '" & Me.txtCity & "*'))" End If ' Do State next If Not IsNothing(Me.txtState) Then ' .. build the predicate ' Test for both Work and Home state varWhere = (varWhere + " AND ") & "(([WorkStateOrProvince] LIKE '" & _ Me.txtState & "*')" & _ " OR ([HomeStateOrProvince] LIKE '" & Me.txtState & "*'))" End If
Chapter 25
1624 Chapter 25 Automating Your Application with Visual Basic
Chapter 25
' Do Contact date(s) next -- this is a toughie ' because we want to end up with one filter on the subquery table ' for both Contact Date range and FollowUp Date range ' Check Contact From first If Not IsNothing(Me.txtContactFrom) Then ' .. build the predicate varDateSearch = "tblContactEvents.ContactDateTime >= #" & _ Format(Me.txtContactFrom, "mm/dd/yyyy") & "#" End If ' Now do Contact To If Not IsNothing(Me.txtContactTo) Then ' .. add to the predicate, but add one because ContactDateTime includes ' a date AND a time varDateSearch = (varDateSearch + " AND ") & _ "tblContactEvents.ContactDateTime < #" & _ CDate(Format(Me.txtContactTo, "mm/dd/yyyy")) + 1 & "#" End If ' Now do Follow-up From If Not IsNothing(Me.txtFollowUpFrom) Then ' .. add to the predicate varDateSearch = (varDateSearch + " AND ") & _ "tblContactEvents.ContactFollowUpDate >= #" & _ Format(Me.txtFollowUpFrom, "mm/dd/yyyy") & "#" End If ' Finally, do Follow-up To If Not IsNothing(Me.txtFollowUpTo) Then ' .. add to the predicate varDateSearch = (varDateSearch + " AND ") & _ "tblContactEvents.ContactFollowUpDate
Let’s take a look at attributes you can assign to Backstage view controls. Table 26-6 lists the Backstage view attributes you can use in your XML customization.
Chapter 26
1700 Chapter 26 The Finishing Touches
Table 26-6 Backstage View Attributes
Chapter 26
Attribute
Value or Type
Description
align
topLeft, top, topRight, left, center, right, bottomLeft, bottom, or bottomRight
Determines where child controls will be aligned in a layoutContainer.
alignLabel
topLeft, top, topRight, left, center, right, bottomLeft, bottom, or bottomRight
Determines the alignment of a label relative to its control.
allowedTaskSizes
largeMediumSmall, largeMe- Determines the sizes that are dium, large, mediumSmall, allowed for a task control in a medium, or small taskGroup or taskFormGroup control.
altText
String
Specifies text that appears when the mouse is hovered over an imageControl.
columnWidthPercent
Positive Integer
Determines the division of columns as a percentage of the width of an entire tab.
expand
horizontal, vertical, both, or neither
Determines how a control expands in a container.
firstColumnMaxWidth
Positive Integer
Determines the maximum width (in pixels) of the first column in a tab.
firstColumnMinWidth
Positive Integer
Determines the minimum width (in pixels) of the first column in a tab.
getAltText
Callback
Defines the macro or procedure that sets the altText for an imageControl.
getHelperText
Callback
Defines the macro or procedure that sets the helperText for a group.
getStyle
Callback
Defines the macro or procedure that sets the style for a group.
helperText
String
Specifies additional text to appear with a group.
isDefinitive
True or False
Determines whether an action should close the Backstage.
layoutChildren
horizontal or vertical
Determines the layout direction for child controls in a layoutContainer.
Using Ribbon Attributes 1701
Attribute
Value or Type
Description
onHide
Callback
Defines the macro or procedure that runs when the Backstage is closed.
onShow
Callback
Defines the macro or procedure that runs when the Backstage is opened.
secondColumnMaxWidth Positive Integer
Determines the maximum width in pixels of the second column in a tab.
secondColumnMinWidth Positive Integer
Determines the minimum width in pixels of the second column in a tab.
style
normal, warning, or error
Determines the appearance for a group.
style
normal, borderless, or large
Determines the size and style for a button.
In addition to attributes you can use in your XML customization, you can create many types of Backstage view controls. Table 26-7 lists the types of controls you can use in a custom Backstage view definition and their associated attributes (properties) and callbacks (event properties). Table 26-7 Backstage Controls
Creating a Custom Quick Access Toolbar If you take a close look at the Quick Access Toolbar in Figure 26-15, you’ll notice that we also have our own custom Quick Access Toolbar. You’ve previously learned that if you set the StartFromScratch attribute of your customization to True, Access disables all the buttons on the Quick Access Toolbar. You can selectively add buttons and commands to your custom Quick Access Toolbar by using the and tags. Near the top of the rbnMain and rbnMainBackstage ribbons in the USysRibbons table, you can see the following XML that we’re using to show a few of the built-in commands on the Quick Access Toolbar: ....(remaining XML customization here)....
Chapter 26
1704 Chapter 26 The Finishing Touches
Setting Focus to a Tab Chapter 26
In the Conrad Systems Contacts and Housing Reservations sample databases, we want to display our main ribbon at all times. For the data entry forms, we want to still see the main tab when the custom ribbon for forms is open but put the focus on the Navigation tab as a visual cue for the users of the application. Instead, the Navigation tab opens to the right of the main tab but does not receive focus. Fortunately, RibbonX does provide a TabSetFormReportExtensibility element that you can use for these cases. When you use the TabSetFormReportExtensibility element, Access places the content into the current tabSet, moves the focus to this tab, and places a caption above the tab. The tab caption matches the Caption property of the current form or report if this property is set. If no caption is set, Access uses the current name of the object. In the rbnForms custom ribbon in both Conrad Systems Contacts and Housing Reservations, we duplicated all the controls in the main ribbon—rbnCSD or rbnProseware—and then added the XML necessary to display the tab we wanted with groups and controls for form navigation. The specific customization for these follows this format: ....(remaining XML customization here)....
INSIDE OUT
Use VBA to Change Ribbon Tab Focus
In Office 2007, the RibbonX architecture did not support a method to place the focus on a specific tab. In Office 2010, Microsoft now added a method that you can use to set focus to a ribbon tab. An example VBA call in Access to put focus on the main ribbon tab—rbnProseware—in the Housing.accdb would be the following: gobjRibbon1.ActivateTab "tabProseware"
In essence, we created our own contextual tab that appears next to the main ribbon tab but receives the focus when the data entry forms open, as shown in Figure 26-16.
Disabling Layout View 1705
Figure 26-16 Use the TabSetFormReportExtensibility element to set focus to a specific tab.
Quite frankly, we could write an entire book about ribbon customization, but you should have enough information at this point to get started building your own custom ribbons. For more information, visit the Microsoft Developer Network website at http://msdn.microsoft.com/. In the remainder of this chapter, you’ll learn additional techniques that you can use to customize your applications for your users.
INSIDE OUT
Use One Line of VBA to Hide All Ribbon Elements
If you’d like to hide all elements of the ribbon, including the Quick Access Toolbar and Backstage view, you can write one line of Visual Basic code. In the Load event of your startup form, enter the following code to hide everything: DoCmd.ShowToolbar "Ribbon", acToolbarNo
Disabling Layout View You might have noticed as you built new forms and reports in your Access 2010 client databases that Access sets the new Allow Layout View property to Yes by default. This is a handy feature while you’re building forms and reports because it allows you to align, position, and resize controls while you view live data. When you’re ready to put your application in production, however, you need to reset this new property to No for all your forms and reports so that the users see your forms and reports as you intended. You could open every form and report in Design view, change the property, and save the form or report. But why do it the hard way? In the Access Options dialog box, you can select an option that disables the ability to open forms and reports in Layout view. Click the File tab on the Backstage view, click Options, and then click the Current Database category. In the Application Options section, clear the Enable Layout View check box, as shown in Figure 26-17.
Chapter 26
1706 Chapter 26 The Finishing Touches
Chapter 26 Figure 26-17 You can disable the ability to view objects in Layout view in the Access Options dialog box.
When you clear this option, Access does not show Layout View as an option in the Views group on the ribbon or on any shortcut menus.
Controlling How Your Application Starts and Runs Especially if you’re distributing your application for others to use, you probably want your application to automatically start when the user opens your database. You’ll also want to create a main form, such as a navigation form, to help the user navigate to the various parts of your application. You should also set properties and write code to ensure that your user can cleanly exit your application.
Setting Startup Properties for Your Database At this point, you know how to build all the pieces you need to fully implement your database application. But what if you want your application to start automatically when you open your database? One way is to create a macro named Autoexec—Access always runs this macro if it exists when you open the database (unless you hold down the Shift key when you open the database). In the Conrad Systems Contacts database, we first use an AutoExec macro to determine whether the database is being run in a trusted environment. You can also specify an opening form in the startup properties for the database. You can set these properties by clicking the File tab on the Backstage view, clicking Options, and then clicking the Current Database category, as shown in Figure 26-18.
Controlling How Your Application Starts and Runs 1707
Chapter 26
Figure 26-18 You can set startup properties for your database in the Current Database category of the Access Options dialog box.
You can specify which form opens your database by selecting a form from the Display Form list. You can also specify a custom title for the application, an icon for the application, and a custom ribbon to override the built-in ribbon. If you always open the database with its folder set to the current directory, you can simply enter the icon file name, as shown in Figure 26-18. If you’re not sure which folder will be current when the application opens, you should enter a fully qualified file name location. Note that you can also ask Access to display the icon you specify as the form and report icon instead of the standard Access icons. If you clear the Display Navigation Pane check box, Access hides the Navigation pane when your application starts. (As you’ll learn in the next section, you can also write code that executes in your startup form to ensure that the Navigation pane is hidden.) You can also hide the status bar if you want by clearing the Display Status Bar check box. We like to use the SysCmd function to display information on the status bar, so we usually leave the Display Status Bar check box selected. We recommend that you always clear the Enable Design Changes For Tables In Datasheet View (For This Database) check box if you’re using a client database. If you leave this check box selected, your users can make design changes to your tables displayed in Datasheet view, as well as any forms that open in Datasheet view. Note that this option is selected by default in a web database and is dimmed, so you cannot change the setting.
1708 Chapter 26 The Finishing Touches
Chapter 26
Finally, you can disable special keys—such as F11 to reveal the Navigation pane, Ctrl+G to open the Debug window, or Ctrl+Break to halt code execution—by clearing the Use Access Special Keys check box. As you can see, you have many powerful options for customizing how your application starts and how it operates.
Starting and Stopping Your Application Although you can set startup properties asking Access to hide the Navigation pane, you might want to include code in the Load event of your startup form to make sure that it is hidden. All the sample databases provided with this book open the frmCopyright form as the startup form. Note that the AutoExec macro in these sample databases first checks to see whether the database is running in a trusted location. If the database is in a trusted location, the macro opens frmCopyright; otherwise, the macro opens the fdlgNotTrusted form followed by the frmCopyrightNotTrusted form. The copyright forms display information about the database. In the trusted version, code behind the form checks connections to linked tables. In both the Conrad Systems Contacts and Housing Reservations sample applications, the code behind the frmCopyright form tells you to open the frmSplash form to actually start the application. When the frmSplash form opens, code in the Load event uses the following procedure to make sure the Navigation pane is hidden: ' Select the Navigation Pane DoCmd.SelectObject acForm, "frmSplash", True ' .. and hide it RunCommand acCmdWindowHide
The procedure hides the Navigation pane by selecting a known object in the Navigation pane to give the Navigation pane the focus and then executing the WindowHide command. The splash form waits for a timer to expire (the Timer event procedure) and then opens a form to sign on to the application. When you sign on successfully, the frmMain form finally opens. The frmMain form in the Conrad Systems Contacts application has no Close button and no control menu button. The database also has an AutoKeys macro defined that intercepts any attempt to close a window using the Ctrl+F4 keys. (You’ll learn about creating an AutoKeys macro in the next section.) Therefore, you must click the Exit button on the frmMain form to close the application. On the other hand, the frmMain form in the Housing Reservations application does allow you to press Ctrl+F4 or click the Close button to close the form and exit the application.
Controlling How Your Application Starts and Runs 1709
You should always write code to clean up any open forms, reset variables, and close any open recordsets when the user asks to exit your application. Because the user can’t close the frmMain form in Conrad Systems Contacts application except by clicking Exit, you’ll find such cleanup code in the command button’s Click event. In the frmMain form in the Housing Reservations database, the cleanup code is in the form’s Close event procedure. The code in both forms is similar, so here’s the exit code in the Conrad Systems Contacts sample application: Private Sub cmdExit_Click() Dim intErr As Integer, frm As Form, intI As Integer Dim strData As String, strDir As String Dim lngOpen As Long, datBackup As Date Dim strLowBkp As String, strBkp As String, intBkp As Integer Dim db As DAO.Database, rst As DAO.Recordset If vbNo = MsgBox("Are you sure you want to exit?", _ vbYesNo + vbQuestion + vbDefaultButton2, _ gstrAppTitle) Then Exit Sub End If ' Trap any errors On Error Resume Next ' Make sure all forms are closed For intI = (Forms.Count - 1) To 0 Step -1 Set frm = Forms(intI) ' Don't close myself! If frm.Name "frmMain" Then ' Use the form's "Cancel" routine frm.cmdCancel_Click DoEvents End If ' Note any error that occurred If Err 0 Then intErr = -1 Next intI ' Log any error beyond here On Error GoTo frmMain_Error ' Skip backup check if there were errors If intErr = 0 Then Set db = CurrentDb ' Open ztblVersion to see if we need to do a backup Set rst = db.OpenRecordset("ztblVersion", dbOpenDynaset) rst.MoveFirst lngOpen = rst!OpenCount datBackup = rst!LastBackup rst.Close Set rst = Nothing ' If the user has opened 10 times ' or last backup was more than 2 weeks ago...
Chapter 26
1710 Chapter 26 The Finishing Touches
Chapter 26
If (lngOpen Mod 10 = 0) Or ((Date - datBackup) > 14) Then ' Ask if they want to backup... If vbYes = MsgBox("CSD highly recommends backing up " & _ "your data to avoid " & _ "any accidental data loss. Would you like to backup now?", _ vbYesNo + vbQuestion, gstrAppTitle) Then ' Get the name of the data file strData = Mid(db.TableDefs("ztblVersion").Connect, 11) ' Get the name of its folder strDir = Left(strData, InStrRev(strData, "\")) ' See if the "BackupData" folder exists If Len(Dir(strDir & "BackupData", vbDirectory)) = 0 Then ' Nope, build it! MkDir strDir & "BackupData" End If ' Now find any existing backups - keep only three strBkp = Dir(strDir & "BackupData\CSDBkp*.accdb") Do While Len(strBkp) > 0 intBkp = intBkp + 1 If (strBkp < strLowBkp) Or (Len(strLowBkp) = 0) Then ' Save the name of the oldest backup found strLowBkp = strBkp End If ' Get the next file strBkp = Dir Loop ' If more than two backup files If intBkp > 2 Then ' Delete the oldest one Kill strDir & "BackupData\" & strLowBkp End If ' Now, setup new backup name based on today's date strBkp = strDir & "BackupData\CSDBkp" & _ Format(Date, "yymmdd") & ".accdb" ' Make sure the target file doesn't exist If Len(Dir(strBkp)) > 0 Then Kill strBkp ' Create the backup file using Compact DBEngine.CompactDatabase strData, strBkp ' Now update the backup date db.Execute "UPDATE ztblVersion SET LastBackup = #" & _ Date & "#", dbFailOnError MsgBox "Backup created successfully!", vbInformation, gstrAppTitle End If ' See if error log has 20 or more entries If db.TableDefs("ErrorLog").RecordCount > 20 Then ' Don't ask if they've said not to... If Not (DLookup("DontSendError", "tblUsers", _ "UserName = '" & gstrThisUser & "'")) Then DoCmd.OpenForm "fdlgErrorSend", WindowMode:=acDialog Else db.Execute "DELETE * FROM ErrorLog", dbFailOnError End If
Controlling How Your Application Starts and Runs 1711
End If End If Set db = Nothing End If ' Restore original keyboard behavior ' Disabled in this sample ' Application.SetOption "Behavior Entering Field", gintEnterField ' Application.SetOption "Move After Enter", gintMoveEnter ' Application.SetOption "Arrow Key Behavior", gintArrowKey ' We're outta here! frmMain_Exit: On Error GoTo 0 DoCmd.Close acForm, Me.Name ' In a production application, would quit here DoCmd.SelectObject acForm, "frmMain", True Exit Sub frmMain_Error: ErrorLog "frmMain", Err, Error Resume frmMain_Exit End Sub
After confirming that the user really wants to exit, the code looks at every open form. All forms have a public cmdCancel_Click event procedure that this code can call to ask the form to clear any pending edits and close itself. The DoEvents statement gives that code a chance to complete before going on to the next form. Notice that the code skips the form named frmMain (the form where this code is running). If there were no errors closing all the forms, then the code opens a table that contains a count of how many times this application has run and the date of the last backup. Every 10th time the application has run, or two weeks after the last backup, the code offers to create a backup of the application data. If the user confirms creating a backup, the code creates a Backup subfolder if it does not exist, deletes the oldest backup if there are three or more in the folder, and then backs up the data using the CompactDatabase method of the DBEngine. Next, the code checks to see whether more than 20 errors have been logged by code running in the application. If so, it opens a dialog box that gives the user the option to e-mail the error log, print out the error log, skip printing the error log this time, or turn off the option to print the log. Because the error log option form opens in Dialog mode, this code waits until that form closes. Finally, the code closes this form and selects an object in the Navigation pane to reveal that pane. If this weren’t a demonstration application, the code would use the Quit method of the Application object to close and exit Access. This might seem like a lot of extra work, but taking care of details like this really gives your application a professional polish.
Chapter 26
1712 Chapter 26 The Finishing Touches
Creating an AutoKeys Macro Chapter 26
As noted earlier, the Conrad Systems Contacts sample application (Contacts.accdb) has an AutoKeys macro defined to intercept pressing Ctrl+F4. You can normally press this key combination to close any window that has the focus, but the application is designed so that you must close the frmMain form using the Exit button, not Ctrl+F4. You can create an AutoKeys macro to define most keystrokes that you want to intercept and handle in some other way. You can define something as simple as a StopMacro action to effectively disable the keystroke, create a series of macro actions that respond to the keystrokes, or use the RunCode action to call complex Visual Basic code. Figure 26-19 shows you the AutoKeys macro in the Conrad Systems Contacts database, open in Design view.
Figure 26-19 The design of this AutoKeys macro intercepts the Ctrl+F4 combination.
The critical part of a macro defined as an AutoKeys macro is the submacro name. When the submacro name is a special combination of characters that match a key name, the submacro executes whenever you press those keys. Table 26-8 shows you how to construct submacro names in an AutoKeys macro to respond to specific keys. Table 26-8 AutoKeys Macro Key Codes
AutoKeys Submacro Name
Key Intercepted
^letter or ^number
Ctrl+[the named letter or number key]
{Fn}
The named function key (F1–F12)
^{Fn}
Ctrl+[the named function key]
+{Fn}
Shift+[the named function key]
{Insert}
Insert
^{Insert}
Ctrl+Insert
+{Insert}
Shift+Insert
Performing a Final Visual Basic Compile 1713
AutoKeys Submacro Name
Key Intercepted
{Delete} or {Del}
Delete
^{Delete} or ^{Del}
Ctrl+Delete
+{Delete} or +{Del}
Shift+Delete
Keep in mind that you can also intercept any keystroke on a form in the KeyDown and KeyPress events when you want to trap a particular key on only one form or control.
Performing a Final Visual Basic Compile The very last task you should perform before placing your application in production is to compile and save all your Visual Basic procedures. When you do this, Access stores a compiled version of the code in your database. Access uses the compiled code when it needs to execute a procedure you have written. If you don’t do this, Access has to load and interpret your procedures the first time you reference them—each and every time you start your application. For example, if you have several procedures in a form module, the form will open more slowly the first time because Access has to also load and compile the code. To compile and save all the Visual Basic procedures in your application, open any module—either a module object or a module associated with a form or report. Choose Compile project-name from the Debug menu, as shown in Figure 26-20. If your code compiles successfully, be sure to save the result by choosing File, Save or by clicking the Save button on the toolbar. (If you have errors in any of your code, the compiler halts at the first error it finds, displays the line of code, and displays an error message dialog box.) After successfully compiling and saving your Visual Basic project, close your database and compact it, as described in Chapter 5, “Modifying Your Table Design.”
Figure 26-20 Choose the Debug, Compile project-name command to compile all the Visual Basic procedures in your database.
Chapter 26
1714 Chapter 26 The Finishing Touches
Chapter 26
As you’ve seen in this book, you can quickly learn to build complex client and web applications. You can use the relational database management system (RDMS) in Access 2010 to store and manage your data locally, on a network, or on a server running Microsoft SharePoint, and you can access information in other popular database formats or in any server- or mainframe-hosted database that supports the Open Database Connectivity (ODBC) standard. You can get started with macros to become familiar with event-oriented programming in web and client databases. With a little practice, you’ll soon find yourself writing Visual Basic event procedures like a pro. In Chapter 27, “Distributing Your Application,” you’ll learn how to set up your application so that you can distribute it to others.
c hapte r n C 2 7o
Chapter TitleYour Application Distributing
Using Linked Tables in a Desktop Database. . . . . . . . . 1716
Creating Custom Data Type Parts . . . . . . . . . . . . . . . . . 1731
Packaging and Signing Your Database. . . . . . . . . . . . . 1739
A
lthough you can certainly use Microsoft Access 2010 to create database applications only for your personal use, most serious users of Access 2010 eventually end up building applications to be used by others. If you have created a stand-alone desktop client database application and your users all have the same version of Access installed on their computers, you can simply give them a copy of your database file to run. However, most database applications become really useful when multiple users share the data. In Chapter 8, “Importing and Linking Data,” you learned about linking tables from another database and using the Linked Table Manager. You also learned about some of the advantages of using a client-server architecture to allow multiple users running the same application to share data. Both these topics help you understand how to design and secure a multi-user application. However, they don’t provide you with the techniques you can employ in your application design to ensure that your application installs and runs smoothly and to ensure that your users can’t tamper with your code. In this chapter, you’ll learn
●●
How to split a desktop client database to use shared data on a server and linked tables on each client computer and how to create code that verifies and corrects linked table connection properties when your application starts
●●
The advantages of runtime mode and design considerations for using it
●●
How to create an execute-only version of your application so that users can’t tamper with your code
●●
Techniques for creating application shortcuts to simplify starting your application
●●
How to apply an encrypted database password to your database
●●
How to package your database and digitally sign it
●●
Tools you can use in Access 2010 Developer Extensions and Runtime to distribute your application to users who don’t have Access 1715
1716 Chapter 27 Distributing Your Application
Using Linked Tables in a Desktop Database Chapter 27
Your first foray into the world of shared applications will most likely involve copying your completed database to a file server and instructing users to open the database from the server. That’s basically not a good idea because Access client doesn’t run on the server—it runs on each user’s desktop. If you have several users sharing a database file, the copy of Access running on each user computer has to load all your “code” definitions—the queries, forms, reports, macros, and modules—over the network. If one user applies a sort or filter to a form and then closes it, Access will try to save the changed definition in the copy on the server, and it might run into locking or corruption problems if another user has the form open at the same time. Also, if your application needs to keep information about how each user works with the application, it would be more complicated to store this information in the database because all users share the same file. The solution is to create a data-only .accdb file on a server and use linked tables in a desktop client application that you install on multiple desktop computers and link to the data server. When you separate the data tables into a shared file on a server, you’re actually building a simple client-server application, much like a published Access Services application running on Microsoft SharePoint 2010. The main advantage to splitting your database over simply sharing a single desktop client database is that your application needs to retrieve only the data from the tables over the network. Because each user will have a local copy of the queries, forms, reports, macros, and modules, Access running on each user workstation will be able to load these parts of your application quickly from the local hard drive. Using a local copy of the desktop application on each client computer also makes it easy to create local tables that save settings for each user. For example, the Conrad Systems Contacts application allows each user to set a preference to open a search dialog box for companies, contacts, and invoices or to display all records directly.
INSIDE OUT
Is Your Desktop Application Designed for Client-Server?
When you build a desktop database application, it’s all too easy to design forms and reports that always display all records from your tables when the user opens them. It’s also tempting to create combo boxes or list boxes that display all available values from a lookup table. These issues have little to no impact when you’re the only user of the application or you share your application with only a few other users. However, fetching all rows by default can have serious performance implications when you have multiple users who need to share a large amount of data over a network. A successful client-server application fetches only the records required for the task at hand. You can design an application so that it never (or almost never) opens a form to edit data or a report to display data without first asking the user to specify the
Using Linked Tables in a Desktop Database 1717
records needed for the task at hand. For example, the Conrad Systems Contacts application opens a list of available companies, contacts, or invoices from which the user can choose only the desired records. This application also offers a custom query by form search to filter specific records based on the criteria the user enters. You can also design the application so that it uses information about the current user to filter records. For example, the Housing Reservations database always filters employee and reservations data to display information only for the currently signed on employee. When a department manager is signed on, the application shows data only for the current manager’s department. Even so, the two main sample applications aren’t perfect examples. Both applications use a ZIP code table that contains more than 50,000 records to help users enter valid address data, and this huge table is the row source for several combo boxes. In the desktop database version, each user has a local copy of the ZIP code table, so the performance impact is minimal. If you decide to split your database application into a client-server architecture, you need to think about keeping any tables similar to this in the local database on each user’s computer. You could certainly do this with a ZIP code table because the data is relatively static. The bottom line is you should take a look at the way your desktop application fetches data for the user. If it always fetches all records all the time, it’s probably not a good candidate for upsizing to a client-server application.
Taking Advantage of the Database Splitter Wizard You could split out the tables in your application into a separate file and link them into the database that contains all your queries, forms, reports, and modules “by hand” by first creating a new empty database (see Chapter 4, “Designing Client Tables”) and then importing all your tables into that database using the techniques described in Chapter 8. You could then return to your original database and delete all the tables. Finally, you could move the data database (the one containing the tables) to a file server and then link these tables into your original code database (the one containing all your queries, forms, reports, and modules), again using the techniques in Chapter 8. Fortunately, there’s an easier way to do this in one step using the Database Splitter wizard. Open your original database, and on the Database Tools tab, in the Move Data group, click Access Database. (You can try this with one of your own databases or a backup copy of the Housing.accdb sample database. Note that you might need to hold down the Shift key while opening the copy of the Housing.accdb to bypass all the startup options, which ensures that Access is not running any background processes before starting the wizard.) The wizard displays the window shown in Figure 27-1.
Chapter 27
1718 Chapter 27 Distributing Your Application
Chapter 27 Figure 27-1 The Database Splitter wizard helps you move the tables into a separate database.
When you click Split Database, the wizard opens a second window where you can define the name and location of the back-end, or data-only, database. Be sure to choose a location for this database on a network share that is available to all potential users of your application. Click the Split button in that window, and the wizard exports all your tables to the new data-only database, deletes the tables in your original database, and creates links to the moved tables in your original database. You can now give each user a copy of the code database—containing your queries, forms, reports, modules, and linked table objects pointing to the new data-only database—to enable them to run the application using a shared set of tables. One disadvantage to using the Database Splitter wizard is that it splits out all tables that it finds in your original desktop database. If you take a look at the desktop database version of the Conrad Systems Contacts application (Contacts.accdb), you can see that the application also uses some local tables (tables that remain in the code database). For example, the ErrorLog table contains records about errors encountered when the user runs the application. If the error was caused by a failure in the link to the server, the code that writes the error record wouldn’t be able to write to this table if the table was in the server database. The database also contains local copies of lookup tables that aren’t likely to change frequently, such as the tlkpStates table, which contains U.S. state postal abbreviations and names, and the ztblYears table, which provides a list of years for the frmCalendar form. Access can fetch data from local tables faster than it can from ones linked to a database on a server, so providing local copies of these tables improves performance. Although splitting a database application makes it easier for multiple users to share your application, this technique works well only for applications containing a moderate amount of data (less than 200 MB is a good guideline) with no more than 20 simultaneous users. Remember that Access is fundamentally a desktop database system. All the work—including solving complex queries—occurs on the client computer, even when you have placed all the data on a network share. Each copy of Access on each client computer uses the file sharing and locking mechanisms of the server operating system. Access sends many
Using Linked Tables in a Desktop Database 1719
low-level file read, write, and lock commands (perhaps thousands to solve a single query) from each client computer to the file server rather than sending a single Structured Query Language (SQL) request that the server solves. When too many users share the same application accessing large volumes of data, many simple tasks can start, taking minutes instead of seconds to complete.
Creating Startup Code to Verify and Correct Linked Table Connections If you were careful when you created your linked tables, you used a Universal Naming Convention (UNC) path name instead of a physical or logical drive letter. Unless the network share name is different on various client computers, this should work well to establish the links to the data file when the user opens your application. However, you can’t always assume everything will go perfectly all the time. In Chapter 8, you learned how to use the Linked Table Manager to repair any broken connections. However, you can’t expect your users to run this wizard if the linked table connections are broken. You should include code that runs when your startup form opens that verifies and corrects the links if necessary. Also, over time, you might make changes to the structure of the data tables and issue an updated version of the client desktop database that works with the newer version of the tables. Your startup code can open and check a version table in the shared data database and warn the user if the versions don’t match. You can find sample code that accomplishes all these tasks in the desktop database version of the Conrad Systems Contacts database (Contacts.accdb). Open the database, and then open the modStartup module. Select the ReConnect function, where you’ll find the following code: Public Function ReConnect() Dim db As DAO.Database, tdf As DAO.TableDef Dim rst As DAO.Recordset, rstV As DAO.Recordset Dim strFile As String, varRet As Variant, frm As Form Dim strPath As String, intI As Integer ' This is a slightly different version of reconnect code ' Called by frmSplash - the normal start-up form for this application On Error Resume Next ' Point to the current database Set db = CurrentDb ' Turn on the hourglass - this may take a few secs. DoCmd.Hourglass True ' First, check linked table version Set rstV = db.OpenRecordset("ztblVersion") ' Got a failure - so try to reattach the tables If Err 0 Then GoTo Reattach ' Make sure we're on the first row rstV.MoveFirst
Chapter 27
1720 Chapter 27 Distributing Your Application
Chapter 27
' Call the version checker If Not CheckVersion(rstV!Version) Then ' Tell caller that "reconnect" failed ReConnect = False ' Close the version recordset rstV.Close ' Clear the objects Set rstV = Nothing Set db = Nothing ' Done DoCmd.Hourglass False Exit Function End If ' Versions match - now verify all the other tables ' NOTE: We're leaving rstV open at this point for better efficiency ' in a shared database environment. ' JET will share the already established thread. ' Turn on the progress meter on the status bar varRet = SysCmd(acSysCmdInitMeter, "Verifying data tables...", _ db.TableDefs.Count) ' Loop through all TableDefs For Each tdf In db.TableDefs ' Looking for attached tables If (tdf.Attributes And dbAttachedTable) Then ' Try to open the table Set rst = tdf.OpenRecordset() ' If got an error - then try to relink If Err 0 Then GoTo Reattach ' This one is OK - close it rst.Close ' And clear the object Set rst = Nothing End If ' Update the progress counter intI = intI + 1 varRet = SysCmd(acSysCmdUpdateMeter, intI) Next tdf ' Got through them all - clear the progress meter varRet = SysCmd(acSysCmdClearStatus) ' Turn off the hourglass DoCmd.Hourglass False ' Set a good return ReConnect = True ' Edit the Version table rstV.Edit ' Update the open count - we check this on exit to recommend a backup rstV!OpenCount = rstV!OpenCount + 1 ' Update the row rstV.Update ' Close and clear the objects rstV.Close Set rstV = Nothing
Using Linked Tables in a Desktop Database 1721
Set db = Nothing ' DONE! Exit Function Reattach: ' Clear the current error Err.Clear ' Set a new error trap On Error GoTo BadReconnect ' Turn off the hourglass for now DoCmd.Hourglass False ' ... and clear the status bar varRet = SysCmd(acSysCmdClearStatus) ' Tell the user about the problem - about to show an open file dialog MsgBox "There's a temporary problem connecting to the CSD data." & _ " Please locate the CSD data file in the following dialog.", _ vbInformation, "CSD Contacts Manager" ' Establish a new ComDlg object With New ComDlg ' Set the title of the dialog .DialogTitle = "Locate CSD Contacts Data File" ' Set the default file name .FileName = "ContactsData.accdb" ' ... and start directory .Directory = CurrentProject.Path ' ... and file extension .Extension = "accdb" ' ... but show all accdb files just in case .Filter = "CSD File (*.accdb)|*.accdb" ' Default directory is where this file is located .Directory = CurrentProject.Path ' Tell the common dialog that the file and path must exist .ExistFlags = FileMustExist + PathMustExist If .ShowOpen Then strFile = .FileName Else Err.Raise 3999 End If End With ' Open the "info" form telling what we're doing DoCmd.OpenForm "frmReconnect" ' ... and be sure it has the focus Forms!frmReconnect.SetFocus ' Attempt to re-attach the Version table first and check it Set tdf = db.TableDefs("ztblVersion") tdf.Connect = ";DATABASE=" & strFile tdf.RefreshLink ' OK, now check linked table version Set rst = db.OpenRecordset("ztblVersion") rst.MoveFirst ' Call the version checker If Not CheckVersion(rst!Version) Then
Chapter 27
1722 Chapter 27 Distributing Your Application
Chapter 27
' Tell the caller that we failed ReConnect = False ' Close the version recordset rst.Close ' ... and clear the object Set rst = Nothing ' Bail Exit Function End If ' Passed version check - edit the version record rst.Edit ' Update the open count - we check this on exit to recommend a backup rst!OpenCount = rst!OpenCount + 1 ' Write it back rst.Update ' Close the recordset rst.Close ' ... and clear the object Set rst = Nothing ' Now, reattach the other tables ' Strip out just the path name strPath = Left(strFile, InStrRev(strFile, "\") - 1) ' Call the generic re-attach function If AttachAgain(strPath) = 0 Then ' Oops - failed. Raise an error Err.Raise 3999 End If ' Close the information form DoCmd.Close acForm, "frmReconnect" ' Clear the db object Set db = Nothing ' Return a positive result ReConnect = True ' ... and exit Connect_Exit: Exit Function BadReconnect: ' Oops MsgBox "Reconnect to data failed.", vbCritical, _ "CSD Contacts Manager" ' Indicate failure ReConnect = False ' Close the info form if it is open If IsFormLoaded("frmReconnect") Then DoCmd.Close acForm, "frmReconnect" ' Clear the progress meter varRet = SysCmd(acSysCmdClearStatus) ' ... and bail Resume Connect_Exit End Function
Using Linked Tables in a Desktop Database 1723
The code begins by attempting to open the linked ztblVersionTable. If that action generates an error, the code immediately jumps to the Reattach label about halfway down the listing. If the version-checking table opens successfully, the code next calls the CheckVersion function (not shown here) that compares the version value in the table with a public constant saved in the modGlobals module. If the versions don’t match, that function displays an appropriate error message and returns a False value to this procedure. If the version check fails, this procedure returns a False value to the original calling procedure (in the frmSplash form’s module) and exits. If the versions do match, the code next loops through all the table definitions in the database and attempts to open a recordset on each one to verify the link. Note that the code leaves the recordset open on the version-checking table. If it didn’t do this, each subsequent open and close would need to establish a new network connection to the file server, and the checking of all tables would take minutes instead of seconds. Note also that the code uses the SysCmd system function to display a progress meter on the Access status bar. If all linked tables open successfully, the procedure returns True to the calling procedure and exits. If opening any of the tables fails, the code immediately jumps to the Reattach label to attempt to fix all the links. The code beginning at the Reattach label clears all errors, sets an error trap, and then displays a message informing the user that there’s a problem. After the user clicks OK in the dialog box, the code creates a new instance of the ComDlg class module, sets its properties to establish an initial directory and ask for the correct file type, and uses the ShowOpen method of the class to display the Open File dialog box in Windows. The class module returns a True value if the user successfully locates the file, and the code retrieves the class module’s FileName property to find out the path and name of the file chosen by the user. If the ShowOpen failed, the code raises an error to be logged by the error-handling code at the end of the procedure. Next, the code opens a form that is a dialog box informing the user that a reconnect is in progress. The code attempts to fix the link to the version-checking table using the path and file that the user selected. Notice that the code sets the Connect property of the TableDef object and then uses the RefreshLink method to reestablish the connection. If the table isn’t in the file that the user selected, the RefreshLink method returns an error, and the code after the BadReconnect label near the end of the procedure executes because of the error trap. After checking that the version of the code matches the version of the database, the code calls the AttachAgain function (not shown here) and passes it the path and file name. You can also find this function in the modStartup module. The function loops through all the
Chapter 27
1724 Chapter 27 Distributing Your Application
Chapter 27
TableDef objects, resets the Connect property for linked tables, and uses RefreshLink to fix the connection. Because this sample database also has some linked Microsoft Excel worksheets, you’ll find that code in the AttachAgain function checks the type of linked table and sets up the Connect property appropriately. If you’d like to see how this code works, you can open the Contacts.accdb file and then use Windows Explorer to temporarily move the ContactsData.accdb, Fictitious Companies.xlsx, and Fictitious Names.xlsx files to another folder. Open the frmSplash form, and you should see the code prompt you to identify where you moved the ContactsData.accdb file. The code in the AttachAgain procedure assumes that the two Excel files are in the same folder as the ContactsData.accdb file. You can study the other functions called by the ReConnect function in the modStartup module on your own. We provided comments for every line of code to help you understand how the code works.
Note In the initial release of Access 2010, there is a product bug that prevents our ReConnect function from correctly reconnecting the tblContacts linked table. The code fails to reconnect this linked table because this particular table contains a Multi-Value Field. Microsoft is aware of this issue and is looking into it. For the sample databases to work properly, you need to install them in the following directory: C:\Microsoft Press\Access 2010 Inside Out. If you cannot install the files to that directory, you’ll need to reconnect your linked tables manually.
Understanding Runtime Mode When Access starts in runtime mode, it does not allow the user to access the Navigation pane or to use any of the built-in ribbons. Therefore, the user can only run your application, not edit any of the objects. As you might expect, many keystrokes are also unavailable, such as pressing F11 to show the Navigation pane or pressing Ctrl+Break to halt Microsoft Visual Basic code execution. You can obtain additional tools and a license to freely distribute runtime versions of your applications by downloading the Access 2010 Runtime Tools from Microsoft’s website. In versions of Access before Access 2007, you had to purchase the developer tools and runtime extensions separately. The big news is that for Access 2010,
Understanding Runtime Mode 1725
Microsoft is offering these tools at no additional charge. This set of software tools includes a royalty-free license to distribute the runtime modules for Access 2010. This allows you to distribute your database with the modules to execute in runtime mode to users who do not have Access installed on their systems. You can download the Access 2010 Runtime Tools from the following location: http://www.microsoft.com/downloads/details. aspx?FamilyID=57a350cd-5250-4df6-bfd1-6ced700a6715&displaylang=en You can use the Package Solution Wizard to create installation files that include your database application, the runtime modules necessary to run your application, and any supporting files (such as ActiveX controls or icons). The wizard creates a standard Windows Installer setup file (.msi). After you install the Package Solution Wizard from your Office 2010 installation DVD-ROM or CD-ROM, you can start the wizard by clicking the File tab on the Backstage view, clicking Save & Publish, and then clicking the Package Solution button under Package and Distribute. See “Choosing Options When You Have No Previous Version of the Microsoft Office System,” on page 1377, for more information on installing the Package Solution Wizard. The wizard creates a standard Windows Installer setup file (.msi), but you’ll need to download and install the Runtime tools to package the Runtime with your setup file. To execute successfully in runtime mode, your application must have the following: ●●
All features of the application must be implemented with forms and reports. The user will not have access to the Navigation pane to execute queries or to open tables.
●●
The application must have a startup form or an Autoexec macro that opens a startup form.
●●
All forms and reports must have custom ribbons because runtime mode does not provide the built-in ribbon.
●●
You must implement error trapping in all your macros and Visual Basic procedures. Any untrapped errors cause the application to exit.
●●
If you automate your application with Visual Basic or use macro actions that are not trusted, you must ensure either that the user places your database in a trusted location or that you digitally sign the database and instruct the user how to trust the signature. For more about digitally signing a database, see “Packaging and Signing Your Database,” on page 1739.
Chapter 27
1726 Chapter 27 Distributing Your Application
Chapter 27
●●
The application should execute the Quit method of the Application object to terminate. If you simply close the final form, the user will be left staring at an empty Access workspace.
●●
If you automate your application with Visual Basic, you should ensure that your code compiles successfully, with no errors.
The primary sample databases, Conrad Systems Contacts (Contacts.accdb), Housing Reservations (Housing.accdb), and Back Office Software System (BOSS.accdb), meet the preceding requirements except that the startup form is set to frmCopyright to display important information each time you open one of the databases, and the Exit button on the main switchboard form merely closes the form and attempts to return to the Navigation pane. If you would like to see what runtime mode looks like, you can test it using existing databases. Open the Housing.accdb desktop database, click the File tab on the Backstage view, click Options, and then click the Current Database category. In the Application Options section, select frmSplash in the Display Form list, and then click OK. Close the Housing.accdb database. The sample files include a shortcut, Housing Runtime, that opens this database in runtime mode. This shortcut should work so long as you installed the Office 2010 system in the default folder (C:\Program Files\Microsoft Office\Office 14) and the sample files in the default folder (C:\Microsoft Press\Access 2010 Inside Out). If necessary, you can change the shortcut by right-clicking the shortcut and selecting Properties on the shortcut menu. The target setting in this shortcut is as follows: "C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE" "C:\Microsoft Press \Access 2010 Inside Out\Housing.accdb" /runtime
After you change the Display Form setting in the Access Options dialog box and correct any settings in the shortcut target, you can double-click the shortcut to start the application in runtime mode. Click OK in the opening message box, and then sign on as any employee of your choosing to see the main switchboard form. Try pressing F11 to see whether anything happens—the Navigation pane should not appear. You can move around in the application using the command buttons on the various switchboard forms and the buttons on the custom ribbons. When you click Exit on the main switchboard, code in the form closes all open forms and then closes the switchboard. You’ll be left looking at a blank Access workspace and a very limited set of options when you click the File tab on the Backstage view. You can click Close Database from here to close this limited copy of Access or click Exit. Be sure to open the Housing.accdb file again (without the Runtime shortcut), click Exit on the signon form, and then change Display Form in the Access Options dialog box back to (none) before proceeding further.
Creating a Database Template 1727
Change the File Extension to Test the Runtime Mode
You can also test your application in runtime mode by changing the file extension on your database. In Windows Explorer, right-click the Housing.accdb sample database file, click Rename, and change the file name to Housing.accdr. Windows prompts you that changing the file extension might make the file unusable. Click Yes in this message box and then open the Housing.accdr database. You’ll notice you see the limited ribbon, Quick Access Toolbar, and Backstage options as you did when using the runtime shortcut.
Creating a Database Template When you create a client or web database from the New tab on the Backstage view, you’re actually creating a new database (.accdb) from a database template. A database template is a file that holds the definition of an Access database. Database templates have an .accdt file extension and are essentially zip files that contain all the data and definitions describing a complete Access database. Database templates can be reused over and over to create additional, identical copies of an Access database. For example, when you create (or instantiate, as Microsoft uses the term) a new Access database file from the Backstage view, you select a client or web template to use, and Access instantiates the database template to create a fully functioning database. If you select the same template again on the Backstage view, you can create additional copies of the database. You can use a database template, then, as a distribution mechanism to your users. In fact, when you download Access templates from Microsoft’s website, you’re using a database template. As you learned in Chapter 4, Access 2010 now includes Application Parts that you can use to help create your client and web databases. An Application Part is a database object or group of database objects that you can add to an existing open database. Application Parts also have the .accdt file extension and essentially are just parts of a database instead of a complete database. The main difference for you to remember is that you can only instantiate an Application Part into an existing database, and you create an entirely new database file when you instantiate a database template from the Backstage view. Note that you can create database templates and Application Parts for both client and web databases. To create a database template of any completed database application or an Application Part, open the database and close any objects. Click the File tab on the Backstage view, click Save & Publish, and then double-click the Template button under Save Database As. Access opens the Create New Template From This Database dialog box, as shown in Figure 27-2.
Chapter 27
INSIDE OUT
1728 Chapter 27 Distributing Your Application
Chapter 27 Figure 27-2 You can set your options for creating your database template in the Create New Template From This Database dialog box.
Access uses this same dialog box when you are creating a complete database template or an Application Part. If you want to create an Application Part, you need to have only the objects you want in the source database. For example, if you want to create an Application Part for a new form, just have that form by itself in an otherwise empty database container. When you create your Application Part, Access includes all objects in the database, which, in this case, would be just your one form. The options in the Create New Template From This Database dialog box are as follows: ●●
Name Enter the name of the database template you want to create. This field is required.
●●
Description Enter an optional description for the database template. The description appears in the tooltip when you hover over the Application Part in the Application Parts gallery. This description also appears in the Solutions Gallery if you upload a web database template to a server running SharePoint 2010.
●●
Category If you’re creating an Application Part, you can select in which section of the Application Parts gallery your new custom Application Part appears. You can choose User Templates, the default, or type in a new category. You can use this option to organize your Application Parts.
●●
Icon If you want, you can select an icon to appear for your Application Part in the Application Parts Gallery. Access displays the icon at 64x32 pixels.
Creating a Database Template 1729
●●
Preview If you want, you can select a graphic to appear for your database template in the right task pane on the Backstage view.
●●
Primary Table If you have at least one table in your custom Application Part, Access opens the Create Relationship dialog box when you instantiate your custom Application Part from the Application Parts gallery. Use this option to tell Access which table to use as the default table choice in the Create Relationship dialog box. Note that this option is available only when you select the Application Part check box option.
●●
Instantiation Form If you want, you can select a form from the list of saved forms in your database to use as an instantiation form when a user instantiates your template. This option is useful when you want to display a splash form one time or perform some special startup routines that are necessary after Access instantiates the template. However, be warned that Access deletes the form immediately after the form is closed. We recommend you use this option only with extreme caution. If you have a startup form defined in the Access Options for your database, Access honors that setting when you instantiate the template and create a new database. Don’t be confused by the terms startup form and instantiation form; they are not the same. If you select an instantiation form, Access only uses the form once and then deletes the form. Note that this option is not enabled unless you have at least one form in your database.
●●
Application Part Select this option, cleared by default, if you want the template to appear in the Application Parts gallery. If you leave this option cleared, the template appears only in the My Templates section on the New tab of the Backstage view.
●●
Include Data in Template Select this option, cleared by default, if you want Access to include all the data from the source database in the database template.
At the bottom of the dialog box, you can click the two links to learn more setting template properties and how to share your template on Microsoft’s website. In Figure 27-2, you can see we provided a name for our new template (based on the ContactsMap.accdb sample database), a description, and selected the option to include the sample data. After you click OK, Access generates the database template or Application Part. After a few moments (or longer if your database has many objects and data) Access displays a confirmation message indicating the location of your new template file, as shown in Figure 27-3.
Figure 27-3 Access informs you where it saved your new template file.
Chapter 27
1730 Chapter 27 Distributing Your Application
Chapter 27
Access, by default, saves the template in this location: C:\Users\\AppData\ Roaming\Microsoft\Templates\Access. You’ll notice that the folder where Access saves the template—AppData—might be a hidden folder on your computer. When you click the File tab on the Backstage view, click New, and then click My Templates, you’ll see your new template listed here, as shown in Figure 27-4 You can now create a new database file from this saved template. Access lists any templates it finds in the folder listed above in My Templates section of the New tab on the Backstage view. If you’ve created an Application Part, you can see your new option by clicking the Application Parts button in the Template group on the Create tab. Access displays your Application Part at the bottom of the Application Part Gallery in the category you created. You can send your saved database templates and Application Parts to users for them to use in their own applications.
Figure 27-4 You can see your new template displayed in the Backstage view.
INSIDE OUT
Displaying Custom Templates for All Users
If you add database templates and Application Parts to the C:\Program Files\Microsoft Office\Templates\1033\Access\ folder, Access displays those templates to all users of the same computer. Note that the location path above assumes an English-language installation of Office.
Creating Custom Data Type Parts 1731
Similar to database templates and Application Parts, you can create your own custom Data Type Parts and use them in your applications or distribute them to other users. To create a Data Type Part, open the table that contains the fields you want to use for your custom Data Type Part in Datasheet view. Next, highlight the field or fields you want to use, click the More Fields button in the Add & Delete group on the Fields tab, and then click Save Selection As New Data Type at the bottom of the gallery. Access opens the Create New Data Type From Fields dialog box, as shown in Figure 27-5.
Figure 27-5 Enter your custom Data Type Part options on the Create New Data Type From Fields dialog box.
The options in this dialog box are essentially the same as the ones you saw previously when creating database templates and Application Parts. You can see in Figure 27-5 we’ve defined a name and description for our custom Data Type Part and left the default Category as User Defined Types. After you click OK, Access generates the custom Data Type Part and displays a confirmation message upon success. Access saves the Data Type Part with an .accft file extension in the same folder as the custom database templates and Application Parts. If you open a table in Datasheet view, you’ll now see your custom Data Type Part displayed in the Data Type Part gallery, as shown in Figure 27-6.
Figure 27-6 Access displays your custom Data Type Part in the Data Type Parts gallery.
Chapter 27
Creating Custom Data Type Parts
1732 Chapter 27 Distributing Your Application
Chapter 27
INSIDE OUT
Displaying Custom Templates for All Users
If you want to remove a custom Application Part or Data Type Part from the galleries, you have two options. First, you can navigate to the hidden folder where Access stores the .accdt and .accft files and either delete the files or move them out of that folder. Second, you can right-click the gallery and click Delete Application Part From Gallery or Delete Data Type Part From Gallery. If you choose the second option, Access displays a warning message indicating that it will permanently delete the file from your hard drive. If you want to keep the file, you should choose the first option and move the file to a different location for storage.
Creating an Execute-Only Database Even if you have secured your database, you might still want to be sure that no one can examine or change the Visual Basic procedures you created. After you have fully compiled your Visual Basic project, Access no longer needs the original text of your Visual Basic statements. You can create a special execute-only copy of your database by using one of the utilities supplied with Access. An additional advantage of an execute-only database is that it might be significantly smaller than a copy that contains all the code—particularly if you have written many Visual Basic procedures. To create an execute-only copy of any completed database application, open the database, and close any open objects. Click the File tab on the Backstage view, click Save & Publish, and then click the Make ACCDE button under Advanced. (Note that if you’re using an Access .adp project file, this button says Make ADE.) The Save As dialog box asks you for a location and name for your new database or project. It then makes sure the current database is fully compiled and saved, copies the database to a new file with the appropriate .accde or .ade extension, removes the Visual Basic source code, and compacts the new file. If you open an .accde file (you can find a file called Contacts.accde on the companion CD), you’ll find that you can’t open any Visual Basic module—neither the module of any form or report module nor any module object. You also won’t be able to open a form or a report in Design view or Layout view. (This is an additional benefit of an .accde file.) Figure 27-7 shows the Modules list in the Contacts.accde database file. Notice that the Design View button is disabled on the shortcut menu, indicating that you cannot view the source code of an existing module and that the only way to run code is through the database application’s interface. The Module and Class Module buttons in the Macros & Code group on the Create tab are also disabled, so you cannot create new modules. You’ll find that the Design View option is also disabled for all forms and reports, and all the commands in the Forms and Reports groups on the Create tab are unavailable.
Creating an Application Shortcut 1733
When you create an execute-only version of your database, you should create the file using the same version of Access your users are using.
Figure 27-7 You can’t edit any modules in the Contacts.accde database file.
Creating an Application Shortcut When you’re all done, you might need to create a way for users to easily start your application. If your users all have a copy of Access, you could give them your database application files and simply instruct them to open the appropriate file. But what if the user doesn’t have Access, so you have to set them up to execute your application with the runtime version of Access? What if you want to also define certain utility functions that the user might need to execute from time to time? The answer is to create a shortcut. You use shortcuts all the time in Windows to start programs on your computer. When you install an application on your computer, the setup program usually creates a shortcut that it adds to your Start menu. Some setup programs also add a shortcut on your desktop. The icon for a shortcut on your desktop has a small white box in the lower-left corner with an arrow in it. You can right-click a shortcut and choose Properties from the shortcut menu to see the definition of the shortcut.
Chapter 27
Note
1734 Chapter 27 Distributing Your Application
Chapter 27
To create a shortcut on your Windows desktop for your Access application, right-click the desktop, click New, and then click Shortcut. You can also create a shortcut in a folder by opening Windows Explorer, navigating to the folder you want, pressing the Alt key to view the menu bar, clicking New on the File menu, and then clicking Shortcut. In either case, Windows opens the Create Shortcut Wizard to help you find the program you want the shortcut to open. Click Browse, and find C:\Program Files\Microsoft Office\Office14\ MSACCESS.EXE. Click OK to select the file, and then click the Next button. Give your shortcut a name, such as the name of the database you plan to open with the shortcut, and then click Finish. Right-click your new shortcut and click Properties. You’ll see a dialog box similar to Figure 27-8.
Figure 27-8 You can modify the Target setting for a Windows shortcut in the shortcut’s Properties dialog box.
At the top of the Shortcut tab is the icon the shortcut displays and the name of the shortcut. You can click the General tab and enter a new name to rename your shortcut. Target Type tells you that this shortcut starts an application. Target Location displays the original location of the program that this shortcut starts. The Target box allows you to specify the program or file that you want to run. Note that at this point, your new shortcut starts only the Access program—it doesn’t specify a file to open or any parameters. You can specify the database file name and enter any parameters used by the program in the Target box. Immediately following the name of the Access program in the Target box, enter a space followed by the database you want to open (with its full path). If the path or file name
Creating an Application Shortcut 1735
contains any blanks or special characters, you must enclose the file path in double quotes. Follow the name of the database with the options you need to perform the task you want. For example, to open the Housing.accdb sample database from the default installation, the target setting in this shortcut is as follows: "C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE" "C:\Microsoft Press \Access 2010 Inside Out\Housing.accdb"
Note You can also specify only the name of a database file in the Target box in a shortcut, and Windows opens the program that can process this file (in this case, Access) when you double-click the shortcut. However, Access won’t recognize any parameters that you include after the file name. You must specifically ask to open the Access program (MSACCESS.EXE) and add the file name and parameters.
Table 27-1 summarizes the shortcut command-line options you can use. When you include multiple command-line options, separate each with a space. Table 27-1 Access Shortcut Command-Line Options
Option
Description
Opens the specified database. If the path or file name contains blanks, you must enclose the string in double quotes. Must be the first option after the folder and file location for MSACCESS. EXE.
/cmd Specifies a program parameter that can be retrieved by a Visual Basic procedure using the built-in Command function. Must be the last option on the command line. /compact []
Compacts and repairs the specified database but does not open the database. If you omit the target file name, Access compacts the database into the original file name and location.
/convert
Converts the specified version 11 or earlier database to Access 2007/2010 file format and stores it in the target file.
/excl
Opens the specified database with exclusive access. Only one user at a time can use a database that is opened exclusively.
/profile
Specifies the name of a user profile in the Windows registry. You can use a profile to override database engine settings and specify a custom application title, icon, or splash screen.
Chapter 27
1736 Chapter 27 Distributing Your Application
Chapter 27
Option
Description
/pwd
Specifies the password for the user named in the /user parameter. If the password contains the / or ; character, enter the character twice. For example, if the password is #ab/cd;de, enter #ab//cd;;de. This option applies to databases in Access 2003 and earlier (.mdb) format that have user-level security implemented.
/repair
Repairs the specified database but does not open the database.
/ro
Opens the specified database in read-only mode.
/runtime
Specifies that Access will execute with runtime version options.
/user
Specifies the logon user ID. This option applies to databases in Access 2003 and earlier (.mdb) format that have user-level security implemented.
/wrkgrp Uses the specified workgroup file. This option applies to databases in Access 2003 and earlier (.mdb) format that have userlevel security implemented. /x macroname
Runs the specified macro after opening the specified database.
Using a command-line option, you can also create a shortcut to perform the maintenance task of compacting your database. For example, to compact the Contacts.accdb database and save the compacted version to a file named ContactsCompact.accdb in the same folder, enter the following on the Target line: "C:\Program Files\Microsoft Office\OFFICE14\MSACCESS.EXE" "C:\Microsoft Press\Access 2010 Inside Out\Contacts.accdb" /compact "C:\Microsoft Press\Access 2010 Inside Out\ContactsCompact.accdb"
This previous text assumes you’ve installed the sample files in the default folders. In the Start In box, specify the starting folder for the application. In the Shortcut Key box, you can enter a single letter or number that the user can press with the Ctrl+Alt key combination to run the shortcut. The shortcut key must be unique for all shortcuts on your system. In the Run list, you can choose to start the application in a normal-size window (the default), minimized as an icon on your taskbar, or maximized to fill your screen. In the Comment box, you can enter text that appears when the user rests the mouse pointer on the shortcut. Click Open File Location to verify that the target you entered is valid. Click Change Icon to select a different icon stored within the target program (MSACCESS.EXE has 80 available icons) or to locate an icon file on your hard disk. Click Advanced if you need to set up this shortcut to run under a specific Windows user ID.
Encrypting Your Database 1737
On the Compatibility tab of the Properties dialog box, you can find an option to run the program in compatibility mode as though it’s running on an older operating system such as Microsoft Windows 2000 or Microsoft Windows XP. You can also force your display to 256 colors, use 640×480 screen resolution, or disable Windows themes when this program runs. On the Security tab, you can allow or deny permissions to use this shortcut for specific Windows users or groups. After you have completed the settings you want, click OK to save your changes to the shortcut. You can now double-click the shortcut to run the program with the options you specified.
INSIDE OUT
Creating an Object Shortcut
You can create a shortcut to a specific database object by selecting the object in the Navigation pane and then dragging it to your desktop. Access creates a shortcut file on your desktop for that object. When you double-click the shortcut, Access opens first and then opens the specific object.
Encrypting Your Database Access 2010 includes a feature to encrypt your database with a password. You can use this feature to prompt users for a password before opening the database. When you encrypt the database, Access makes the data unreadable to tools that can read binary data stored in the physical file. To encrypt your database with a password, you must first open your database in exclusive mode. Click the File tab on the Backstage view, and then click Open. Select your database, and then, in the Open dialog box, click the arrow on the Open button and then click Open Exclusive, as shown in Figure 27-9.
Figure 27-9 You must open your database in exclusive mode to encrypt the database with a password.
Chapter 27
1738 Chapter 27 Distributing Your Application
Chapter 27
After your database opens, click the File tab on the Backstage view, click Info, and then click Encrypt With Password. Access opens the Set Database Password dialog box, as shown in Figure 27-10. Enter your password in the Password text box, and then reenter it in the Verify text box. Click OK, and Access checks to see whether the two passwords match. If the passwords match, the next time you open the database, Access prompts you for the database password. Note that you might receive a warning message when you save the password, indicating that row level locking will be ignored because you are encrypting the file. Click OK to dismiss this message. If you want to remove the password later, you’ll need to open the database in exclusive mode and then click the Decrypt Database button on the Info tab of the Backstage view. In the Unset Database Password dialog box, type your password in the Password text box, and then click OK. The next time you open the database, Access does not prompt you for a password.
Figure 27-10 Enter your password in the Set Database Password dialog box.
INSIDE OUT
How Useful Is Encryption?
Encrypting your database does provide a thin layer of security, but it’s not foolproof. If you distribute this database to many users, each user has to know the password to open and use the database. Because all users need to share one common password, we don’t recommend encryption for multiple-user scenarios. If you’re creating this database for your own personal use, encrypting might be an option to keep other people out of your database. Just remember, however, a determined hacker could still gain access to your database, given enough time and determination. If you’re really concerned about security, you should consider using network file share permissions or a server-based back-end data store such as Microsoft SQL Server or SharePoint to control permissions.
Packaging and Signing Your Database 1739
If you want to send a database to other users, you can certainly put it in a zip file and e-mail it. However, unless the recipient really trusts that the e-mail came from you (it’s easy to spoof a sending e-mail address), the recipient might not be willing to open your file. Access 2010 provides a tool that lets you compress your database file and include it inside a file that is digitally signed. So, what is “digitally signed?” If you’ve surfed the Internet at all, you’ve probably encountered several digitally signed files. For example, when a website wants to download and install an ActiveX control and you have security enabled in your browser, your browser prompts you to decide whether to download and run the file. If the file is digitally signed, you’ll see verified information about the publisher that has been authenticated over the Internet by a commercial certificate authority such as VeriSign, GeoTrust, or GoDaddy. In many cases, you can select an option to accept all signed files from a specific trusted source (such as Microsoft) so that you won’t be prompted again if you encounter another signed file from the same source. Access 2010 lets you package your database into a compressed Deployment file (.accdc) and then sign it with a digital certificate that is ready to send to your users. When a user attempts to open your file, Access 2010 uses the digital certificate to verify the source of the file and that all objects in the database have not been changed since the database was signed. If the user trusts the digital certificate, Access 2010 opens and extracts your database file ready for the user to run. But there’s one catch. If you need to distribute this database to other users, you must purchase a digital certificate from a commercial certificate authority, and they’re not inexpensive. When you own a commercial certificate, you can use it to “sign” any file that you publish (perhaps on your website) or send to others. The program that the recipient uses to open the file can send the certificate information over the Internet to the validating authority. The validating authority verifies the certificate and sends back information about the publisher of the file. The recipient can decide to trust the information to avoid being prompted in the future, decide to open the file anyway, or cancel the request.
Chapter 27
Packaging and Signing Your Database
1740 Chapter 27 Distributing Your Application
Chapter 27
INSIDE OUT
Using a Self-Signing Certificate
If you want to test how packaging and signing works, you can create and use a selfsigning certificate. The Office 2010 system includes a tool to create self-signing digital certificates—SelfCert—that you can use for packaging databases. These certificates, however, are valid only for the computer on which you create them. To create a digital certificate for yourself in Windows, click the Start button, click All Programs, click your Microsoft Office folder, click Microsoft Office Tools, and then click Digital Certificate For VBA Projects. In the Create Digital Certificate dialog box, enter the name of the certificate you want to create and then click OK. Because a self-signing digital certificate is valid only on the computer on which you create it, if you package and sign a database with a self-signing certificate and then send it to someone else, the certificate is no longer valid.
To package and digitally sign your database, open the database, click the File tab on the Backstage view, click Save & Publish, and then click the Package And Sign command under Advanced. Access opens the Windows Security dialog box, as shown in Figure 27-11. Click the link displayed in the middle of the dialog box to review all the details of the selected certificate. Select the certificate you want to use from the list, and then click OK. (In this example, we used a self-signing certificate for demonstration purposes.)
Figure 27-11 Select the digital certificate you want to use to sign the package.
Access opens the Create Microsoft Access Signed Package dialog box, as shown in Figure 27-12. Enter or browse to the location in which you want to save your signed database package. In the File Name box, enter a name for this new packaged file and then click Create. Access compresses your database, “signs” the file using the digital certificate you selected, and places the database and signature into an .accdc file in the location you specified.
Packaging and Signing Your Database 1741
You can package and sign only those databases saved in the .accdb file format. In addition, you can include only one database in a package. If you want to digitally sign the Visual Basic code in an .mdb or .adp file, open the Visual Basic Editor, and click Digital Signature on the Tools menu. Your VBA project must be compiled. If you make any further changes to your database after signing it, the digital signature becomes invalid.
Figure 27-12 Enter a file name and location for your packaged database.
When you or your user opens a signed database, Access displays the Microsoft Access Security Notice dialog box (shown in Figure 27-13) if you have not previously trusted this publisher. If you’re unsure of the source of this certificate, you can click the Show Signature Details link to examine all the details about the publisher. If you click Trust All From Publisher, Access always trusts any files from this source. You can see a list of trusted publishers in the Trusted Publishers list in the Trust Center, which you can access from the Access Options dialog box.
Chapter 27
Note
1742 Chapter 27 Distributing Your Application
Chapter 27 Figure 27-13 Click Open if you trust the publisher and want to open the database.
Click Open if you trust the publisher, and Access opens the Extract Database To dialog box, as shown in Figure 27-14. Enter a name in the File Name text box, select a location to save the extracted database, and then click OK. Access extracts the database from the .accdc file, saves it to the location you specified, and then opens the extracted file. Note that Access might still disable content in this database based upon your settings in the Trust Center.
Figure 27-14 Select a location to extract the packaged database.
This concludes the CD chapter portion of Microsoft Access 2010 Inside Out. Be sure to also read the reference articles on the CD that you’ll find essential for increasing your knowledge about building applications using Access.
ou don’t have to go deeply into application and database design theory to build a solid foundation for your database project. You’ll read about the fundamentals of application design in the next section of this article, and then you’ll apply those fundamentals in the succeeding sections, “An Application Design Strategy” and “Data Analysis.” The “Database Design Concepts” section teaches you a basic method for designing the tables that you’ll need for your application and for defining relationships between those tables.
Application Design Fundamentals Methodologies for good computer application design were first devised in the 1960s by recognized industry consultants such as James Martin, Edward Yourdon, and Larry Constantine. At the dawn of modern computing, building an application or fixing a broken one was so expensive that the experts often advised spending 60 percent or more of the total project time getting the design right before writing a single line of code. Today’s application development technologies make building an application much cheaper and quicker. In fact, the pace of computing is several orders of magnitude faster than it was just a decade ago. An experienced user can sit down with Microsoft Access 2010 on a computer and build in an afternoon what took months to create on an early mainframe system (if it was even possible). Today’s technologies also give you the power to build very complex applications. But even with powerful tools, creating a database application (particularly a moderately complex one) without first spending some time determining what the application should do and how it should operate invites a lot of expensive time reworking the application. Even though it’s easier than ever to go back and fix mistakes or to redesign “on the fly,” if your application design is not well thought out, it will be expensive and time-consuming to track down any problems or to add new functionality later.
1743
1744 Article 1 Designing Your Database Application
The following is a brief overview of the typical steps involved in building a database application. Article 1
Step 1: Identifying Tasks Before you start building an application, you should have some idea of what you want it to do. It is well worth your time to make a comprehensive list of all the major tasks you want to accomplish with the application—including those that you might not need right away but might want to implement in the future. By major tasks, we mean application functions that will ultimately be represented in a form or a report in your Access database. For example, “Enter customer orders” is a major task that you would accomplish by using a form created for that purpose, while “Calculate extended price” is most likely a subtask of “Enter customer orders” that you would accomplish by using the same form.
Step 2: Charting Task Flow To be sure your application operates smoothly and logically, you should group the major tasks by topic and then order those tasks within groups on the basis of the sequence in which the tasks must be performed. For example, you should separate employee-related tasks and sales-related tasks into two topic groups. Within sales, an order must be entered into the system before you can print the order or examine commission totals. You might discover that some tasks are related to more than one group or that completing a task in one group is a prerequisite to performing a task in another group. Grouping and charting the flow of tasks helps you discover a natural flow that you can ultimately reflect in the way you link the forms and reports in your finished application. Later in this article, you’ll see how we laid out the tasks performed in one of the sample applications included with this book.
INSIDE OUT
Understanding the Work Process
When you’re designing an application for someone else, these first two steps are absolutely the most important. Learning the work process of the business is critical to building an application that works correctly for the user. These first two steps help you understand how the business is run. Remember, your application is trying to make life easier for the users by automating some critical process that they’re doing some other way. If you do a lot of work for small businesses or small departments within larger businesses, walking the user through this process often helps them understand their own business, and often leads to new efficiencies even before you start to write a line of code.
Application Design Fundamentals 1745
After you develop your task list, perhaps the most important design step is to list the bits of data—the data elements—required by each task and the changes that will be made to that data. A given task will require some input data (for example, a price to calculate an extended amount owed on an order); the task might also update the data. The task might delete some data elements (remove invoices paid, for example) or add new ones (insert new order details); or the task might calculate some data and display it but not save the data anywhere in the database.
Step 4: Organizing the Data After you determine all the data elements you need for your application, you must organize the data elements by subject and then map the subjects into tables in your database. A subject is a person, place, thing, or action that you need to track in your application. Each subject normally requires several data elements—individual fields such as name or address—to fully define the subject. With a relational database system such as Access, you use a process called normalization to help you design the most efficient and most flexible way to store the data. See “Database Design Concepts,” later in this article, for a simple method of creating a normalized design.
Step 5: Designing a Prototype and a User Interface After you build the table structures needed to support your application, you can easily mock up the application flow in forms and tie the forms together using simple macros or Microsoft Visual Basic event procedures. You can build the actual forms and reports for your application “on screen,” switching to Form view, Layout view, or Print Preview periodically to check your progress. If you’re building the application to be used by someone else, you can easily demonstrate and get approval for the “look and feel” of your application before you spend time writing the complex code that’s needed to actually accomplish the tasks. (Parts 4 and 5 of this book show you how to design and construct forms and reports for desktop and web applications; Part 6 shows you how to use macros to automate your application; Part 8 shows you how to use Visual Basic to link forms and reports to build an application.)
Article 1
Step 3: Identifying Data Elements
1746 Article 1 Designing Your Database Application
Step 6: Constructing the Application Article 1
For very simple applications, you might find that the prototype is the application. Most applications, however, will require that you write code to fully automate all the tasks you identified in your design. You’ll probably also need to create certain navigation forms that facilitate moving from one task to another. For example, you might need to construct forms that provide the road map to your application. You might also need to build forms to gather user input to allow users to easily filter the data they want to use in a particular task. You might also want to build custom ribbons for most of, if not all, the forms in the application.
Step 7: Testing, Reviewing, and Refining As you complete various components of your application, you should test each option that you provide. When you automate your application using Visual Basic and macros, you’ll have many debugging tools at your disposal to verify correct application execution and to identify and fix errors.
INSIDE OUT
Get Feedback from Your Users
If at all possible, you should provide completed portions of your application to users so that they can test your code and macros and provide feedback about the flow of the application. Despite your best efforts to identify tasks and lay out a smooth task flow, users will invariably think of new and better ways to approach a particular task after they’ve seen your application in action. Also, users often discover that some features they asked you to include are not so useful after all. Discovering a required change early in the implementation stage can save you a lot of time reworking things later.
The refinement and revision process continues even after the application is put into use. Most software developers recognize that after they’ve finished one “release,” they often must make design changes and build enhancements. For major revisions, you should start over at Step 1 to assess the overall impact of the desired changes so that you can smoothly integrate them into your earlier work.
An Application Design Strategy 1747
Step 1: Identifying tasks Step 2: Charting task flow Step 3: Identifying data elements Step 4: Organizing the data Step 5: Designing a prototype and a user interface Step 6: Constructing the application Step 7: Testing, reviewing, and refining
An Application Design Strategy The two major schools of thought on designing databases are process-driven design (also known as top-down design), which focuses on the functions or tasks you need to perform, and data-driven design (also known as bottom-up design), which concentrates on identifying and organizing all the bits of data you need. The method we describe here incorporates some of the best ideas from both philosophies. The method we like to use starts by identifying and grouping tasks to decide whether you need only one database or more than one database. (This is a top-down approach.) As explained previously, databases should be organized around a group of related tasks, or functions. For each task, you choose the individual elements of data you need. Next, you gather all the data fields for all related tasks and begin organizing them into subjects. (This is a bottom-up approach.) Each subject forms the foundation for the individual tables in your database. Finally, you apply the rules you will learn in the “Database Design Concepts” section of this article to create your tables.
Note The examples in the rest of this article are based on the Conrad Systems Contacts sample database application on the companion CD. In the chapters in this book, you can learn how to build various parts of the application as you explore the architecture and features of Access 2010. Conrad Systems Contacts is not only a contacts management application (Companies, People, Events, and Reminders) but also an order entry application (Products, Sales, and Invoices). As such, it is considerably more complex than the Northwind Traders application that is included with Access 2010. It also employs many techniques not found in the product documentation.
Article 1
Typical Application Development Steps
1748 Article 1 Designing Your Database Application
Oh, No! Not Another Order-Entry Example! Article 1
You might have noticed that when you study database design—whether in a seminar, by reading a book, or by examining sample databases—nearly all the examples (including the one presented here) seem to be order-entry applications. There are several good reasons why you encounter this sort of example over and over again. ●●
A large percentage of business-oriented database applications use the common order-entry model. If you build a database, it’s likely to use this model.
●●
Using the order-entry model makes it easy to demonstrate good database design techniques.
●●
At the core of the model, you’ll find a many-to-many relationship example. (An order might be for many products, and any one product can appear in many orders.) Many-to-many relationships are common to most database applications yet often trip up even the most seasoned computer user.
You might argue, “Wait a minute, I’m building a hospital patient tracking system, not an order-entry system!” Or perhaps you’re creating a database to reserve rooms in corporate housing for employees visiting from out of town. (The Housing Reservations sample database that is included with this book does this.) Aren’t you “selling” hospital beds to patients? Isn’t reserving a room for an employee “selling” that room? If you look at your business applications from this viewpoint, you’ll be able to compare your project to the order-entry example with ease. Even if you’re writing a personal application to keep track of your wine collection, you’re “selling” a rack position in your cellar to your latest bottle purchase, and you’re probably also tracking the “supplier” of your purchases. The concept of data subjects related to each other in a many-to-many fashion is important in all but the simplest of database applications. This type of data relationship can be found in nearly all business or personal database applications. For example, a particular patient might need many different medications, and any one medication is administered to many patients. A movie in your home collection has many starring actors, and any one actor appears in many movies. As you’ll discover, a well-designed order-entry database contains several many-to-many relationships.
An Application Design Strategy 1749
Let’s assume that you’ve been hired by the owner of Conrad Systems to build a Contacts and Sales Tracking database. The database application must allow the owner to enter companies or organizations, the people in these companies, and the various types of contacts a user within Conrad Systems made while marketing several software products. If the contact results in a sale, the application should track the sale and print invoices. The first design step you should perform is to list all the major tasks that this database application must implement. A partial list might include the following: ●●
Enter company/organization data
●●
Enter person data
●●
Link persons with companies/organizations
●●
Indicate the primary contact person for a company and the primary company for a person
●●
Enter product information
●●
Perform a company search
●●
Perform a person search
●●
Log a contact event with a person
●●
Sell a product during a contact event
●●
Create an invoice for products ordered
●●
Print an invoice
●●
Log contact events after the sale
Figure A1-1 shows a blank application design worksheet that you should fill out for each task.
Article 1
Analyzing the Tasks
1750 Article 1 Designing Your Database Application
Article 1 Figure A1-1 You can use an application design worksheet to help you describe tasks.
Note You can find the Application Design Worksheet #1 in the Documents subfolder of the files you install from the companion CD, in the ArticleA1-01.doc file. Worksheet #2 is in the ArticleA1-02.doc file.
Consider the task of logging a new contact event (such as a letter received). For this task, the user might need to search for the person or the person’s company. If the search is by company, then the user should be able to look at a list of people who are contacts for that company and select the specific person. The user should then be able to directly enter the details about the letter received and schedule a follow-up if necessary. In this particular application, Conrad Systems also wants to be able to log a sale as a contact event and be able to easily specify the product sold as part of entering the event. The program must also automatically create the related product sale record for the contact when this happens.
An Application Design Strategy 1751
Some of the terminology we are using here might be a bit confusing. A “contact” might be either a person (the person contacted) or an event (the telephone call or letter or what have you). Throughout this book, we use contact to refer to the person and contact event to refer to the action.
Data or Information? You need to understand the difference between data and information before you start building your data design. This bit of knowledge makes it easier for you to determine what you need to store in your database. Data is the set of static values you store in the tables of the database, while information is data that is retrieved and organized in a way that is meaningful to the person viewing it. You store data and you retrieve information. The distinction is important because of the way that you construct a database application. You first determine the tasks that are necessary (what information you need to be able to retrieve), and then you determine what must be stored in the database to support those tasks (what data you need to construct and supply that information). Whenever you refer to or work with the structure of your database or the items stored in the tables, queries, macros, or code, you’re dealing with data. Likewise, whenever you refer to or work with query records, filters, forms, or reports, you’re dealing with information. The process of designing a database and its application becomes clearer once you understand this distinction. Unfortunately, these two terms are ones that folks in the computer industry have used interchangeably. But armed with this new knowledge, you’re ready to tackle data design.
Selecting the Data After you identify all the tasks, you must list the data items you need to perform each task. On the task worksheet, you enter a name for each data item, a usage code, and a brief description. In the Usage column, you enter one or more usage codes—I, O, U, D, and C— which stand for input, output, update, delete, and calculate. A data item is an input for a task if you need to read it from the database (but not update it) to perform the task. For
Article 1
Note
1752 Article 1 Designing Your Database Application
Article 1
example, a contact person name and address are some of the inputs needed to create a contact event. Likewise, data is an output for a task if it is new data that you enter as you perform the task or that the task calculates and stores based on the input data. For example, the payment due date of an invoice is an output; quantity sold and the selling price for a product in a new order are outputs as well. You update data in a task if you read data from the database, change it, and write it back. A task such as recording a company’s change of address would input the old address, update it, and write the new one back to the database. As you might guess, a task deletes data when it removes the data from the database. In the Contacts database, you might have a task to remove a product from the list of products owned by a contact person if that person decides to return the product. Finally, calculated data creates new values from input data to be displayed or printed but not written back to the database. In the Subject column of the task worksheet, you enter the name of the subject to which you think each data element belongs. For example, an address might belong to a Contact. A completed application design worksheet for the Enter a Contact Event task might look like the one shown in Figure A1-2.
Figure A1-2 A completed worksheet for the Enter a Contact Event task might look like this.
An Application Design Strategy 1753
You might be wondering why we appear to have duplicate data here—ContactEventRequiresFollowUp and ContactFollowUp or ContactEventFollowUpDays and ContactFollowUpDate. The two ContactEvent data elements define the default actions that should occur for a particular type of event, and the two Contact fields are items that should be calculated by the application whenever the user chooses an event that requires a follow-up. The latter is something we call point-in-time data, which we discuss later in this article. You might not be able to spot this sort of subtle distinction as you first start to document your tasks, but you’ll sort it out later in the design process as you finalize your table design following the rules we list in “Normalization Is the Solution” on page 1760.
Organizing Tasks You should use task worksheets as a guide in laying out an initial structure for your application. Part of the planning you do on these worksheets is to consider usage—whether a piece of data might be needed as input, for updating, or as output of a given task. Wherever you have something that is required as input, you should have a precedent task that creates that data item as output. For example, for the worksheet shown in Figure A1-2, you must gather company, contact, and product data before you can record a contact event. Similarly, you need to create the contact event type data in some other task before you can use that data in this task. Therefore, you should have a task for gathering basic company data, a task for entering basic contact person data, a task for creating product data, and a task for defining contact event types. It’s useful to lay out all your defined tasks in a relationship diagram. You can see relationships among the tasks in the Conrad Systems Contacts database in Figure A1-3. When one task is optionally precedent to another task, the two tasks are linked with dashed lines. For example, you do not have to define all products before you define simple contact event types. You can create an event for a contact (but you can’t sell a product in that event) before you define the default company for a contact.
Article 1
1754 Article 1 Designing Your Database Application
Article 1 Figure A1-3 This diagram shows the relationships among tasks in the Conrad Systems Contacts database.
Data Analysis Now you’re ready to begin a more thorough analysis of your data and to organize the individual elements into data subjects. These subjects become candidates for tables in your database design.
Choosing the Database Subjects If you’ve been careful in identifying the subject for each data item you need, the next step is very easy. You create another worksheet, similar to the worksheet shown in Figure A1-4, to help you collect all the data items that belong to each subject. In the top part of the worksheet, you list the related subjects that appear in any given task and indicate the kind of relationship.
Data Analysis 1755
Article 1
Figure A1-4 This application design worksheet will help to identify related subjects.
If there are potentially many instances of the related subject for one instance of the current subject (for example, many contacts within a company), enter Many in the Relationship column. If there is potentially only one instance of the related subject to one instance of the current subject (for example, one and only one contact refers a company), enter One in the Relationship column. For details about relationship types, see “Efficient Relationships Are the Result,” on page 1768. It’s important to understand these relationships because they have a significant effect on the database structure and on how you work with two related subject tables in Access. If you take care in filling out and revising your worksheets, you can ultimately use each worksheet to create a table in Access. You’ll learn more about these relationships later in this article. You can see a completed worksheet for the Companies subject in Figure A1-5.
1756 Article 1 Designing Your Database Application
Article 1 Figure A1-5 Here is a completed worksheet for the Companies subject.
As you copy each data item to the subject worksheet, you designate the data type (Text, Number, Currency, Memo, and so on) and the data length in the Data Type column. You can enter a short descriptive phrase for each data item in the Description column. When you create your table from the worksheet, the description is the default information that Access will display on the status bar at the bottom of the screen whenever the field is selected on a datasheet or in a form or a report. Finally, in the Validation Rule column, you should make a note of any validation rules or input mask restrictions that always apply to the data field. Later, you can define these rules in Access, and Access will check each time you create new data to ensure that you haven’t violated any of the rules. Validating data can be especially important when you create a database application for other people to use.
Mapping Subjects to Your Database After you fill out all the subject worksheets, each worksheet becomes a candidate to be a table in your database. For each table, you must confirm that all the data you need is included. You should also be sure that you don’t include any unnecessary data. For example, if any customers need more than one line for an address, you should consider adding a second data field. If you expect to have more than one type of product category (in Conrad Systems’ case, they sell Single, Multi-User, and Remote versions of their software,
Database Design Concepts 1757
as well as support for each), you should create a separate worksheet for product categories that you’ll use to define a table that contains records for each product type. In the next section, you’ll learn how to use four simple rules to create a flexible and logical set of tables from your subject worksheets.
Database Design Concepts When using a relational database system such as Access 2010, you should begin by designing each database around a specific set of tasks or functions. For example, you might design one database for customers and orders that contains data about each customer, the products available for sale, the orders for each customer, and the product sales history. You might have another database that handles human resources for your company. It would contain all relevant data about the employees and their dependents, such as names, job titles, employment histories, departmental assignments, insurance information, and the like.
INSIDE OUT
Review Your Work
If you have filled out the subject worksheets for your application before you start this process, it’s a good idea to go back and make any necessary corrections to those worksheets as you follow the rules in this section to refine your table structure. At the end of the process, each subject worksheet should map to exactly one table.
At this point, you face your biggest design challenge: How do you organize data within each task-oriented database so that you take advantage of the relational capabilities of Access and avoid inefficiency and waste? If you followed the steps outlined earlier in this article for analyzing application tasks and identifying database subjects, you’re well on your way to creating a logical, flexible, and usable database design. But what if you just dove in and started laying out your tables without first analyzing tasks and subjects? The rest of this article shows you how to apply some rules to transform a makeshift database design into one that is robust and efficient.
Waste Is the Problem A table stores the data you need for the tasks you want to perform. A table is made up of columns, or fields, each of which contains a specific kind of data (such as a customer name or a credit rating), and rows, or records, that collect all the data about a particular person, place, or thing. You can see this organization in the Companies table in the Conrad Systems Contacts database, as shown in Figure A1-6.
Article 1
1758 Article 1 Designing Your Database Application
Article 1 Figure A1-6 The Companies table in Datasheet view is an example of how data is organized in a table.
Note The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred.
For the purposes of this design exercise, let’s say you want to build a new database (named Contacts) for tracking contacts, contact events, and products sold during contact events without the benefit of first analyzing the tasks and subjects you’ll need. You might be tempted to put all the data about the task you want to do—keeping track of customers and their contacts with you and the products they might buy during a contact—in a single Contact Events table, whose fields are represented in Figure A1-7.
Database Design Concepts 1759
Article 1
Figure A1-7 This design for the Contacts database uses a single Contact Events table.
There are many problems with this technique. For example: ●●
Every day that a contact calls you, you have to duplicate the Company Name, Company Address, Contact Name, and Contact Address fields in another record for the new contact event. Repeatedly storing the same name and address in your database wastes a lot of space—and you can easily make mistakes if you have to enter basic information about a contact more than once.
●●
You have no way of predicting how many contact events you’ll have in a given day or how many products might be ordered. If you keep track of each day’s contact events in a single record, you have to guess the largest number of individual events and products and leave space for Event Time 1, Event Time 2, Event Time 3, Product Name 1, Product Name 2, and so on, all the way to the maximum number. Again, you’re wasting valuable space in your database. If you guess wrong, you’ll have to change your design just to accommodate a day when a contact calls you (or you call them) more times than you have allocated in your record. Later, if you want to find out what products were sold to which contacts, you’ll have to search each Product Name field in every record.
●●
You waste space in the database storing data that can easily be calculated when it’s time to print a report. For example, you’ll certainly want to calculate the total invoice amount, but you do not need to keep the result in a field.
1760 Article 1 Designing Your Database Application
●●
Article 1
Designing one complex field to contain all the parts of simple data items (for example, lumping together Street Address, City, State, and Postal Code) makes it difficult to search or sort on part of the data. In this example, it would be impossible to sort on company or contact postal code because that piece of information might appear anywhere within the more complex single address fields.
Normalization Is the Solution You can minimize the kinds of problems noted above (although it might not always be desirable to eliminate all duplicate values), by using a process called normalization to organize data fields into a group of tables. The mathematical theory behind normalization is rigorous and complex, but the tests you can apply to determine whether you have a design that makes sense and that is easy to use are quite simple—and can be stated as rules.
Field Uniqueness Because wasted space is one of the biggest problems with an unnormalized table design, it makes sense to remove redundant fields from a table. Therefore, the first rule is about field uniqueness. Rule 1: Each field in a table should represent a unique type of information. This means that you should break up complex compound fields and get rid of the repeating groups of information. In this example, you should separate the complex address fields into simple fields and new tables designed to eliminate the repeating contact event and product information. When you create separate tables for the repeating data, you include some “key” information from the main table to create a link between the new tables and the original one. One possible result might look like the diagram in Figure A1-8.
Database Design Concepts 1761
Article 1
Figure A1-8 This design for the Contacts database eliminates redundant fields.
These tables are much simpler because you can store one record per contact event. Also, you don’t have to reserve room in your records to hold a large number of events per day per contact. All the lengthy address information is now in a separate table so that you don’t have to repeat it for each event. Because an invoice might cover multiple products purchased, there’s also a separate table for that. Notice that the Contact Events table includes certain key information to link it to the Contacts table (Company Name and Contact Name) and to the Invoices table (Invoice Number). Searching and sorting the information will now also be easier. You can sort the Contacts records on the postal code, or do a search on the separate city and state fields. Can you spot a field that we failed to break up into separate elements? If your answer is the Contact Name field, you’re correct! As you’ll see in the final solution, we need to break this field into at least separate First Name and Last Name fields.
1762 Article 1 Designing Your Database Application
Article 1
The duplicate data problem is now somewhat worse because you are repeating the Company Name and Contact Name fields in each Contact Events record. This duplicate data is necessary, however, to maintain the links between the tables. The potentially long Product Name field is also redundant in the Contact Events table—when you sell the same product more than once, the Product Name will appear in multiple rows. (Maybe Products should have a separate table?) What happens if you misspell a product name in one of the rows? Will you be able to find all contacts who bought the same product? You can solve this problem by following the second rule.
Primary Keys In a good relational database design, each record in any table must be uniquely identified. That is, some field (or combination of fields) in the table must yield a unique value for each record in the table. This unique identifier is called the primary key. Rule 2: Each table must have a unique identifier, or primary key, that is made up of one or more fields in the table. Whenever possible, you should use the simplest data that naturally provides unique values. You should always be able to find a field or some combination of fields whose values are unique across all rows. (In relational design terminology, these are called candidate keys.) You should consider the simplest combination of fields as the best candidate to be your primary key. However, in the case of the Contacts table, as currently designed in Figure A1-8, you would probably need a combination of Company Name, Contact Name, and perhaps one of the contact address or city fields to guarantee uniqueness. When this happens, it is preferable to generate an artificial unique ID field to use as the Primary Key (Contact ID). However, you might want to add code in your final application that checks for a potential duplicate name (another record previously saved that has the same name as the new record about to be saved) and warns the user before inserting a new unique record. Access provides a handy data type called AutoNumber to make it easy to create a unique ID field like Contact ID. You can learn more about the AutoNumber data type in Chapter 4, “Designing Client Tables.” After we assign Contact ID as the primary key of the Contacts table, it becomes much easier to link a contact with a contact event by substituting Contact ID for the Company Name and Contact Name fields in the Contact Events table. Although Contact ID in the Contact Events table perhaps looks like duplicate information, it’s really the link that you can use to associate or relate the rows from the two tables. Relational databases are equipped to support this design technique by giving you powerful tools to bring related information back together easily. You can learn more about these tools in Chapter 9, “Creating and Working with Simple Queries.”
Database Design Concepts 1763
A less ideal solution would be to create another ID field to uniquely identify the rows in Contact Events. Now, with the addition of Contact ID, it’s easy to see that the combination of Contact ID, Contact Date, and Contact Event Time are most likely unique to each row, so we should use the this combination of elements as a natural primary key. For the new Invoices table, the choice is simple. Invoice Number might be an AutoNumber ID field, but it is probably a unique number entered by the user when creating a new invoice record. Some companies like to use a year prefix combined with a unique sequence number within the year as an invoice number. The Invoice Number is still in the Contact Events table to identify which products were billed on what invoice number. You can see the result of adding primary keys in Figure A1-9.
Figure A1-9 The Conrad Systems Contacts database tables now have primary keys defined.
Functional Dependence Defining a primary key helps you better identify the true subject of the table. Now, you can check to see whether you included all the data relevant to the subject of the table and whether each of the fields in the table describes an attribute of the subject (and not some other subject). In relational terminology, you should check to see whether each field is functionally dependent on the primary key that defines the subject of the table. Rule 3: For each unique primary key value, the values in the data columns must be relevant to, and must completely describe, the subject of the table. This rule works in two ways. First, you shouldn’t have any data in a table that is not relevant to the subject (as defined by the primary key) of the table. Second, the data in the table should completely describe the subject.
Article 1
1764 Article 1 Designing Your Database Application
Article 1
Let’s start by looking at the Contacts table as defined in Figure A1-9. The subject of this table is the people who are our contacts. We certainly need to know the company or organization with which a person is associated. What if a person has more than one such association? For example, a person might work for a company but also be a member of one or more professional organizations. We certainly do not want to repeat the contact name and personal address information multiple times for each different association. Is the company information in a contact row unique to the individual defined by that row? Probably not. Even if we’re certain that a person is associated with only one company or organization, we’ll have to duplicate the company information in multiple rows when a company has more than one person associated with it. The solution is to identify companies (organizations) as a separate subject with its own unique identifier. If a person is related to one and only one company, we can place a linking copy of the Company ID in the Contacts table. In this case, let’s assume that a person can be related to more than one company or organization. A company has many persons, and a person might belong to many companies or organizations. In relational terminology, this is called a many-to-many relationship, which you can read more about later in this article. To define this in our table design, we need a linking table that stores the multiple relationships of the companies and people—a table called Company Contacts. While we’re at it, let’s refine the Contact Name field by splitting it into separate First Name and Last Name fields (so we can sort and search by just the last name), and let’s complete the Company Contacts table by adding an indicator field that defines which company is the primary one for the contact. Now, we should turn our attention to the Contact Events table. In the table shown in Figure A1-9, we have not only information about the event but also information about a product that might be sold during the event. In fact, the user of this database might make many calls or mail out many brochures or letters before actually selling a product. The product information isn’t fully functionally dependent on the subject of this table, so it needs to be in a separate subject table. In fact, a product is not going to be purchased by an individual contact—it will be bought by the contact’s primary company or organization. So, we also need to create a separate Contact Products table to store the products that a contact might purchase after dozens of contacts. This table should have all the information relevant to a company purchasing a product for an employee, but nothing extra. This moves the extra product information from the old Contact Events table and makes the fields in that table relevant only to events and nothing else. Finally, we should completely define the Invoices subject by adding other relevant information such as the purchasing company’s purchase order number, the date the invoice payment is due, and an indicator field to mark when the invoice is paid. You can see the result of applying the rule in this step in Figure A1-10.
Database Design Concepts 1765
Article 1
Figure A1-10 Creating additional subject tables in the Conrad Systems Contacts database ensures that all fields in a table are functionally dependent on the primary key of the table.
Field Independence The last rule checks to see whether you’ll have any problems when you make changes to the data in your tables. Rule 4: You must be able to make a change to the data in any field (other than to a field in the primary key) without affecting the data in any other field. Take a look again at the Contact Products table in Figure A1-10. As we applied the second and third rules, we left product information with the Contact Products table because it seems reasonable that you need to know about the product sold to a contact. Note that if you need to correct the spelling of a product name, you can do so without affecting any other fields in that record. If you misspelled the same product name for many contact products, however, you might have to change many records. Also, if you entered the wrong product (for example, an order is actually for a Single-User edition, not a Multi-User edition), you can’t change the product name without also changing that record’s category and pricing information. The Product Category, Product Name, and Product Price fields are not independent of one another. In fact, Product Category and Product Price are functionally dependent on Product Name. (See Rule 3.) Although it wasn’t obvious at first, Product Name describes another subject that is different from the subject of contact products. You can see how carefully applying this fourth rule helps you identify changes that you perhaps should have made when applying earlier rules. This situation calls for another table in your design: a separate Products table, as shown in Figure A1-11.
1766 Article 1 Designing Your Database Application
Article 1
Now, if you misspell a product name, you can simply change the product name in the Products table. Also, instead of using the Product Name field (which might be 40 or 50 characters long) as the primary key for the Products table, you can create a shorter Product ID field (perhaps a five-digit number) to minimize the size of the relational data you need in the Contact Products table.
Figure A1-11 This design for the Conrad Systems Contacts database follows all the design rules.
Note also that we removed the Invoice Total field from the Invoices table because any change to a price in Contact Products would make this value incorrect. The database is not going to maintain this calculated value for you, so you would have to write extra code or create a macro in your application to recalculate and update the value each time a contact ordered another product. It’s a simple matter to build a query to sum the product prices for the records related to an invoice to calculate the total owed. (See Chapters 9 and 10 for details.) You can also calculate the total invoice value when the invoice is complete—perhaps as part of the report that prints the invoice. An alternative (but less rigorous) way to check for field independence is to see whether you have the same data repeated in your records. In the previous design, whenever you created a sale for a particular product during a contact event, you had to enter the product’s name, category, and price in the record. With a separate Products table, if you need to correct a product name spelling or change a list price or product category, you have to make the change only in one field of one record in the Products table. If you entered the wrong product in a contact product record, you have to change only the Product ID to fix the problem.
Database Design Concepts 1767
Note that we added a new field, a separate Product Sold Price field, in the Contact Products table. Why not link to the new Products table to find out the price? Why isn’t this duplicate data that violates Rule 1? This is an example of why it is very important to understand how the business runs. In this case, Conrad Systems sometimes offers a discount off “list price” to a company that purchases multiple copies of Conrad Systems’ products. The price in the Contact Products table is the actual sales price that the user enters when the company buys the product. You can learn more about the concept of such point-in-time data later in this article. The actual Conrad Systems Contacts sample database includes 10 tables, which are all shown in the Relationships window in Figure A1-12. Notice that we created additional fields in each table to fully describe the subject of each table, and we added other tables to support some of the other tasks identified earlier in this section. For example, many fields were added to both the Companies and Contacts tables to fully capture all the pertinent information about those subjects. There are also three lookup tables to help ensure accurate data entry and to provide additional information about the nature of some classification codes. A lookup table helps you restrict the list of values that are valid for a field in a main table, and they might also contain additional fields that help further define the meaning of each value in the list. You can learn more about defining lookup properties in Chapter 4.
Figure A1-12 The tables in the Conrad Systems Contacts sample database are shown in the Relationships window.
Article 1
1768 Article 1 Designing Your Database Application
The Four Rules of Good Table Design Article 1
Rule 1: Each field in a table should represent a unique type of information. Rule 2: Each table must have a unique identifier, or primary key, that is made up of one or more fields in the table. Rule 3: For each unique primary key value, the values in the data columns must be relevant to, and must completely describe, the subject of the table. Rule 4: You must be able to make a change to the data in any field (other than to a field in the primary key) without affecting the data in any other field.
Efficient Relationships Are the Result When you apply good design techniques, you end up with a database that efficiently links your data. You probably noticed that when you normalize your data as recommended, you tend to get many separate tables. Before relational databases were invented, you had to either compromise your design or manually keep track of the relationships between files or tables. For example, you had to put company data in your contacts and invoices tables or write your program to first open and read a record from one table and then search for the matching record in the related table. Relational databases solve these problems. With a good design, you don’t have to worry about how to bring the data together when you need it.
Foreign Keys You might have noticed as you followed the Conrad Systems Contacts design example that each time we created a new table, we left behind in the other table a field that could link the two, such as the Company ID, Contact ID, and Product ID fields in the Contact Products table. The Invoice Number field in Contact Products is also a link to the Invoices table. These “linking” fields are called foreign keys. In a well-designed database, foreign keys result in efficiency. You keep track of related foreign keys as you lay out your database design. When you define your tables in Access, you link primary keys to foreign keys to tell Access how to join the data when you need to retrieve information from more than one table. You can also ask Access to maintain the integrity of your table relationships—for example, Access will ensure that you don’t create a contact event for a contact that doesn’t exist. When you ask Access to maintain this referential integrity, Access automatically creates indexes for you. Indexes help Access find data more quickly when you’re searching, filtering, or linking data.
Database Design Concepts 1769
One-to-Many and One-to-One Relationships In most cases, the relationship between any two tables is one-to-many. That is, for any one record in the first table, there are many related records in the second table; but, for any record in the second table, there is exactly one matching record in the first table. You can see several instances of this type of relationship in the design of the Conrad Systems Contacts database. For example, each company might have several invoices, but a single invoice record applies to only one company. Occasionally, you might want to break down a table further because you use some of the data in the table infrequently or because some of the data in the table is highly sensitive and should not be available to everyone. You might also hit an Access storage limit for individual records if you’ve defined too many fields and store a lot of data in those fields. For example, you might want to keep track of certain company data for marketing purposes, but you don’t need access to that data all the time. Or you might have data about credit ratings that should be accessible only to authorized people. In either case, you can create a separate table that also has a primary key of Company ID. The relationship between the original Companies table and the Company Info or Company Credit table is one-to-one. That is, for each record in the first table, there is exactly one record in the second table.
Creating Table Links The last step in designing your database is to create the links between your tables. For each subject, identify those for which you wrote Many under Relationship on the worksheet. Be sure that the corresponding relationship for the other table is One. If you see Many in both places, you must create a separate linking table to handle the relationship. (Access won’t let you define a many-to-many relationship directly between two tables.) In the example of the Add/Edit a Contact task, a contact might be associated with many companies or organizations, and a company most likely has many contacts. The Company Contacts table in the Conrad Systems Contacts database is a linking table that clears up this many-to-many relationship between companies and contacts. Contact Products is another table that works as an intersection table because it has a one-to-many relationship with both Contacts and Products. (A contact might purchase several products, and a product is most likely owned by many contacts.) After you straighten out the many-to-many relationships and create additional subject worksheets to reflect the linking tables, you need to create the links between subjects. To complete the links, you should place a copy of the primary key from the one subject into a field in the many subject. For example, by looking at the worksheet for Companies shown in Figure A1-5, you can surmise that the primary key for the Companies subject, Company ID, also needs to be a field in the Company Contacts and Invoices subjects.
Article 1
For details about referential integrity and defining indexes, see Chapter 4.
1770 Article 1 Designing Your Database Application
When to Break the Rules Article 1
As a starting point, for every application that you build, you should always analyze the tasks you need to perform, decide on the data required to support those tasks, and create a welldesigned (also known as normalized) database table structure. After you have a design that follows all the rules, you might discover changes that you need to make, either to follow specific business rules or to make your application more responsive to the needs of your users. In every case for which you decide to “break the rules,” you should know the specific reason for doing so, document your actions, and be prepared to add procedures to your application to manage the impact of those changes. The following sections discuss some of the reasons why you might need to break the rules.
Improving Performance of Critical Tasks The majority of cases for breaking the rules involve manipulating the design to achieve better performance for certain critical tasks. For example, although modern relational database systems (like Access) do a good job of linking many related tables to perform complex tasks, you might encounter situations in which the performance of a multiple-table link (also called a joined query—see Chapter 10 for details) is not fast enough. Sometimes if you denormalize selected portions of the design, you can achieve the required performance. For example, instead of building a separate table of product category codes that requires a link, you might place the category descriptions directly in the products table. If you choose to do this, you will need to add procedures to the forms you provide to enter these categories or create data macros at the data layer to make sure that any similar descriptions aren’t duplicate entries. We chose to do this in the Conrad Systems Contacts database, and we solved the problem by using a combo box that allows the user to choose a value only from a validated list in another table. You’ll learn more about working with combo box controls in Chapter 13, “Building a Form.” Another case for breaking the rules is the selective inclusion of calculated values in your database. For example, if a critical management report needs the calculated totals for all orders in a month, but the data is retrieved too slowly when calculating the detailed values for thousands of product purchase records per order and thousands of orders, you might want to add a Calculated field for order total in the Orders or Invoices table. You’ll learn more about creating Calculated fields in tables in Chapter 6, “Designing Web Tables.” Your application will spend a few extra fractions of a second processing each order so that month-end totals can be obtained quickly.
When to Break the Rules 1771
Sometimes you need to break the rules to follow known business rules. In the previous design exercise, we considered removing the Price field from the Contact Products table because it duplicated the price information in the Products table. However, if your business rules say that the price of a product can change over time, you might need to include the price in your order details to record the price at the point in time that the order was placed. If your business rules dictate this sort of change, you should add procedures to your application to automatically copy the “current” price to any new order detail row. You can see another case in the Conrad Systems Contacts database. Some of the billing address information in the Invoices table looks like it duplicates information in the Companies table. If you examine the way the database works, you’ll find some code that copies the company information to the invoice information when you create a new invoice. Again, this address information in the Invoice is point-in-time data. It is the address that was current at the time the invoice was created. The company address might change later, but we will always know where we mailed a particular invoice.
Note You can find the Housing Reservations sample application on the companion CD.
There’s yet another example in the Housing Reservations database. In this database, the user creates room reservation requests that indicate that an employee needs a specific type of room over a range of dates. Some of this request information gets copied to the actual reservation record at the time the housing manager confirms the reservation. It is also company policy to honor the quoted rate at the time the reservation is made so that the manager who approves the reservation knows exactly what will be charged. (Likewise, if this were a commercial hotel, you would expect to pay the rate quoted at the time of the reservation, not the current rate at the time you check in three months later.) If you look at the database design for the Housing Reservations database, shown in Figure A1-13, you’ll see what looks like duplicate information in the Reservation Requests and the Reservations tables. In this case, check-in and check-out information is copied from Reservation Requests to Reservations when a reservation is confirmed. Likewise, the daily and weekly rates that are current at the time the reservation is made are copied to the reservation by code in the application.
Article 1
Capturing Point-in-Time Data
1772 Article 1 Designing Your Database Application
Article 1 Figure A1-13 The design for the Housing Reservations database includes duplicate point-intime pricing information in the Reservations table.
Note also that there’s a Total Charge field in the record that must be calculated by code within the application. The application spends a little computing time for each change to the records in the table to save processing time in reports that might need to work with hundreds of rows. If you look behind the Reservations form in the Housing Reservations database, you’ll find lots of code to accomplish both the rate copy and the total calculation.
Creating Report Snapshot Data One additional case for breaking the rules involves accumulating data for reporting. As you can see if you study the examples in Chapter 18, “Advanced Report Design,” the queries required to collect data for a complex report can be quite involved. If you have a lot of data required for your report, running the query could take an unacceptably long time, particularly if you need to run several large reports from the same complex collection of data. In this case, it’s acceptable to create temporary but “rule-breaking” tables that you load once with the results of a complex query to run your reports. We call these tables “snapshots” because they capture the results of a complex reporting query for a single moment in time. You can look in Chapter 11, “Modifying Data with Action Queries,” for some ideas about how to build action queries that save a complex data result to a temporary table. If you use the resulting “snapshot” data from these tables, you can run several complex reports without having to run long and complex queries more than once. Chapter 4, “Designing Client Tables,” shows you how to create a new database and tables, and Chapter 5, “Modifying Your Table Design,” shows you how to make changes later if you discover that you need to modify your design.
nderlying every query in Microsoft Access 2010 is the Structured Query Language (SQL) database command language. Although you can design most queries using the simple Access 2010 design grid (or the view, function, or stored procedure designer in an Access project file), Access stores every query you design as an SQL command. When you use one of the designers, Access creates the SQL for you. However, for advanced types of queries that use the results of a second query as a comparison condition, you need to know SQL to define the second query (called a subquery). Also, you cannot use the design grid to construct all types of queries available in the product; you must use SQL for some of them. Understanding SQL is essential to building queries in an Access project file, because you’re using Microsoft SQL Server.
Note This article does not document all the syntax variants accepted by Access, but it does cover all the features of the SELECT statement and of action queries. Wherever possible, American National Standards Institute (ANSI) standard syntax is shown to provide portability across other databases that also support some form of SQL. You might notice that Access modifies the ANSI-standard syntax to a syntax that it prefers after you define and save a query. You can find some of the examples shown in the following pages in the ContactsDataCopy.accdb sample database. When an example is in the sample database, you’ll find the name of the sample query in italics immediately preceding the query in the text. For a discussion of the syntax conventions used in this article, see the “Conventions and Features Used in This Book” section in the book’s front matter.
1773
1774 Article 2 Understanding SQL
How to Use This Article Article 2
This article contains two major sections: SQL select queries and SQL action queries. Within the first section, you can find keywords used in SQL in alphabetical order. You can also find entries for the basic building blocks you need to understand and use in various clauses: Column-Name, Expression, Search-Condition, and Subquery. If you’re new to SQL, you might want to study these building block topics first. You can then study the major clauses of a SELECT statement in the order in which they appear in a SELECT statement: PARAMETERS, SELECT, FROM, WHERE, GROUP BY, HAVING, UNION, and ORDER BY. In the second section, you can find a discussion of the syntax for the four types of queries that you can use to update your database, also in alphabetical order: DELETE, INSERT, SELECT INTO, and UPDATE. As you study these topics, you’ll find references to some of the major clauses that you’ll also use in a SELECT statement. You can find the details about those clauses in the first section.
SQL SELECT Queries The SELECT statement forms the core of the SQL database language. You use the SELECT statement to select or retrieve rows and columns from database tables. The SELECT statement syntax contains six major clauses: SELECT, FROM, WHERE, GROUP BY, HAVING, and ORDER BY. In an Access desktop application (.accdb), Access implements three significant extensions to the standard language: TRANSFORM, to allow you to build crosstab queries; IN, to allow you to specify a remote database connection or to specify column names in a crosstab query; and DISTINCTROW in a SELECT statement, to limit the rows returned from the
to rows that have different primary key values in the tables that supply columns in the . In a previous version format database (.mdb), you can also use WITH OWNERACCESS OPTION in a SELECT statement to design queries in a secured database that can be run by users who are authorized to use the query, including those who have insufficient access rights to the tables referenced in the query.
SQL SELECT Queries 1775
When you save a query that you have written in SQL in your database, Access often examines your SQL command and adds brackets or extra parentheses to make the command easier to parse and compile. In some cases, Access restates complex predicates or changes the ANSI-standard syntax to one it prefers. For this reason, the examples shown in the book might not exactly match what you see in the sample queries when you open them in SQL view. If you enter the SQL exactly as shown in the book, it will return the same result as the sample query you find in the database.
Aggregate Functions: AVG, CHECKSUM_AGG, COUNT, MAX, MIN, STDEV, STDEVP, SUM, VAR, and VARP See Table 10-1 (on page 647 of the printed book).
BETWEEN Predicate Compares a value with a range of values.
Syntax [NOT] BETWEEN AND
Notes The data types of all expressions must be compatible. Comparison of alphanumeric literals (strings) in Access or a default installation of SQL Server is case-insensitive. Let a, b, and c be expressions. Then, in terms of other predicates, a BETWEEN b AND c is equivalent to the following: (a >= b) AND (a c)
The result is undefined if any of the expressions is Null.
Article 2
Note
1776 Article 2 Understanding SQL
Example Article 2
To determine whether the SoldPrice is greater than or equal to $100 and less than or equal to $500, enter the following: SoldPrice BETWEEN 100 AND 500
See also Expression, SELECT Statement, Subquery, and WHERE Clause, in this article.
Column-Name Specifies the name of a column in an expression.
Notes You must supply a qualifier to the field name only if the name is ambiguous within the context of the query or subquery (for example, if the same field name appears in more than one table or query listed in the FROM clause). The table-name, select-query-name, or correlation-name that qualifies the field name must also appear in the FROM clause of the query or subquery. If a table or query has a correlation name, you must use the alias, not the actual name of the table or query. (A correlation name is an alias you assign to the table or query name in the FROM clause.) You must supply the enclosing brackets in an Access desktop application (.accdb) only if the name contains an embedded blank or the name is also a reserved word (such as select, table, name, or date). Embedded blanks and enclosing brackets are not supported in the ANSI standard. You can use names that have embedded blanks in SQL Server by including a SET QUOTED_IDENTIFIER ON command and then enclosing each nonstandard name in double quotes ("). When you open a query from an Access project, Access automatically includes this command in the command stream that it sends to SQL Server. If the field-name is a multi-value field, a query referencing the field-name returns the individual values separated by commas. A query datasheet provides a combo box that you can use to edit the multiple values. If you bind the column to a combo box control on a form, you can edit the field on the form. To edit the individual values in separate rows, use fieldname.Value in your query. For records in the table that have multiple values in the field,
SQL SELECT Queries 1777
the query returns one row per value. The effect is identical to linking to a related many-tomany lookup table using a join. (See FROM Clause, on page 675, for details about defining a join in a query.) Note, however, that when you ask for field-name.Value from more than one multi-valued column in a table, the resulting query is not updatable because the query returns the Cartesian product of the multiple values in the two fields for each row in the source table. If the field-name is an attachment data type, a query datasheet provides an attachment control to allow you to edit the data. You can also edit the data if you bind the field to an Attachment control in a form. You can individually reference one of the three properties of an attachment field: field-name.FileData, field-name.FileName, or field-name.FileType. All three properties return one row per separate attachment for each record in the source table, but you cannot update the values. The FileData property returns the binary attached file, the FileName property returns the original name of the file, and the FileType property returns the file extension.
Examples To specify a field named Customer Last Name in a table named Customer List in an Access desktop application (.accdb), use the following: [Customer List].[Customer Last Name]
To reference the same column in a view, stored procedure, or function for SQL Server, use the following: "Customer List"."Customer Last Name"
To specify a field named StreetAddress that appears in only one table or query in the FROM clause, enter the following: StreetAddress
To reference the individual values of a multi-valued field named ContactType, enter the following: ContactType.Value
See also FROM Clause, SELECT Statement, and Subquery in this article.
Comparison Predicate Compares the values of two expressions or the value of an expression and a single value returned by a subquery.
Article 2
1778 Article 2 Understanding SQL
Syntax Article 2
{= | | > | < | >= | 150): SELECT tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate, Sum(tblContactProducts.SoldPrice) AS InvoiceTotal FROM (tblCompanies INNER JOIN tblInvoices ON tblCompanies.CompanyID = tblInvoices.CompanyID) INNER JOIN tblContactProducts ON tblInvoices.InvoiceID = tblContactProducts.InvoiceID GROUP BY tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate HAVING Sum(tblContactProducts.SoldPrice) > 150;
See also Aggregate Functions, GROUP BY Clause, Search-Condition, SELECT Statement, and WHERE Clause in this article.
IN Clause In a desktop database (.accdb), specifies the source for the tables in a query. The source can be another Access database; a dBASE, or any database for which you have an Open Database Connectivity (ODBC) driver. This is an Access extension to standard SQL.
Syntax IN
Enter “source database name” and [source connect string]. (Be sure to include the quotation marks and the brackets.) If your database source is Access, enter only “source database name”. Enter these parameters according to the type of database to which you are connecting, as shown in Table A2-1. Table A2-1 IN Parameters for Various Database Types
The IN clause applies to all tables referenced in the FROM clause and any subqueries in your query. You can refer to only one external database within a query, but if the IN clause points to a database that contains more than one table, you can use any of those tables in your query. If you need to refer to more than one external file or database, attach those files as tables in Access and use the logical attached table names instead. For ODBC, if you omit the DSN= or DATABASE= parameter, Access prompts you with a dialog box showing available data sources so that you can select the one you want. If you omit the UID= or PWD= parameter and the server requires a user ID and password, Access prompts you with a login dialog box for each table accessed. For dBASE, you can provide an empty string ("") for source database name and provide the path or dictionary filename using the DATABASE= parameter in source connect string instead, as in "[dBase IV; DATABASE=C:\MyDB\dbase.dbf]"
Example In a desktop database (.accdb), to retrieve the Company Name field in the Northwind Traders sample database without having to attach the Customers table, enter the following: SELECT Customers.CompanyName FROM Customers IN "C:\My Documents\Shortcut to NORTHWIND.ACCDB";
See also SELECT Statement in this article.
IN Predicate Determines whether a value is equal to any of the values or is unequal to all values in a set returned from a subquery or provided in a list of values.
Syntax [NOT] IN {() | ({literal},...) |}
SQL SELECT Queries 1789
Comparison of strings in Access or a default installation of SQL Server is case-insensitive. The data types of all expressions, literals, and the column returned by the subquery must be compatible. If the expression is Null or any value returned by the subquery is Null, the result is undefined. In terms of other predicates, IN is equivalent to the following: =
IN () is equivalent to the following: = ANY ()
IN (a, b, c,...), where a, b, and c are literals, is equivalent to the following: ( = a) OR ( = b) OR ( = c) ...
NOT IN ... is equivalent to the following: NOT ( IN ...)
Examples To test whether StateOrProvince is on the west coast of the United States, enter the following: [StateOrProvince] IN ('CA', 'OR', 'WA')
To list all contacts who have not purchased a multi-user product, enter the following (qxmplContactsNotMultiUser): SELECT tblContacts.ContactID, tblContacts.FirstName, tblContacts.MiddleInit, tblContacts.LastName FROM tblContacts WHERE tblContacts.ContactID NOT IN (SELECT ContactID FROM tblContactProducts INNER JOIN tblProducts ON tblContactProducts.ProductID = tblProducts.ProductID WHERE tblProducts.CategoryDescription = 'Multi-User');
See also Expression, Quantified Predicate, SELECT Statement, Subquery, and WHERE Clause in this article.
Article 2
Notes
1790 Article 2 Understanding SQL
LIKE Predicate Article 2
Searches for strings that match a pattern.
Syntax column-name [NOT] LIKE match-string [ESCAPE escape-character]
Notes String comparisons in Access or a default installation of SQL Server are case-insensitive. If the column specified by column-name contains a Null, the result is undefined. Comparison of two empty strings or an empty string with the special asterisk (*) character (% character in SQL Server) evaluates to True. You provide a text string as a match-string value that defines what characters can exist in which positions for the comparison to be true. Access and SQL Server understand a number of wildcard characters (shown in Table A2-2) that you can use to define positions that can contain any single character, zero or more characters, or any single number. Table A2-2 Wildcard Characters for String Comparisons
Desktop Database Project File
Meaning
?
_
Any single character
*
%
Zero or more characters (used to define leading, trailing, or embedded strings that don’t have to match any of the pattern characters)
#
[0-9]
Any single number
You can also specify in the match string that any particular position in the text or memo field can contain only characters from a list that you provide. To define a list of comparison characters for a particular position, enclose the list in brackets ([ ]). You can specify a range of characters within a list by entering the low-value character, a hyphen, and the high-value character, as in [A-Z] or [3-7]. If you want to test a position for any characters except those in a list, start the list with an exclamation point (!) in a desktop database or a caret symbol (^) in a project file. If you want to test for one of the special characters *, ?, #, and [, (and _ or % in a project file), you must enclose the character in brackets. Alternatively, in a project file, you can
SQL SELECT Queries 1791
specify an ESCAPE clause. When you place the escape character in the match string, the database ignores the character and uses the following character as a literal comparison value. Therefore, you can include the escape character immediately preceding one of the special characters to use the special character as a literal comparison instead of a pattern character. Desktop databases do not support the ESCAPE clause.
Examples In a desktop database, to determine whether a contact’s LastName is at least four characters long and begins with Smi, enter the following: tblContacts.LastName LIKE "Smi?*"
In a project file, write the previous test as follows: tblContacts.LastName LIKE 'Smi_%'
In a desktop database, to test whether PostalCode is a valid Canadian postal code, enter the following: PostalCode LIKE "[A-Z]#[A-Z] #[A-Z]#"
In a project file, to test whether a character column named Discount ends in 5%, enter the following: Discount LIKE '%5$%' ESCAPE '$'
See also Expression, SELECT Statement, Subquery, and WHERE Clause in this article.
NULL Predicate Determines whether the expression evaluates to Null or not Null. This predicate evaluates only to True or False and will not evaluate to undefined.
Syntax IS [NOT] NULL
Article 2
1792 Article 2 Understanding SQL
Example Article 2
To determine whether the contact work phone number column contains the Null value, enter the following: tblContacts.WorkPhone IS NULL
See also Expression, SELECT Statement, Subquery, and WHERE Clause in this article.
ORDER BY Clause Specifies the sequence of rows to be returned by a SELECT statement or a subquery.
Syntax ORDER BY {column-name | column-number [ASC | DESC]},...
Notes You use column names or relative output column numbers to specify the columns on whose values the rows returned are ordered. (If you use relative output column numbers, the first output column is 1.) You can specify multiple columns in the ORDER BY clause. When you specify multiple columns, the list is ordered primarily by the first column. If rows exist for which the values of that column are equal, they are ordered by the next column in the ORDER BY list, and so on. When multiple rows contain the matching values in all the columns in the ORDER BY clause, the database can return the matching rows in any order. You can specify ascending (ASC) or descending (DESC) order for each column. If you do not specify ASC or DESC, ASC is assumed. Using an ORDER BY clause in a SELECT statement is the only means of defining the sequence of the returned rows. When you include the DISTINCT keyword or use the UNION query operator in the SELECT statement, the ORDER BY clause can include only columns specified in the SELECT clause. Otherwise, you can include any column in the logical table returned by the FROM clause. To use ORDER BY in a view, function, or stored procedure in SQL Server, you must also include the TOP keyword in the SELECT clause. To fetch and sort all rows, specify TOP 100 PERCENT. Note, however, that a view, function, or stored procedure returns the result ordered only when you directly execute the query from code. When Access runs a query in SQL Server that is identified as the record source of a form or report or the row source of a combo box or list box, it sends a SELECT * FROM queryname command to the server. The server returns the rows sorted only when you specify the ORDER BY clause again in the record source or row source as part of a SELECT statement on the query.
SQL SELECT Queries 1793
To calculate the total for all invoices and list the result for each customer and invoice in descending sequence by order total, enter the following (qxmplOrderTotalSorted): SELECT TOP 100 PERCENT tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate, Sum(tblContactProducts.SoldPrice) AS InvoiceTotal FROM (tblCompanies INNER JOIN tblInvoices ON tblCompanies.CompanyID = tblInvoices.CompanyID) INNER JOIN tblContactProducts ON tblInvoices.InvoiceID = tblContactProducts.InvoiceID GROUP BY tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate ORDER BY Sum(tblContactProducts.SoldPrice) DESC;
Note The TOP keyword is optional in a desktop database (.accdb). In SQL Server, you can also specify the calculated column alias name in the ORDER BY clause: ORDER BY InvoiceTotal DESC. In a desktop database, you must repeat the calculation expression as shown in the example.
In a desktop database (.accdb), to create a mailing list for all companies and all contacts, sorted in ascending order by postal code, enter the following (qxmplSortedMailingList): SELECT tblCompanies.CompanyName, tblCompanies.Address, tblCompanies.City, tblCompanies.StateOrProvince, tblCompanies.PostalCode FROM tblCompanies UNION SELECT [FirstName] & " " & ([MiddleInit]+". ") & [LastName] AS Contact, tblContacts.HomeAddress, tblContacts.HomeCity, tblContacts.HomeStateOrProvince, tblContacts.HomePostalCode FROM tblContacts ORDER BY 5;
Note If you decide to use column names in the ORDER BY clause of a UNION query, the database derives the column names from the names returned by the first query. In this example, you could change the ORDER BY clause to read ORDER BY PostalCode.
Article 2
Examples
1794 Article 2 Understanding SQL
To create the same mailing list in a view or in-line function in an SQL Server database, enter the following: Article 2
SELECT TOP 100 PERCENT CompanyName, Address, City, StateOrProvince, PostalCode FROM (SELECT tblCompanies.CompanyName, tblCompanies.Address, tblCompanies.City, tblCompanies.StateOrProvince, tblCompanies.PostalCode FROM tblCompanies UNION SELECT tblContacts.FirstName + ' ' + IsNull(tblContacts.MiddleInit + '. ', '') + tblContacts.LastName AS Contact, tblContacts.HomeAddress, tblContacts.HomeCity, tblContacts.HomeStateOrProvince, tblContacts.HomePostalCode FROM tblContacts) AS U ORDER BY 5;
Notice that you must UNION the rows first and then select and sort them all. See also INSERT Statement, SELECT Statement, and UNION Query Operator in this article.
PARAMETERS Declaration In a desktop database (.accdb), precedes an SQL statement to define the data types of any parameters you include in the query. You can use parameters to prompt the user for data values or to match data values in controls on an open form. (In an SQL Server database, you declare the parameters for a function or procedure as part of the CREATE statement.)
Notes If your query prompts the user for values, each parameter name should describe the value that the user needs to enter. For example, [Print invoices from orders on date:] is much more descriptive than [Enter date:]. If you want to refer to a control on an open form, use this format: [Forms]![Myform]![Mycontrol]
To refer to a control on a subform, use this format: [Forms]![Myform]![Mysubformcontrol].[Form]![ControlOnSubform]
Valid data type entries are shown in Table A2-3.
SQL SELECT Queries 1795
SQL Parameter Data Types
Equivalent Access Data Type
Char, Text(n) , VarChar
Text
Text1, LongText, LongChar, Memo
Memo
TinyInt, Byte, Integer1
Number, Byte
SmallInt, Short, Integer2
Number, Integer
Integer, Long, Integer4
Number, Long Integer
Real, Single, Float4, IEEESingle
Number, Single
Float, Double, Float8, IEEEDouble
Number, Double
Decimal, Numeric
Number, Decimal
UniqueIdentifier, GUID
Number, Replication ID
DateTime, Date, Time
Date/Time
Money, Currency
Currency
Bit, Boolean, Logical, YesNo
Yes/No
Image, LongBinary, OLEObject
OLE Object
Text, LongText, LongChar, Memo
Hyperlink2
Binary, VarBinary
Binary3
1
1
Text with a length descriptor of 255 or less maps to the Access Text data type. Text with no length descriptor is a Memo field.
2
Internally, Access stores a Hyperlink in a Memo field but sets a custom property to indicate a Hyperlink format.
3
The ACE supports a Binary data type (raw hexadecimal), but the Access user interface does not. If you encounter a non-Access table that has a data type that maps to Binary, you will be able to see the data type in the table definition, but you won’t be able to successfully edit this data in a datasheet or form. You can manipulate Binary data in Visual Basic.
Example To create a parameter query that summarizes the sales and the cost of goods for all items sold in a given month, enter the following (qxmplMonthSalesParameter): PARAMETERS [Year to summarize:] Short, [Month to summarize:] Short; SELECT tblProducts.ProductName, Format([DateSold],"mmmm"", ""yyyy") AS OrderMonth, Sum(tblContactProducts.SoldPrice) AS TotalSales FROM tblProducts INNER JOIN tblContactProducts ON tblProducts.ProductID = tblContactProducts.ProductID WHERE (Year([DateSold]) = [Year to summarize:]) AND (Month([DateSold]) = [Month to summarize:]) GROUP BY tblProducts.ProductName, Format([DateSold],"mmmm"", ""yyyy");
Article 2
Table A2-3 SQL Parameter Data Types
1796 Article 2 Understanding SQL
See also SELECT Statement in this article.
Article 2
Quantified Predicate Compares the value of an expression to some, any, or all values of a single column returned by a subquery.
Syntax {= | | > | < | >= | AllSupport): SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.UnitPrice FROM tblProducts WHERE tblProducts.UnitPrice >All (SELECT tblProducts.UnitPrice FROM tblProducts WHERE tblProducts.CategoryDescription = 'Support');
To find the products whose price is greater than any of the products in the Support category, enter the following (qxmplProductPrice>AnySupport): SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.UnitPrice FROM tblProducts WHERE tblProducts.UnitPrice >Any (SELECT tblProducts.UnitPrice FROM tblProducts WHERE tblProducts.CategoryDescription = 'Support');
See also Expression, SELECT Statement, Subquery, and WHERE Clause in this article.
SQL SELECT Queries 1797
Describes a simple or compound predicate that is True, False, or undefined for a given row or group. Use a search condition in the WHERE clause of a SELECT statement, a subquery, a DELETE statement, or an UPDATE statement. You can also use a search condition within the HAVING clause in a SELECT statement. The search condition defines the rows that should appear in the resulting logical table or the rows that should be acted upon by the change operation. If the search condition is True when applied to a row, that row is included in the result.
Notes If you include a comparison predicate in the form of comparison-operator , the database returns an error if the subquery returns no rows. The database effectively applies any subquery in a predicate within a search condition to each row of the table that is the result of the previous clauses. The database then evaluates the result of the subquery with regard to each candidate row. The order of evaluation of the Boolean operators is NOT, AND, OR, XOR (exclusive OR), EQV (equivalence), and IMP (implication). You can include additional parentheses to influence the order in which the Boolean expressions are processed. SQL Server does not support the XOR, EQV, and IMP logical operators.
INSIDE OUT
Using XOR, EQV, and IMP in the Access Query Designer
You can express AND and OR Boolean operations directly by using the design grid. If you need to use XOR, EQV, or IMP, you must create an expression in the Field row, clear the Show check box, and set the Criteria row to False.
When you use the Boolean operator NOT, the following holds: NOT (True) is False, NOT (False) is True, and NOT (undefined) is undefined. The result is undefined whenever a predicate references a null value. If a search condition evaluates to False or undefined when applied to a row, the row is not selected. The database returns True, False, or undefined values as a result of applying Boolean operators (AND, OR, XOR, EQV, IMP) against two predicates or search conditions according to the tables shown in Figure A2-1.
Article 2
Search Condition
1798 Article 2 Understanding SQL
Article 2 Figure A2-1 Truth tables for SQL Boolean operators
Example In a desktop database, to find all products for which the unit price is greater than $100 and for which the category description number is equal to Multi-User or the product has a prerequisite, but not both, enter the following (qxmplXOR): SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.CategoryDescription, tblProducts.UnitPrice, tblProducts.PreRequisite FROM tblProducts WHERE tblProducts.UnitPrice>100 AND ((tblProducts.CategoryDescription = "Multi-User") XOR (tblProducts.PreRequisite Is Not Null));
SQL SELECT Queries 1799
In a project file, to find all products for which the unit price is greater than $100 and for which the category description number is equal to Multi-User or the product has a prerequisite, but not both, enter the following: SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.CategoryDescription, tblProducts.UnitPrice, tblProducts.PreRequisite FROM tblProducts WHERE tblProducts.UnitPrice>100 AND ((tblProducts.CategoryDescription = "Multi-User") OR (tblProducts.PreRequisite Is Not Null)) AND NOT ((tblProducts.CategoryDescription = "Multi-User") AND (tblProducts.PreRequisite Is Not Null));
See also DELETE Statement, Expression, HAVING Clause, Predicates (BETWEEN, Comparison, EXISTS, IN, LIKE NULL, and Quantified), SELECT Statement, Subquery, UPDATE Statement, and WHERE Clause in this article.
SELECT Statement Fetches data from one or more tables or queries to create a logical table (recordset). The items in the select list identify the columns or calculated values to return from the source tables to the new recordset. You identify the tables to be joined in the FROM clause, and you identify the rows to be selected in the WHERE clause. Use GROUP BY to specify how to form groups for an aggregate query, and use HAVING to specify which resulting groups should be included in the result.
Syntax SELECT [ALL | DISTINCT | DISTINCTROW | TOP number [PERCENT]] FROM {table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | },... [IN ] [WHERE ] [GROUP BY column-name,...] [HAVING ] [UNION [ALL] ] [ORDER BY {column-name [ASC | DESC]},...] [WITH OWNERACCESS OPTION];
and where is ({table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | } {INNER | {{LEFT | RIGHT | FULL} [OUTER]} JOIN {table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | } ON )
Notes You can supply a correlation name for each table name or query name and use this correlation name as an alias for the full table name when qualifying column names in the , in the , or in the WHERE clause and subclauses. If you’re joining a table or a query to itself, you must use correlation names to clarify which copy of the table or query you’re referring to in the select list, join criteria, or selection criteria. If a table name or a query name is also an SQL reserved word (for example, Order), you must enclose the name in brackets. In SQL Server, you must enclose the name of a table or query that is also an SQL reserved word in brackets or double quotes. If you decide to use quotes, you must also ensure that the server has received the command SET QUOTED_IDENTIFIER ON. Note that when you open a query in an Access project, Access includes the required SET QUOTED_IDENTIFIER ON command in the command string to ensure that any names that you have enclosed in quotes are recognized correctly by SQL Server. However, if you execute an SQL Server query from a desktop database with a pass-through query, you must use brackets or quotes and include this command in the pass-through query. When you list more than one table or query without join criteria, the source is the Cartesian product of all the tables. For example, FROM TableA, TableB instructs the database to search all the rows of TableA matched with all the rows of TableB. Unless you specify other restricting criteria, the number of logical rows that the database processes could equal the number of rows in TableA times the number of rows in TableB. The database then returns the rows in which the selection criteria specified in the WHERE and HAVING clauses are true. (See FROM Clause, on page 675, for further details about specifying joins.) You can further define which rows the database includes in the output recordset by specifying ALL, DISTINCT, DISTINCTROW (in a desktop database only), TOP n, or TOP n PERCENT.
SQL SELECT Queries 1801
ALL includes all rows that match the search criteria from the source tables, including potential duplicate rows. DISTINCT requests that the database return only rows that are different from any other row. You cannot update any columns in a query that uses DISTINCT because the database can’t identify which of several potentially duplicate rows you intend to update. DISTINCTROW (the default in Access 7.0—Access 95—and earlier) requests that Access return only rows in which the concatenation of the primary keys from all tables supplying output columns is unique. Depending on the columns you select, you might see rows in the result that contain duplicate values, but each row in the result is derived from a distinct combination of rows in the underlying tables. DISTINCTROW is significant only when you include a join in a query and do not include output columns from all tables. For example, the statement SELECT tblContacts.WorkStateOrProvince FROM tblContacts INNER JOIN tblContactProducts ON tblContacts.ContactID = tblContactProducts.ContactID WHERE tblContactProducts.DateSold > #7/1/2010#;
returns 92 rows in the ContactsDataCopy.accdb sample database—one row for each product owned by a contact. On the other hand, the statement SELECT DISTINCTROW tblContacts.WorkStateOrProvince FROM tblContacts INNER JOIN tblContactProducts ON tblContacts.ContactID = tblContactProducts.ContactID WHERE tblContactProducts.DateSold > #7/1/2010#;
returns only 29 rows—one for each distinct row in the tblContacts table, the only table with output columns. The equivalent of the second example in ANSI-standard SQL is as follows: SELECT tblContacts.WorkStateOrProvince FROM tblContacts WHERE tblContacts.ContactID IN (Select tblContactProducts.ContactID FROM tblContactProducts WHERE tblContactProducts.DateSold > '2010-07-01');
We suspect that Microsoft implemented DISTINCTROW in version 1 because the first release of Access did not support subqueries. Specify TOP n or TOP n PERCENT to request that the recordset contain only the first n or first n percent of rows. In general, you should specify an ORDER BY clause when you use TOP to indicate the sequence that defines which rows are first, or top. The parameter n must be a positive integer and must be less than or equal to 100 if you include the PERCENT keyword. If you do not include an ORDER BY clause, the sequence of rows returned is undefined. In a TOP query, if the nth and any rows immediately following the nth row are duplicates, the database returns the duplicates; thus, the recordset might have more than
Article 2
1802 Article 2 Understanding SQL
Article 2
n rows. Note that if you specify an order, using TOP does not cause the query to execute any faster; the database must still solve the entire query, order the rows, and return the top rows. When you include a GROUP BY clause, the select list must be made up of one or more of the SQL aggregate functions or one or more of the column names specified in the GROUP BY clause. A column name in a GROUP BY clause can refer to any column from any table in the FROM clause, even if the column is not named in the select list. If you want to refer to a calculated expression in the GROUP BY clause, you must assign an output column name to the expression in the select list and then refer to that name in the GROUP BY clause. If the GROUP BY clause is preceded by a WHERE clause, the database forms the groups from the rows selected after it applies the WHERE clause. If you use a HAVING clause but do not include a GROUP BY clause, the select list must be formed using SQL aggregate functions. If you include a GROUP BY clause preceding the HAVING clause, the HAVING search condition applies to each of the groups formed by equal values in the specified columns. If you do not include a GROUP BY clause, the HAVING search condition applies to the entire logical table defined by the SELECT statement. You use column names or relative output column numbers to specify the columns on whose values the rows returned are ordered. (If you use relative output column numbers, the first output column is 1.) You can specify multiple columns in the ORDER BY clause. When you specify multiple columns, the list is ordered primarily by the first column. If rows exist for which the values of that column are equal, they are ordered by the next column in the ORDER BY list, and so on. When multiple rows contain the matching values in all the columns in the ORDER BY clause, the database can return the matching rows in any order. You can specify ascending (ASC) or descending (DESC) order for each column. If you do not specify ASC or DESC, ASC is assumed. Using an ORDER BY clause in a SELECT statement is the only means of defining the sequence of the returned rows. In an .mdb-format desktop database that has user-level security implemented, the person running the query not only must have rights to the query but also must have the appropriate rights to the tables used in the query. (These rights include reading data to select rows and updating, inserting, and deleting data using the query.) If your application has multiple users, you might want to secure the tables so that no user has direct access to any of the tables and all users can still run queries defined by you. Assuming you’re the owner of both the queries and the tables, you can deny access to the tables but allow access to the queries. To make sure that the queries run properly, you must add the WITH OWNERACCESS OPTION clause to allow users the same access rights as the table owner when accessing the data via the query. Access 2010 does not support user-level security in .accdb-format databases.
SQL SELECT Queries 1803
If the select-list references a multi-value field, the query returns the individual values separated by commas. A query datasheet provides a combo box that you can use to edit the multiple values. If you bind the column to a combo box control on a form, you can edit the field on the form. To edit the individual values in separate rows, use field-name.Value in your query. For records in the table that have multiple values in the field, the query returns one row per value. The effect is identical to linking to a related many-to-many lookup table using a join. (See FROM Clause, on page 675, for details about defining a join in a query.) Note, however, that when you ask for field-name.Value from more than one multi-valued column in a table, the resulting query is not updatable because the query returns the Cartesian product of the multiple values in the two fields for each row in the source table. If the select-list contains an attachment data type, the query datasheet provides an attachment control to allow you to edit the data. You can also edit the data if you bind the field to an Attachment control in a form. You can individually reference one of the three properties of an attachment field: field-name.FileData, field-name.FileName, or field-name. FileType. All three properties return one row per separate attachment for each record in the source table, but you cannot update the values. The FileData property returns the binary attached file, the FileName property returns the original name of the file, and the FileType property returns the file extension.
Examples To select information about all companies and contacts and any products purchased, enter the following (qxmplAllCompanyContactsAnyProducts): SELECT tblCompanies.CompanyName, tblContacts.FirstName, tblContacts.LastName, CP.ProductName, CP.DateSold, CP.SoldPrice FROM ((tblCompanies INNER JOIN tblCompanyContacts ON tblCompanies.CompanyID = tblCompanyContacts.CompanyID) INNER JOIN tblContacts ON tblContacts.ContactID = tblCompanyContacts.ContactID) LEFT JOIN (SELECT tblContactProducts.ContactID, tblProducts.ProductName, tblContactProducts.DateSold, tblContactProducts.SoldPrice FROM tblProducts INNER JOIN tblContactProducts ON tblProducts.ProductID = tblContactProducts.ProductID WHERE tblProducts.TrialVersion = 0) AS CP ON tblContacts.ContactID = CP.ContactID;
Article 2
1804 Article 2 Understanding SQL
Note Article 2
If you save the previous query in a previous version of Access, when you open the query in Design view, you’ll find that Access saves the inner with brackets, like this: [SELECT tblContactProducts.ContactID, tblProducts.ProductName, tblContactProducts.DateSold, tblContactProducts.SoldPrice FROM tblProducts INNER JOIN tblContactProducts ON tblProducts.ProductID = tblContactProducts.ProductID WHERE tblProducts.TrialVersion = 0]. AS CP
This is the internal syntax supported by the JET database engine installed with Access 2003 and earlier. The ACE supplied with Access 2010 no longer modifies the SQL— you’ll find the sample query saved exactly as stated in the example without brackets.
To find the average and maximum prices for products by category name, enter the following (qxmplCategoryAvgMaxPrice): SELECT tblProducts.CategoryDescription, Avg(tblProducts.UnitPrice) AS AvgOfUnitPrice, Max(tblProducts.UnitPrice) AS MaxOfUnitPrice FROM tblProducts WHERE tblProducts.TrialVersion = 0 GROUP BY tblProducts.CategoryDescription;
To find the invoice amounts for all invoices that total more than $150, enter the following (qxmplTotalInvoices>150): SELECT tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate, Sum(tblContactProducts.SoldPrice) AS InvoiceTotal FROM (tblCompanies INNER JOIN tblInvoices ON tblCompanies.CompanyID = tblInvoices.CompanyID) INNER JOIN tblContactProducts ON tblInvoices.InvoiceID = tblContactProducts.InvoiceID GROUP BY tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate HAVING Sum(tblContactProducts.SoldPrice) > 150;
SQL SELECT Queries 1805
SELECT TOP 100 PERCENT tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate, Sum(tblContactProducts.SoldPrice) AS InvoiceTotal FROM (tblCompanies INNER JOIN tblInvoices ON tblCompanies.CompanyID = tblInvoices.CompanyID) INNER JOIN tblContactProducts ON tblInvoices.InvoiceID = tblContactProducts.InvoiceID GROUP BY tblCompanies.CompanyName, tblInvoices.InvoiceID, tblInvoices.InvoiceDate ORDER BY Sum(tblContactProducts.SoldPrice) DESC;
Note The TOP keyword is optional in a desktop database (.accdb). In SQL Server, you can also specify the calculated column alias name in the ORDER BY clause: ORDER BY InvoiceTotal DESC. In a desktop database, you must repeat the calculation expression as shown in the example.
In a desktop database (.accdb), to create a mailing list for all companies and all contacts, sorted in ascending order by postal code, enter the following (qxmplSortedMailingList): SELECT tblCompanies.CompanyName, tblCompanies.Address, tblCompanies.City, tblCompanies.StateOrProvince, tblCompanies.PostalCode FROM tblCompanies UNION SELECT [FirstName] & " " & ([MiddleInit]+". ") & [LastName] AS Contact, tblContacts.HomeAddress, tblContacts.HomeCity, tblContacts.HomeStateOrProvince, tblContacts.HomePostalCode FROM tblContacts ORDER BY 5;
Note If you decide to use column names in the ORDER BY clause of a UNION query, the database derives the column names from the names returned by the first query. In this example, you could change the ORDER BY clause to read ORDER BY PostalCode.
Article 2
To calculate the total for all invoices and list the result for each customer and invoice in descending sequence by order total, enter the following (qxmplOrderTotalSorted):
1806 Article 2 Understanding SQL
To create the same mailing list in a view or in-line function in an SQL Server database, enter the following: Article 2
SELECT TOP 100 PERCENT CompanyName, Address, City, StateOrProvince, PostalCode FROM (SELECT tblCompanies.CompanyName, tblCompanies.Address, tblCompanies.City, tblCompanies.StateOrProvince, tblCompanies.PostalCode FROM tblCompanies UNION SELECT tblContacts.FirstName + ' ' + IsNull(tblContacts.MiddleInit + '. ', '') + tblContacts.LastName AS Contact, tblContacts.HomeAddress, tblContacts.HomeCity, tblContacts.HomeStateOrProvince, tblContacts.HomePostalCode FROM tblContacts) AS U ORDER BY 5;
Notice that you must UNION the rows first and then select and sort them all. See also FROM Clause, GROUP BY Clause, HAVING Clause, INSERT Statement, Search-Condition, and UNION Query Operator in this article.
Subquery Selects from a single column any number of values, or no values at all, for comparison in a predicate. You can also use a subquery that returns a single value in the select list of a SELECT clause.
Syntax (SELECT [ALL | DISTINCT | DISTINCTROW | TOP number [PERCENT]] FROM {table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | },... [WHERE ] [GROUP BY column-name,...] [HAVING ] [ORDER BY {column-name [ASC | DESC]},...])
where select-list is {* | { | table-name.* | query-name.* | correlation-name.*}}
SQL SELECT Queries 1807
({table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | } {INNER | {{LEFT | RIGHT | FULL} [OUTER]} JOIN {table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | } ON )
Notes You can use the special asterisk (*) character in the of a subquery only when the subquery is used in an EXISTS predicate or when the FROM clause within the subquery refers to a single table or query that contains only one column. You can supply a correlation name for each table name or query name and use this correlation name as an alias for the full table name when qualifying column names in the , in the , or in the WHERE clause and subclauses. If you’re joining a table or a query to itself, you must use correlation names to clarify which copy of the table or query you’re referring to in the select list, join criteria, or selection criteria. You must also use a correlation name if one of the tables in the FROM clause is the same as a table in the outer query. If a table name or a query name is also an SQL reserved word (for example, Order), you must enclose the name in brackets. In SQL Server, you must enclose the name of a table or query that is also an SQL reserved word in double quotes. Note that when you open a query in an Access project, Access includes the required SET QUOTED_IDENTIFIER ON command in the command string. However, if you execute an SQL Server query from a desktop database with a pass-through query, you must include this command in the passthrough query. When you list more than one table or query without join criteria, the source is the Cartesian product of all the tables. For example, FROM TableA, TableB instructs the database to search all the rows of TableA matched with all the rows of TableB. Unless you specify other restricting criteria, the number of logical rows that the database processes could equal the number of rows in TableA times the number of rows in TableB. The database then returns the rows in which the selection criteria specified in the WHERE and HAVING clauses are true. (See also FROM Clause, on page 675, for further details about specifying joins.)
Article 2
and where is
1808 Article 2 Understanding SQL
Article 2
You can further define which rows the database includes in the output recordset by specifying ALL, DISTINCT, DISTINCTROW (in a desktop database only), TOP n, or TOP n PERCENT. ALL includes all rows that match the search criteria from the source tables, including potential duplicate rows. DISTINCT requests that the database return only rows that are different from any other row. DISTINCTROW (the default in Access version 7.0 and earlier) requests that Access return only rows in which the concatenation of the primary keys from all tables supplying output columns is unique. Depending on the columns you select, you might see rows in the result that contain duplicate values, but each row in the result is derived from a distinct combination of rows in the underlying tables. DISTINCTROW is significant only when you include a join in a query and do not include output columns from all tables. (See SELECT Statement, on page 675, for more information about DISTINCTROW.) Specify TOP n or TOP n PERCENT to request that the recordset contain only the first n or first n percent of rows. In general, you should specify an ORDER BY clause when you use TOP to indicate the sequence that defines which rows are first, or top. The parameter n must be an integer and must be less than or equal to 100 if you include the PERCENT keyword. If you do not include an ORDER BY clause, the sequence of rows returned is undefined. In a TOP query, if the nth and any rows immediately following the nth row are duplicates, the database returns the duplicates; thus, the recordset might have more than n rows. Note that if you specify an order, using TOP does not cause the query to execute any faster; the database must still solve the entire query, order the rows, and return the top rows. In the search condition of the WHERE clause of a subquery, you can use an outer reference to refer to the columns of any table or query that is defined in the outer queries. You must qualify the column name if the table or query reference is ambiguous. A column name in the GROUP BY clause can refer to any column from any table in the FROM clause, even if the column is not named in the . If the GROUP BY clause is preceded by a WHERE clause, the database creates the groups from the rows selected after the application of the WHERE clause. When you include a GROUP BY or HAVING clause in a SELECT statement, the select list must be made up of either SQL aggregate functions or column names specified in the GROUP BY clause. If a GROUP BY clause precedes a HAVING clause, the HAVING clause’s search condition applies to each of the groups formed by equal values in the specified columns. If you do not include a GROUP BY clause, the HAVING clause’s search condition applies to the entire logical table defined by the SELECT statement.
SQL SELECT Queries 1809
To find all contacts who own at least one product, enter the following (qxmplContactSomeProduct): SELECT tblContacts.FirstName, tblContacts.MiddleInit, tblContacts.LastName FROM tblContacts WHERE EXISTS (SELECT * FROM tblContactProducts INNER JOIN tblProducts ON tblContactProducts.ProductID = tblProducts.ProductID WHERE tblContactProducts.ContactID = tblContacts.ContactID AND tblProducts.TrialVersion = 0);
Note In this example, the inner subquery makes a reference to the tblContacts table in the SELECT statement by referring to a column in the outer table (tblContacts.ContactID). This forces the subquery to be evaluated for every row in the SELECT statement, which might not be the most efficient way to achieve the desired result. (This type of subquery is also called a correlated subquery.) Whenever possible, the database query plan optimizer solves the query efficiently by reconstructing the query internally as a join between the source specified in the FROM clause and the subquery. In many cases, you can perform this reconstruction yourself, but the purpose of the query might not be as clear as when you state the problem using a subquery.
To select contacts who first purchased a product before 2011 and list them in ascending order by postal code, enter the following (qxmplContactsPurchaseBefore2011): SELECT TOP 100 PERCENT tblContacts.FirstName, tblContacts.MiddleInit, tblContacts.LastName, tblContacts.HomeCity, tblContacts.HomePostalCode FROM tblContacts WHERE #01/01/2011# > (SELECT Min(tblContactProducts.DateSold) FROM tblContactProducts WHERE tblContactProducts.ContactID = tblContacts.ContactID) ORDER BY tblContacts.HomePostalCode;
Note The previous query also uses a correlated subquery.
Article 2
Examples
1810 Article 2 Understanding SQL
To find the products whose price is greater than any of the support products, enter the following (qxmplProductsPrice>AnySupport): Article 2
SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.UnitPrice FROM tblProducts WHERE tblProducts.UnitPrice >Any (SELECT tblProducts.UnitPrice FROM tblProducts WHERE tblProducts.CategoryDescription = "Support");
See also Expression, Predicates (BETWEEN, Comparison, EXISTS, IN, LIKE NULL, and Quantified), and SELECT Statement in this article.
TRANSFORM Statement In a desktop database, produces a crosstab query that lets you summarize a single value by using the values found in a specified column or in an expression as the column headers and using other columns or expressions to define the grouping criteria to form rows. The result looks similar to a spreadsheet and is most useful as input to a graph object. This is an Access extension to standard SQL.
Syntax TRANSFORM PIVOT [IN ()]
where is an expression created with one of the aggregate functions, contains a GROUP BY clause, and is a list of required values expected to be returned by the PIVOT expression, enclosed in quotes and separated by commas. (You can use the IN clause to force the output sequence of the columns.)
Notes The parameter is the value that you want to appear in the “body” of the crosstab datasheet. PIVOT defines the column or expression that provides the column headings in the crosstab result. You might, for example, use this value to provide a list of months with aggregate rows defined by product categories in the GROUP BY clause. You can use more than one column or expression in the SELECT statement to define the grouping criteria for rows.
SQL SELECT Queries 1811
To produce a total sales amount for each month in the year 2010, categorized by product, enter the following (qxmpl2010SalesByProductXtab): TRANSFORM Sum(tblContactProducts.SoldPrice) AS SumOfSoldPrice SELECT tblProducts.ProductID, tblProducts.ProductName, Sum(tblContactProducts.SoldPrice) AS TotSales FROM tblProducts INNER JOIN tblContactProducts ON tblProducts.ProductID = tblContactProducts.ProductID GROUP BY tblProducts.ProductID, tblProducts.ProductName PIVOT Format([DateSold],”mmm yyyy”) IN ("Jan 2010","Feb 2010","Mar 2010","Apr 2010","May 2010", "Jun 2010","Jul 2010","Aug 2010","Sep 2010", "Oct 2010","Nov 2010","Dec 2010");
Note This example shows a special use of the IN predicate to define not only which months should be selected but also the sequence in which Access displays the months in the resulting recordset.
See also GROUP BY Clause, HAVING Clause, SELECT Statement, and Total Functions in this article.
UNION Query Operator Produces a result table that contains the rows returned by both the first SELECT statement and the second SELECT statement.
Syntax UNION [ALL] [ORDER BY {column-name | column-number [ASC | DESC]},...]
Article 2
Example
1812 Article 2 Understanding SQL
Notes Article 2
When you specify ALL, the database returns all rows in both logical tables. When you do not specify ALL, the database eliminates duplicate rows. The tables returned by each must contain an equal number of columns, and each column must have identical attributes. You must not use the ORDER BY clause in the that are joined by query operators; however, you can include a single ORDER BY clause at the end of a statement that uses one or more query operators. This action will apply the specified order to the result of the entire statement. The database derives the column names of the output from the column names returned by the first . If you want to use column names in the ORDER BY clause, be sure to use names from the first query. You can also use the output column numbers to define ORDER BY criteria. In a project file, you can include the ORDER BY clause at the end of the statement in a stored procedure, but you cannot include this clause in a view or in-line function. To sort a UNION in a view or in-line function, you must create a view on the query containing the UNION and then sort the view. You can also embed the UNION query in a FROM clause of a query and then sort the result. You can combine multiple SELECT statements using UNION to obtain complex results. You can also use parentheses to influence the sequence in which the database applies the operators, as shown here: SELECT...UNION (SELECT...UNION SELECT...)
Example In a desktop database (.accdb), to create a mailing list for all companies and all contacts, sorted in ascending order by postal code, enter the following (qxmplSortedMailingList): SELECT tblCompanies.CompanyName, tblCompanies.Address, tblCompanies.City, tblCompanies.StateOrProvince, tblCompanies.PostalCode FROM tblCompanies UNION SELECT [FirstName] & " " & ([MiddleInit]+". ") & [LastName] AS Contact, tblContacts.HomeAddress, tblContacts.HomeCity, tblContacts.HomeStateOrProvince, tblContacts.HomePostalCode FROM tblContacts ORDER BY 5;
SQL SELECT Queries 1813
If you decide to use column names in the ORDER BY clause of a UNION query, the database derives the column names from the names returned by the first query. In this example, you could change the ORDER BY clause to read ORDER BY PostalCode.
To create the same mailing list in a view or in-line function in an SQL Server database, enter the following: SELECT TOP 100 PERCENT CompanyName, Address, City, StateOrProvince, PostalCode FROM (SELECT tblCompanies.CompanyName, tblCompanies.Address, tblCompanies.City, tblCompanies.StateOrProvince, tblCompanies.PostalCode FROM tblCompanies UNION SELECT tblContacts.FirstName + ' ' + IsNull(tblContacts.MiddleInit + '. ', '') + tblContacts.LastName AS Contact, tblContacts.HomeAddress, tblContacts.HomeCity, tblContacts.HomeStateOrProvince, tblContacts.HomePostalCode FROM tblContacts) AS U ORDER BY 5;
Notice that you must UNION the rows first and then select and sort them all. See also ORDER BY Clause and SELECT Statement in this article.
WHERE Clause Specifies a search condition in an SQL statement or an SQL clause. The DELETE, SELECT, and UPDATE statements and the subquery containing the WHERE clause operate only on those rows that satisfy the condition.
Syntax WHERE
Notes The database applies the to each row of the logical table assembled as a result of executing the previous clauses, and it rejects those rows for which the does not evaluate to True. If you use a subquery within a predicate in the (often called an inner query), the database must execute the subquery before it evaluates the predicate.
Article 2
Note
1814 Article 2 Understanding SQL
Article 2
In a subquery, if you refer to a table or a query that you also use in an outer FROM clause (often called a correlated subquery), the database must execute the subquery for each row being evaluated in the outer table. If you do not use a reference to an outer table in a subquery, the database must execute the subquery only once. A correlated subquery can also be expressed as a join, which generally executes more efficiently. If you include a predicate in the in the form
the database returns an error if the subquery returns no rows. The order of evaluation of the logical operators used in the is NOT, AND, OR, XOR (exclusive OR), EQV (equivalence), and then IMP (implication). (SQL Server does not support the XOR, EQV, and IMP logical operators.) You can include additional parentheses to influence the order in which the database processes expressions.
Examples In a desktop database, to find all products for which the unit price is greater than $100 and for which the category description number is equal to Multi-User or the product has a prerequisite, but not both, enter the following (qxmplXOR): SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.CategoryDescription, tblProducts.UnitPrice, tblProducts.PreRequisite FROM tblProducts WHERE tblProducts.UnitPrice>100 AND ((tblProducts.CategoryDescription = "Multi-User") XOR (tblProducts.PreRequisite Is Not Null));
In a project file, to find all products for which the unit price is greater than $100 and for which the category description number is equal to Multi-User or the product has a prerequisite, but not both, enter the following: SELECT tblProducts.ProductID, tblProducts.ProductName, tblProducts.CategoryDescription, tblProducts.UnitPrice, tblProducts.PreRequisite FROM tblProducts WHERE tblProducts.UnitPrice>100 AND ((tblProducts.CategoryDescription = "Multi-User") OR (tblProducts.PreRequisite Is Not Null)) AND NOT ((tblProducts.CategoryDescription = "Multi-User") AND (tblProducts.PreRequisite Is Not Null));
See also DELETE Statement, Expression, Predicates (BETWEEN, Comparison, EXISTS, IN, LIKE NULL, and Quantified), Search Condition, SELECT Statement, Subquery, and UPDATE Statement in this article.
SQL Action Queries 1815
Use SQL action queries to delete, insert, or update data or to create a new table from existing data. Action queries are particularly powerful because they allow you to operate on sets of data, not single rows. For example, an UPDATE statement or a DELETE statement affects all rows in the underlying tables that meet the selection criteria you specify.
DELETE Statement Deletes one or more rows from a table or a query. The WHERE clause is optional. If you do not specify a WHERE clause, all rows are deleted from the table or the query that you specify in the FROM clause. If you specify a WHERE clause, the database applies the search condition to each row in the table or the query, and only those rows that evaluate to True are deleted.
and where is ({table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | } {INNER | {{LEFT | RIGHT | FULL} [OUTER]} JOIN {table-name [[AS] correlation-name] | select-query-name [[AS] correlation-name] | () AS correlation-name | } ON )
Notes When you specify a query name in a DELETE statement, the query must not be constructed using the UNION query operator. The query also must not contain an SQL aggregate function, the DISTINCT keyword, a GROUP BY or HAVING clause, or a subquery that references the same base table as the DELETE statement.
Article 2
SQL Action Queries
1816 Article 2 Understanding SQL
Article 2
When you join two or more tables in the FROM clause, you can delete rows only from the many side of the relationship if the tables are related one-to-many; if the tables are related one-to-one, you can delete rows from either side. When you include more than one table in the FROM clause, you must also specify from which table the rows are to be deleted by using table name.* in the . When you specify only one table in the FROM clause, you do not need to provide a . You can supply a correlation name for each table or query name. You can use this correlation name as an alias for the full table name when qualifying column names in the WHERE clause and in subclauses. You must use a correlation name when referring to a column name that occurs in more than one table in the FROM clause. If you use a subquery in the , you must not reference the target table or the query or any underlying table of the query in the subquery.
Examples To delete all rows in the tblContactProducts table, enter the following: DELETE FROM tblContactProducts;
To delete all rows in the tblContactEventsHistory table for events that occurred before January 1, 2010, enter the following (qxmplDeleteOldEventHistory): DELETE tblContactEventsHistory.* FROM tblContactEventsHistory WHERE tblContactEventsHistory.ContactDateTime < #01/01/2010#;
See also IN Clause, INSERT Statement, Predicates (BETWEEN, Comparison, EXISTS, IN, LIKE NULL, and Quantified), Search-Condition, and Subquery in this article.
INSERT Statement (Append Query) Inserts one or more new rows into the specified table or query. When you use the VALUES clause, the database inserts only a single row. If you use a SELECT statement, the number of rows inserted equals the number of rows returned by the SELECT statement.
If you do not include a column name list, you must supply values for all columns defined in the table in the order in which they were declared in the table definition. If you include a column name list, you must supply values for all columns in the list, and the values must be compatible with the receiving column attributes. You must include in the list all columns in the underlying table whose Required attribute is Yes and that do not have a default value. If you include an IN clause in both the INSERT and the FROM clause of the SELECT statement, both must refer to the same source database. If you supply values by using a SELECT statement, the statement’s FROM clause cannot have the target table of the insert as its table name or as an underlying table. The target table also cannot be used in any subquery. You cannot include an attachment field in the list of column names for an INSERT into a table. If the target table contains an attachment field, you must include the column-name list and specify any other fields into which you want to insert data. It is not possible to insert data into an attachment field using SQL. You cannot include a calculated data type field in the list of column names for an INSERT into a table. If the target table contains a calculated data type field, you must include the column-name list and specify any other fields into which you want to insert data. It is not possible to insert data into a calculated data type field using SQL. You cannot include a multi-valued field in the list of column names for an INSERT into a table unless the multi-value field is the only field in the column-name list and you include the Value property of the field. You can include a WHERE clause only when the target of the insert is the Value property of a single multi-valued field. In this case, you use the WHERE clause to specify which rows in the parent table should be affected by the INSERT. If you use a select-statement as the source of the inserted values when the target is the hidden recordset represented by the Value property of a multi-value field, the WHERE clause applies to the target table, not the select-statement, unless you can qualify the column names in the predicate to make it clear that the WHERE clause applies to the selectstatement. You cannot include a WHERE clause filtering the select-statement and a second WHERE clause filtering the target table. Because Access allows you to define column-value constraints (validation rules in a desktop database), table constraints (validation rule in a desktop database), and referential integrity checks, any values that you insert must pass these validations before Access will allow you to run the query.
Article 2
Notes
1818 Article 2 Understanding SQL
Examples Article 2
To insert a new row in the tblProducts table, enter the following: INSERT INTO tblProducts (ProductName, CategoryDescription, UnitPrice) VALUES ('Support Renewal', 'Multi-User', 99);
To insert old event records into a history table and avoid duplicates, enter the following (qxmplArchiveContactEventsByDate): PARAMETERS LastDateToKeep DateTime; INSERT INTO tblContactEventsHistory (ContactID, ContactDateTime, ContactEventType, ContactNotes ) SELECT tblContactEvents.ContactID, tblContactEvents.ContactDateTime, tlkpContactEventTypes.ContactEventTypeDescription, tblContactEvents.ContactNotes FROM tlkpContactEventTypes INNER JOIN (tblContactEvents LEFT JOIN tblContactEventsHistory ON (tblContactEvents.ContactID = tblContactEventsHistory.ContactID) AND (tblContactEvents.ContactDateTime = tblContactEventsHistory.ContactDateTime)) ON tlkpContactEventTypes.ContactEventTypeID = tblContactEvents.ContactEventTypeID WHERE (tblContactEvents.ContactDateTime=#1/1/2010#) AS Active ON tblContacts.ContactID = Active.ContactID SET tblContacts.Inactive = True WHERE Active.ContactID IS NULL;
Article 2
1822 Article 2 Understanding SQL
Note Article 2
Although the previous query updates rows on the one side of a relationship, the query is valid because the IS NULL test in conjunction with the LEFT JOIN returns exactly one unique row per contact.
See also Expression, IN Clause, Predicates (BETWEEN, Comparison, EXISTS, IN, LIKE NULL, and Quantified), Search-Condition, and WHERE Clause in this article.
c hapte A rticl er3n o
Chapter Title Exporting Data
Exporting to Another Access Database. . . . . . . . . . . . . 1823
Exporting to a Mail Merge Document in Word. . . . . . 1826
Exporting to a Spreadsheet or to a dBASE File. . . . . . 1824
his article provides details about exporting data from Microsoft Access 2010 to other Access databases and other file types. You can export (copy) any object in an Access database to any other Access database. You can also export data from Access tables to spreadsheet files, other databases, text files, Microsoft Word 2010 mail merge documents, and tables stored in databases that support Open Database Connectivity (ODBC).
Exporting to Another Access Database Exporting objects from one Access database to another works much like importing Access objects. (See Chapter 8, “Importing and Linking Data,” for details.) To export any object from one Access database to another Access database, do the following:
1. Open the Access database from which you want to export an object. 2. Select the object you want to export in the Navigation pane. On the External Data tab, in the Export group, click the Access command. Access opens the Export – Access Database dialog box. Click Browse, and then select the folder and the name of the desktop database (.accdb) or project file (.adp) to which you want to export the object. (You can export queries in an Access project only to another project file.) After you make these selections, click Save. You can also enter the path and file name directly in the File Name box. Click OK to continue.
3. Next, Access opens the Export dialog box. Use the Export dialog box to specify a name for the object in the target database. You can keep the name that Access suggests, or you can change it to make it more appropriate to the target database. Note that if you’re exporting a table, you can choose to export both the table definition and the data or the definition only. Click OK to export the object.
1823
1824 Article 3 Exporting Data
4. If the export name you type already exists in the target database, Access warns you Article 3
and asks whether you want to replace the existing object. Click Yes to proceed, or click No to stop the export procedure. If the export procedure succeeds, you’ll find a new object in the target database. Because objects can refer to other objects by name within an Access database, you should carefully check name references in the target database.
Exporting to a Spreadsheet or to a dBASE File Use the following procedure to export data from a table, a select query, or a crosstab query to a spreadsheet (Microsoft Excel 2010) or to a foreign database (dBASE) file:
1. Open the Access database from which you want to export an object. 2. Select the table or query you want to export in the Navigation pane. In the Export group on the External Data tab, click Excel, or click More and then click dBase File. Access opens the Export – Excel Spreadsheet or Export – dBase File dialog box. Click Browse, and select the file type, folder, and name of the file to which you want to export the selected object. After you make these selections, click Save. You can also enter the path and file name directly in the File Name box. For all file types, you can also select the File Format from a drop-down list. For Excel 2010, you can ask to have the data exported with formatting and layout, open the destination file after exporting the data, or export only selected records. To export selected records, you must have the table or query datasheet open with the records that you want to export selected.
3. Click OK to perform the export. If the export procedure succeeds, you’ll find a new file that you can use with your spreadsheet application or with another database program.
Note When you export a table or query to a spreadsheet, Access uses each field’s caption as the column header. If the field does not have a caption, the field name appears in the column header.
Exporting to a Text File 1825
Be Careful When Exporting Long Field Names to dBASE
Access truncates long field names when it exports data to dBASE files. If this results in a duplicate field name, Access will not export your data. To correct this problem, make a temporary copy of your table, edit the field names in the temporary table to avoid duplicates, and try the export procedure again using the temporary table. You should avoid changing the field names in your permanent table because you might cause errors in queries, forms, and reports that use the table.
Exporting to a Text File You can export data from an Access table, a select query, or a crosstab query to a text file in one of two formats: delimited or fixed-width. You might find this procedure particularly useful for copying data from an Access table to a text editor or for uploading the data to a host computer. To export the data from an Access table, a select query, or a crosstab query to a text file, do the following:
1. Open the Access database from which you want to export the data in a table. 2. Choose the table or query you want to export in the Navigation pane, and then click the Text File command in the Export group on the External Data tab. Access opens the Export – Text File dialog box. Click Browse, select the folder, and enter the name of the file to which you want to export the data. After you make these selections, click Save. You can also enter the path and file name directly in the File Name box.
3. In the Export – Text File dialog box, you can ask to have the data exported with formatting and layout, open the destination file after exporting the data, or export only selected records. To export selected records, you must have the table or query datasheet open with the records that you want to export selected. If you select the Export Data With Formatting And Layout check box and then click OK, Access opens the Encode As dialog box, where you can choose from Windows (Default), MS-DOS, Unicode, or Unicode (UTF-8) formats. Click OK in this dialog box to perform the export.
Article 3
INSIDE OUT
1826 Article 3 Exporting Data
Article 3
If you do not select the Export Data With Formatting And Layout check box and click OK, Access starts the Export Text Wizard, in which you can select Delimited or Fixed Width and then click Next.
4. If you’re exporting to a delimited text file, you can set the delimiter to separate the exported fields and the qualifier character to surround text strings. You can also tell the wizard to create an optional first record containing your field names. If you’re exporting to a fixed-width format, you can adjust the column widths using a graphical interface in the wizard. You can also click the Advanced button in the wizard to edit or select an import/export specification. On the final page of the wizard, you verify the export file name and click Finish to export your data. If the export procedure is successful, you’ll find a new file in the text format you selected.
Exporting to a Mail Merge Document in Word Perhaps one of the most useful features of Access 2010 is that it enables you to embed data from an Access table or query directly in a Word 2010 document. This is especially helpful when you have a database of addresses that you want to use with the Word mail merge feature. To embed data from an Access database in a Word document, do the following:
1. Open your database, and select the table or query in the Navigation pane whose data you want to embed in a Word document.
2. On the External Data tab, in the Export group, click the Word Merge command. This starts the Microsoft Word Mail Merge Wizard.
3. Select the option to link to an existing Word document or the option to create and link to a new document. If you choose to embed the data in an existing document, the wizard displays the Select Microsoft Word Document dialog box, which asks you to specify the document location. When you finish, click OK.
4. The wizard starts Word and activates a mail merge link back to your table or query. If you chose to create and link a new document, you can use the Mail Merge pane in Word to finish creating that document.
Exporting to an ODBC Database 1827
You can export data from an Access table or query to define a new table in any database that supports the ODBC standard. To export data in an Access table or query to another database system that supports ODBC SQL, you must have the ODBC driver for that database installed on your computer. Your computer must also be linked to the network that connects to the server running Microsoft SQL server you want, and you must have an account on that server. Check with your system administrator for information about correctly connecting to the ODBC database to which you want to export data. For details about defining an ODBC data source, see “Creating a Data Source to Link to an ODBC Database”, on page 448.
To export data to an ODBC database, do the following:
1. Open the Access database from which you want to export your data. 2. Select the table or query that you want to export. Click More in the Export group on the External Data tab, and then click ODBC Database.
3. Access asks for a name for the new table on the server. Type the name you want, and click OK.
4. Access opens the Select Data Source dialog box, in which you can select the data source name of the database server that will receive your data. Select the server alias name, and click OK.
5. If the server does not use Windows authentication, the ODBC driver displays the server login dialog box for the data source you selected. Enter your login ID and password, and click OK. If you are authorized to create tables in more than one database on the server and you want to connect to a database other than your default database, enter your user ID and password, and then click Options to open the lower part of the dialog box. When you click in the Database text box, Access logs on to the server and returns a list of available database names. Select the one you want, and click OK. If you don’t specify a database name, and if multiple databases exist on the server, Access will prompt you to select the database you want. When the server uses Windows authentication, choose Use Trusted Connection in the SQL Server Login dialog box, and Access will use your Windows user ID to log you on to the server. With a trusted connection, you connect to the database specified in the data source name, and you won’t be able to connect to a different database on the server.
Article 3
Exporting to an ODBC Database
1828 Article 3 Exporting Data
Exporting Data to SharePoint Article 3
You can export data from an Access table to a Microsoft SharePoint list if you have appropriate permissions to the SharePoint site. Contact your SharePoint administrator to give you permissions if you are having trouble accessing the SharePoint site. To export the data from an Access table, do the following:
1. Open the Access database from which you want to export the data in a table. 2. Choose the table you want to export in the Navigation pane, click the More button in the Export group on the External Data tab and then click SharePoint List. Access opens the Export – SharePoint Site dialog box. Under Specify A SharePoint Site, enter a valid address to a SharePoint Services site or subdirectory. Any SharePoint Services sites that you have previously imported from, linked to, or exported to are displayed in a list box. If one of these sites is the location to which you want to export the table, you can click that address, and Access fills in the address text box below the list with that link. Enter a valid SharePoint Services address in the text box below the list, or select a previously visited SharePoint Services address from the list box.
3. Under Specify A Name For The New List, give this new list a name. Keep in mind that the name you use is exactly how it appears to users on the SharePoint Services site. If you name it tblContacts, for instance, that is the name displayed to users. Also, if you use the same name as an existing list, SharePoint appends a number to the end of the list to avoid duplication. For example, if you want to name your new list Contacts and a Contacts list is already present on the site, the new list is named Contacts1.
4. Under Description, you can enter some information to describe the use of this list if you want. This description is shown on the SharePoint site next to the name of the list. Select the Open The List When Finished check box if you want Access to immediately display the new list in your browser after the export is complete. The wizard also displays a message noting that any tables related to this one will also be exported to the SharePoint site. Click OK to start the export process. If you are not signed in to your SharePoint site, you might be prompted to enter your logon information before continuing. During the export process, Access displays a message screen with progress indicators.
Exporting Data to SharePoint 1829
5. When the export is complete, Access displays a confirmation message on the last page of the wizard. This page also offers you the option to save the export steps you just performed if you plan to repeat these steps on a regular basis. You can execute saved exports by clicking the Saved Exports button in the Export group on the External Data tab on the ribbon. If the export process encounters any problems, Access displays a message on this page informing you of the errors and creates a local table of those it encounters. Click Close to close the wizard.
To successfully export an Access table to a SharePoint site, your table schema must be compatible with SharePoint column and list structures. If you are continually encountering errors exporting your table to SharePoint, we recommend running the Web Compatibility Checker tool on the table to help identify potential issues that you need to correct. You can learn about the Web Compatibility Checker in Chapter 6, “Designing Web Tables.”
Article 3
c hapte A rticl er4n o
Chapter Title Function Reference
I
n Microsoft Access 2010, finding all the most useful functions in Help can be difficult at best. Following is a list of functions, categorized by type, that you might need to use. The tables list the function name and a brief description of what the function does. You can easily find details about the particular function syntax in Help if you know the function name. Table A4-1 Arithmetic Functions
Name
Description
Abs
Returns the absolute value of a number.
Asc
Returns the integer value of a character.
Atn
Returns the arctangent of a number.
Cos
Returns the cosine of a number that is an angle specified in radians.
DDB
Returns a Double containing the depreciation of a value for a specific time period.
Exp
Returns the value of the base of the natural logarithm (e) raised to the exponent you supply. See also Log.
Fix
Returns the value of the number you supply truncated to an integer. If the number is negative, Fix returns the first integer that is greater than or equal to the number. See also Int.
FV
Calculates the future value of an annuity.
Int
Returns the value of the number you supply truncated to an integer. If the number is negative, Int returns the first integer that is less than or equal to the number. See also Fix.
IPmt
Returns the interest payment for a given period of an annuity.
IRR
Returns the internal rate of return for a series of periodic cash flows.
LBound Returns the lowest available subscript for the array and dimension you specify. See also UBound.
Log
Returns the natural logarithm of the number you supply. See also Exp.
MIRR
Returns the Modified Internal Rate of Return for a series of periodic cash flows.
NPER
Returns the number of payment periods for an annuity.
NPV
Returns the net present value of an investment.
PMT
Returns the payment required for an annuity.
1831
1832 Article 4 Function Reference
Article 4
Name
Description
PPMT
Returns the amount applied to the principal for a given payment period of an annuity.
PV
Returns the present value of an annuity.
RATE
Returns the interest rate of an annuity.
Rnd
Returns a random number.
Round
Rounds a number to the specified number of decimal places.
Sin
Returns the sine of a number that is an angle specified in radians.
SLN
Returns the straight-line depreciation of an asset for a single period.
Sqr
Returns the square root of a number.
SYD
Returns the sum of the years’ digits depreciation of an asset.
Tan
Returns the tangent of a number that is an angle specified in radians.
UBound Returns the highest available subscript for the array and dimension you specify. See also LBound. Table A4-2 Conversion Functions
Name
Description
Array
Converts a list of values into a Variant data type array.
Asc
Converts a character to the equivalent integer code.
CBool
Evaluates an expression and returns True (–1) or False (0).
CByte
Converts a value to a Byte data type.
CCur
Converts a value to a Currency data type.
CDate
Converts a value to a Date/Time data type.
CDbl
Converts a value to a Double data type.
CDec
Converts a numeric value to a Decimal data type.
Chr
Converts an integer representing a character code to a string containing that character.
CInt
Converts a value to an Integer data type. The function rounds fractions.
CLng
Converts a value to a Long Integer data type. The function rounds fractions.
CSng
Converts a value to a Single data type.
CStr
Converts a value to a String data type. A Null value generates an error. Boolean values convert to “yes” or “no.” A date converts to a string in your system’s short date format.
CVar
Converts a value to a Variant data type. If the value is a number, the value must be in the ranges valid for CDbl.
Format
Converts a number, string, or date/time value to a string formatted according to the format expression supplied.
Name
Description
Hex
Converts a number to a string representation of the hexadecimal value of the number.
Nz
Returns zero, a zero-length string (“”), or another specified value when a Variant is Null.
Oct
Converts a number to a string representation of the octal value of the number.
Str
Converts a number to a string.
Val
Converts the numbers found in a string to a valid numeric data type.
Table A4-3 Date/Time Functions
Name
Description
Date
Returns the current system date as a Variant.
DateAdd
Adds a specified interval to a date value.
DateDiff
Finds the difference between two date/time values in the interval you specify.
DatePart
Returns a requested portion of a date/time value (second, minute, hour, week, weekday, day, day of year, month, quarter, or year).
DateSerial
Returns a date value calculated from supplied integer year, month, and day values. The year value must be from 100 to 9999.
DateValue
Returns the date portion of a date/time value.
Day
Returns the day portion of a date/time value. See also DatePart.
Hour
Returns the hour portion of a date/time value. See also DatePart.
Minute
Returns the minute portion of a date/time value. See also DatePart.
Month
Returns the numeric month portion of a date/time value. See also DatePart.
MonthName
Returns the name of the month of a date/time value.
Now
Returns the current system date and time as a Variant.
Second
Returns the seconds portion of a date/time value. See also DatePart.
Time
Returns the current system time as a Variant.
Timer
Returns a Double containing the number of seconds elapsed since midnight, accurate to .01 seconds.
TimeSerial
Returns a time value calculated from supplied integer hour, minute, and second values.
TimeValue
Returns the time portion of a date/time value.
WeekDay
Returns the integer day of the week from a date/time value. Sunday is 1, Monday is 2, and so on.
WeekDayName Returns the name of the day from a date/time value. Year
Returns the year portion of a date/time value. See also DatePart.
Article 4
1833
1834 Article 4 Function Reference
Table A4-4 Logic Functions
Article 4
Name
Description
Choose
Returns a value from a list based on an integer index in the first argument.
IIF
Evaluates the first argument for True/False. If True, the function evaluates the second argument; otherwise, the function evaluates the third argument.
IsArray
Returns True if the argument you supply is an array.
IsDate
Returns True if the argument you supply can be converted to a date.
IsEmpty
Returns True if the Variant argument you supply has never been initialized.
IsError
Returns True if the number you supply is a valid error value.
IsMissing
Returns True if an optional argument to your Sub or Function procedure has not been supplied.
IsNull
Returns True if the argument you supply is the Null value. Note that you cannot compare a variable to the constant Null (If A = Null Then…).
IsNumeric
Returns True if the argument you supply can be evaluated as a number.
IsObject
Returns True if the argument you supply is an object variable.
Sgn
Returns an indication whether the number you supply is negative, positive, or zero.
StrComp
Compares two strings. If you want, you can specify a comparison that is binary or case-sensitive. (Default string comparison in Access is not case-sensitive.)
Switch
Accepts a series of pairs of expressions (primary and secondary). The primary expression of each pair must be an expression that can be evaluated to True or False. Evaluates the expressions left to right and returns the secondary expression for the first primary expression that evaluates True.
TypeName Returns the data type of the variable or expression you supply as a spelledout name of the data type. See also VarType. Updated
Returns a Boolean value indicating whether the specified field is dirty for the current record.
VarType
Returns an integer code indicating the data type of the variable or expression you supply. See also TypeName.
Table A4-5 String Functions
Name
Description
Chr
Returns the character value of an integer character code.
Filter
Returns an array of values from an input array that contains or excludes a specified search string.
First
Returns a field value from the first record in the result set returned by a query.
Name
Description
Format
Returns a string containing the value you supply, formatted according to the format string you specify.
FormatCurrency Formats the number you supply as a currency string. FormatDateTime Formats the date/time value you supply as a date and/or time string. FormatNumber
Formats the number you supply as a string with the specified decimal places and negative indicator characters. See also Str.
FormatPercent
Multiplies the number you supply by 100 and returns a string with a trailing percent (%) sign.
Hex
Returns a string containing the hexadecimal (base 16) value of the number you supply.
InStr
Returns the integer offset position of a search string within another string, searching the target string from the beginning.
InStrRev
Returns the integer offset position of a search string within another string, searching the target string from the end.
Join
Concatenates the one-dimensional array you supply into a single string separated by the delimiter you specify. See also Split.
LCase
Converts a string to all lowercase characters. See also UCase and StrConv.
Last
Returns a field value from the last record in the result set returned by a query.
Left
Returns the requested number of leftmost characters from a string.
Len
Returns the current length of a string.
LTrim
Returns a string with any leading blanks removed from the string you specify.
Mid
Returns the specified number of characters starting from a specified position in the middle of a string.
Oct
Returns a string containing the octal (base 8) value of the number you supply.
Partition
Returns a string range name for a numeric variable based on the range start, stop, and interval values you supply.
Replace
Examines a string you supply and returns a string with all occurrences of one string replaced by another string.
Right
Returns the requested number of rightmost characters from a string.
RTrim
Returns a string with any trailing blanks removed from the string you specify.
Space
Returns a string containing the specified number of spaces.
Split
Returns a zero-based one-dimensional array. It fills the array with the substrings that it finds by parsing a string you supply with a delimiter you specify. See also Join.
Article 4
1835
1836 Article 4 Function Reference
Article 4
Name
Description
Str
Converts a number to a string. See also FormatNumber and Format.
StrConv
Converts a string according to the method you specify. Options include all uppercase, all lowercase, and proper case. See also LCase and UCase.
StrReverse
Returns a string in which the order of characters in the string you supply is reversed.
String
Returns a string of the length you specify, filled with the character you supply.
Trim
Returns a string with any leading and trailing blanks removed from the string you specify.
UCase
Converts a string to all uppercase characters. See also LCase and StrConv.
Table A4-6 User Interface/System/File System Functions
Name
Description
Command
Returns the string of characters following the /cmd switch in the command or shortcut you used to start your application.
CurDir
Returns the current path or the current path on the specified drive.
Dir
Returns a file name based on a supplied path and search criteria. After calling Dir once with a path argument and criteria, you can call Dir without arguments to fetch additional files in the path that also meet the criteria. Dir returns a zero-length string when no more files meet the criteria.
DoEvents
Pauses the currently executing code so that Access or the operating system can process other events.
Environ
Returns an operating system environment variable, either by name or by relative number.
EOF
Return a Boolean value indicating whether the specified file opened for random or sequential input has reached the end of a file.
Error
Returns the text of the message associated with the specified error number.
FileAttr
Returns a long integer indicating the file mode for the specified file number.
FileDateTime
Returns the create date or the last modification date of the file path you specify.
FileLen
Returns the size of the file path you specify.
FreeFile
Returns an integer value of the next file number available to use in an Open statement.
GetAllSettings Returns a two-dimensional array from the registry of the keywords and settings for the specified application and section name. GetAttr
Returns the attributes of the file or path you specify.
Name
Description
GetSetting
Returns the registry value for a specific application and key name.
Input
Fetches the next character from a file opened in input or binary mode.
InputBox
Prompts the user with a message you supply and returns the user response.
Loc
Returns a long integer indicating the current position within the specified open file.
LOF
Returns a long integer indicating the size in bytes of the specified open file.
MsgBox
Displays a message you supply in a dialog box and returns an indication of which button the user clicked in response.
QBColor
Returns the red, green, and blue (RGB) color value as a long integer for one of the 16 original Quick Basic color numbers. The numbers are 0 through 15 and, in order, are black, blue, green, cyan, red, magenta, yellow, white, gray, light blue, light green, light cyan, light red, light magenta, light yellow, and bright white.
RGB
Returns the RGB value based on red, green, and blue values you supply.
Seek
Returns the current read/write position for the specified file as a long integer.
Shell
Executes the program you specify.
Table A4-7 SQL Aggregate Functions
Name
Description
Avg
Calculates the arithmetic mean of a set of values contained in a specified field on a query.
Count
Calculates the number of records returned by a query.
Max
Returns the maximum of a set of values contained in a specified field on a query.
Min
Returns the minimum of a set of values contained in a specified field on a query.
StDev
Returns estimates of the standard deviation for a population sample represented as a set of values contained in a specified field on a query.
StDevP
Returns estimates of the standard deviation for a population represented as a set of values contained in a specified field on a query.
Sum
Returns the sum of a set of values contained in a specified field on a query.
Var
Returns estimates of the variance for a population sample represented as a set of values contained in a specified field on a query.
VarP
Returns estimates of the variance for a population represented as a set of values contained in a specified field on a query.
Article 4
1837
1838 Article 4 Function Reference
Table A4-8 Access Services Functions
Article 4
Name
Description
CurrentWebUser
In published web applications, returns a String representing the user currently logged in. Returns Null in client-only applications.
CurrentWebUserGroups
In published web applications, returns a String listing the groups to which the currently-logged-in user belongs. Returns Null in client-only applications.
IsClient
Expression that returns true when evaluated on the client and false when evaluated on the server.
IsCurrentWebUser- In published web applications, returns a Boolean value indicating InGroup whether the user currently logged in is a part of the specified group. Returns false in client-only applications. The following table is a list of web-compatible functions and in what context they can be used. You can refer to the previous tables for any function descriptions. Table A4-9 Web-Compatible Functions
Name
Usage Context
Abs
Data macros, queries, reports
Asc
Data macros, queries, reports
Atn
Data macros, queries, reports
Avg
Forms, reports
CDbl
Data macros, forms, queries, reports, user interface macros
Choose
Data macros, queries, reports
Cos
Data macros, queries, reports
Count
Forms, reports
CurrentWebUser
Forms, queries, user interface macros
CurrentWebUserGroups Forms, queries, user interface macros Date
Data macros, forms, queries, reports, user interface macros
DateSerial
Data macros, forms, queries, reports, user interface macros
Day
Data macros, queries, reports
DDB
Data macros, queries, reports
Exp
Data macros, queries, reports
Last
Reports
Fix
Data macros, queries, reports
FormatCurrency
Data macros, forms, queries, reports, user interface macros
FormatDateTime
Data macros, forms, queries, reports, user interface macros
Name
Usage Context
FormatNumber
Data macros, forms, queries, reports, user interface macros
FormatPercent
Data macros, forms, queries, reports, user interface macros
FV
Data macros, queries, reports
Hour
Data macros, queries, reports
IIF
Data macros, forms, queries, reports, user interface macros
InStr
Data macros, forms, queries, reports, user interface macros
Int
Data macros, queries, reports
IPmt
Data macros, queries, reports
IsClient
Forms, user interface macros
IsCurrentWebUserInGroup
Forms, queries, user interface macros
IsEmpty
Data macros, queries, reports
IsNull
Data macros, forms, queries, reports, user interface macros
Last
Reports
LCase or LCase$
Data macros, forms, queries, reports, user interface macros
Left or Left$
Data macros, forms, queries, reports, user interface macros
Len
Data macros, forms, queries, reports, user interface macros
Log
Data macros, queries, reports
Max
Reports
Mid or Mid$
Data macros, forms, queries, reports, user interface macros
Min
Reports
Minute
Data macros, queries, reports
Month
Data macros, queries, reports
MonthName
Data macros, queries, reports
Now
Data macros, forms, queries, reports, user interface macros
NPER
Data macros, queries, reports
Nz
Data macros, forms, queries, reports, user interface macros
PMT
Data macros, queries, reports
PPMT
Data macros, queries, reports
PV
Data macros, queries, reports
RATE
Data macros, queries, reports
Right or Right$
Data macros, forms, queries, reports, user interface macros
Round
Data macros, forms, queries, reports, user interface macros
Second
Data macros, queries, reports
Article 4
1839
1840 Article 4 Function Reference
Article 4
Name
Usage Context
Sgn
Data macros, queries, reports
Sin
Data macros, queries, reports
SLN
Data macros, queries, reports
Space or Space$
Data macros, queries
Sqr
Data macros, queries, reports
StDev
Reports
StDevP
Reports
Str or Str$
Data macros, queries, reports
String or String$
Data macros, queries, reports
Sum
Forms, reports
SYD
Data macros, queries, reports
Tan
Data macros, queries, reports
Time
Data macros, queries, reports
TimeSerial
Data macros, queries, reports
Trim or Trim$
Data macros, queries, reports
UCase or UCase$
Data macros, forms, queries, reports, user interface macros
Updated
Data macros
Var
Reports
VarP
Reports
WeekDay
Data macros, queries, reports
WeekDayName
Data macros, queries, reports
Year
Data macros, queries, reports
c hapte A rticl er5n o
Chapter Color Names Title and Codes
W
hen you’re setting color properties in a form or report in Design or Layout view of Microsoft Access 2010, you normally enter a hexadecimal value that represents the red, green, and blue (RGB) color value. You can also generate these values by clicking the Build (…) button next to any color property. When working with controls, you can select colors from the same palette using the Font Color or Fill/Back Color commands on the Format contextual tab in the Font group on the ribbon. When you rest your mouse pointer on one of the color selections, Access 2010 shows you a color name, but you cannot type the name directly into a color property. The following table lists the color names found in Standard Colors in the first column, the color names recognized by Windows Internet Explorer and most other browsers in the second column, and the equivalent hexadecimal color code in the third column.
Access Color Name
Internet Explorer Color Name
Hexadecimal Code
aliceblue
#F0F8FF
antiquewhite
#FAEBD7
aqua
#00FFFF
Aqua Blue
#4BACC6
Aqua Blue 1
#EDF7F9
Aqua Blue 2
#D1EAF0
Aqua Blue 3
#A4D5E2
Aqua Blue 4
#77C0D4
Aqua Blue 5
Black
#3B8194 aquamarine
#7FFFD4
azure
#F0FFFF
beige
#F5F5DC
bisque
#FFE4C4
black
#000000
blanchedalmond
#FFEBCD
Blue
#0072BC blue
#0000FF
1841
1842 Article 5 Color Names and Codes
Access Color Name Article 5
Internet Explorer Color Name
Hexadecimal Code
blueviolet
#8A2BE2
Brown
#F59D56 brown
#A52A2A
Brown 1
#FEFBF8
Brown 2
#FCE6D4
Brown 3
#F9CDAA
Brown 4
#F7B580
Brown 5
#7A4E2B burlywood
#DEB887
cadetblue
#5F9EA0
chartreuse
#7FFF00
chocolate
#D2691E
coral
#FF7F50
cornflower
#6495ED
cornsilk
#FFF8DC
crimson
#DC143C
cyan
#00FFFF
Dark Blue
#1F497D
Dark Blue (second choice)
#2F3699 darkblue
#00008B
Dark Blue 1
#DFE5ED
Dark Blue 2
#C6D1DE
Dark Blue 3
#8EA3BD
Dark Blue 4
#56769D
Dark Blue 5
#17365D darkcyan
#008B8B
darkgoldenrod
#B8860B
darkgray
#A9A9A9
Dark Gray 1
#929292
Dark Gray 2
#7F7F7F
Dark Gray 3
#727272
Dark Gray 4
#595959
1843
Internet Explorer Color Name
Dark Gray 5
Hexadecimal Code #3F3F3F
darkgreen
#006400
darkkhaki
#BDB76B
darkmagenta
#8B008B
darkolivegreen
#556B2F
darkorange
#FF8C00
darkorchid
#9932CC
Dark Red
#BA1419 darkred
#8B0000
darksalmon
#E9967A
darkseagreen
#8FBC8B
darkslateblue
#483D8B
darkslategray
#2F4F4F
darkturquoise
#00CED1
darkviolet
#9400D3
deeppink
#FF1493
deepskyblue
#00BFFF
dimgray
#696969
dodgerblue
#1E90FF
firebrick
#B22222
floralwhite
#FFFAF0
forestgreen
#228B22
fuchsia
#FF00FF
gainsboro
#DCDCDC
ghostwhite
#F8F8FF
gold
#FFD700
goldenrod
#DAA520
gray
#808080
Green
#22B14C
Green (second choice)
#9DBB61 green
#008000
Green 1
#F7F9F1
Green 2
#E6EDD7
Article 5
Access Color Name
1844 Article 5 Color Names and Codes
Access Color Name
Internet Explorer Color Name
Hexadecimal Code
Article 5
Green 3
#CDDCAF
Green 4
#B5CB88
Green 5
#758C48 greenyellow
#ADFF2F
honeydew
#F0FFF0
hotpink
#FF69B4
indianred
#CD5C5C
indigo
#4B0082
ivory
#FFFFF0
khaki
#F0E68C
lavender
#E6E6FA
lavenderblush
#FFF0F5
lawngreen
#7CFC00
lemonchiffon
#FFFACD
Light Blue
#5C83B4
Light Blue (second choice)
#00B7EF lightblue
#ADD8E6
Light Blue 1
#EFF2F7
Light Blue 2
#D6DFEC
Light Blue 3
#ADC0D9
Light Blue 4
#84A1C6
Light Blue 5
#456287 lightcoral
#F08080
lightcyan
#E0FFFF
lightgoldenrodyellow
#FAFAD2
Light Green
#A7DA4E lightgreen
#90EE90
lightgray
#D3D3D3
Light Gray 1
#ECECEC
Light Gray 2
#D8D8D8
Light Gray 3
#BFBFBF
Light Gray 4
#A5A5A5
1845
Internet Explorer Color Name
Light Gray 5
Hexadecimal Code #8C8C8C
lightpink
#FFB6C1
lightsalmon
#FFA07A
lightseagreen
#20B2AA
lightskyblue
#87CEFA
lightslategray
#778899
lightsteelblue
#B0C4DE
lightyellow
#FFFFE0
lime
#00FF00
limegreen
#32CD32
linen
#FAF0E6
magenta
#FF00FF
Maroon
#C0504D maroon
#800000
Maroon 1
#F9EDED
Maroon 2
#EFD3D2
Maroon 3
#DFA7A5
Maroon 4
#CF7B79
Maroon 5
#903C39 mediumaquamarine
#66CDAA
mediumblue
#0000CD
Medium Gray
#FAF3E8
Medium Gray 1
#CCC8C2
Medium Gray 2
#BBB6AE
Medium Gray 3
#A29D96
Medium Gray 4
#7D7974
Medium Gray 5
#575551 mediumorchid
#BA55D3
mediumpurple
#9370DB
mediumseagreen
#3CB371
mediumslateblue
#7B68EE
mediumspringgreen
#00FA9A
mediumturquoise
#48D1CC
Article 5
Access Color Name
1846 Article 5 Color Names and Codes
Access Color Name Article 5
Internet Explorer Color Name
Hexadecimal Code
mediumvioletred
#C71585
midnightblue
#191970
mintcream
#F5FFFA
mistyrose
#FFE4E1
moccasin
#FFE4B5
navajowhite
#FFDEAD
navy
#000080
oldlace
#FDF5E6
olive
#808000
olivedrab
#6B8E23
Orange
#FFC20E orange
#FFA500
orangered
#FF4500
orchid
#DA70D6
palegoldenrod
#EEE8AA
palegreen
#98FB98
paleturquoise
#AFEEEE
palevioletred
#DB7093
papayawhip
#FFEFD5
peachpuff
#FFDAB9
peru
#CD853F
pink
#FFC0CB
plum
#DDA0DD
powderblue
#B0E0E6
Purple
#8066A0
Purple (second choice)
#6F3198 purple
#800080
Purple 1
#F3F0F6
Purple 2
#DFDBE7
Purple 3
#BFB2CF
Purple 4
#9F8CB7
Purple 5
#604C78
Red
#ED1C24
Access Color Name
White
Internet Explorer Color Name
Hexadecimal Code
red
#FF0000
rosybrown
#BC8F8F
royalblue
#4169E1
saddlebrown
#8B4513
salmon
#FA8072
sandybrown
#F4A460
seagreen
#2E8B57
seashell
#FFF5EE
sienna
#A0522D
silver
#C0C0C0
skyblue
#87CEEB
slateblue
#6A5ACD
slategray
#708090
snow
#FFFAFA
springgreen
#00FF7F
steelblue
#4682B4
tan
#D2B48C
teal
#008080
thistle
#D8BFD8
tomato
#FF6347
turquoise
#40E0D0
violet
#EE82EE
wheat
#F5DEB3
white
#FFFFFF
whitesmoke
#F5F5F5
Yellow
#FFF200 yellow
#FFFF00
yellowgreen
#9ACD32
Article 5
1847
c hapte A rticl er6n o
ChapterActions Macro Title
T
his article provides a summary of all the macro actions available in Microsoft Access 2010. The macros are organized in the following functional categories, as listed in the macro action catalog in Access 2010:
●●
ADP Objects
●●
Data Entry Operations
●●
Data Import/Export
●●
Database Objects
●●
Filter/Query/Search
●●
Macro Commands
●●
System Commands
●●
User Interface Macros
●●
Windows Management
Note that you won’t see the ADP Objects category displayed in the Action Catalog unless you are working with an Access Data Project (.adp). The Trusted column indicates whether the macro action is a trusted action that can run even when the database is not trusted. (A macro action that is trusted has a lightning icon next to its name in the Action Catalog.) When an action is not trusted, Access won’t run the action unless it is in a trusted database. (A macro action that is not trusted has an exclamation point next to its name in the Action Catalog.)
1849
1850 Article 6 Macro Actions
Table A6-1 ADP Objects
Article 6
Macro Action
Purpose
Trusted
CopyDatabaseFile
No In an Access project file (.adp) connected to a Microsoft SQL Server database, copies the currently connected database to a new file. The user must have system administrator privileges on the server to perform this action. You cannot execute this action in an Access desktop database (.accdb).
OpenDiagram
In an Access project file (.adp) connected to an No SQL Server database, opens a table relationship diagram in the server database in Design view. You cannot execute this action in an Access desktop database (.accdb).
OpenFunction
No In an Access project file (.adp) connected to an SQL Server database, opens a function in the server database in Datasheet, Design, PivotTable, or PivotChart view or in Print Preview. If the function is a data definition command or the equivalent of an Access action query, executes the function without returning data. If the function returns data that is editable, you can specify whether the function datasheet should be opened to add new records only; to add, edit, and delete records; or to provide a read-only view of the data. In Microsoft Visual Basic, you can also use the Open or Execute method to open the function and return any results to a recordset. You must use the OpenFunction macro action within a Visual Basic procedure if you want the function to open in the user interface. You cannot execute this action in an Access desktop database (.accdb).
OpenStoredProcedure
No In an Access project file (.adp) connected to an SQL Server database, opens a stored procedure in the server database in Datasheet, Design, PivotTable, or PivotChart view or in Print Preview. If the stored procedure returns data that is editable, you can specify whether the stored procedure datasheet should be opened to add new records only; to add, edit, and delete records; or to provide a read-only view of the data. In Visual Basic, you can also use the Open or Execute method to open the stored procedure and return any results to a recordset. You cannot execute this action in an Access desktop database (.accdb).
1851
Purpose
Trusted
OpenView
No In an Access project file (.adp) connected to an SQL Server database, opens a view in the server database in Datasheet, Design, PivotTable, or PivotChart view or in Print Preview. If the view returns data that is editable, you can specify whether the view datasheet should be opened to add new records only; to add, edit, and delete records; or to provide a read-only view of the data. In Visual Basic, you can also use the Open or Execute method to open the view and return the results to a recordset. You cannot execute this action in an Access desktop database (.accdb).
TransferSQLDatabase
No In an Access project file (.adp) connected to an SQL Server database, transfers the currently connected database to another server and database name. If you want, you can transfer only the table structure. The user must have system administrator privileges on the target server to perform this action. You cannot execute this action in an Access desktop database (.accdb).
Table A6-2 Data Entry Operations
Macro Action
Purpose
Trusted
DeleteRecord
Deletes the current record from the source table.
Yes
EditListItems
Yes Opens the Edit List Items dialog box, where you can add, edit, or delete items in a combo box or list box control. The Row Source Type must be Value List, and you’ll need to set the focus to the control if the control does not already have focus. You can set the focus to the combo box or list box control by using the GoToControl macro action.
SaveRecord
Saves the current record changes.
Yes
Article 6
Macro Action
1852 Article 6 Macro Actions
Table A6-3 Data Import/Export
Article 6
Macro Action
Purpose
Trusted
AddContactFromOutlook
Adds a saved contact from your Microsoft Out- Yes look address book into your database. Running this macro action opens the Select Names To Add Outlook dialog box, where you can select the saved contact in your address book to add to your Access table. Note that you must have a table, query, or bound form open before running this action. To use the action, your table field properties must also be mapped to WSSFieldID property values. You need to use Visual Basic for Applications (VBA) code to set up these field mappings. If you use the Contacts Application Part, you can examine the field properties for the Contacts table using VBA code to see the WSSFieldID field mappings needed to use this action with a custom table.
CollectDataViaEmail
Yes Opens the Collect Data Through E-mail Messages wizard, where you can create a Hypertext Markup Language (HTML) message or InfoPath form to collect data for your database. Note that you must have a table, query, or form open before running this action.
EmailDatabaseObject
Yes Outputs a table, query, report, module, view, stored procedure, or function datasheet, or a form datasheet to an HTML (.htm, .html), a Microsoft Excel (.xls, .xlsb, .xlsx), a Rich Text Format (.rtf) a portable document format (.pdf), an XML Paper Specification format (.xps), or a text (.txt) file and embeds the data in an electronic mail message. You can output a module as plain text only. You can specify to whom the message is to be sent, the message subject, additional message text, and whether the message can be edited before it is sent. You must have email software installed that conforms to the Messaging Application Programming Interface (MAPI) standard.
1853
Purpose
Trusted
ExportWithFormatting
Yes Outputs the named table, query, form, report, module, view, stored procedure, or function to another file format. The formats include HTML (.htm, .html), Microsoft Excel (.xls, .xlsb, .xlsx), text files (.txt), Rich Text Format (.rtf), Portable Document Format (.pdf) or XML Paper Specification Format (.xps). Modules can be output only in text format. You can also optionally start the application to edit the file. For forms, the data output is from the form’s Datasheet view. For reports, Access outputs all controls containing data (including calculated controls) except ActiveX controls.
ImportExportData
No Exports data to or imports data from another Access, dBASE, Microsoft SharePoint list, or SQL database. You can also use this action to attach tables or files from other Access, dBASE, or SQL database, or from text or spreadsheet files. You can also import or export the definition of queries, views, stored procedures, functions, diagrams, forms, reports, macros, or modules to or from another Access desktop database (.accdb) or project file (.adp).
ImportExportSpreadsheet
Exports data to or links or imports data from Excel or Lotus 1-2-3 spreadsheet files.
No
ImportExportText
Exports data to or links or imports data from text files. You can also link or import tables embedded within HTML (.htm, .html) files.
No
ImportSharePointList
No Imports data or links data from a SharePoint Services site. If you want, you can also import all display values for lookup columns.
RunSavedImportExport
Runs a saved import or export specification you No previously saved using the Import Wizard or Export Wizard.
SaveAsOutlookContact
Yes Saves the current record as a new contact in your Outlook address book. Note that you must have a table, query, or bound form open before running this action. To use the action, your table field properties must also be mapped to WSSFieldID property values. You need to use VBA code to set up these field mappings. If you use the Contacts Application Part, you can examine the field properties for the Contacts table using VBA code to see the WSSFieldID field mappings needed to use this action with a custom table.
Article 6
Macro Action
1854 Article 6 Macro Actions
Article 6
Macro Action
Purpose
Trusted
WordMailMerge
Opens the Microsoft Word Mail Merge Wizard, Yes where you can select the option to link to an existing Word document or create and link to a new document. If you choose to embed the data in an existing document, the wizard displays the Select Microsoft Word Document dialog box, which asks you to specify the document location. Note that you must have a table, query, or form open before running this action.
Table A6-4 Database Objects
Macro Action
Purpose
Trusted
CopyObject
Copies any database object to the current database using a new name or copies any database object to another Access database using any specified name.
No
DeleteObject
Deletes any table, query, form, report, macro, module, No view, stored procedure, function, or diagram. If you do not specify an object, the action deletes the object currently selected in the Navigation pane. In Visual Basic, you should use the Delete method of the object collection to delete an object.
GoToControl
Sets the focus to the specified control. In Visual Basic, you should use the SetFocus method of the control to move the focus.
GoToPage
Moves to the specified page in a form. Yes In Visual Basic, you should use the GoToPage method of the form object.
GoToRecord
Yes Moves to a different record and makes it current in the specified table, query, or form. You can move to the first, last, next, previous, or new record. When you specify the next or the previous record, you can also specify a parameter to move by more than one record. You can also go to a specific record number or to the new-record placeholder at the end of the set. In Visual Basic, you can also use RunCommand RecordsGoToFirst, RecordsGoToLast, RecordsGoToNew, RecordsGoToNext, or RecordsGoToPrevious. A more efficient technique is to search in the form’s recordset and move the form to the desired record by setting the form’s Bookmark property.
Yes
1855
Purpose
Trusted
OpenForm
Dependent Opens a form in Form, Design, Datasheet, PivotTable, PivotChart, or Layout view or in Print Preview. You can on argument also apply a filter or a Where condition in Form, Datasheet, PivotTable, or PivotChart view or in Print Preview. Access ignores any filter or Where condition when you open the object in Design view. If the form is already open, the OpenForm action puts the focus on the form and applies any new Filter or Where Condition argument you specify. From a Visual Basic procedure, you normally execute the macro action to open a form. However, you can also open a form that has a module by setting a form object equal to a new instance of the form’s class module. See Chapter 24, “Understanding Visual Basic Fundamentals,” on the companion CD, for details. This action is not trusted when you set the View argument to Design or Layout.
OpenReport
Dependent Prints a report or opens a report in Report view (the default), Print Preview, Layout view, or Design view. For on argument printing, Report view, and Print Preview, you can also specify a filter or a Where condition. This action is not trusted when you set the View argument to Design or Layout.
OpenTable
Dependent Opens a table in Datasheet, Design, PivotTable, or on argument PivotChart view or in Print Preview. You can specify whether the table datasheet should be opened to add new records only; to add, edit, and delete records; or to provide a read-only view of the data. In Visual Basic, you can also use the OpenRecordset method to create a recordset from a table. This action is not trusted when you set the View argument to Design.
PrintObject
Prints the currently selected object.
Yes
PrintPreview
Opens the currently selected object in Print Preview.
Yes
RenameObject
Renames the specified object in the current database.
No
RepaintObject
Yes Forces the repainting of the window for the specified object. Forces recalculation of any formulas in controls on that object. If you do not specify an object type and name, repaints the active window. In Visual Basic, you should use the Repaint method of a form.
SaveObject
No Saves any table, query, form, report, macro, module, view, stored procedure, function, or diagram. If you do not specify an object type and object name, the definition of the currently active object is saved. If you provide only an object name, the active object is saved with the new name you specify (in a Save As operation).
Article 6
Macro Action
1856 Article 6 Macro Actions
Article 6
Macro Action
Purpose
Trusted
SelectObject
Yes Selects the specified object. Restores the object’s window if it was minimized. If the object is in the process of opening (for example, a form referenced in a previous OpenForm action), SelectObject forces the object to finish opening before performing the next action. Use this action after OpenForm or BrowseTo when you need to immediately reference the form, a property of a control on the form, or data in a control on the form. In Visual Basic, you should use the SetFocus method of the form to force it to finish opening or to move the focus to the form window.
SetProperty
Changes selected properties of a control on a form or Yes report or selected properties of a form or report. The properties that you can change with this action are Enabled, Visible, Locked, Left, Top, Width, Height, Fore Color, Back Color, Caption and Value. If you are using a web database, you cannot set the Left, Top, Width, or Height properties on web form controls. In Visual Basic, you should use a Let statement.
SetValue
Changes the value of any control or property that you No can update. For example, you can use the SetValue action to calculate a new total in an unbound control or to affect the Visible property of a control (which determines whether you can see that control). In Visual Basic, you should use a Let statement.
Table A6-5 Filter/Query/Search
Macro Action
Purpose
Trusted
ApplyFilter
Restricts the information displayed in a table, form, or report by applying a named filter, a query, or an SQL WHERE clause to the records in the table or to the records in the underlying table or query of the form or report. ApplyFilter always operates on the currently active window and does not work for subforms. In Visual Basic, you should set the Filter or OrderBy property of the form or report and set FilterOn or OrderByOn to True.
Yes
FindNextRecord
Finds the next record that meets the criteria previously set by a FindRecord macro action or in the Find And Replace dialog box. In Visual Basic, you should provide your own custom search form and perform the search by using the Find, FindFirst, or FindNext method of the form’s recordset.
Yes
1857
Purpose
Trusted
FindRecord
Yes Finds a record that meets the search criteria. You can specify in the macro action all the parameters available in the Find And Replace dialog box. In Visual Basic, you should provide your own custom search form and perform the search by using the Find, FindFirst, or FindNext method of the form’s recordset.
OpenQuery
In an Access desktop database (.accdb), opens a query Dependent in Datasheet, Design, PivotTable, or PivotChart view or on argument in Print Preview. If you specify an action query, Access performs the updates specified by the query. If the query returns data that is editable, you can specify whether the query datasheet should be opened to add new records only; to add, edit, and delete records; or to provide a read-only view of the data. In Visual Basic, you can use the OpenRecordset method to create a recordset from a query that returns records or use the Execute method to run an action query. You cannot execute this action in an Access project file (.adp). This action is not trusted when you set the View argument to Design.
Refresh
Refreshes the data in the active object (form, report, or Yes datasheet). In Visual Basic, you can use the Refresh method for the same functionality.
RefreshRecord
Refreshes the data in the current record only for the active object (form, report, or datasheet).
Yes
RemoveFilterSort
Removes any filter or sort applied to the active object (form, report, or datasheet).
Yes
Requery
Refreshes the data in a control that is bound to a query Yes (such as a list box, a combo box, a subform, or a control based on an aggregate function, such as DSum). When other actions (such as inserting or deleting a record in the underlying query) might affect the contents of a control that is bound to a query, use the Requery action to update the control values. Use Requery without an argument to refresh the data in the active object (form, report, or datasheet). In Visual Basic, you should use the Requery method of the object.
Article 6
Macro Action
1858 Article 6 Macro Actions
Article 6
Macro Action
Purpose
Trusted
RunSQL
Executes the specified action query statement (INSERT No INTO, DELETE, SELECT…INTO, UPDATE) or data definition query statement (CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX, DROP INDEX). (Note: You can’t enter more than 255 characters in the SQL Statement argument. If you need to run a more complex query, define a query object and use the OpenQuery action.) In Visual Basic, you should use the Execute method to run an action or data definition query contained in a string argument of any length. Also, the RunSQL command executed from Visual Basic accepts an SQL statement up to 32,767 characters.
SearchForRecord
Searches for a record using the search criteria you spec- Yes ify and makes it current in the specified table, query, or form. You can start your search from the previous, next, first, or last record. In Visual Basic, you should provide your own custom search form and perform the search by using the Find, FindFirst, or FindNext method of the form’s recordset.
SetFilter
Restricts the information displayed in a table, form, or report by applying a named filter, a query, or an SQL WHERE clause to the records in the table or to the records in the underlying table or query of the form or report. When you are working with web forms, you cannot use the ApplyFilter action, so you need to use the SetFilter action to apply a filter to a web form.
SetOrderBy
Yes Applies a sort to the records in a table, or the records from the form or report’s underlying table or query. When you are working in a web database, you can use the SetOrderBy action to sort the records displayed in a web form.
ShowAllRecords
Removes any filters previously applied to the active table, query, or form.
Yes
Yes
Table A6-6 Macro Commands
Macro Action
Purpose
Trusted
CancelEvent
Cancels the event that caused this macro to run. Yes You can’t use a CancelEvent action in a macro that defines menu commands or in response to an event that cannot be canceled. In Visual Basic, you should set the Cancel parameter of the event procedure to True to cancel the event.
1859
Purpose
Trusted
ClearMacroError
Clears any information stored in the MacroError Yes object, including the error number, error description, macro name, action name, condition, and any arguments. Access resets the error number to 0 after you run this action.
Echo
Controls the display of intermediate actions while No a macro runs. In Visual Basic, you should set the Echo property of the Application object to True or False.
OnError
Specifies how Access should handle an error when Yes running your macro. You can turn off error trapping, skip to the next action, or go to a specific macro in the same macro group to handle the error.
OpenVisualBasicModule
No Opens a module or procedure in Design view. If you specify a module name and no procedure name, Access opens the module to the Declarations section. You can also specify only a procedure name so long as the procedure is a public procedure in a standard module. In a Visual Basic procedure, you should open a module by setting a module object equal to the name of the module in the Modules collection. To open the module of a form or report, the form or report itself must be open.
RemoveAllTempVars
Clears from memory all temporary variables that Yes you create by using the SetTempVar action. Access automatically clears all temporary variables from memory when you close the database.
RemoveTempVar
Clears from memory a single temporary variable Yes that you create by using the SetTempVar action. Access automatically clears all temporary variables from memory when you close the database.
RunCode
Executes a Visual Basic function procedure. Other Yes actions following this action execute after the function completes. You cannot call a Visual Basic subprocedure from this action. (Note: If the function returns values, you cannot inspect them in the macro.) In Visual Basic, you should call the subprocedure or assign the function call to a return variable.
Article 6
Macro Action
1860 Article 6 Macro Actions
Article 6
Macro Action
Purpose
Trusted
RunDataMacro
Runs a named data macro attached to a table. If the named data macro has any parameters, Access displays text boxes on the macro design surface for each parameter value. Actions following this action run after the named data macro completes if you set the Wait For Post Processing form property to Yes.
Yes
RunMacro
Runs a macro. Actions following this RunMacro action run after the called macro completes. You can specify a number of times for the macro to execute or a condition that, when true, halts the macro execution. Caution: A macro can run itself, but you should provide conditional testing that exits the macro so that you don’t create an unending loop. In Visual Basic, use the Do and For statements to create iterative or conditional code loops. Although it is possible to execute RunMacro in a Visual Basic procedure, you should write the equivalent Visual Basic statements within your procedure instead.
Yes
RunMenuCommand
Executes an Access built-in command. The list of Dependent available commands includes all commands that on argument you can execute from any of the ribbons. If you use macros to define a custom menu, you can use a RunMenuCommand action to make selected Access menu commands available on your custom menu. Any command that modifies a design element (such as applying an AutoFormat) is not trusted.
SetLocalVar
Yes Creates a temporary local variable and lets you set it to a value that you can reference while the macro executes. The value of the variable stays in memory so long as the macro is running. Once the macro finishes, Access clears the local variable from memory. You’ll find this action useful when you need to perform calculations inside the macro actions, such as calculating a running sum.
SetTempVar
Yes Creates a temporary variable and lets you set it to a value that you can reference in other areas of your database. The value of the variable stays in memory as long as the database remains open or until you clear the variable using either the RemoveTempVar or RemoveAllTempVars action.
1861
Purpose
Trusted
SingleStep
Places the currently running macro in Single Step Yes mode and opens the Single Step dialog box. Click Continue to run the rest of the macro. If you single-step through an entire macro, Single Step mode will still be in effect when the next macro runs. When executed from Visual Basic, the next macro to execute will run in Single Step mode.
StartNewWorkflow
Yes Opens the Workflows dialog box, which lists all defined workflows for a linked SharePoint list. You can click the Start button next to a specific workflow to start it. If no workflows are defined for the linked SharePoint list, Access displays no information in the Workflows dialog box. Note that you can use this action only with linked SharePoint lists.
StopAllMacros
Stops all macros, including any macros that called Yes this macro. You cannot execute this action from Visual Basic.
StopMacro
Stops the current macro. You cannot execute this action from Visual Basic.
WorkflowTasks
Opens the Workflows Tasks dialog box, where you Yes can view a list of any workflow tasks associated with a linked SharePoint list. If no workflows are defined for the linked SharePoint list, Access displays no information in the Workflow Tasks dialog box. Note that you can use this action only with linked SharePoint lists.
Yes
Table A6-7 System Commands
Macro Action
Purpose
Trusted
Beep
Produces a sound.
Yes
CloseDatabase
Closes all Access windows and closes the database. If you have any unsaved objects open, Access prompts you to save them.
Yes
DisplayHourglassPointer
Changes the mouse pointer to an hourglass icon Yes while a macro runs. In Visual Basic, you can also set the MousePointer property of the Screen object.
OpenSharePointList
Browses to the selected linked SharePoint list in No the Navigation pane using your web browser. Note that you can use this action only if you have one or more linked SharePoint lists in your database.
Article 6
Macro Action
1862 Article 6 Macro Actions
Article 6
Macro Action
Purpose
Trusted
OpenSharePointRecycleBin
Browses to the Recycle Bin page on your Share- No Point site. Note that you can use this action only if you have one or more linked SharePoint lists in your database.
PrintOut
Prints the active datasheet, form, module, or report. You can specify a range of pages, the print quality, the number of copies, and collation. Use an Open action first if you want to apply a filter or a Where condition.
QuitAccess
Closes all Access windows and exits Access. You Depends can set options to save all changes (the default), on prompt the user to save, or exit without saving. argument In Visual Basic, you should use the Quit method of the Application object, which has the same options. If you specify Prompt, this macro is trusted. If you specify Save All or Exit, the macro is not trusted.
RunApplication
Starts another Windows-based or MS-DOS– based application. In Visual Basic, use the Shell function or ActiveX application automation to open and control another application.
No
SendKeys
Stores keystrokes in the keyboard buffer. If you intend to send keystrokes to a modal form or a dialog box, you must execute the SendKeys action before opening the modal form or the dialog box. In Visual Basic, you should use the SendKeys statement.
No
SetWarnings
No When enabled, causes an automatic Enter key response to all system warning or informational messages while a macro runs. For warning messages displayed in a dialog box, pressing Enter selects the default button (usually OK or Yes). Run this action when your code is about to execute action queries and you do not want the user to see the update warnings. Setting SetWarnings to No does not halt the display of error messages. Use the Echo macro action with the Echo On argument set to No to avoid displaying the error messages. In Visual Basic, you should set the SetWarnings property of the Application object to True or False.
No
1863
Avoid SendKeys If Possible
Although you can set an optional parameter to wait until Windows processes the keystrokes, you have only limited control over where Windows actually delivers the keys. For example, if the user clicks another window at the moment you issue the SendKeys action, Windows delivers the keystrokes to that window. If you want to deliver the keystrokes to a dialog box, you must issue the SendKeys with no wait, immediately open the dialog box, and hope that Windows will send the keystrokes there. For example, if you want to open the Find dialog box to perform a search on the LastName control and set the default Match to Any Part Of Field, you need to execute the following commands: GoToControl Control Name: LastName SendKeys Keystrokes: %HA%N Wait: No RunCommand Command: Find
The SendKeys command queues up Alt+H A Alt+N, which is the key combination you could use to move to the Match option (H is the hotkey), press A to select the entry beginning with that letter (Any Part Of Field), and then use Alt+N to get back to the Find What (N is the hotkey) box. This works a vast majority of the time, but if some other application pops forward a dialog box right after the SendKeys and before the RunMenuCommand, the keystrokes won’t go where you intended. The bottom line is always to work hard to figure out an alternative way to accomplish a task that you might be tempted to do with SendKeys. In the previous example, a custom search form would work much better. See Chapter 25, “Automating Your Application with Visual Basic,” on the companion CD, for details about how to build a custom search form (also known as custom query by form).
Article 6
INSIDE OUT
1864 Article 6 Macro Actions
Table A6-8 User Interface Macros
Article 6
Macro Action
Purpose
Trusted
AddMenu
Yes Adds a drop-down menu to a custom menu bar or to a custom shortcut menu for a form or a report. This is the only action allowed in a macro referenced by a Menu Bar or Shortcut Menu Bar property. The arguments to AddMenu specify the name of this menu bar and the name of another macro that contains all the named commands for the menu and the actions that correspond to those commands. An AddMenu action can also build submenus by referring to another macro that uses an AddMenu action. Any custom menu that you define with macros appears on the Add-Ins tab on the ribbon when you open a form or report that references the menu macro. This feature is retained for compatibility with versions of Access before Access 2007.
BrowseTo
Yes Browses to a different top-level form object or report object or browse to a different form or report displayed inside a subform control, such as a navigation control. You can also apply a filter or a Where condition to the form or report you browse to. If you are browsing to a web continuous form in a web database, you can also specify a specific page that you want to browse to when you view the form in a web browser. If the form returns data that is editable, you can specify whether the form should be opened to add new records only; to add, edit, and delete records; or to provide a read-only view of the data. If the underlying query for the form or report has any parameters, Access displays text boxes on the macro design surface for each parameter value.
LockNavigationPane
Prevents users from deleting objects or deleting object shortcuts in the Navigation pane.
Yes
MessageBox
Displays a warning or an informational message in a dialog box, and also produces a sound if you want. The user must click OK to close the dialog box and proceed. In Visual Basic, you should use the MsgBox function. When you use the function, your code can also specify optional buttons and test the return value to determine which button the user clicked.
Yes
1865
Purpose
Trusted
NavigateTo
Selects the category to display from the list avail- Yes able under Navigate To Category on the Navigation Pane menu. Use the optional Group argument to filter the selected category to display a specific group of objects.
Redo
Redoes the last action. This action performs the same functionality as clicking the Redo button on the Quick Access Toolbar.
Yes
SetDisplayedCategories
Shows or hides the selected available category listed under Navigate To Category on the Navigation Pane menu. You can also show or hide all categories.
Yes
SetMenuItem
Sets the enabled or checked status of a menu item Yes on a custom menu bar or a custom shortcut menu. Menu items can be enabled or disabled, checked or unchecked. In Visual Basic, you should set the Enabled property of a custom CommandBar control to enable or disable it. Set the State property of a custom CommandBar control to check or uncheck it. Any custom menu that you define with macros or in Visual Basic code appears on the Add-Ins tab on the ribbon when you open a form or report that references the menu. This feature is retained for compatibility with versions of Access before Access 2007.
ShowToolbar
Shows or hides any custom toolbars. Although you No cannot design custom toolbars in the user interface, you can define a custom toolbar with macros or in Visual Basic. In Visual Basic, you can also set the Visible property of a CommandBar object. Any custom toolbar that you define with macros or in Visual Basic code appears on the Add-Ins tab on the ribbon when you open a form or report that references the menu or when you execute a ShowToolbar command. This feature is retained for compatibility with versions of Access before Access 2007.
UndoRecord
Undo all changes to the current record. This action Yes performs the same functionality as clicking the Undo button on the Quick Access Toolbar.
Article 6
Macro Action
1866 Article 6 Macro Actions
Table A6-9 Windows Management
Article 6
Macro Action
Purpose
Trusted
CloseWindow
Closes either the specified window or, if no window is specified, the active window for a table, query, form, or report. If the Navigation pane has the focus when you execute a CloseWindow action with no window specified, Access closes the database. You can also indicate whether to save the object when Access closes it. This action is not trusted unless you set the Save argument to Prompt.
Depends on argument
MaximizeWindow
Maximizes the active window.
Yes
MinimizeWindow
Minimizes the active window.
Yes
MoveAndSizeWindow
Moves and sizes the active window.
Yes
RestoreWindow
Restores a maximized or minimized window to its Yes previous size.
The following table lists the 26 web-supported macro actions and their arguments. Web macro actions, in general, support fewer arguments than client macro actions. You can refer to the tables above for descriptions of these macros. Note that all web macros are trusted. Table A6-10 Web-Supported Macro Actions
Category
Macro Action
Arguments
Data Entry Operations
DeleteRecord
None
SaveRecord
None
GoToControl
Control Name
GoToRecord
Record
OpenForm
Form Name, Where Condition, Data Mode, Window Mode
OpenReport
Report Name, Where Condition, Window Mode
SetProperty
Control Name, Property, Value
RefreshRecord
None
Requery
Control Name
SetFilter
Where Condition, Control Name
SetOrderBy
Order By, Control Name
ClearMacroError
None
OnError
Go to, Macro Name
Database Objects
Filter/Query/Search
Macro Commands
Category
User Interface Macros
Windows Management
Macro Action
Arguments
RemoveAllTempVars
None
RemoveTempVar
Name
RunDataMacro
Macro Name
RunMacro
Macro Name
RunMenuCommand
Command
SetLocalVar
Name, Expression
SetTempVar
Name, Expression
StopAllMacros
None
StopMacro
None
BrowseTo
Object Type, Object Name, Path to Subform Control, Where
MessageBox
Message
UndoRecord
None
CloseWindow
None
Microsoft renamed some of the macro action names in Access 2010. The following table lists the older macro names and their new equivalents. Note that you can still type the older macro name in the Add New Action combo box and then press Enter, and Access displays the new macro action name on the macro design surface. You can also type the older name in the Action Catalog search box, and Access filters the search to any similar macro names or descriptions. Table A6-11 Renamed Macro Actions