Appending to Multiple Files in Format Screens by PAUL MAHAR 

 The evolution towards true multiple-record appending climbs another rung.
While dBASE IV allows extremely easy creation of complex data entry screens
with no programming, it does not contain any built-in menus for creating
data entry screens for multiple databases. dBASE IV version 1.5 introduced
the ability for format to edit records from more than one database,
enabling you to APPEND to one of the files. However, some business
applications require data entry across multiple files. For example, an
invoice with a section for a single customer and one or more line items
lends itself well to a multiple-file data entry screen: one part devoted to
customer information such as name, address, and account type, and a
separate section for one or more line items for a particular order. In the
past, screens of this type required extensive programming and resulted in
complex systems that were costly to create and maintain. With a little
knowledge about where and how to add small pieces of dBASE code and
utilizing the robust EDIT and BROWSE commands, you can use the screen
designer as a basis for multi-file data entry. Using UDFs in Browse and
Edit Wherever it's possible to enter an expression, you can implement a
user-defined function (UDF). UDFs are indispensable when controlling the
BROWSE/EDIT environment. For example, UDFs may be used in the "Accept value
when" and "Default value" prompts in the Edit options section of the screen
designer. The following chart shows the order in which dBASE IV executes
UDFs in a format file and gives examples of some of their common uses. For
many operations in a UDF, you need to SET DBTRAP OFF. Your UDF can freely
use work areas that are not being updated by the current EDIT or BROWSE
operation. You can USE files in other work areas, set format TO, invoke
BROWSE, update other tables, perform lookups, and so on. When working with
UDFs in Browse and Edit, at least one table must be open in update mode and
the following restrictions apply:   

* A UDF cannot REPLACE a field that is not editable on the screen.  
* A UDF cannot REPLACE fields that are i*the end-of-file record. 
* You cannot APPEND a blank record to the  active table.  
* The REPLACE command does not update  the screen.  

 Given the flexibility of UDFs, it is possible, with a little creativity,
to extend the functionality of our data entry form to allow editing of
multiple files.  Creating Multiple Detail-line Forms dBASE IV makes it easy
to create relational tables that are linked by a common key field such as
ID numbers (for example,  a social security number or phone number) or
names. Often, the tables form a one-to-many relationship. For instance,
many businesses work with invoices containing one customer and many line
items. In dBASE IV, you can create the files, relate them using QBE, and
report on the related data easily without programming. However, dBASE IV
offers no automated way to create data entry screens that contain more than
one table. Version 1.5 to the Rescue! Thanks to some new features in
version 1.5, you can now create multi-table forms with a minimum amount of
coding and without modifying templates. The two most useful new features
for multiple detail-line forms are "nested reads" and SET KEY TO <exp>.  A
read occurs when dBASE IV is accepting keyboard input via the READ, EDIT,
BROWSE, or APPEND commands. For example, an EDIT screen (the first read)
contains a validation routine that displays a dialog box requiring user
input. dBASE IV version 1.5 fully supports nested reads even when you are
in a BROWSE or EDIT screen. This facilitates using format screen validation
for both parent and child tables. The dBASE IV version 1.5 SET KEY command
uses indexes to speed up the filtering operation.  To create a simple
multi-table form, use the sample tables provided with dBASE IV. Index the
Orders file by Cust_ID. You can find the Orders and Cust tables in your
dBASE Samples directory.  .USE Orders EXCLUSIVE .INDEX ON Cust_ID TAG
Cust_ID  The screen like the one in Figure 1 allows updating of both the
clients and orders by pressing F4, which calls a UDF that enables the
multiple updates.

 Records   Go To   Exit                                              
CUST_ID     A00001                            PHONE       (213)555-4300         
CATEGORY    ARCHITECTS                        TERMS       NET 30                
CUSTOMER    SMITH AND ASSOCIATES              COMMENTS                          
ADDRESS1    7500 SANTA MONICA AVENUE          CONTACT     JUSTIN ASHTON         
ADDRESS2    SUITE 1200                        PHONE_CONT  (213)555-4300         
CITY        Los Angeles                       PHONE_EXT   444                   
STATE       CA                                DATE_LAST   07/07/86              
ZIP         90055                                                               
                                                                                
DATE_TRANSPART_IDPART_QTYPO_NUMBERNOTESEMP_IDINVOICED͸
03/05/88  C-111-6000       570010    memo 661-22-3333F                  
03/04/88  C-222-2010       370005    memo 661-22-3333F                  
12/14/92                             memo                               
                                                                        
                                                                        
                                                                        
                                                                        
                                                                        
                                                                        
                                                                        
 
Edit    U:\\CUST              Rec 1/7          File ExclLockDel          
               Help: F1        Edit orders: F4        Menu: F10                 

             Figure 1. A multi-file append format screen.  

After you index the Orders file on Cust_ID, the tables will have the
following structures: 

Structure for database: U:\CUST.DBF
Number of data records:       7
Date of last update   : 12/09/92
Field  Field Name  Type       Width    Dec    Index
    1  CUST_ID     Character      6               Y
    2  CATEGORY    Character     15               N
    3  CUSTOMER    Character     30               N
    4  ADDRESS1    Character     25               N
    5  ADDRESS2    Character     20               N
    6  CITY        Character     20               N
    7  STATE       Character      2               N
    8  ZIP         Character     10               N
    9  PHONE       Character     13               N
   10  TERMS       Character     10               N
   11  COMMENTS    Character     20               N
   12  CONTACT     Character     20               N
   13  PHONE_CONT  Character     13               N
   14  PHONE_EXT   Character      4               N
   15  DATE_LAST   Date           8               N
** Total **                     217

Structure for database: U:\ORDERS.DBF
Number of data records:      20
Date of last update   : 12/14/92
Field  Field Name  Type       Width    Dec    Index
    1  CUST_ID     Character      6               Y
    2  DATE_TRANS  Date           8               N
    3  PART_ID     Character     10               N
    4  PART_QTY    Numeric        3               N
    5  PO_NUMBER   Character      5               N
    6  NOTES       Memo          10               N
    7  EMP_ID      Character     11               N
    8  INVOICED    Logical        1               N
** Total **                      55

The two tables link on the common field Cust_ID to form a one-to-many
relationship. That is, each customer can have many orders, but each order
belongs to only one customer. Cust_ID is the primary key field, the only 
field that is common to both tables. 

Create a Sample Multi-table Form 
1.  Use the screen generator that comes with dBASE IV version 1.5 to create
a simple format screen with the layout shown in Figure 2.  Cust.DBF should
be open when creating this screen design.   

 Layout   Fields   Words   Go To   Exit                              
[123567]
X
CUST_IDXXXXXXPHONEXXXXXXXXXXXXX
CATEGORYXXXXXXXXXXXXXXXTERMSXXXXXXXXXX
CUSTOMERXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXCOMMENTSXXXXXXXXXXXXXXXXXXXX
ADDRESS1XXXXXXXXXXXXXXXXXXXXXXXXXCONTACTXXXXXXXXXXXXXXXXXXXX
ADDRESS2XXXXXXXXXXXXXXXXXXXXPHONE_CONTXXXXXXXXXXXXX
CITYXXXXXXXXXXXXXXXXXXXXPHONE_EXTXXXX
STATEXXDATE_LASTMM/DD/YY
ZIPXXXXXXXXXX











Form    U:\CUST               Row:0 Col:0      File:Orders             Ins
            Add field:F5  Select:F6  Move:F7  Copy:F8  Size:Shift-F7            
      Figure 2.Sample format design to go with Multi procedure. 
               Make sure Cust.DBF is opened.  

2.	Create a screen format to use with the BROWSE FORMAT command. 
Don't worry about the layout of the format, as BROWSE FORMAT only looks 
at the field order, messages, picture templates, and validation for 
fields that allow editing. BROWSE ignores all other format information.
Make sure that the Orders screen format does not contain the Cust_ID 
field.   
.USE orders  
.CREATE SCREEN orders  
Press Alt-L for Layout. 
Select Quick layout. 
Highlight Cust_ID field. 
Press Del to delete Cust_ID field. 
Press Ctrl-End to save format.  

3. Create a dBASE Program called Multi.PRG. The Multi procedure is the main
routine that opens both tables and formats and calls the initial edit.
Multi.PRG defines the BROWSE window with the dBASE IV default NORMAL
colors, so it blends into the standard format.  	 
 This procedure re-maps some function keys. The F2 key is disabled so users
can't toggle between BROWSE and EDIT. F4 is the "hot key" to access the
BROWSE window. EDIT includes the "NOORGANIZE" option to prevent switching
index tags and losing the essential link between parent-and-child
files.  	  
 To modify this program for relating more than two tables, set up unique ON
KEY LABEL commands for accessing each different BROWSE window. 	 
 The AddRec procedure sets up a new blank record for editing, with the
required Cust_ID field. This ensures that the new order record links to the
proper customer in the customer table.  You must embed the ShowZoom() UDF
into the format screen. It repaints the BROWSE window every time the user
moves the record pointer.  This UDF selects the second file, Orders.DBF, to
allow adding, editing, and deleting of records. It uses the command   
SET KEY TO Cust_ID    
to match the master file (Cust.DBF). This ensures that only records with
matching Cust_ID values display. The NOCLEAR option leaves the BROWSE image
on the screen after the cursor returns to the customer EDIT format.  
4.  Open the Multi.PRG as a procedure. If the procedure is not opened with
the SET PROCEDURE command, dBASE IV doesn't find the necessary UDFs. Modify
the customer format screen. Add the ShowZoom() function to the format
screen as a calculated field that appears before all editable fields.  

.SET PROCEDURE TO Multi  
.USE CUST 
.MODIFY SCREEN Cust  
Press F5. 
Select <create> under CALCULATED. 
Select Expression.  
Enter Showzoom().  

 The function will run at this point and will generate some runtime errors
that will not occur in the completed procedure. The function also stuffs
the keyboard buffer with an Escape, which will cause the "Cancel Procedure"
dialog to appear in the design surface.  

Select Ignore 3 times 
Select No 
Select Template 
Modify template to include only one X 
Press Ctrl-End to save calculated field 
Press Ctrl-End to save format	  
.SET PROCEDURE TO  

5.  Use the ZoomKeys() UDF to display function keys while in EDIT mode. To
insert ZoomKeys() UDF, enter the following:  

. SET PROCEDURE TO multi 
. MODIFY SCREEN Orders  
Highlight the ORDERS->DATE_TRANS field 
Press F5 
Select Edit options 
Select Permit edit if 
Enter ZoomKeys(PROGRAM())  

6.  Run the program by issuing the command at the dot prompt:  

.DO Multi  
Press F4 to edit orders. 
Press Alt-A to add orders. 
Press F3 to return to customer information.  

 That's it's multiple detail-line forms made easy. Now there's no need to
rewrite templates or to manually write a BROWSE routine. Simply follow the
steps above, substituting your names where the CLIENT and ORDER table names
appear. You can also modify these procedures to be generic routines that
control the link between any two tables. To do this, just modify each
routine to take parameters for the key field name, the table names, and any
fields that determine if the second file is blank.

Multi-file Append Procedures and Functions

PROCEDURE multi
   SET DBTRAP OFF                            && To use recursive calls 
   SET DESIGN OFF
   SET ESCAPE OFF
   DEFINE WINDOW zoom                        ;
          FROM 10,0 TO 21,79 COLOR ,,W+/B    && Set colors do NORMAL
   CLOSE DATABASES
   USE orders ORDER TAG cust_id              && open both files and
   SET FORMAT TO orders                      && associated formats
   SELECT SELECT()
   USE cust   ORDER TAG cust_id   
   SET FORMAT TO cust

   ON KEY LABEL F2 ?? CHR(7)                 && disable flip 
   ON KEY LABEL F4 DO zoom                   && Use F4 NEXT to reach
   EDIT NOORGANIZE                           && order window
   ON KEY LABEL F2                           && Noorganized required
   ON KEY LABEL F4                           && to ensure relational
   CLEAR                                     && integrity
   CLOSE DATABASES
   RELEASE WINDOW zoom
   SET DBTRAP ON
   SET DESIGN ON
   SET ESCAPE ON
RETURN

PROCEDURE zoom
   PRIVATE x_addrec
   STORE .F. TO x_addrec
   ON KEY LABEL F4
   IF RLOCK()
      SELECT orders
      SET KEY TO cust->cust_id
      GOTO TOP
      IF EOF()
         APPEND BLANK
         REPLACE cust_id WITH cust->cust_id
      ENDIF
      ON KEY LABEL F3 KEYBOARD CHR(23)
      ON KEY LABEL Alt-A DO addrec
      BROWSE NOAPPEND NOMENU NOCLEAR     ;
             COMPRESS FORMAT WINDOW zoom
      DO WHILE x_addrec
         STORE .F. TO x_addrec
         APPEND BLANK
         REPLACE cust_id    WITH cust->cust_id, ;
                 date_trans WITH DATE()
         SKIP -1
         KEYBOARD CHR(24) CLEAR
         BROWSE NOAPPEND NOMENU NOCLEAR          ;
                COMPRESS FORMAT WINDOW zoom
      ENDDO
      ON KEY LABEL Alt-A
      SELECT cust
   ENDIF
   @ 23,10 SAY   "     Help: F1        Edit orders: F4" + ;
                 "        Menu: F10     " COLOR W+/N
   ON KEY LABEL F3 
   ON KEY LABEL F4 DO zoom
   RELEASE x_addrec
RETURN

PROCEDURE addrec
   KEYBOARD CHR(23) CLEAR
   STORE .T. TO x_addrec
RETURN

FUNCTION showzoom
   * This function is added as a calculated field to the
   * CUST format.  The calculated field must be placed
   * prior to all updatable fields.
   SELECT orders                   
   SET KEY TO cust->cust_id
   GOTO TOP
   IF EOF()                               && if no orders link to
      APPEND BLANK                        && create one
      REPLACE cust_id WITH cust->cust_id
   ENDIF
   KEYBOARD CHR(27) CLEAR                 && Immediate exit of BROWSE
   BROWSE NOAPPEND NOMENU NOCLEAR COMPRESS ;
          FORMAT WINDOW zoom              && Use NOMENU to prevent    
   SELECT cust                            && excess screen redraw
   @ 23,10 SAY   "     Help: F1        Edit orders: F4" + ;
                 "        Menu: F10     " COLOR W+/N
RETURN (SPACE(1))                         && return space to format

FUNCTION zoomkeys
  * shows function keys for child table.
  * included in orders format under Accept value when on first field.
  PARAMETERS p_program
  IF p_program = "ZOOM"
     ACTIVATE SCREEN
     @ 23,10 SAY "Help: F1         Save orders: F3" + ;
                 "        Add records: Alt-A"    COLOR W+/N
     * note you do not have to reactivate window
  ENDIF
  RELEASE p_program
RETURN (.T.)
                                                                                                                                                                          

