Chapter 19. Using External Data

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

Why This Chapter Is Important

Microsoft Access is very capable of interfacing with data from other sources. It can use data from any OLEDB or ODBC data source, as well as data from FoxPro, dBASE, Paradox, Lotus, Excel, and many other sources. In this chapter, you will learn how to interface with external data sources, with the user interface, and by using code.

External data is data stored outside the current database. It can refer to data stored in another Microsoft Access database, as well as data stored in a multitude of other file formats—including ISAM, spreadsheet, ASCII, and more. This chapter focuses on accessing data sources other than ODBC and OLE DB data sources. ODBC and OLEDB data sources are discussed briefly in Chapter 20, “Developing Multiuser and Enterprise Applications.” They are covered in extensive detail in Alison Balter’s Mastering Access 2002 Enterprise Development.

Access is an excellent front-end product, which means that it provides a powerful and effective means of presenting data—even data from external sources. Data is stored in places other than Access for many reasons. Large databases, for example, can be managed more effectively on a back-end database server such as Microsoft SQL Server. Data often is stored in a FoxPro, dBASE, or Paradox file format because the data is being used by a legacy application written in one of those environments. Text data often has been downloaded from a mainframe. Regardless of the reason why data is stored in another format, it is necessary that you understand how to manipulate this external data in your VBA modules. With the capability to access data from other sources, you can create queries, forms, and reports.

When accessing external data, you have three choices. You can import the data into an Access database, access the data by linking to it from your Access database, or open a data source directly. Importing the data is the optimum route (except with ODBC data sources) but not always possible. If you can’t import external data, you should link to external files because Microsoft Access maintains a lot of information about these linked files. This optimizes performance when manipulating the external files. Sometimes a particular situation warrants accessing the data directly. You therefore should know how to work with linked files, as well as how to open and manipulate files directly.

Importing, Linking, and Opening Files: When and Why

When you import data into an Access table, a copy is made of the data and is placed in an Access table. After data is imported, it is treated like any other native Access table. In fact, neither you nor Access has any way of knowing from where the data came. As a result, imported data offers the same performance and flexibility as any other Access table.

Linking to external data is quite different from importing data. Linked data remains in its native format. By establishing a link to the external data, you can build queries, forms, and reports that present the data. After you create a link to external data, the link remains permanently established unless you explicitly remove it. The linked table appears in the database window just like any other Access table, except that its icon is different. In fact, if the data source permits multiuser access, the users of your application can modify the data as can the users of the applications written in the data source’s native database format (such as FoxPro, dBASE, or Paradox). The main difference between a linked and a native table is that you cannot modify the linked table’s structure from within Access.

Opening an external table is similar to linking to the table, except that a permanent relationship is not created. When you link to an external table, connection information is maintained from session to session. When you open a table, you create a recordset from the table, and no permanent link is established.

Selecting an Option

It is important that you understand when to import external data, when to link to external data, and when to open an external table directly. You should import external data in either of these circumstances:

  • You are migrating an existing system into Access.

  • You want to use external data to run a large volume of queries and reports, and you will not update the data. You want the added performance that native Access data provides.

When you are migrating an existing system to Access and you are ready to permanently migrate test or production data into your application, you import the tables into Access. You might also want to import external data if the data is downloaded from a mainframe into ASCII format on a regular basis, and you want to use the data for reports. Instead of attempting to link to the data and suffering the performance hits associated with such a link, you can import the data each time it is downloaded from the mainframe.

You should link to external data in any of the following circumstances:

  • The data is used by a legacy application requiring the native file format.

  • The data resides on an ODBC-compliant database server.

  • You will access the data on a regular basis (making it prohibitive to keep the data up-to-date if it is not linked).

Often, you won’t have the time or resources to rewrite an application written in FoxPro, Paradox, or some other language. You might be developing additional applications that will share data with the legacy application, or you might want to use the strong querying and reporting capabilities of Access instead of developing queries and reports in the native environment.

By linking to the external data, users of existing applications can continue to work with the applications and their data. Your Access applications can retrieve and modify data without concern for corrupting, or in any other way harming, the data.

If the data resides in an ODBC database such as Microsoft SQL Server, you want to reap the data-retrieval benefits provided by a database server. By linking to the ODBC data source, you can take advantage of Access’s ease of use as a front-end tool, while taking advantage of client/server technology.

Finally, if you intend to access data on a regular basis, linking to the external table instead of temporarily opening the table directly provides you with ease of use and performance benefits. After you create the link, in most cases, Access treats the table just like any other Access table.

You should open an external table directly in either of these circumstances:

  • You rarely need to establish a connection to the external data source.

  • You have determined that performance actually improves by opening the data source directly.

If you rarely need to access the external data, it might be appropriate to open it directly. Links increase the size of your MDB file. This size increase is not necessary if you rarely will access the data. Furthermore, in certain situations, when accessing ISAM (indexed sequential access method) data, you might find that opening the table directly provides better performance than linking to it.

Although this chapter covers the process of importing external data, this is essentially a one-time process and doesn’t require a lot of discussion. It is important to note, however, that after data is imported into an Access table, it no longer is accessed by the application in its native format. The majority of this chapter focuses on linking to or directly opening external data tables.

Looking at Supported File Formats

Microsoft Access enables you to import, link to, and open files in these formats:

  • Microsoft Jet databases (including previous versions of Jet)

  • Access projects (ADP and ADE files)

  • ODBC databases

  • HTML documents

  • XML documents (import and open only)

  • Microsoft Exchange/Outlook

  • dBASE III, dBASE IV, and dBASE 5.0

  • Paradox 3.x, 4.x, and 5.x

  • Microsoft Excel spreadsheets, versions 3.0, 4.0, 5.0, and 8.0

  • Lotus WKS, WK1, WK3, and WK4 spreadsheets (import and open only)

  • ASCII text files stored in a tabular format

Importing External Data

The process of importing external data is quite simple. You can import external data by using the user interface or by using VBA code. If you are planning to import the data only once or twice, you should use the user interface. If you are importing data on a regular basis (for example, from a downloaded mainframe file), you should write code that accomplishes the task transparently to the user.

Using the User Interface

To import an external data file using the user interface, follow these steps:

  1. Right-click anywhere within the database window.

  2. Choose Import (or choose File|Get External Data|Import). The Import dialog box appears, as shown in Figure 19.1.

    The Import dialog box.

    Figure 19.1. The Import dialog box.

  3. From the Files of Type drop-down list, select the type of file you are importing.

  4. Select the file you want to import and click Import.

  5. Depending on the type of file you select, the import process finishes, or you see additional dialog boxes. If you select Excel Spreadsheet, for example, the Import Spreadsheet Wizard appears, as shown in Figure 19.2. This wizard walks you through the process of importing spreadsheet data.

    The Import Spreadsheet Wizard.

    Figure 19.2. The Import Spreadsheet Wizard.

Caution

If you find that you can’t bring a large (4M–5M) text file directly into an Access database, change the text file into an Excel spreadsheet first and then import that file.

Using Code

The DoCmd object has three methods that assist you with importing external data. They are TransferDatabase, TransferText, and TransferSpreadsheet, each of which is covered in this section.

Importing Database Data Using Code

You use the TransferDatabase method of the DoCmd object to import data from a database such as FoxPro, dBASE, Paradox, or another Access database. Listing 19.1, included in basImport, shows an example that uses the TransferDatabase method.

Example 19.1. Using the TransferDatabase Method

Sub ImportDatabase()
  DoCmd.TransferDatabase _
    TransferType:=acImport, _
    DatabaseType:="dBASE III", _
    DatabaseName:= CurrentProject.Path, _
    ObjectType:=acTable, _
    Source:="Customer", _
    Destination:="tblCustomers", _
    StructureOnly:=False
End Sub

Note

This code and all the code in this chapter are located in the CHAP19EX.MDB file on the sample code CD-ROM.

Note

Table 19.1 lists the arguments for the TransferDatabase method.

Table 19.1. TransferDatabase Arguments

Argument

Specifies

TransferType

Type of transfer being performed.

DatabaseType

Type of database being imported.

DatabaseName

Name of the database. If the table is a separate file (as is the case with dBASE, Paradox, and earlier versions of FoxPro), the database name is the name of the directory that contains the table file. Do not include a backslash after the name of the directory.

ObjectType

Type of object you want to import. This argument is ignored for all but Access objects.

Source

Name of the object you are importing. Do not include the file extension.

Destination

Name of the imported object.

StructureOnly

Whether you want the structure of the table only or the structure and data.

StoreLogin

Whether you want to save the login ID and password for an ODBC database in the connection string for linked tables.

Importing Text Data Using Code

You use the TransferText method of the DoCmd object to import text from a text file. Listing 19.2 shows an example of this method.

Example 19.2. Using the TransferText Method

Sub ImportText()
  DoCmd.TransferText _
    TransferType:=acImportDelim, _
    TableName:="tblCustomerText", _
    FileName:=CurrentProject.Path & "Customer.Txt"
End Sub

Table 19.2 lists the arguments for the TransferText method.

Table 19.2. TransferText Arguments

Argument

Specifies

TransferType

Type of transfer you want to make.

SpecificationName

Name for the set of options that determines how the file is imported.

TableName

Name of the Access table that will receive the imported data.

FileName

Name of the text file to import from.

HTMTableName

Name of the table or list in the HTML file that you want to import or link to

CodePage

A long integer used to indicate the character set of the code page

HasFieldHeadings

Whether the first row of the text file contains field headings.

Importing Spreadsheet Data Using Code

You use the TransferSpreadsheet method of the DoCmd object to import data from a spreadsheet file. Listing 19.3 shows an example that uses the TransferSpreadsheet method.

Example 19.3. Using the TransferSpreadsheet Method

Sub ImportSpreadsheet()
  DoCmd.TransferSpreadsheet _
    TransferType:=acImport, _
    SpreadsheetType:=acSpreadsheetTypeExcel9, _
    TableName:="tblCustomerSpread", _
    FileName:=CurrentProject.Path & "Customer.Xls", _
    HasFieldNames:=True
End Sub

Table 19.3 lists the arguments for the TransferSpreadsheet method.

Table 19.3. TransferSpreadsheet Arguments

Argument

Specifies

TransferType

Type of transfer you want to make.

SpreadsheetType

Type of spreadsheet to import from. The default is Excel 3.0.

TableName

Name of the Access table that will receive the imported data.

FileName

Name of the spreadsheet file to import from.

HasFieldNames

Whether the first row of the spreadsheet contains field headings.

Range

Range of cells to import.

Creating a Link to External Data

If you need to keep the data in its original format but want to treat the data just like any other Access table, linking is the best solution. All the information required to establish and maintain the connection to the remote data source is stored within the linked table definition. You can create links through the user interface and by using code. This section covers both alternatives.

One of the most common types of links is a link to another Access table. This type of link is created so that the application objects (queries, forms, reports, macros, and modules) can be placed in a local database and the tables can be stored in another database on a file server. Numerous benefits are associated with such a configuration. Chapter 20 discusses these benefits in more detail.

Using the User Interface

It is very common to create a link using the user interface. If you know what links you want to establish at design time, this is probably the easiest way to establish links to external data. You can establish links using the Database Splitter or by establishing them manually.

Using the Database Splitter to Create Links

The Database Splitter was designed to split databases that already have been built with the tables and other database objects all in one physical MDB database file. It automates the process of moving the data tables to another database. The Database Splitter is covered in detail in Chapter 20.

Note

You can create links to tables only from an Access database, not from an Access project.

Creating Links to Access Tables

To create a link to an Access table, follow these steps:

  1. Right-click anywhere within the Database window.

  2. Choose Link Tables. The Link dialog box appears, as shown in Figure 19.3.

    The Link dialog box.

    Figure 19.3. The Link dialog box.

  3. Select the name of the database containing the table to which you want to link.

  4. Click the Link button. The Link Tables dialog box appears, as shown in Figure 19.4.

    The Link Tables dialog box.

    Figure 19.4. The Link Tables dialog box.

  5. Select the tables to which you want to establish a link.

  6. Click OK. The link process finishes. Notice the arrows in Figure 19.5, which indicate that the tblCustomer, tblOrders, and tblOrderDetails tables are linked tables instead of tables stored in the current database.

    Linked tables in the Database window.

    Figure 19.5. Linked tables in the Database window.

Creating Links to Other Types of Tables

The process of creating links to other types of database files is a little different. It works like this:

  1. Right-click anywhere within the Database window.

  2. Choose Link Tables. The Link dialog box appears.

  3. In the Files of Type drop-down list, select the type of table to which you are linking.

  4. Select the external file containing the data to which you will be linking.

  5. Click the Link button. The next dialog box varies, depending on the type of table to which you want to link. With a dBASE file, for example, the Select Index Files dialog box appears, as shown in Figure 19.6. It is important that you select any index files associated with the data file. These indexes are updated automatically by Access as you add, change, and delete table data from within Access.

    The Select Index Files dialog box.

    Figure 19.6. The Select Index Files dialog box.

  6. You receive a message indicating that the index was added successfully and that you can add other indexes if you choose. Click OK.

  7. Add any additional indexes and click Close.

  8. The Select Unique Record Identifier dialog box appears, as shown in Figure 19.7 (see Note below if the dialog doesn’t appear). This dialog box enables you to select a unique identifier for each record in the table. Select a unique field and click OK.

    The Select Unique Record Identifier dialog box.

    Figure 19.7. The Select Unique Record Identifier dialog box.

Note

You must install the Jet 4.0 Service Pack 5 or have the BDE (Borland Database Engine) for the Select Unique Record Identifier dialog box to appear. If you do not have one of these tools, the data in the database cannot be edited. For more information, see the Microsoft knowledge base article Q283294.

Notice the icon indicating the type of file you linked to, as shown in Figure 19.8.

An icon indicating that the file database is linked to a dBASE database file.

Figure 19.8. An icon indicating that the file database is linked to a dBASE database file.

Note

Earlier versions of Access supported links to FoxPro files using the FoxPro ISAM driver. With Jet 4.0, you must link to FoxPro tables using the Visual FoxPro ODBC Driver.

Using Code

Creating a link to an external table using code is a six-step process. Here are the steps involved in establishing the link:

  1. Create a reference to the Microsoft ADO Extension 2.6 for DDL and Security (ADOX) library.

  2. Create a Catalog object.

  3. Set the Connection property of the Catalog object to the database that will contain the linked table.

  4. Create a new Table object.

  5. Set properties of the Table object.

  6. Append the Table object to the Catalog.

Listing 19.4 shows the code for linking to an external table, which, in this case, exists in another Microsoft Access database.

Example 19.4. Linking to an External Table

Sub LinkToAccessTableProps()
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.Table

    'Instantiate a Catalog Object
    Set cat = New ADOX.Catalog

    'Set the connection of the Catalog object
    'to the connection associated with the current
    'project
    cat.ActiveConnection = CurrentProject.Connection

    'Instantiate a table object
    Set tbl = New ADOX.Table

    'Establish the name of the new table object
    tbl.Name = "tblLinkedTable"

    'Point the catalog of the new table at the
    'catalog object established above
    Set tbl.ParentCatalog = cat

    'Set necessary properties of the new table object
    tbl.Properties("Jet OLEDB:Create Link") = True
    tbl.Properties("Jet OLEDB:Link Datasource") = _
        CurrentProject.Path & "Chap19Data.mdb"
    tbl.Properties("Jet OLEDB:Link Provider String") = ";pwd=password"
    tbl.Properties("Jet OLEDB:Remote Table Name") = "tblClients"

    'Append the new table object to the tables collection
    'of the catalog object
    cat.Tables.Append tbl
End Sub

In Listing 19.4, a Catalog object is created. The ActiveConnection property of the Catalog object is pointed at the connection associated with the current database. Next, a Table object is created. The Name property of the Table object is set equal to tblLinkedTable. The ParentCatalog property of the Table object is set to point at the Catalog object. Four properties in the properties collection of the Table object are set to the appropriate values, and the Table object is appended to the Catalog object. This process is discussed in further detail in the following sections.

Providing Connection Information

When you link to an external table, you must provide information about the type, name, and location of the external database. This is accomplished by setting the following properties in the Properties collection of the Table object:

  • Jet OLEDB:Link Provider String

  • Jet OLEDB:Remote Table Name

  • Jet OLEDB:Link Datasource

The following three lines of code illustrate the process of setting the provider string, name, and location of the source table:

tbl.Properties("Jet OLEDB:Link Provider String") = ";pwd=password"
tbl.Properties("Jet OLEDB:Remote Table Name") = "tblClients"
tbl.Properties("Jet OLEDB:Link Datasource") = CurrentProject.Path &
"Chap19Data.mdb"

The Jet OLEDB:Link Provider is the ISAM format that will be used for the link. Each source database type is a different folder in the Windows registry. The folders are located in the HKEY_LOCAL_MACHINESOFTWAREMicrosoftJet4.0ISAM Formats section of the registry. Valid source database types are as follows:

dBASE

dBASE III, dBASE IV, and dBASE 5.0

Excel

Excel 3.0, Excel 4.0, Excel 5.0, and Excel 8.0

HTML

HTML Export and HTML Import

Jet

Jet 2.x, Jet 3.x

Lotus

Lotus WK1, Lotus WK3, Lotus WK4, Lotus WJ2, and Lotus WJ3

Exchange

Exchange 4.0

Outlook

Outlook 9.0

Paradox

Paradox 3.x, Paradox 4.x, Paradox 5.x, and Paradox 7.x

Text

N/A

The Jet OLEDB:Link Datasource must include a fully qualified path to the file. You can specify the path with a drive letter and directory path or by using universal naming conventions (UNCs). For a local database, you must specify the path like this:

tbl.Properties("Jet OLEDB:Link Datasource") = "c:DatabasesChap19Data"

For a file server, you can specify the UNC path or the drive letter path. The UNC path looks like this:

tbl.Properties("Jet OLEDB:Link Datasource") = _
    "\FILESERVERNAMEDatabasesChap19Data"

In this case, the database called Chap19Data is stored on the databases share of a particular file server.

Creating the Link

Listing 19.5 shows how you put all the connection information together to establish a link to an external table.

Example 19.5. Establishing a Link to an External Table

Sub LinkToDBase(strDirName As String, strTableName As String, _
   strAccessTable)
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.Table

    'Instantiate a Catalog object
    Set cat = New ADOX.Catalog
    cat.ActiveConnection = CurrentProject.Connection

    'Instantiate a Table object
    Set tbl = New ADOX.Table
    tbl.Name = strAccessTable
    Set tbl.ParentCatalog = cat

    'Set necessary properties of the new Table object
    tbl.Properties("Jet OLEDB:Create Link") = True
    tbl.Properties("Jet OLEDB:Link Datasource") = strDirName
    tbl.Properties("Jet OLEDB:Link Provider String") = & _
    "dBASE III;HDR=NO;IMEX=2;"
    tbl.Properties("Jet OLEDB:Remote Table Name") = strTableName

    'Append the new table object to the tables collection
    'of the catalog object
    cat.Tables.Append tbl
End Sub

Here is an example of how this subroutine is called:

Call LinkToDBase("c:customerdata","customer","tblCustomers")

The LinkToDBase subroutine receives three parameters:

  • The name of the directory in which the dBASE file is stored.

  • The name of the file (the name of the table, without the DBF extension) to which you want to connect.

  • The name of the Access table that you are creating.

The subroutine creates two object variables: a Catalog object variable and a Table object variable. It points the ActiveConnection property of the Catalog object variable at the connection associated with the current database. Next, it establishes properties of the Table object. The Link Datasource is the name of the directory within which the dBASE file is stored. The Link Provider String specifies that the type of table you are linking to is a dBASE III file. The Remote Table Name is the name of the dBASE file that you are linking to. After setting these properties, you are ready to append the table definition to the database.

You have seen how you can link to a dBASE table. Listing 19.6 puts together everything you have learned thus far in this chapter by creating a link to an Access table stored in another database.

Example 19.6. Creating a Link to an Access Table Stored in Another Database

Sub LinkToAccess(strDBName As String, strTableName As String, _
   strAccessTable)
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.Table

    'Instantiate a Catalog object
    Set cat = New ADOX.Catalog

    'Set the ActiveConnection property of the Catalog object
    'to the connection associated with the current project
    cat.ActiveConnection = CurrentProject.Connection

    'Instantiate a Table object
    Set tbl = New ADOX.Table

    'Set the Name property of the Table object to the name
    'you wish to give to the linked table
    tbl.Name = strAccessTable

    'Set the ParentCatalog property of the Table object
    'to the Catalog object
    Set tbl.ParentCatalog = cat

    'Set all necessary properties of the Table object
    tbl.Properties("Jet OLEDB:Create Link") = True
    tbl.Properties("Jet OLEDB:Link Datasource") = strDBName
    tbl.Properties("Jet OLEDB:Link Provider String") = ";pwd=password"
    tbl.Properties("Jet OLEDB:Remote Table Name") = strTableName

    'Append the Table object to the Tables collection
    'associated with the CatalogObject
    cat.Tables.Append tbl
End Sub

Notice that the Jet OLEDB Link Provider string no longer specifies the type of database to which you are connecting. Everything else in this routine is the same as the routine that connected to dBASE. Also, notice the parameters passed to this routine:

Call LinkToAccess("C:databases
orthwind.mdb","Customers","tblCustomers")

The database passed to the routine is an actual Access database (as opposed to a directory), and the table name is the name of the Access table in the other database (instead of the DBF filename).

Note

Whether you link to an external database using the user interface or code, you should always use the UNC path, rather than a drive letter. This ensures that all users with access to the network share are able to see the data, regardless of their drive letter mappings.

Opening an External Table

There are times when you will want to open—rather than link to—an external table. Linking provides ease of use when dealing with external tables. After you link to a table, it is treated just like any other Access table. The disadvantage of linking is that it uses ODBC. ODBC is not the most efficient means of interacting with a database for which you have a native OLEDB provider. Therefore, you might want to programmatically open an external table without creating a link to it. Opening an external table is a two-step process:

  1. Establish a connection to the external data source.

  2. Point a Recordset object at the result of executing a SQL statement against the Connection object.

Providing Connection Information

The connection information you provide when you open an external table is similar to the information you provide when you link to the table. The connection information is provided as the ConnectionString argument of the Open method of the Connection object. Here’s an example:

cnn.Open "Providersqlodedb;" & _
        "Data Source=(local);" & _ _
        "Initial Catalog=Pubs;" & _
        "User ID=sa;Password=;"

Here, the connection string is to the SQL Server database called Pubs on the local machine.

Opening the Table

The Recordset object is pointed at the result of executing a Select statement against the Connection object:

Set rst = cnn.EXEcute("Select * from Authors")

Listing 19.7 shows what the entire process looks like in code.

Example 19.7. Using the OpenDatabase Method

Sub OpenExternalSQL(strDBName As String, strTableName As String)
    Dim cnn As ADODB.Connection
    Dim rst As ADODB.Recordset

    'Instantiate Connection and Recordset objects
    Set cnn = New ADODB.Connection
    Set rst = New ADODB.Recordset

    'Use the Open method of the Connection object to establish
    'a connection to the SQL Server database
    cnn.Open "Provider=sqloledb;" & _
        "Data Source=(local);" & _
        "Initial Catalog=" & strDBName & ";" & _
        "User Id=sa;Password=; "


    'Use the Execute method of the Connection object to execute
    'a Select statement and return the result as a Recordset
    Set rst = cnn.Execute("Select * from " & strTableName)

    'Loop through the resulting recordset,
    'printing the value of the first field
    Do Until rst.EOF
        Debug.Print rst.Fields(0).Value
        rst.MoveNext
    Loop

    'Close the Connection
    cnn.Close
End Sub

Listing 19.7 is called with this code:

Call OpenExternalSQL("Pubs","authors")

Notice that you are not appending a table definition here. Instead, you are creating a temporary recordset that refers to the external data. After the external table is opened as a recordset, the code traverses through each record of the table, printing the value of the first field. Of course, after the recordset is opened, you can manipulate it in any way you want. The table does not show up as a linked table in the database window. In fact, when the routine completes and the local variable goes out of scope, the recordset no longer exists.

Now that you have seen how you can link to external tables as well as open them, you are ready to take a look at how you can refine both these processes. This involves learning the Windows registry settings that affect the linking process, learning more about the parameters that are available to you when specifying connection information, learning how to specify passwords, learning how to refresh and remove links, and learning how to create an external table using VBA code.

Understanding Windows Registry Settings

Each ISAM driver has a separate key in the Windows registry. These keys are located in the appropriate ISAM driver in the HKEY_LOCAL_MACHINESOFTWAREMicrosoftJet4.0ISAM Formats section of the registry. These keys are used to configure the driver after initialization. As you can see in Figure 19.9, the setup program has created keys for several data sources. If you look at a specific data source (in this case, dBASE III), you can see all the settings that exist for the dBASE driver. The IndexFilter is set to dBASE Index(*.ndx), for example. At times, you will need to modify one of the registry settings to customize the behavior of the ISAM driver; this is covered later in this chapter in the section “Looking at Special Considerations.”

The Windows registry with keys for ISAM drivers.

Figure 19.9. The Windows registry with keys for ISAM drivers.

Using the Jet OLEDB:Link Provider String

The Jet OLEDB:Link Provider String is used when linking to external tables. It includes the source database type, user ID, and password. A semicolon must be used to separate each part of the connection string.

Each source database type has a valid name. This is the name that must be used when accessing that type of data. These database types are found in the Windows registry under HKEY_LOCAL_MACHINESoftwareMicrosoftJet4.0ISAM Formats. You must accurately specify the source database type, or you will be unable to access the external data.

The user ID is used whenever a username must be specified in order to successfully log on to the data source. This is most common when dealing with back-end databases such as Oracle, Sybase, or Microsoft SQL Server. This part of the provider string can be required to log on the user to the system where the source data resides. The UID keyword refers to the user ID.

As with the user ID, the password most often is included when dealing with back-end data. It also can be used on other database types that support passwords, such as Paradox, or when linking to an external Access table. The PWD keyword is used when specifying the password.

Finally, the dataset name refers to a defined ODBC data source. The DSN keyword refers to the dataset name in the connection string. The following is an example of a Jet OLEDB Link Provider String:

tbl.Properties("Jet OLEDB:Link Provider String") = "ODBC" & _
        ";DATABASE=Pubs" & _
        ";UID=Alison" & _
        ";PWD=MyPass" & _
        ";DSN=PublisherData"

In the example, the SQL Server database being accessed is Pubs, the user ID is Alison, the Password is MyPass, and the data source name is PublisherData.

Working with Passwords

In working with passwords, you probably won’t want to hard-code the password into your application because that defeats the purpose of placing a password on your database. In Listing 19.8, the database’s password is included in the code, allowing the link to be made to the secured table without any password validation.

Example 19.8. Embedding a Database Password in Code

Sub LinkToSecured()
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.Table
    'Instantiate a Catalog object
    Set cat = New ADOX.Catalog

    'Set the ActiveConnection property of the Catalog
    'object to the connection associated with the
    'current project
    cat.ActiveConnection = CurrentProject.Connection

    'Instantiate a Table object
    Set tbl = New ADOX.Table

    'Set the Name property of the Table object
    tbl.Name = "tblLinkedTable"

    'Associate the ParentCatalog of the Table object
    'with the Catalog object
    Set tbl.ParentCatalog = cat

    'Set properties of the Table object
    tbl.Properties("Jet OLEDB:Create Link") = True
    tbl.Properties("Jet OLEDB:Link Provider String") = "ODBC" & _
        ";DATABASE=Pubs" & _
        ";UID=SA" & _
        ";PWD=" & _
        ";DSN=PublisherData"
    tbl.Properties("Jet OLEDB:Remote Table Name") = "Authors"

    'Append the Table object to the Tables collection
    'associated with the Catalog object
    cat.Tables.Append tbl
End Sub

An invalid password results in a message appearing, requiring the user to log on. Unless you are using integrated Windows NT security to log on to your database server, it is best to require the user to supply the password at runtime. In Listing 19.9, the code prompts the user for a password. The password entered by the user is used as part of the connection string.

Example 19.9. Requiring Password Validation

Sub ReallySecure()
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.Table
    Dim strPassword As String
    'Instantiate a Catalog object
    Set cat = New ADOX.Catalog

    'Set the ActiveConnection property of the Catalog
    'object to the connection associated with the
    'current project
    cat.ActiveConnection = CurrentProject.Connection

    Set tbl = New ADOX.Table

    'Set the Name property of the Table object
    tbl.Name = "tblLinkedTable"

    'Associate the ParentCatalog of the Table object
    'with the Catalog object
    Set tbl.ParentCatalog = cat

    'Prompt the user for the password
    strPassword = InputBox("Please Enter Your Password", "Database" & _
    "Security!!!")

    'Set properties of the Table object
    tbl.Properties("Jet OLEDB:Create Link") = True
    tbl.Properties("Jet OLEDB:Link Provider String") = "ODBC" & _
        ";DATABASE=Pubs" & _
        ";UID=SA" & _
        ";PWD=" & strPassword & _
        ";DSN=PublisherData"
    tbl.Properties("Jet OLEDB:Remote Table Name") = "Authors"

    'Append the Table object to the Tables collection
    'associated with the Catalog object
    cat.Tables.Append tbl
End Sub

Notice that the password is retrieved from the user and stored in a variable called strPassword. This strPassword variable is included in the connection string at runtime.

Refreshing and Removing Links

Refreshing links refers to updating the link to an external table. It is done when the location of an external table has changed. Removing links refers to permanently removing a link to an external table.

Access cannot find external tables if their locations have moved. You need to adjust for this in your VBA code. Furthermore, there might be times when you want to remove a link to external data—when it is no longer necessary to use the data, or when the data has been imported permanently into Access.

Updating Links That Have Moved

To refresh a link using VBA code, simply redefine the Jet OLEDB:Link Datasource. Listing 19.10 shows the code to refresh a link.

Example 19.10. Refreshing a Link

Sub RefreshLink()
    Dim cat As ADOX.Catalog
    Dim tdf As ADOX.Table

    Set cat = New ADOX.Catalog
    Set cat.ActiveConnection = CurrentProject.Connection
    tdf.Properties("Jet OLEDB:Link Datasource") = _
        strNewLocation
End Sub

You can modify this routine to prompt the user for the directory containing the data tables, as Listing 19.11 shows.

Example 19.11. Prompting the User for the Database Path and Name

Sub RefreshLink()
    'Initiate error handling
    On Error GoTo RefreshLink_Err
    Dim cat As ADOX.Catalog
    Dim tdf As ADOX.Table
    Dim strNewLocation As String
    Dim strTemp As String

    'Instantiate a Catalog object
    Set cat = New ADOX.Catalog

    'Set the ActiveConnection property of the Catalog
    'object to the connection associated with the
    'current project
    Set cat.ActiveConnection = CurrentProject.Connection
    'Point the TableeDef object at the tblClients table
    Set tdf = cat.Tables("tblClients")

    'Attempt to retrieve the Name property of the table
    strTemp = tdf.Columns(0).Name

    'Exit the routine if all goes well
    Exit Sub

RefreshLink_Err:

    'If an error occurs, prompt the user for the new name
    'and location
    strNewLocation = InputBox("Please Enter Database Path and Name")

    'Set the properties of the TableDef object to the
    'information provided by the user
    tdf.Properties("Jet OLEDB:Link Datasource") = _
        strNewLocation
    Set cat.ActiveConnection = CurrentProject.Connection
    Set tdf = cat.Tables("tblClients")

    'Try to grab the name property again
    Resume
End Sub

This routine points a Table object to the tblClients table. It then attempts to access the name of the first column in the table. If an error occurs, an input box prompts the user for the new location of the database. The Jet OLEDB:Link Datasource property for the database is modified to incorporate the new location. The code then resumes on the offending line of code. You should modify this routine to give the user a way out. Resume throws the user into an endless loop if the database is not available. An enhanced routine (see Listing 19.13) is presented later in the “Practical Examples” section of this chapter.

Deleting Links

To remove a link using VBA code, simply execute a Delete method of the Tables collection of a Catalog object connected to the database, as shown in Listing 19.12.

Example 19.12. Removing a Link

Sub RemoveLink()
    Dim cat As Catalog

    Set cat = New ADOX.Catalog
    cat.ActiveConnection = CurrentProject.Connection

    cat.Tables.Delete ("tblClients")

End Sub

Looking at Special Considerations

When dealing with different types of external files, various problems and issues arise. If you understand these stumbling blocks before they affect you, you will get a great head start in dealing with these potential obstacles.

dBASE

The major concerns you will have when dealing with dBASE files surround deleted records, indexes, data types, and memo fields. When you delete a record from a dBASE table, it is not actually removed from the table. Instead, it is just marked for deletion. You must Pack the database (a process in a dBASE table that removes deleted rows) must be completed in order for the records to actually be removed from the table. If records are deleted from a dBASE table using an Access application, the records are not removed. Because you cannot pack a dBASE database from within an Access application, the records still remain in the table. In fact, they are not automatically filtered from the Access table. In order to filter deleted records so that they cannot be seen within the Access application, the Deleted value in the HKEY_LOCAL_MACHINESOFTWAREMicrosoftJet4.0EnginesXbase section of the registry must be set to 01 (True).

Access can use the dBASE indexes to improve performance (Jet 4.0 Service Pack 5 the Borland Database Engine must be installed). After you link to a dBASE table and select an index, an INF file is created. This file has the same name as your dBASE database with an INF extension. It contains information about all the indexes being used. Here’s an example of an INF:

[dBASE III]
NDX1=CUSTID.NDX
UNDX1=CUSTID.NDX

dBASE III is the database type identifier. NDX1 is an index number for the first index. The UNDX1 entry specifies a unique index.

The data types available in dBASE files are different from those available in Access files. It is important to understand how the field types are mapped. Table 19.4 shows how each dBASE data type is mapped to a Jet data type.

Table 19.4. Mapping of dBASE Data Types

dBASE Data Type

Jet Data Type

Character

Text

Numeric, Float

Double

Logical

Boolean

Date

Date/Time

Memo

Memo

OLE

OLE Object

Finally, make sure that the dBASE memo files are stored in the same directory as the table. Otherwise, Access is unable to read the data in the memo file.

Text Data

When linking to an ASCII text file, Jet can determine the format of the file directly, or it can use a schema information file, which resides in the same directory as the text file. It always is named SCHEMA.INI, and it contains information about the format of the file, the column names, and the data types. The schema information file is optional for delimited files, but it is required for fixed length files. It is important to understand that ASCII files can never be opened for shared use.

Troubleshooting

Unfortunately, working with external data is not always a smooth process. Many things can go wrong, including connection problems and a lack of temporary disk space.

Connection Problems

Difficulties with accessing external data can be caused by any of the following circumstances:

  • The server on which the external data is stored is down.

  • The user does not have rights to the directory in which the external data is stored.

  • The user does not have rights to the external data source.

  • The external data source was moved.

  • The UNC path or network share name was modified.

  • The connection string is incorrect.

  • The installable ISAM driver has not been installed.

Temp Space

Access requires a significant amount of disk space in order to run complex queries on large tables. This disk space is required whether the tables are linked tables stored remotely in another format, or they reside on the local machine. The application behaves unpredictably if not enough disk space is available to run the query. It therefore is necessary to make sure that all users have enough disk space to meet the requirements of the queries that are run.

Looking at Performance Considerations and Links

Because your application has to go through an extra translation layer, the installable ISAM, performance is not nearly as good with ISAM files as it is with native Jet data. It always is best to import ISAM data whenever possible. If it is not possible to import the data, you need to accept the performance that linking offers or consider linking the best solution to an otherwise unsolvable problem.

Working with HTML Documents

Access 2002 enables you to import, export, and link to HTML documents. Although working with HTML documents is similar to working with other files types, HTML documents deserve special mention. To import an HTML document, follow these steps:

  1. Right-click anywhere within the Database window and choose Import.

  2. From the Files of Type drop-down list, select HTML Documents.

  3. Select the document you want to import and click Import. The Import HTML Wizard appears, as shown in Figure 19.10.

    The first step of the Import HTML Wizard.

    Figure 19.10. The first step of the Import HTML Wizard.

  4. The first step of the wizard attempts to parse the HTML document into fields. You can accept what the wizard has done or click Advanced. The Import Specification dialog box that appears enables you to designate field names, data types, and indexes for each field; and to select any fields you want to eliminate from the imported file. (See Figure 19.11.) This dialog box also enables you to modify the date order, date delimiter, and more.

    The Import Specification dialog box enables you to designate the specifics of the import.

    Figure 19.11. The Import Specification dialog box enables you to designate the specifics of the import.

  5. After you make any required changes to the import specifications, click OK to return to the Import HTML Wizard. Click Next to advance to the next step of the wizard, which enables you to select whether the imported data is stored in a new table or in an existing table. Make your selection and then click Next.

  6. Designate a field name, data type, and index for each field, as shown in Figure 19.12. Make any desired changes here and click Next.

    Customizing the properties of each imported field.

    Figure 19.12. Customizing the properties of each imported field.

  7. The fourth step of the wizard enables you to indicate that you want Access to add a primary key to the table, that you want to select your own primary key, or that you don’t want the imported table to have a primary key. Make your selection and click Next.

  8. The final step of the wizard enables you to assign a name to the table. You even can have the wizard analyze the table after importing it. Click Finish after you make your selection.

Not only can you import an HTML document, but you also can link to one. To link to an HTML document, follow these steps:

  1. Right-click anywhere within the Database window and choose Link Tables.

  2. From the Files of Type drop-down list, select HTML Documents.

  3. Select the table you want to link to and click Link. The Link HTML Wizard appears.

  4. Click the Advanced button to modify any link specifications and return to the first step of the wizard. Click Next to move to the second step of the wizard.

  5. Specify information about each field you are linking to. Make any required changes and click Next.

  6. Supply a name for the linked table and click Finish.

Whereas an imported HTML document acts like any other Access table, the data in a linked HTML document cannot be modified from within Access. You can use the linked document to create queries, reports, and forms.

Splitting the Database Using the Database Splitter

Begin by using the Database Splitter (covered in Chapter 20, “Developing Multiuser and Enterprise Applications”) to separate the tables from the rest of the database objects. The CHAP19EX.MDB and CHAP19DATA.MDB files are included on the sample code CD-ROM. The CHAP19DATA.MDB file contains all the tables, and CHAP19EX.MDB contains the rest of the database objects.

Splitting the Database Using the Database Splitter

Refreshing Links

If you distribute your application and all users did not have the same path to the CHAP19DATA.MDB file, the application would not load successfully. The LinkTables routine, located in the Switchboard startup form, ensures that the tables are successfully linked, as Listing 19.13 shows.

Example 19.13. Loading the Application and Checking Table Attachments

Sub LinkTables()
    Dim objFileDialog As FileDialog

    On Error GoTo LinkTables_Err:

    DoCmd.Hourglass True

    'Determine if links are ok
    If Not VerifyLink Then

        'If not ok, attempt to relink with expected file name
        If Not ReLink(CurrentProject.FullName, True) Then

            'If still not ok, ask user to locate file
            Set objFileDialog = FileDialog(msoFileDialogOpen)

            With objFileDialog
                .AllowMultiSelect = False
                .Show
            End With

            'Attempt to link to file that user selected
            If Not ReLink(objFileDialog.SelectedItems(1), False) Then

                'If not successful, display a message a quit app
                MsgBox "You Cannot Run This App Without " & _
                   "Locating Data Tables"
                DoCmd.Close acForm, "frmSplash"
                DoCmd.Quit
            End If
        End If
    End If

    DoCmd.Hourglass False
    Exit Sub

LinkTables_Err:
    DoCmd.Hourglass False
    MsgBox "Error # " & Err.Number & ": " & Err.Description
    Exit Sub
End Sub

Notice that the VerifyLink routine is called from the LinkTables routine. The VerifyLink routine appears in Listing 19.14.

Example 19.14. The VerifyLink Routine Tests to See Whether Any Table Links Are Broken

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
    End With

    VerifyLink = (Err.Number = 0)

End Function

The routine begins by pointing the ActiveConnection property of the Catalog object to the connection associated with the current database. It then loops through each table in the Tables collection of the Catalog object. If the table is a linked table, it attempts to access the name of the first column in the table. If any of the links are broken, an error occurs, and the For...Each loop is exited. If no error occurs, the function returns True; otherwise, the function returns False.

If the VerifyLink routine returns False, the ReLink routine is called. Listing 19.15 shows the ReLink routine.

Example 19.15. The ReLink Routine Attempts to Re-establish the Broken Links

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

    ' Relink a broken linked Access table.

    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

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

    Set cat = New ADOX.Catalog

    'Instantiate database information class
    Set oDBInfo = New DBInfo
    With cat
        .ActiveConnection = CurrentProject.Connection

        'Extract the name and path from the passed database
        oDBInfo.FullName = strDir
        strPath = oDBInfo.FilePathOnly
        strName = Left(oDBInfo.FileName, InStr(oDBInfo.FileName, ".") - 1)

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

        'Loop through each table, attempting to update the link
        For Each tdfRelink In .Tables
            intCounter = intCounter + 1
            Call SysCmd(acSysCmdUpdateMeter, intCounter)
            If .Tables(tdfRelink.Name).Type = "LINK" And _
                Left(tdfRelink.Name, 3) = "tbl" Then
                tdfRelink.Properties("Jet OLEDB:Link Datasource") = _
                strPath & strName & IIf(DefaultData, "Data.Mdb", ".mdb")
           End If
           If Err.Number Then
                Exit For
            End If
        Next tdfRelink
    End With

    'Reset the progress meter
    Call SysCmd(acSysCmdRemoveMeter)

    vntStatus = SysCmd(acSysCmdClearStatus)

    ReLink = (Err = 0)
End Function

The ReLink function receives two parameters. The first parameter is the name of the database the function will attempt to link to. 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. This custom class is covered in further detail in Chapter 32, “Distributing Your Application.” Class modules are covered in Chapter 13, “Exploiting the Power of Class Modules.” 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 to loop through all the tables in the database. As it loops through each table, it attempts to establish a link to a database with the name passed as parameter to the ReLink function.

This ReLink function is called twice from the LinkTables routine, shown in Listing 19.13. The first time it is passed, the FullName property of the CurrentProject object and the boolean is True, indicating that it will try to locate the table in a database with the same location as the application database. If that attempt is not successful, the LinkTables routine uses the FileDialog object to display the File Open dialog, allowing the user to attempt to locate the database. The ReLink function is called again, searching for the table in the database selected by the user. If it is still unsuccessful, the routine quits the application.

Summary

The capability to link to external data is one of Access 2002’s strongest attributes. It is important that you understand how to link to external data via the user interface and by using VBA code. This chapter taught you how to link to external tables, open external data sources directly, refresh and remove links, and create external tables using VBA code. Many of the techniques covered in this chapter are covered extensively in Alison Balter’s Mastering Access 2002 Enterprise Development.

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

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