Chapter 32. Distributing Your Application

<feature><title>In This Chapter</title> </feature>

Why This Chapter Is Important

Many developers are responsible for designing applications that are distributed to many users. The most basic distribution option is to require each user to purchase a copy of Access and then simply provide each user with a copy of the database (MDB) files required for the application. The developer then can go to each user and configure the application appropriately.

Although distributing an application by copying it to each user’s machine does not require much specialized knowledge on the part of the developer, it generally is not very practical. For example, in many situations, the developer is distributing an application to users dispersed throughout the country or even the world. Many Access applications are mass marketed to hundreds or even thousands of users. In these situations, it is mandatory to use a professional setup program to properly install the application. For these reasons, most developers distribute their applications using the Packaging Wizard, an important component of the Microsoft Office Developer Edition.

Introducing the Packaging Wizard

The Packaging Wizard enables you to easily create distribution disks containing all the files necessary to run your application. The Packaging Wizard creates a highly professional-looking setup program that your users will run when they want to install your application. Using the Packaging Wizard, they can customize what is included with your application. You can even provide your users with the familiar Standard, Compressed, and Custom options that they have come to know from installing other Microsoft products.

Loading the Packaging Wizard Add-In

Before you can use the Packaging Wizard, you must activate the Packaging Wizard add-in. To do this:

  1. Activate the VBE (Visual Basic Development Environment).

  2. Select Add-in Manager from the Add-in menu. The Add-in Manager dialog box appears.

  3. Select Packaging Wizard.

  4. Check the Loaded/Unloaded check box.

  5. Check Load on Startup if you want the wizard to be loaded each time that you launch Access.

  6. Click OK. The Packaging Wizard should now appear as an option under the Add-in menu.

Distributing Your Application to Run with a Full Copy of Access

Many developers distribute their applications to end users who own and have installed Microsoft Access. These users might be responsible for designing their own ad hoc queries and reports. It is important that you, the developer, properly secure your application for these users, provide them your application with only the functionality you want included, and present your application with professional polish.

Many of the topics in this chapter apply to your application, whether you are distributing the application to users with the Access runtime version or with the full copy of Access. You probably should include a switchboard, custom menu bars, and custom toolbars in your application whether, for example, you are distributing your application with the runtime version or for use under the full version of Access.

Using Full Versions Versus Runtime Versions of Access

Many people have the misconception that using the Packaging Wizard and distributing your application using the Access runtime version somehow means that the application is compiled. This is not the case at all! In fact, if you do not properly secure the database, anyone can install his or her own copy of Access and modify the application’s data and other objects just as you can. Using the Packaging Wizard and distributing your application with the Access runtime version does not modify the database in any way. It simply gives you the license to freely distribute the engine required to run your application.

Actually, the engine is not even a modified version of the Access executable! The MSACCESS.EXE file that you distribute is the same as the MSACCESS.EXE that you use to build your application. When you create installation disks for your users with the Packaging Wizard, the installation process copies the same MSACCESS.EXE file to the installation disks. So how can there be any difference between the retail and runtime versions of Access?

When the user installs your application, the installation process copies the MSACCESS.EXE to the user’s machine. During this process, the installation program checks a Windows Registry licensing key to see whether the user owns a copy of Access. If the licensing key indicates that the user does not own a copy of Access, or if the key does not exist, the licensing key (which is a set of numbers and letters) is updated to indicate that the user will be using the runtime version of the product. When Access executes and the runtime licensing key is found, the product launches in runtime mode.

When the runtime licensing key is found, Access behaves differently than it does when the full licensing key is found. If you are not aware of the differences, you will be quite surprised when certain aspects of your application no longer function as expected. The following is a list of the limitations of the runtime versions of the product:

  • The Database window is hidden.

  • Design views are hidden.

  • Built-in toolbars are not supported.

  • Some menu items are not available.

  • Certain keys are disabled.

Hidden Database Window

When users launch your application using the runtime version of Access, the Database window is not visible. It’s actually there, but it is hidden because its colors are set to the same colors as the Windows background color. This means that you can interact with the Database window using code, but the users of your application will be unable to interact with the Database window directly.

The fact that the Database window is hidden tends to be a double-edged sword. On one hand, it prevents most users from modifying the objects in your application. On the other hand, it puts the responsibility on you to build a complete interface for your application. Remember that, for you as a developer, the Database window is a starting point. You must provide a different starting point and navigational tools for your users to maneuver throughout your application.

Hidden Design Views

The users of your application won’t have direct access to any design views, which means that they are unable to create or modify tables, queries, forms, reports, macros, or modules. You still can get to all this functionality through code, though. You can build a wizard that enables your users to define all aspects of a query or some other object, for example, and then build the query (or other object) using ADO (ActiveX Data Objects) code. Again, this helps protect your application from novice users, but it puts the pressure on you to ensure that your application provides its users with all the functionality they need.

Built-In Toolbars Not Supported

All built-in toolbars are completely unavailable with the runtime version of Access, which means that you must design your own toolbars and attach them to your forms and reports as appropriate. This is covered in the “Adding Custom Menus and Toolbars” section of this chapter.

Unavailable Menu Items

Built-in toolbars are not supported at all when using the runtime version of Access. Menus are simply modified after the runtime key is found. Many menu items are hidden in the runtime version. These hidden menu items prevent users from making changes to your application.

Although many of the menu commands are hidden from the user, they can be accessed by using the DoMenuItem command. In other words, the functionality is there, but it is simply hidden from your users.

Disabled Keys

Several keystrokes are unavailable to your users when they run your application with the runtime version of Access. Table 32.1 lists these keystrokes.

Table 32.1. Disabled Keys

Keys

Function

Ctrl+Break

Halts macro and code execution

Shift (when opening the database)

Prevents execution of the AutoExec macro and ignores Startup properties

Alt+F1/F11

Displays the Database window

F12

Displays the Save As dialog box

Shift+F12

Saves a database object

Ctrl+G

Displays the Debug window

Ctrl+F11

Toggles between custom and built-in toolbars

As you can see, these are keys that you would rarely, if ever, want your users to use. You might consider the disabling of these keystrokes a positive side effect of using the runtime version of the product.

Preparing Your Database for Use with the Access Runtime Version

Several steps are required to prepare your database for use with the Access runtime version. Although many of these steps are mandatory when distributing your application with the runtime version, they also are good as a general practice when developing a polished application. To prepare your application for use with the Access runtime version, follow these steps:

  1. Create the application.

  2. Create Help files and associate the Help topics with the application’s objects, if desired.

  3. Test and debug the application.

  4. Run and test the application with the /Runtime command line argument.

  5. Run the Packaging Wizard.

  6. Deploy the application.

  7. Package and distribute the application.

Creating the Application

You must be concerned about several things when designing an application for use with the Access runtime version. Although the following items are niceties in any application, they are a mandatory aspect of developing an application for use with the Access runtime version:

  • Build the application around forms.

  • Build error handling into the application.

  • Build custom menus and toolbars into the application.

  • Set startup options for the application.

  • Properly secure the application.

Building the Application Around Forms and Menus

The first step when creating the application with runtime distribution in mind is to build the application around forms and menus. This means that everything in the application needs to be form and menu driven. Your application generally should begin by displaying a Main Switchboard, or a startup form with a main menu. The user then can navigate from the Main Switchboard to additional switchboards, such as a Data Entry Switchboard, Reports Switchboard, Maintenance Switchboard, and so on.

An alternative is to display the most commonly used form when the application launches. Menu and toolbar items are used to navigate to other parts of your application. For example, if the application’s main purpose is to maintain membership information for a union, the startup form could be the membership form. Other forms, such as the member payments form, could be accessed via a menu attached to the membership form. This second option is my personal favorite.

Building Error Handling into the Application

It is imperative that you build error handling into your application. If an error occurs when someone is using the runtime version of Access and no error handling is in place, an error message is displayed, and the user instantly is returned to the Windows desktop. Therefore, it is crucial that you build error handling into all your routines. Creating a generic error handler to assist you with this task is covered in Chapter 16, “Error Handling: Preparing for the Inevitable.”

Adding Custom Menus and Toolbars

As mentioned earlier in this chapter, limited versions of the standard Access menus are available under the Access runtime version, but toolbars are not available at all. You therefore must provide your users with whatever menu bar and toolbar functionality the application requires.

As discussed in Chapter 9, “Advanced Form Techniques,” you can attach a menu bar to a form using the Menu Bar property of the form. When a specific menu bar is associated with a particular form or report, the menu appears whenever the form or report becomes the active window. It generally is easier to base a form or report’s menu on one of the standard Access menus and then add or remove menu items as appropriate.

You must build each toolbar that you want to use with your application. As covered in Chapter 9, you can specify the toolbar that you want to be visible with your form or report by using the Toolbar property of the form or report. At times, you might prefer to control the toolbars that display by using code. By using this method, you can give the users access to your own toolbars or custom toolbars. Listing 32.1 shows the code placed in the Activate event of the form or report.

Example 32.1. Code for the Activate Event

Private Sub Form_Activate()
On Error GoTo Err_Form_Activate
    Call ToolBarShow("tbrMainForm", True)
    Me.fsubClients.Requery

Exit_Form_Activate:
    Exit Sub

Err_Form_Activate:
    MsgBox Err.Description
    Resume Exit_Form_Activate
End Sub

The Activate event of the frmClients form calls a user-defined procedure called ToolbarShow. It passes the ToolbarShow routine two parameters: the name of the toolbar it will affect and a Boolean variable indicating whether you wish to hide or show the specified toolbar. Listing 32.2 shows the ToolBarShow routine.

Example 32.2. The ToolBarShow Routine

Sub ToolBarShow(strToolbar As String, fShow As Boolean)
   DoCmd.ShowToolbar strToolbar, _
         IIf(fShow, acToolbarYes, acToolbarNo)
   DoCmd.ShowToolbar "Form View", _
         IIf(fShow, acToolbarNo, acToolbarWhereApprop)
End Sub

The ToolBarShow routine handles both the showing and hiding of custom toolbars. It receives a string and a Boolean variable. The ShowToolbar method, contained in the DoCmd object, makes the toolbars visible or hidden. The command does this by taking the name of the toolbar and a Boolean value (both are passed in as parameters) and toggling the visible property for that toolbar to True for visible or False for hidden, depending on which was passed into the function. If you pass the ToolBarShow routine the string tbrMainForm and the Boolean True, for example, it shows the tbrMainForm toolbar.

In case the application will run in both the retail and runtime versions of Access, you should ensure that the standard toolbar is hidden when the form is active. The second ShowToolbar method indicates that the Form View toolbar will be hidden if you are displaying the custom toolbar and will be shown, where appropriate, if you are hiding the custom toolbar. The Deactivate event of the form looks like this:

Private Sub Form_Deactivate()
    Call ToolBarShow("tbrMainForm", False)
End Sub

This routine hides the tbrMainForm toolbar and shows the Form View toolbar where appropriate.

Clearly, it is important that you perform all the menu and toolbar handling required by your application. This ensures that all menu bars and toolbars are available when they should be, and only when they should be.

Setting Startup Options

Access 2000 and Access 2002 provide you with several startup options that enable you to control what happens to your application when it is loaded. Table 32.2 lists each option in the Startup dialog box.

Table 32.2. Startup Options

Option

Function

Application Title

Sets the AppTitle property, which displays a custom title in the application title bar.

Application Icon

Sets the AppIcon property, which displays a custom icon in the application title bar.

Menu Bar

Sets the StartupMenuBar property, which specifies the custom menu bar displayed by default when the application is loaded.

Allow Full Menus

Sets the AllowFullMenus property, which allows or restricts the use of Access menus.

Allow Default Shortcut Menus

Sets the AllowShortcutMenus property, which allows or restricts the use of standard Access shortcut menus (menus accessed with a right-click).

Display Form/Page

Sets the StartupForm property, which specifies the form displayed when the application is loaded.

Display Database Window

Sets the StartupShowDBWindow property, which determines whether the Database window is visible when the application is opened.

Display Status Bar

Sets the StartupShowStatusBar property, which determines whether the status bar is visible when the application is opened.

Shortcut Menu Bar

Sets the StartupShortcutMenuBar property, which specifies that a menu bar be displayed by default as the shortcut (right-click) menu bar.

Allow Built-in Toolbars

Sets the AllowBuiltInToolbars property, which indicates whether built-in toolbars are available to your users.

Allow Toolbar/Menu Changes

Sets the AllowToolbarChanges property, which determines whether your users can customize toolbars in the application.

Use Access Special Keys

Sets the AllowSpecialKeys property, which determines whether the user can use keys such as F11 to display the Database window, Ctrl+F11 to toggle between custom and built-in toolbars, and so on.

Note

Notice the Use as Form and Report Icon property available when an Application icon is designated. When checked, the icon designated as the Application icon is used as the icon for forms and reports.

As you might have guessed, many of these options apply only when you are running the application under the full version of Access (as opposed to the runtime version.) You do not need to set the Display Database Window property, for example, if your application will be running only under the runtime version of Access. The Database window is never available under the runtime version of the product, so Access ignores this property when the application is run under the runtime version. Nevertheless, I like setting these properties to ensure that the application behaves as I want it to under both the retail and runtime versions of the product.

All the properties can be set by using the Startup dialog box or by using code. If you use code, you must make sure that the property exists for the Database object before you set it. If the property does not exist, you must append the property to the Database object.

Only users with Administer permission for the database can modify the Startup properties. If you want to ensure that certain users cannot modify the startup options of the database, you must make sure that they do not have Administer permissions.

Note

As part of setting startup options for your database, you should determine what code, if any, is run when the application is loaded. You can accomplish this in one of two ways. You can start the application with an AutoExec macro and then issue a RunCode action to execute a VBA procedure. The other option is to designate a Startup form for the application and then call a custom routine from the Open event of the Startup form. I always use the second option because it provides you with more control, and you can include error handling in the code module behind the startup form, whereas an AutoExec macro cannot contain error handling. The code shown in Listing 32.3 is called from the Open event of the Startup form for the Time and Billing application. This code, and the rest of the code in this chapter, is located in the CHAP32.MDB database file on the sample code CD-ROM.

Example 32.3. Setting Options from a Startup Form Routine

Private Sub Form_Open(Cancel as Integer)
    'Turn the hourglass on
    DoCmd.Hourglass True

    'Display the splash screen
    DoCmd.OpenForm "frmSplash"

    'Verify links and attempt to relink if necessary
    If LinkTables Then

        'If linking successful, load company info
        Call GetCompanyInfo
    Else

        'If linking unsuccessful, close the splash screen
        'and Quit
        DoCmd.Close acForm, "frmSplash"
        Cancel = True
        DoCmd.Quit
    End If

    'Turn hourglass off
    DoCmd.Hourglass False
End Sub

This routine, placed in the Open event of the startup form, first displays an hourglass. It uses the OpenForm method to open a form called frmSplash. The routine calls a user-defined function that ensures that the database tables are linked successfully. This LinkTables routine is covered in the “Automating the Process of Linking to Tables” section of this chapter. If the LinkTables function returns False, the frmSplash form is closed, and the application is exited. As long as the tables’ links have been established successfully, the routine proceeds to call a routine called GetCompanyInfo, where it loads frequently used information into a type structure. The hourglass mouse pointer is removed, and the splash screen is unloaded after it reaches a timer value.

Securing the Application

Don’t fool yourself! Remember that the runtime version of Access in no way secures your application. It simply provides you with royalty-free distribution. You must perform all the same measures to secure your application under the runtime version of Access that you perform under the retail version of the product. The bottom line is that you must take measures to secure your application if you want it and its data to be secure. The basics of security are covered in Chapter 27, “Database Security Made Easy.” The intricacies of security are covered in Chapter 28, “Advanced Security Techniques.” Distributing your application as an MDE (compiled database) provides an additional level of security while improving performance and decreasing the size of the database file. MDE files are covered in the next section.

Distributing Your Application as an MDE

The process of creating an MDE file compiles all modules, removes all source code from your database, and compacts the destination database. All code will run, but the user will be unable to modify forms, reports, and modules. Besides protecting the objects in your database, this process reduces the size of the database and some of the overhead associated with it, thereby improving application performance. Creating and distributing an MDE file is not as simple as it might appear at first glance. Chapter 27 covers the process of creating an MDE file and the important issues that surround this file format.

Adding Custom Help to the Application

To add polish to your application and ensure that the help you provide to your users applies to what they are looking at in your application, you must provide a custom Help file. In essence, adding help to your application involves first creating Help files. You then must add help to the various objects in your application. There are many excellent tools available that can assist you in this.

Testing and Debugging the Application

Before you even bother trying to run your application under the runtime version, you should fully test and debug the application under the retail version of the product. When you are fairly confident that you have all the kinks worked out of the application, you are ready to test it in the runtime environment.

Running and Testing the Application with the /Runtime Command-Line Switch

If you have the Microsoft Office 2002 Developer tools installed, Microsoft provides a very easy way to test an application and see how it will perform under the runtime version of Access without having to actually create distribution disks. You can do this by using the /Runtime command-line switch. The /Runtime switch forces Access to load in runtime mode. Here’s how it works:

c:program filesmicrosoft officeofficemsaccess.exe c:databaseschap32.mdb /runtime

After you load the application with the /Runtime switch, you should once again test all aspects of the application. At times, you might want to test to see whether the application has been launched with the runtime or retail version of the product. You can accomplish this with the following code:

If Not SysCmd(acSysCmdRuntime) _
      And CurrentUser <> "Admin" Then
      MsgBox "You aren't allowed here"
End If

The SysCmd function, when passed the constant acSysCmdRuntime, checks to see whether the application was launched using the runtime version of Access. In this case, if the program was run with the retail version of Access and CurrentUser is not Admin, a message is displayed, indicating that the user is not allowed. Of course, you easily could modify this routine to check for other users and to quit the application if an unauthorized person attempts to launch the application without the runtime version of the product.

Tip

If you want to simulate the runtime environment on the machine of a user who has Access installed, you must copy the file mso9rt.dll to the directory on the user’s machine called program filescommon filesmicrosoft sharedvbavba6.

Note

The Packaging Wizard was unavailable at the time of this writing. Some of this text may therefore be inaccurate. For an update of this section, please visit http://www.samspublishing.com and enter the ISBN for this book in the search box.

Running the Packaging Wizard

After you have fully tested and prepared your application for distribution, you are ready to run the Packaging Wizard. The Packaging Wizard walks you through all the steps required to build distribution disks that include all the components your application needs to run. You launch the Packaging Wizard from VBE, as follows:

  1. Activate the VBE.

  2. Select Packaging Wizard from the Add-ins menu. The Packaging Wizard starting dialog box appears.

  3. The Packaging Wizard starting dialog box provides you with an introduction to the Packaging Wizard and what it does. Click Next to proceed to the next step.

Identifying Application and Package Information

The first step of the wizard, gives you the opportunity to

  • Designate the file you wish to package

  • Name the package that you are creating

  • Rename, delete, and duplicate packaging scripts

Identify the file you want to package, and supply a package name. Then click Next.

Supplying Application Information

The second step of the wizard, allows you to specify application information. You must supply

  • The application title

  • Your company name

  • Version information

  • The setup language

Click Next when ready to continue.

List of Files to Search for Dependency Information

The third step of the wizard, enables you to designate all files that you want to scan for dependency information. This information is used to ensure that all necessary files are included in the package. Click Add File to add any additional files that you wish to scan. Click Next when done.

Inclusion of the Runtime

The fourth step of the wizard, enables you to determine whether the Access Runtime is included with the packaged application. If you opt to include the Access Runtime, you can designate whether you want to include system files and Internet Explorer 5.1. Finally, you can designate the language of the Access runtime that you wish to include. Click Next to continue.

Modifying Installation Locations

The fifth step of the Packaging Wizard allows you to designate where to install each file in the package. For each file, indicate where to place the file, and whether it is shared by other applications. Click Next when done.

Inclusion of Database Components

The sixth step of the wizard enables you to select the database components you want to include with your package.

Selecting Start Menu Items to be Created

In the seventh step of the Packaging Wizard, you can designate Start menu groups and items that are created during the installation process. Click New Folder to create a new folder and New Shortcut to create a new shortcut. If you click a shortcut and click Properties, the Start Menu Item Properties dialog box appears. Designate the Name, Command Line, Start In path, Database information, and Profile information for the item. Click OK to return to the Start Menu Shortcuts step of the wizard. Click a shortcut and click Remove to remove a shortcut. Click Next when you’re finished designating all options.

Choosing a File to Run When the Installation Is Complete

The eighth step of the Packaging Wizard allows you to specify a command to execute when the installation is complete. For example, you can designate that you want Access to open a ReadMe file when the installation of the application is complete.

The Final Step

The final step of the Packaging Wizard prompts you either to build the setup program, or to save the package script without building it. Select the appropriate option and click Finish.

Deploying the Application

Before you can begin installing the application on workstations, you must deploy your project’s packages to a distribution site. Once again, this is accomplished using the Packaging Wizard. Complete the following steps:

  1. From the opening window of the Packaging Wizard, select Deploy.

  2. In the first step of the wizard, you select the package to deploy. Click Next when ready.

  3. The second step enables you to designate the type of deployment you want to perform. You can deploy to a folder, or via the Web. The steps that follow differ, depending on your selection. Click Next after you make your selection.

  4. If you select Folder, the third step of the Packaging Wizard prompts you to designate where you want to deploy the package. You can deploy locally, or to a network. Make your selection and click Next.

  5. In the final step, designate a name for the deployment script. This script is used for future deployments of the package. When ready, click Finish.

  6. When the process is complete, a Deployment report appears. Click Save Report if you want to save the report. Click Close when done. You are returned to the opening screen of the Packaging Wizard.

Distributing the Application

The most important thing you must do when packaging and distributing your application is test the application on a machine that has never had a copy of Access or any Access runtime application installed. This ensures that your application includes all required components. I like to keep a “virgin” machine available for testing my application setups. Here’s what I do:

  1. Use Symantec Ghost to create an image of the operating system drive on the test machine.

  2. Install my application.

  3. Test my application.

  4. Restore from the Ghost image.

By following these steps, I ensure that I always have a “clean” machine on which to test my application. Obviously, it is imperative that you test all aspects of your application on the machine on which you performed the installation from your setup disks.

Tip

Several third-party software packages are available to help you to back up and restore your Windows installation easily. My favorite program is Ghost, available from Symantec.

When you are ready to test the Setup process, follow these steps:

  1. Select Run from the Windows Start menu.

  2. In the Run dialog box, locate the Setup files that the Deploy portion of the Packaging Wizard created. Click OK.

  3. After being notified of the setup’s progress, the Application Setup dialog box appears.

  4. Click OK to continue.

  5. Select a location for the application installation.

  6. Click the command button to install the application to the specified directory. The Choose Program Group dialog box appears. Select a program group and click Continue.

The installation process is completed. If you opted during the Packaging Wizard to create desktop shortcuts, they are created automatically when the Setup program is executed.

Looking at Other Issues

Two additional issues have not yet been covered regarding the distribution of your application. The first involves ensuring that the application database can establish any links that it has to external tables. The second involves the prospect of using replication to effectively distribute changes to your application.

Automating the Process of Linking to Tables

Access hard-codes locations for table links. This means that, if you install your application on another machine, the tables will not link successfully unless the other machine has exactly the same folder structure as you do on your machine. The code shown in Listing 32.4 checks to see whether the required tables are available. If they are not found in the expected location, the routine attempts to locate them in the same folder that holds them in the application database. If they still cannot be found, the user is given an opportunity to locate the files. If they still cannot be found, the application terminates.

Example 32.4. The LinkTables Routine

Sub LinkTables()
    On Error GoTo LinkTables_Err:

        Dim objFileDialog As FileDialog
        Dim strFileName As String

        'Determine if links are ok
        If Not VerifyLink Then

            'If links not ok, attempt to link with default file name
            'in the current folder
            If Not ReLink(CurrentProject.FullName, True) Then

                'If still unsuccessful, allow user to locate the data database
                MsgBox "You Must Locate Tables to Proceed" & vbCrLf & _
                    "The Tables are Located in the Chap32Data Database" & _
                    vbCrLf & _
                    "in the Directory Where You Placed the Sample Files"

                Set objFileDialog = Application.FileDialog(msoFileDialogOpen)

                With objFileDialog
                    .Show
                    .AllowMultiSelect = False
                    strFileName = .SelectedItems(1)
                End With

                'Attempt to relink with the database the user selected
                If Not ReLink(strFileName, False) Then

                    'If still unsuccessful, display message to the user and
                    'return false from this routine
                    MsgBox "You Cannot Run This App Without Locating Data Tables"
                    LinkTables = False
                Else

                    'User successfully designated new location; return True
                    LinkTables = True
                    End If
                Else

                    'Data database located with default name in the same location
                    'as the application database; return True
                    LinkTables = True
                End If
            Else

                'Table links not broken; return True
                LinkTables = True
            End If

        Exit Function

    LinkTables_Err:
        MsgBox "Error # " & Err.Number & ": " & Err.Description
        Exit Function

    End Sub
The LinkTables Routine

The routine begins by executing a function called VerifyLink. The VerifyLink function is shown in Listing 32.5 and is found in the FinalLibrary.MDA file on the sample code CD. It first creates an ADOX Catalog object. It sets the ActiveConnection property of the Catalog object to the Connection property of the CurrentProject. The CurrentProject object returns a reference to the database using the library, rather than to the library itself. The heart of the routine is the For...Next loop. It loops through each Table object in the Tables collection of the Catalog object. If the table is linked, it attempts to reference the first field in the table. If an error occurs, the table link must be broken. The error number is non-zero, and the routine exits the For...Next loop. Because the function returns whether or not the error number is equal to zero, False is returned if an error occurs, and True is returned if no error occurs.

Example 32.5. The VerifyLink Function

Function VerifyLink() As Boolean
    'Verify connection information in linked tables.

    'Declare Required Variables
    Dim cat As ADOX.Catalog
    Dim tdf As ADOX.Table
    Dim strTemp As String

     'Point Database object variable at the current database
     Set cat = New ADOX.Catalog

     With cat
         Set .ActiveConnection = CurrentProject.Connection

         'Continue if links are broken.
         On Error Resume Next

         'Open one linked table to see if connection
         'information is correct.
         'For Each tdf In .Tables
         '    If tdf.Type = "LINK" Then
         '        strTemp = tdf.Columns(0).Name
         '        If Err.Number Then
         '            Exit For
         '        End If
         '    End If

         'Next tdf

         'If code above is too slow, this is the
         'less conservative alternative
         For Each tdf In .Tables

             If tdf.Type = "LINK" Then
                 strTemp = tdf.Columns(0).Name
                 Exit For
             End If

           Next tdf


       End With

       VerifyLink = (Err.Number = 0)

End Function

If the VerifyLink function returns a False, the Relink function is executed. The Relink function is shown in Listing 32.6. It receives two parameters. The first parameter is the name of the database to which the function will attempt to link. The second parameter is a Boolean variable that designates whether the database is considered the default database.

The function begins by modifying the status bar. It then creates a Catalog object and an instance of a custom class called DBInfo. The ActiveConnection property of the Catalog object is set equal to the Connection property of the current project. Next the FullName property of the DBInfo class is set equal to the name of the file that is passed as a parameter to the function. The DBInfo class extracts the path and the filename from the full filename. Just as with the VerifyLink function, the ReLink function uses a For...Next loop. As it loops through each table in the database, it attempts to establish a link to a database with the name passed as a parameter to the Relink function.

This is where the DefaultData parameter comes into play. The first time that the LinkTables routine calls the Relink function, it passes the name and path of the application database as the first parameter, and True for the second parameter. The Relink function then attempts to link to a database located in the same folder as the application database, but with the word Data appended to the end of the filename. For example, if the application database is named Membership, the Relink function looks for a database called MembershipData in the same location as the application database. If it is successful, it returns True, and, if it is unsuccessful, it returns False. I use this method to attempt to re-establish the link because I commonly place both the application and data databases on a client’s network, both in the same folder. When I do this, I employ a naming convention where the data database has the same name as the application database, but with the word Data appended to it.

If no data database with the expected filename is found in the folder where the application database is located (False was returned from the Relink function), the LinkTables routine uses the FileDialog object to display a File Open dialog box. This gives the user the opportunity to locate the data database. The filename and path that the user selects in the dialog box is passed to the Relink routine, along with False as the second parameter. Because the user has selected the file that he believes contains the data, there is no reason to append the word Data onto the filename. Once again the Relink routine loops through the Tables collection of the Catalog object, attempting to re-establish the broken links. If successful, it returns True, and, if unsuccessful, it returns False. If False is returned from the second call to the Relink function, the LinkTables routine exits the Access application.

Example 32.6. The Relink Function

Function ReLink(strDir As String, DefaultData As Boolean) _
    As Boolean

    Dim cat As ADOX.Catalog
    Dim tdfRelink As ADOX.Table
    Dim oDBInfo As DBInfo
    Dim strPath As String
    Dim strName As String
    Dim intCounter As Integer
    Dim vntStatus As Variant

    'Update status bar
    vntStatus = SysCmd(acSysCmdSetStatus, "Updating Links")

    Set cat = New ADOX.Catalog
    Set oDBInfo = New DBInfo

    With cat

        'Use File Information class to extract the application
        'database file name
        .ActiveConnection = CurrentProject.Connection
        oDBInfo.FullName = strDir
        strPath = oDBInfo.FilePathOnly
        strName = Left(oDBInfo.FileName, InStr(oDBInfo.FileName, ".") - 1)

        'Disable error handling
        On Error Resume Next

        'Update progress meter
        Call SysCmd(acSysCmdInitMeter, "Linking Data Tables", .Tables.Count)

        'Loop through each table, attempting to relink
        For Each tdfRelink In .Tables
            intCounter = intCounter + 1
            Call SysCmd(acSysCmdUpdateMeter, intCounter)
            If .Tables(tdfRelink.Name).Type = "LINK" Then
                tdfRelink.Properties("Jet OLEDB:Link Datasource") = _
                    strPath & strName & IIf(DefaultData, "Data.Mdb", ".mdb")
           End If

           'If an error occurs, exit the loop
           If Err.Number Then
                Exit For
            End If
        Next tdfRelink
    End With

    'Remove the progress meter
    Call SysCmd(acSysCmdRemoveMeter)

    'Clear the status bar
    vntStatus = SysCmd(acSysCmdClearStatus)

    'Return whether or not an error occurred
    ReLink = (Err = 0)

End Function

Using Replication to Efficiently Distribute Your Application

You might not want to rebuild and redistribute Setup disks each time you change the design of your application database. Not only is this time-consuming, but also it is difficult to ensure that each user runs the Setup process in order to obtain the application database. If your organization is networked, it generally is much more effective to distribute application updates using replication. This involves making changes to the Design Master and then synchronizing with a hub after the changes are completed and tested properly. Replication is covered briefly in Chapter 20, “Developing Multiuser and Enterprise Applications,” and in detail in Alison Balter’s Mastering Access 2002 Enterprise Development.

Summary

The process of preparing an application for distribution actually starts in the planning stages of the application. It involves everything from providing a means by which the users of the application can navigate from task to task, to preparing the distribution disks. It also involves important steps such as properly securing the application to ensure that the integrity of its data and objects are maintained, and building in a solid error handler to ensure that all errors are handled gracefully. Remember that whether your users will be running your application using the retail or runtime version of Access, by using the techniques you learned in this chapter, you can add professional polish and pizzazz to any application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.28.36