Icon Setting Master-Detail Links on Tables

Introduction
A master-detail link is a property-based linkage between a master TDataSource component and a detail TDBISAMTable component. Once a master-detail link is established, any changes to the master TDataSource component will cause the detail TDBISAMTable component to automatically reflect the change and show only the detail records that match the current master record based upon the link criteria. Master-detail links use ranges for their functionality, and therefore are dependent upon the active index in the detail table. Like ranges, master-detail links may be combined with expression filters set using the Filter and Filtered propertes and/or callback filters set using the OnFilterRecord event to further filter the records in the detail table.

Defining the Link Properties
Setting master-detail links on tables is accomplished through four properties in the detail TDBISAMTable component. These properties are the MasterSource, MasterFields, IndexName, and IndexFieldNames properties.

The first step in setting a master-detail link is to assign the MasterSource property. The MasterSource property refers to a TDataSource component. This makes master-detail links very flexible, because the TDataSource component can provide data from any TDataSet-descendant component such as a TDBISAMTable or TDBISAMQuery component as well as many other non-DBISAM dataset components.

Information For the link to be valid, the TDataSource DataSet property must refer to a valid TDataSet-descendant component.

The next step is to assign the IndexName property, or IndexFieldNames property, so that the active index, and the fields that make up that index, will match the fields that you wish to use for the link. The only difference between specifying the IndexName property versus the IndexFieldNames property is that the IndexName property expects the name of an index, whereas the IndexFieldNames only expects the names of fields in the table that match the fields found in an index in the table from left-to-right. The IndexFieldNames property also does not require that all of the fields in an existing index be specified in order to match with that existing index, only enough to be able to select the index so that it will satisfy the needs of the master-detail link.

Finally, the MasterFields property must be assigned a value. This property requires a field or list of fields separated by semicolons from the master data source that match the fields in the active index for the detail table.

To illustrate all of this we'll use an example. Let's suppose that we have two tables with the following structure and we wish to link them via a master-detail link:

Customer Table

Field #    Name              DataType     Size
----------------------------------------------
1          CustomerID        ftString     10
2          CustomerName      ftString     30
3          ContactName       ftString     30
4          Phone             ftString     10
5          Fax               ftString     10
6          EMail             ftString     30

Information Indexes in this case are not important since this will be the master table

Orders Table

Field #    Name              DataType     Size
----------------------------------------------
1          CustomerID        ftString     10
2          OrderNumber       ftString     10
3          OrderDate         ftDate       0
4          OrderAmount       ftBCD        2

   
Index Name      Fields In Index             Options
------------------------------------------------------
(none)          CustomerID;OrderNumber      ixPrimary

We would use the following example code to establish a master-detail link between the two tables. In this example it is assumed that a TDataSource component called CustomerSource exists and points to a TDBISAMTable component for the "customer" table:

begin
   with OrdersTable do
      begin
      { Select the primary index, which contains the
        CustomerID and OrderNumber fields }
      IndexName:='';
      { Assign the MasterSource property }
      MasterSource:=CustomerSource;
      { Set the MasterFields property to point to the
        CustomerID field from the Customer table }
      MasterFields:='CustomerID';
      end;
end;

Now any time the current record in the CustomerSource data source changes in any way, the OrdersTable will automatically reflect that change and only show records that match the master record's CustomerID field. Below is the same example, but changed to use the IndexFieldNames property instead:

begin
   with OrdersTable do
      begin
      { Select the primary index, which contains the
        CustomerID and OrderNumber fields }
      IndexFieldNames:='CustomerID';
      { Assign the MasterSource property }
      MasterSource:=CustomerSource;
      { Set the MasterFields property to point to the
        CustomerID field from the Customer table }
      MasterFields:='CustomerID';
      end;
end;

Information Because a master-detail link uses data-event notification in the TDataSource component for maintaining the link, if the TDataSet component referred to by the TDataSource component's DataSet property calls its DisableControls method, it will not only disable the updating of any data-aware controls that refer to it, but it will also disable any master-detail links that refer to it also. This is the way the TDataSet and TDataSource components have been designed, so this is an expected behavior that you should keep in mind when designing your application.
Image