Download as pdf or txt
Download as pdf or txt
You are on page 1of 25

4009FM.

qxd 08/02/01 2:53 PM Page xii

CONTENTS AT A GLANCE
Introduction xxxviii

Chapter 1: What’s New in Access 2002 1

AL
Chapter 2: The Access Event Model 11

Chapter 3: Using VBA Class Modules 41

RI
Chapter 4: Database Design 85

TE
Chapter 5: Access SQL 113

MA
Chapter 6: ActiveX Data Objects 189

Chapter 7: Controlling Controls 297

Chapter 8: Topics in Form Design and Usage 431


D
Chapter 9: Topics in Report Design 587
TE

Chapter 10: Controlling Your Printer 675


GH

Chapter 11: Shared Office Programmability 699

Chapter 12: Using Access As an Automation Client 795


RI

Chapter 13: Access As an Automation Server 861


PY

Chapter 14: Error Handling and Debugging 897

Chapter 15: Application Optimization 953


CO

Chapter 16: Accessing DLLs and the Windows API 1013

Chapter 17: Harnessing Wizard Magic 1053

Chapter 18: Building Add-Ins 1143

Appendix A: The Reddick VBA Naming Conventions, Version 7 1217

Appendix B: Data Access Objects 1239

Appendix C: Controlling Your Printer 1299

Index 1363
4009FM.qxd 08/02/01 2:53 PM Page xiii

CONTENTS
Introduction xxxviii

Chapter 1 What’s New in Access 2002 1


A Brief Access History 2
Access 2002 5
Access 2002 Programmability 5
Access 2002 Forms and Reports 6
Access 2002 Data Access 6
Access 2002 Internet and Intranet Features 7
Other Access 2002 Improvements 8
Microsoft Office XP Developer Features 8
Summary 9

Chapter 2 The Access Event Model 11


So Many Events, So Little Time 12
Hooking In 13
Form Events 16
Cancelable Events 24
The Sequence of Events 25
Logging Events 25
How the Event-Logging Facility Works 26
General Form Actions 27
Keyboard Actions 30
Mouse Actions 32
Data-Related Actions 33
The Error Event 39
The Indispensable Timer Event 39
Actions That Can’t Be Trapped 40
Summary 40
4009FM.qxd 08/02/01 2:53 PM Page xiv

xiv Contents

Chapter 3 Using VBA Class Modules 41


Why Use Class Modules? 42
Classes Let You Create Your Own Objects 42
Classes Let You Hide Complex Processes 44
Classes Make Development Simpler 45
How Class Modules Work 45
Classes Are Like Cookie Cutters 45
Objects Are the Cookies 46
A Simple Example: A Text File Class 47
Creating an Object Class 47
Inserting a New Class Module 47
Naming Your Class 47
Creating a Property Using a Public Variable 48
Creating a Method 48
Using the Object Class 50
Using Property Procedures 55
Retrieving Values with Property Get 55
Setting Values with Property Let 56
Setting Values with Property Set 57
A Simple Database Example 58
Advanced Class Module Techniques 61
Defining Enumerated Types 62
Class Hierarchies 64
Creating a Parent Property 65
Collections of Objects 67
Creating Your Own Collections 69
Defining and Using Custom Events 78
Summary 83

Chapter 4 Database Design 85


The Relational Model 86
Relational Database Design 87
Tables, Uniqueness, and Keys 88
Foreign Keys and Domains 89
Relationships 90
4009FM.qxd 08/02/01 2:53 PM Page xv

Contents xv

Normalizing a Set of Tables 92


Before First Normal Form: Relations 93
First Normal Form 93
Second Normal Form 96
Third Normal Form 97
Higher Normal Forms 99
Integrity Rules 100
General Integrity Rules 100
Database-Specific Integrity Rules 101
A Practical Approach to Database Design 103
Normalizing a Database with Existing Data 106
Breaking the Rules: When to Denormalize 109
Summary 110

Chapter 5 Access SQL 113


Where Can You Use Access SQL? 115
Learning Access SQL 116
The SELECT Statement 117
The SELECT Clause 117
The FROM Clause 118
The WHERE Clause 119
The ORDER BY Clause 121
Joining Tables 121
The ALL, DISTINCTROW, and DISTINCT Predicates 128
The TOP Predicate 129
The WITH OWNERACCESS OPTION Declaration 131
Aggregating Data 131
Aggregate Queries without a GROUP BY Clause 133
Using a GROUP BY Clause 133
Using the HAVING Clause 135
Creating Crosstab Queries with the TRANSFORM Statement 137
Union Queries 142
Using the TABLE Option 143
The ALL Option 144
Sorting the Results 144
Compatible Queries 144
4009FM.qxd 08/02/01 2:53 PM Page xvi

xvi Contents

Subqueries 145
Checking Values against a Lookup Table 146
Comparing Values against Other Values 147
Checking for Existence 149
Using Subqueries in the SELECT Clause 150
Example: Using a Subquery to Find Duplicates 150
Parameterized SQL 151
Using External Data Sources 152
Using Linked Tables 152
Using the IN Clause 152
Using Direct Table References 157
Updating Data with SQL 158
The UPDATE Statement 158
The DELETE Statement 159
The INSERT INTO Statement 160
The SELECT INTO Statement 162
Data Definition with SQL 162
The CREATE TABLE Statement 163
The CONSTRAINT Clause 164
The CREATE INDEX Statement 166
The ALTER TABLE Statement 167
The DROP Statement 168
Creating SQL Pass-Through Queries 169
Jet 4 ANSI SQL-92 Extensions 172
Enabling ANSI SQL-92 Query Mode 173
Jet 4 Table Extensions 174
Jet 4 View and Stored Procedure Extensions 179
Jet 4 Transaction Extensions 181
Jet 4 Security Extensions 182
Differences between Access SQL, SQL-92, Jet SQL-92, and T-SQL 186
Summary 187

Chapter 6 ActiveX Data Objects 189


ADO? What About DAO? 190
Setting References 191
Which Library to Use? 193
4009FM.qxd 08/02/01 2:53 PM Page xvii

Contents xvii

Dueling Object Hierarchies 194


ADO, UDA, and OLE DB 198
Nuts and Bolts: Syntax Explained 198
Properties and Methods 199
Using Object Variables 199
The Connection Object 201
Referring to Objects 208
Bang (!) versus Dot (.) versus Quotes ("") 209
Ordinal Positions 211
Using Default Collections 211
Enumerating Objects in Collections 212
Working with Properties 213
Types of Properties 214
Enumerating the Properties 215
Data Definition Using ADOX 216
Creating Objects 216
Working with Recordsets 228
Meet the Cursors 228
Creating a Recordset 229
Direct Table Access 231
Consistent versus Inconsistent Updates 232
Cursor Locations 233
Recordset Property Interactions 234
The Supports Method 237
Creating Recordset Objects 240
Moving through a Recordset 241
Finding the Number of Rows in a Recordset 243
Testing for Boundaries 243
Testing for an Empty Recordset 244
Looping through All the Rows 245
Using Arrays to Hold Recordset Data 245
Creating a Recordset Based on a Command Object 247
Finding Specific Records 249
Using Bookmarks 257
4009FM.qxd 08/02/01 2:53 PM Page xviii

xviii Contents

The Clone Method 260


Sorting Recordsets 261
Filtering Recordsets 265
Refreshing Recordsets 266
Editing Data in a Recordset Object 267
Persisting Recordsets 271
Using Recordsets in Place of Arrays 274
Using Command Objects for Bulk Operations 276
Schema Recordsets 278
Using the CurrentProject and CurrentData Collections 282
A Case Study: Using the Collections 284
Designing frmDBC 285
Choosing an Object Type and an Action 285
Displaying the Object List 286
Filling the Object List 286
Gathering Options 288
Gathering Lists of Objects 288
Deciding Whether to Add an Object 289
Adding the Object 294
Finishing It Up 294
Using frmDBC in Your Own Applications 294
Summary 294

Chapter 7 Controlling Controls 297


Controls and Their Uses 298
Code Associated with Forms: Class Modules 299
Working with Groups of Controls 300
Some Standard Control Properties 301
Using the Tag Property to Create Your Own Properties 301
The ControlType Property 305
The ControlTipText and ShortCutMenuBar Properties 306
The TabStop and TabIndex Properties 309
The DisplayWhen Property 310
Using the Dirty and Undo Events 311
4009FM.qxd 08/02/01 2:53 PM Page xix

Contents xix

Controlling Text Layout 313


Using Labels 314
The Parent Property 314
Using Text Boxes 315
Carrying Values Forward into New Records 316
The ControlSource Property and Calculated Controls 321
Using Two-State Controls (the Yes/No Crowd) 323
The Toggle Button 323
The Option Button 324
The Check Box 324
Using Option Groups—Controls inside Controls 325
Moving Controls to a New Neighborhood 327
Assigning and Retrieving Values 327
Returning “Real” Information from Option Groups 328
Using Controls’ Controls Collection 331
Using List and Combo Boxes 332
Differences between List and Combo Boxes 333
Important Properties of List and Combo Boxes 334
Multiselect List Boxes 342
Dealing with LimitToList 345
Taming the NotInList Event 346
Auto-Drop Combo Boxes 351
The BeforeUpdate and AfterUpdate Events 351
Filling a List or Combo Box Programmatically 355
Emulating a Permanently Open Combo Box 371
Making Multiple Selections in a List Box 380
How and When to Use Subforms 392
Creating a Subform 393
Relating the Parent to the Child 394
Retrieving Calculated Values from Subforms 395
Going All the Way 397
Using Command Buttons 398
Command Button Properties 399
Command Button Events 407
4009FM.qxd 08/02/01 2:53 PM Page xx

xx Contents

The Tab Control 407


What Works and What Doesn’t 408
How the Tab Control Works 409
Where Am I? 410
Using the Tab Control 410
Modifying Tabs at Runtime 412
Using the Tab Control As a Container 417
Using Default Control Properties to Your Advantage 418
Using the DefaultControl Method to Set Up Default Properties 419
Creating Controls Programmatically 420
Functions That Create Forms and Controls 420
What Are These Controls, Anyway? 426
Using SendMessage to Limit Input Characters 427
Summary 429

Chapter 8 Topics in Form Design and Usage 431


New Form Views in Access 2002 432
Introduction to Class Modules in Forms 433
Controlled Closing 435
Does a Specific Form Exist? 438
Is a Specific Form Loaded? 440
Creating Pop-up Forms 443
Using Pop-up Tools 444
How Do the Sample Forms Work? 444
Using the Sample Forms 446
Creating User-Defined Properties 448
Using a Public Form Variable 448
Using Property Let/Set/Get Procedures 448
Using Form Procedures as Methods 450
Filtering Data 451
The Filter Property 452
The FilterOn Property 455
The Filter Event 455
The ApplyFilter Event 456
Fine-Tuning Filter by Form 458
4009FM.qxd 08/02/01 2:53 PM Page xxi

Contents xxi

Ordering Your Rows 459


Working with Forms’ Data 460
At the New Record? 460
What’s the Current Row, and How Many Rows Are There, Anyway? 461
Has the Form’s Data Been Changed? 462
Which Rows Are Selected? 464
Using the Recordset and RecordsetClone Properties 464
The RecordsetClone Property 464
The RecordsetClone Dilemma 468
Using a Form’s Recordset Property 469
Recordset versus RecordsetClone 472
Conditional Formatting 473
Working with Conditions 474
Working with Conditional Formatting at Design Time 476
Working with Conditional Formatting at Runtime 478
Form-Level Error Handling 484
Controlling the Pesky Users 487
Using the Cycle Property 487
Trapping Keys Globally: The KeyPreview Property 488
Displaying Multiple Instances of Forms 491
What Happens When You Create a New Instance? 492
How Do You Create a New Instance? 492
A Better Solution 493
Closing a Form Instance 495
Closing All the Instances 496
Using Multiple Instances for Pop-up Forms 497
Using Subforms in Your Applications 500
Nested Subforms versus Separate, Synchronized Subforms 500
Using Synchronized Subforms 502
Is the Form Loaded as a Subform? 504
Managing Linking Yourself 505
Creating Self-Disabling Navigation Buttons 506
Subforms and Transactions 519
Windows Handles, Classes, Access Forms, and MDI 526
The Windows Handle (or hWnd) 526
4009FM.qxd 08/02/01 2:53 PM Page xxii

xxii Contents

Window Classes 526


Multiple Document Interface (MDI) 528
Manipulating Forms 528
Demonstrating the FormInfo Features 529
Members of the FormInfo Class 530
How Does It Work? 541
Removing a Form’s Caption Bar 546
Saving and Restoring Form Locations 551
What’s Left? 554
Automatically Resizing Forms 554
Understanding Screen Resolutions 555
Scaling Forms as They Load 557
Using FormResize 558
Managing Features on a Control-by-Control Basis 563
How It Works 571
Programming New Form Views 577
Handling Chart Events 579
Summary 585

Chapter 9 Topics in Report Design 587


Reports versus Forms 588
Filtering Your Reports 590
Controlling Sorting and Grouping 594
The Section Property 595
Referring to Sections by Name 596
Working with the Section Property 596
Accessing Group Levels 601
GroupLevel Properties 602
Section Design-Time Properties 607
The CanGrow/CanShrink Properties 608
The NewRowOrCol Property 613
The ForceNewPage Property 614
The KeepTogether Property 615
The RepeatSection Property 615
4009FM.qxd 08/02/01 2:53 PM Page xxiii

Contents xxiii

Events of Reports and Their Sections 616


Report Events 616
Section Events 621
Section Runtime Properties 623
The MoveLayout, NextRecord, and PrintSection Properties 624
The FormatCount Property 625
The PrintCount Property 625
The WillContinue/HasContinued Properties 626
Examples Using Report and Section Events and Properties 628
Printing Multiple Labels 628
Printing Mailing Labels Starting at a Specific Location 630
Inserting Blank Lines 636
Handling Odd and Even Pages 637
Controlling the Starting Page Number 639
Numbering Items on a Report 640
Some Simple Sample Reports 641
The Sales Report 641
The Phone Book 648
Companies, Contacts, and Hardware 654
Altering Your Report’s Layout Programmatically 660
Creating a Report Based on a Crosstab Query 663
Retrieving the Real Field Names 666
Calculating the Number of Fields to Display 666
Fixing the Caption and ControlSource Properties 666
Cleaning Up 667
Some Final Issues 667
Distributing Access Reports 668
Summary 673

Chapter 10 Controlling Your Printer 675


Working with the Print Destinations 677
Fill a List or Combo Box with All Installed Printer Names 678
Select a New Default Printer 679
Modify a Report’s Output Destination 679
Doing It All by Hand 682
4009FM.qxd 08/02/01 2:53 PM Page xxiv

xxiv Contents

Modifying Printer Settings 683


Modifying Layout Settings 685
Retrieving Printer Capabilities 686
Using the PrinterCapabilities Class 689
Demonstrating the PrinterCapabilities Class 690
How Do I… 691
Programmatically Iterate through the List of Installed Printers? 691
Determine the Default Printer? 691
Fill a List or Combo Box with a List of Installed Printers? 692
Change the Default Printer? 693
Change a Report’s Output Device? 694
Modify Printer Characteristics for a Form or Report? 695
Modify Layout Characteristics for a Form or Report? 696
Find Out the Capabilities of a Printer? 696
Summary 698

Chapter 11 Shared Office Programmability 699


References Are Everything 700
The FileSearch Object Model 701
How Does It Work? 702
Getting Started with Searches 704
Using Advanced Search Techniques 707
Working with CommandBars 716
Where Are CommandBars Stored? 718
What Kinds of Objects Are There? 719
Referring to CommandBars and Their Items 737
Tips to Get You Started 739
Working with Other CommandBarControl Objects 747
Making Things Happen 752
Where Am I? 754
Doing Things the CommandBar Way 754
The Office Assistant 761
Using the Assistant: Advantages and Limitations 762
The Assistant Object Model 763
4009FM.qxd 08/02/01 2:53 PM Page xxv

Contents xxv

Working with the Assistant 764


Working with Balloons 771
Using the Office FileDialog Object 788
Is There More? 793
Summary 794

Chapter 12 Using Access As an Automation Client 795


Automation Basics 796
Terminology 796
What’s the Value of Automation? 798
Object Classes 798
Type Libraries: The Key to Classes 799
Browsing Objects with the Object Browser 801
Creating Object Instances 804
Early Binding and Late Binding 804
A Simple Early Binding Example 805
When to Instantiate 806
CreateObject and GetObject 807
Understanding Class Instancing 809
Controlling Other Applications 812
Learning an Application’s Object Model 812
Differences in Application Behavior 814
Memory and Resource Issues 815
Creating Automation Solutions with Microsoft Office 815
The Office Object Models 816
Example: Word As a Report Writer 821
Creating the Word Template 821
Building the Invoice 823
Example: Outlook Time Reporting 828
Outlook and Exchange 829
Conversing with Outlook 829
Creating New Journal Entries 831
Loading Journal Information 832
Example: Creating a PowerPoint Presentation 835
Understanding PowerPoint Slides 835
4009FM.qxd 08/02/01 2:53 PM Page xxvi

xxvi Contents

Working with PowerPoint Shapes 837


Creating a Simple Presentation 838
Apply Slide Show Effects 841
Example: Populating an Excel Worksheet 842
Using an Existing File 842
Our Scenario 842
Creating an Object from an Existing Document 843
Updating the Worksheets and Chart 844
Using ActiveX Controls 847
ActiveX Control Registration 847
Inserting ActiveX Controls 849
Modifying ActiveX Control Properties 850
Using ActiveX Control Events 852
Using Bound ActiveX Controls 852
Calendar Control Example 853
Using ActiveX Controls from Other Products 854
Tapping into Events Using WithEvents 855
What Is WithEvents? 855
Using WithEvents 856
Using Event Sinking with Forms 858
Summary 859

Chapter 13 Access As an Automation Server 861


Working with Access As an Automation Server 862
Using the Access Type Library 863
Differences from Regular Access 863
Access Automation Server Behavior 864
A Class for Access Automation 865
Beginning an Automation Session 866
Loading a Database or Project 869
Dealing with Secure Workgroups 871
Controlling Window Visibility 872
Determining Whether a Project Is Loaded 873
Quitting Access 874
4009FM.qxd 08/02/01 2:53 PM Page xxvii

Contents xxvii

Running Access Reports Using Automation 875


The Sample Application 876
Initiating an Automation Session 876
Opening a Database 877
Getting a List of Reports 878
Previewing Reports 880
Calling User-Defined Functions from an Automation Client 881
Global Functions 881
Form-Level Functions 883
Writing Automation-Friendly Applications 885
The UserControl Property 885
Hiding the Access Main Window 885
Preventing Users from Closing the Database 886
Being User-Input Aware 888
Creating Your Own Error Stack 888
Switching Back to the Client Application 895
Summary 896

Chapter 14 Error Handling and Debugging 897


Dealing with Syntax Errors 898
Dealing with Runtime Errors 899
Invoking an Error Handler with the On Error Statement 899
Creating Intelligent Error Handlers 901
Raising Errors 908
Inline Error Handling 909
Hierarchy of Error Handlers 911
The OnError Property and the Error Event 912
Handling Data Access Errors 914
Creating an Error-Reporting Subroutine 916
Implementing a Call Stack 923
Dealing with Logic Errors, aka Bugs! 927
Avoiding Bugs 927
Fixing Bugs As They Appear 928
Using Comments 928
4009FM.qxd 08/02/01 2:53 PM Page xxviii

xxviii Contents

To Strip or Not to Strip 930


Organizing Your Code 930
Modularizing Your Code 931
Using Option Explicit 931
Avoid Variants If at All Possible 932
Use ByVal with Care 933
Beware the Simple Dim Statement 933
Grouping Your Dim Statements 933
Using the Tightest Possible Scope 934
Using Consistent Naming Conventions 934
Your Friend, the MsgBox Function 935
The VBA Debugging Tools 936
Using the Immediate Window 941
Using Breakpoints 944
Techniques and Strategies for Debugging 946
Systematic Debugging 947
Debugging Difficulties 948
Resetting the Stopped State 949
Using Assertions 949
Summary 950

Chapter 15 Application Optimization 953


Tuning Your Application’s Performance 954
Understanding How the Jet Query Engine Works 955
Query Definition 955
Query Compilation 955
Query Optimization 956
Query Execution 959
Forcing Jet to Recompile and Optimize a Query 960
Taking Advantage of Rushmore 960
Keeping Statistics Accurate 960
Configuring the Jet Engine 961
Using the DAO SetOption Method 964
Using the ADO Jet Engine–Specific Connection Properties 964
4009FM.qxd 08/02/01 2:53 PM Page xxix

Contents xxix

Microsoft’s Unsupported Jet Optimization Tools 965


The ShowPlan Option 965
The ISAMStats Method 967
Speeding Up Queries and Recordsets 973
Speeding Up Forms 977
Limiting a Form’s Record Source with Large Recordsets 977
Speeding Up Combo Boxes with Many Rows 977
Other Form Speed-Up Tricks 978
Speeding Up Reports 978
Optimizing VBA’s Use of Modules and Compilation 979
How Does VBA Load Code? 979
Why Compile Code? 980
What Gets Stored When Your Code Is Compiled? 980
When Should You Compile? 980
How Does the Compile On Demand Option Fit In? 981
What Causes Code to Be Decompiled? 982
What Are the Effects of Compilation on Memory and Disk Usage? 983
Are Modules Ever Removed from Memory? 983
What Can You Do to Optimize the Use of Modules? 984
One More Consideration: No Circular References in Libraries 984
What Else Can You Do? 985
Speeding Up VBA: Testing Hypotheses 985
Creating a Stopwatch 986
Getting Reasonable Results 987
How It Works 989
VBA Optimization Tips 992
Summary 1012

Chapter 16 Accessing DLLs and the Windows API 1013


Introducing Dynamic Link Libraries 1015
Calling DLL Procedures from VBA 1016
Using Declare Statements 1017
Passing Arguments to DLLs 1017
Returning Strings from a DLL 1018
4009FM.qxd 08/02/01 2:53 PM Page xxx

xxx Contents

Using the vbNullString Constant 1021


Passing a User-Defined Type to a DLL 1022
Passing an Array 1023
Using Type Libraries with DLL Functions 1024
Distributing Solutions That Use Type Libraries 1025
Creating DLL Function Classes 1025
Using the Clipboard 1025
Using the Clipboard Class 1027
How to Construct a Declare Statement 1027
Public versus Private 1029
Specifying the Procedure Name 1029
Specifying the Lib(rary) 1030
Specifying the Alias 1030
Specifying the Arguments 1033
Converting C Parameters into VBA Declarations 1033
More Advanced Details of Calling DLLs 1035
Understanding Passing by Value and by Reference 1035
Passing Strings to a DLL: The Real Story 1037
Using vbNullString—A Closer Look 1038
Unicode to ANSI and Back 1039
Using the Any Data Type 1040
Using Err.LastDLLError 1043
Using Callback Functions 1043
User-Defined Types and DWORD Packing 1046
Converting Windows API Calls from 16-bit Windows 1047
Summary 1050

Chapter 17 Harnessing Wizard Magic 1053


Using the Procedures 1055
File-Handling Functions 1056
Checking for the Existence of a File 1056
Splitting a Full Path Reference into Components 1057
Getting the Full Path for a File 1059
Using Windows’ Dialog Boxes 1060
Using the CommonDlg Class 1061
4009FM.qxd 08/02/01 2:53 PM Page xxxi

Contents xxxi

Using the Windows Open/Save Common Dialog Boxes 1068


Selecting Colors 1079
Selecting Fonts 1083
Using the ShellBrowse Class 1087
Reading and Writing Registry Values 1094
Retrieving Information about a Key 1095
Retrieving a Value Name 1098
Retrieving a Value from the Registry 1100
Writing a Value to the Registry 1101
Retrieving the Name of a Registry Subkey 1102
Creating a New Key 1104
Font-Handling Functions 1106
Retrieving a List of Fonts 1106
Retrieving a List of Sizes 1108
Using Font Information in Your Own Projects 1109
Using the ScreenInfo Class 1110
What Else Is in That ScreenInfo Class? 1112
Finding the Screen Size for Text in a Given Font 1114
Object-Handling Functions 1118
Retrieving a List of Object Names 1118
Sorting a String Array 1123
Retrieving a List of Objects and Their Types 1123
Sorting the Array of DBObj Structures 1126
Miscellaneous Functions 1126
Retrieving National Language Info 1126
Retrieving Complete Version Information 1128
Working with Toolbar Bitmaps 1133
Using adh_accGetTbDIB 1136
Some Interesting Points 1137
Summary 1139

Chapter 18 Building Add-Ins 1143


Libraries and Wizards and Builders, Oh My! 1144
Entry Points for Add-Ins 1145
4009FM.qxd 08/02/01 2:53 PM Page xxxii

xxxii Contents

Data Access and Add-Ins 1145


Add-Ins and the Registry 1146
Creating Library Databases 1146
Structuring Library Code Modules 1147
Using a Library Database 1147
Library Database Reference Issues 1149
Circular References Are Not Allowed 1151
Editing Loaded Library Code 1151
Using Application.Run to Run Procedures 1152
Using the LoadOnStartup Key with Application.Run 1153
Always Compile Your Libraries 1154
Menu Add-Ins: The Simplest Add-Ins 1154
Building Your Own Builders 1155
The Sample Builder 1155
Writing a Builder Function 1155
Builder Registry Entries 1156
Creating New Builder Entries 1158
The System Color Builder 1159
Developing Custom Wizards 1162
Access Wizard Functions 1162
Defining a Wizard Framework 1164
A Sample Form Wizard 1165
How to Use the State Table 1166
Looking at the Wizard Host Form 1168
Code behind the Host Form 1169
An Example Wizard Form 1171
Global Wizard Functions 1172
Creating Wizard Pages 1174
Finishing the Process 1177
Creating Forms and Controls 1177
Using an Access Table to Store Code 1179
Launching the Wizard 1182
Wizard Registry Entries 1184
Our Framework in Summary 1187
4009FM.qxd 08/02/01 2:53 PM Page xxxiii

Contents xxxiii

Control Wizards: A Hybrid 1188


Control Wizard Functions 1188
Control Wizard Registry Entries 1190
ActiveX Control Wizards 1191
Distributing and Installing Add-Ins 1191
Using Add-In Manager 1192
Creating the USysRegInfo Table 1193
Advanced Add-In Topics 1195
Restoring References Using VBA 1195
Creating MDE Files 1197
COM Add-Ins 1199
COM Add-In Pros and Cons 1200
Using the COM Add-Ins Dialog Box 1201
Exploring IDTExtensibility2 1202
The COMAddIns Collection 1205
Building a Simple COM Add-In 1206
Summary 1215

Appendix A The Reddick VBA Naming Conventions, Version 7 1217


Changes to the Conventions 1218
An Introduction to Hungarian 1218
Tags 1219
Creating Data Types 1221
Constructing Procedures 1223
Prefixes 1224
Suffixes 1225
Filenames 1226
Host Application and Component Extensions to the Conventions 1226
Summary 1237

Appendix B Data Access Objects 1239


DBEngine and the Workspaces Collection 1240
Referring to Objects 1241
CurrentDb versus DBEngine(0)(0) 1243
4009FM.qxd 08/02/01 2:53 PM Page xxxiv

xxxiv Contents

Bang (!) versus Dot (.) 1245


Ordinal Positions 1245
Using Default Collections 1246
Enumerating Objects in Collections 1247
Working with Properties 1247
Types of Properties 1248
Referring to Data Access Object Properties 1248
Enumerating the Properties 1249
Setting and Retrieving Properties 1250
Data Definition Using DAO 1251
Creating Objects 1251
Modifying Objects 1264
Working with Recordsets 1264
Meet the Recordsets 1264
Creating a Recordset 1265
Consistent versus Inconsistent Updates 1267
Creating Recordset Objects 1267
Moving through a Recordset 1268
Using the Move Method 1269
Using the AbsolutePosition and PercentPosition Properties 1269
Finding the Number of Rows in a Recordset 1270
Testing for Boundaries 1272
Testing for an Empty Recordset 1272
Looping through All the Rows 1273
Using Arrays to Hold Recordset Data 1273
Creating a Recordset Based on a Querydef 1275
Finding Specific Records 1276
Using Variables in Strings 1278
Using Bookmarks 1281
Sorting Recordsets 1286
Sorting Table-Type Recordsets 1286
Sorting Dynaset- and Snapshot-Type Recordsets 1288
Filtering Non-Table Recordsets 1289
Using a SQL WHERE Clause 1290
Using the Filter Property 1290
4009FM.qxd 08/02/01 2:53 PM Page xxxv

Contents xxxv

Editing Data in a Recordset Object 1291


When Is a Recordset Modifiable? 1291
Changing Data in a Recordset 1291
Adding New Rows to a Recordset 1292
Using Containers to Handle Saved Documents 1294
Database Properties 1297
Summary 1298

Appendix C Controlling Your Printer 1299


Introducing the PrtDevMode Property 1300
Device Information 1303
Using the DevMode Class 1308
Using the DevMode Class in Your Applications 1314
How Does It Work? 1315
Using LSet to Copy Unformatted Data 1315
Modifying Printer Settings 1319
An Important Reminder 1320
Controlling Print Layout Information 1320
Using PrintLayout in Your Own Applications 1323
Introducing the PrtDevNames Property 1323
Using the DevNames Class 1324
Using the DevNames Class in Your Applications 1327
How Does It Work? 1327
Controlling Your Destination 1334
Saving, Printing, and Restoring 1335
Retrieving Printer Capabilities 1342
Using the PrinterCapabilities Class 1344
Using the PrinterCapabilities Class 1346
How Do I… 1346
Figure Out All These Classes? 1347
Fill a List or Combo Box with a List of Installed Printers? 1348
Programmatically Iterate through the List of Installed Printers? 1349
Determine the Default Printer? 1350
Change the Default Printer? 1351
Change a Report’s Output Device? 1352
4009FM.qxd 08/02/01 2:53 PM Page xxxvi

xxxvi Contents

Modify Printer Characteristics for a Form or Report? 1355


Modify Layout Characteristics for a Form or Report? 1357
Find Out the Capabilities of a Printer? 1358
Summary 1360

Index 1363

You might also like