[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
DBEDIT()

    DBEDIT() displays and edits records from one or more work areas using a
    browse-style table layout that executes within a defined window area.

Syntax

    DBEDIT([<expN1>[,<expN2>[,<expN3>[,<expN4>]]]][,<array1>][,<expC>]
    [,<array2>][,<array3>][,<array4>][,<array5>][,<array6>][,<array7>])

Argument

    <expN1..expN4> are the coordinates of the DBEDIT() window.  Any, or
    all, of these arguments can be specified.

    <array1> is an array of <expC> containing field names or expressions of
    any type.  If this argument is not specified, DBEDIT() defaults to all
    fields in the current work area.

    <expC> is a user-defined function that executes when a key exception is
    pressed or when there are no more keys to process in the keyboard
    buffer.  Specify the function name without the parenthetical suffix or
    arguments.  Note that the behavior of DBEDIT() is affected by the
    presence of this argument.  Refer to the discussion below for more
    information.

    <array2> is an array of <expC> to be used as picture strings for column
    formatting and is the same as TRANSFORM().  Specifying an <expC>
    instead of an array formats all columns with the same picture.

    <array3> is an array of <expC> for column headings.

    <array4> is an array of <expC> used to draw lines separating headings
    and the field display area.  Specifying an <expC> instead of an array
    uses the same character for the heading line separator.

    <array5> is an array of <expC> used to draw lines separating displayed
    columns.  Specifying an <expC> instead of an array uses the same
    character for the column separator.

    <array6> is an array of <expC> used to draw lines separating footings
    and the field display area.  Specifying an <expC> instead of an array
    uses the same character for the footing line separator.

    <array7> is an array of <expC> to display as column footings.  To force
    a column footing onto more than one line, embed a semicolon where you
    want the string to break.  Specying an <expC> instead of an array gives
    all footings the same value.

    All arguments are optional.  You must, however, pass a dummy argument
    for any argument you wish to skip.

Returns

    A logical value.

Usage

    DBEDIT() is an interface function that displays records in a table
    form.  it is useful for full-screen editing of one or more data files.
    It formats the display according to the window coordinates and the
    fields arrray.  All cursor movement keys are handled within DBEDIT.
    This includes PgUp, PgDn, Home, End, the four arrows, and all valid
    Ctrl key combinations that produce cursor movement.  The following are
    the active keys with no function argument specified:

                             DBEDIT() Active Keys
    Key                  Action

    Uparrow              Up one row
    Dnarrow              Down one row
    Leftarrow            Column left
    Rightarrow           Column right
    Ctrl-Leftarrow       Pan left one column
    Ctrl-Rightarrow      Pan right one column
    Home                 Leftmost current screen column
    End                  Rightmost current screen column
    Ctrl-Home            Leftmost column
    Ctrl-End             Rightmost column
    PgUp                 Previous screen
    PgDn                 Next screen
    Ctrl-PgUp            First row of current column
    Ctrl-PgDn            Last row of current column
    Return               Terminate DBEDIT()
    Esc                  Terminate DBEDIT()

    Note that DBEDIT() is not a wait state and so a SET KEY procedure
    cannot be invoked from within DBEDIT()'s native works unless you have
    your own wait state within the user function.

    User Function: When the user function argument (<expC>) is
    specified, all keys indicated above are active with the exception of
    Esc and Return.  When DBEDIT() calls the user function, it
    automatically passes two parameters: "Status" and "fld_ptr".  The
    status parameter indicates the current state of DBEDIT() depending on
    the last key executed before the user function was called.  The
    following are the possible status values:

                           DBEDIT() Status Messages

    Status       Description

      0          Idle, any cursor movement keystrokes have been handled
                 and no keystrokes are pending
      1          Attempt to cursor past beginning-of-file
      2          Attempt to cursor past end-of-file
      3          Database file is empty
      4          Keystroke exception

    Status messages 0, 1, 2, and 4 are used to process keys.

    The other parameter, fld_ptr, is an index into the array of field names
    argument (<array>).  If <array1> is not specified, fld_ptr points to
    the current field in the database structure and can be accessed using
    FIELD().

    When the user function has been called, you must return a value
    instructing DBEDIT() what action to perform next.  The following table
    summarizes the possible request values and their consequences:

                   Requests to DBEDIT() from User Function

    Value     Description
      0       Quit DBEDIT()
      1       Continue DBEDIT()
      2       Force reread/repaint and continue screen refresh; after
              refresh, go to idle
      3       Append mode toggle

    The user function is called in a number of different instances:

    -  A key exception occurs.  This happens when DBEDIT() picks up a
       keystroke from the keyboard that is not a DBEDIT() executable key.
       Any pending keys remain in the keyboard buffer until picked up
       within the user function or DBEDIT() continues.

    -  DBEDIT() goes to idle.  This happens when the keyboard buffer is
       empty or when a request for a screen fresh has been executed
       (request = 2).  In this instance, there is one call to the user
       function.

    -  Beginning or end-of-file are encountered.  This is the same as idle.
       All executable keys are performed and then there is one call with
       the indicating status message.

    Note that when DBEDIT() is first executed, all keys pending in the
    keyboard are executed and then DBEDIT() goes to idle with a user
    function call.  If no keys are pending, the idle state is immediate.

    The structure of the user function should be set up to handle all
    status messages received from DBEDIT().  Status messages
    characteristically indicate the current state of DBEDIT() and point to
    the type of action to be taken by the user function.  The structure
    therefore should consist of a CASE structure that branches control to a
    subprocedure for each status message to process.  Although you may be
    interested in less than all five of the status message values, your
    structure should at a minimum process idle states (status = 0) and key
    exceptions (status = 4).  Ignored status messages can be processed by
    the OTHERWISE clause.  Tests for specific key pressed should then take
    place within the called subprocedure.  The following block of code
    demonstrates the basic structure of the user function.

    FUNCTION UserFunc                   
    PARAMETERS status, fld_ptr          
    PRIVATE request                     
                                        
    key_stroke = LASTKEY()              
                                        
    DO CASE                             
    CASE status = 0                     
       * Idle.                          
       request = ProcessIdle(key_stroke)
                                        
    CASE status = 1                     
       * Beginning-of-file.             
       request = ProcessBof(key_stroke) 
                                        
    CASE status = 2                     
       * End-of-file.                   
       request = ProcessEof(key_stroke) 
                                        
    CASE status = 3                     
       * Empty database file            
       request = ProcessEmpty()         
                                        
    CASE status = 4                     
       * Key exception                  
       request = KeyExcept(key_stroke)  
                                        
    OTHERWISE                           
       request = 1                      
                                        
    ENDCASE                             
                                        
    RETURN request                      

    There are two additional issues to deal with in the user function
    proper.  First, to allow further processing of keys and the subsequent
    use of LASTKEY() within called subprocedures, save the value of the
    last key pressed to a memory variable before entering the main CASE
    structure.  Then pass that key value throughout your subprocedure
    system as a parameter.  Second, to allow execution of statements after
    the CASE structure, make your request to DBEDIT() by assigning the
    request value to a memory variable and then RETURN the value as the
    last statement in the user function.

    The two most important subprocedures in the user function architecture
    are the key exception handler and the idle state processor.  In the key
    exception handler, you should account for user requests for the
    following set of actions:

    -  Exit from DBEDIT()
    -  Toggle delete status of the current record
    -  Field edit
    -  Entry into a menu system

    In addition to these basic facilities, the key exception handler is
    where most of the activity of the user function system takes place.
    For example, the following demonstrates a typical key exception
    handling subprocedure:

    FUNCTION KeyExcept                             
    PARAMETER action_key                           
                                                   
    DO CASE                                        
    CASE action_key = 27                           
       * Esc..exit DBEDIT()                        
       RETURN 0                                    
                                                   
    CASE action_key = 13                           
       * Return..field edit (see discussion below) 
       RETURN FieldEdit()                          
                                                   
    CASE action_key = 7 .AND. (.NOT. EOF()) .AND.; 
       LASTREC()<>0                                
       * Del..toggle delete status                 
       IF DELETED()                                
          RECALL                                   
       ELSE                                        
          DELETE                                   
       ENDIF                                       
       RETURN 1                                    
                                                   
    CASE action_key = -9                           
       * F10..enter menu system                    
       RETURN MenuSys()                            
                                                   
    OTHERWISE                                      
      * Any other key...give them the old raspberry
      TONE(76,5)                                   
      TONE(50,5)                                   
      RETURN 1                                     
    ENDCASE                                        

    The other subprocedure of interest is the idle state processor.  In the
    simplest case, you may just want to update a status area on the screen.
    In a more complex scenario, you can perform actions based on the last
    DBEDIT() key executed.

    To edit a field value, add code like the following to the CASE
    structure in your key exception handling subprocedure.

    CASE keystroke = 13         && return key    
                                                 
       * Save current key expression and value.  
       index_exp = INDEXKEY(0)                   
       index_val = &index_exp                    
                                                 
       *Edit current field value.                
       SET CURSOR ON                             
       field_name = field_list[fld_ptr]          
       @ ROW(), COL() GET &field_name            
       READ                                      
       SET CURSOR OFF                            
                                                 
       * Refresh screen if key value has changed.
       RETURN IF(index_val &index_exp., 2, 1)    

    The basic idea is to test for the key you are using for the field edit
    key and then GET the field pointed to by the fld_ptr parameter in the
    field array.  This means that if you specify a field array as an
    argument to DBEDIT() you must use the same array name in your field
    edit routine.  If you have not specified a field array, obtain the
    field name using FIELD() with fld_ptr as the argument.

    A second issue is the appearance of the cursor.  By default, the
    DBEDIT() cursor is OFF.  You must therefore SET the CURSOR ON before
    executing the READ and SET it OFF after the READ.

    A last issue is updating the screen if a key value has changed.  To set
    this up, you must save both the controlling index key expression and
    its current value before editing the current field value.  Then after
    the field edit is complete, send a request for a screen fresh (a value
    of 2) if the new key value is the same as the old key value.

    Nesting: You can call multiple copies of DBEDIT() within each copy
    of DBEDIT() allowing you multiple browse windows on the screen at one
    time.

Example

    The following demonstrates how to use DBEDIT() with a user function:

    SELECT 2                                             
    USE Customer INDEX Customer                          
    SELECT 1                                             
    USE Sales INDEX Sales                                
    SET RELATION TO Cust_num INTO Customer               
                                                         
    DECLARE field_list[4]                                
    field_list[1] = "Branch"                             
    field_list[2] = "Salesman"                           
    field_list[3] = "Amount"                             
    *                                                    
    * Fields in another work area must include the alias.
    fields[4] = "Customer->Customer"                     
                                                         
    DBEDIT(4, 0, 22, 79, FIELD_LIST, "UserFunc")         

    For an advanced example that demonstrates a full-featured browse, see
    Browse() in Examplep.prg on the distribution disk.  Note that Browse()
    is included in EXTEND.LIB so that to use it you need not compile and
    link it.  The syntax is:

    Browse([<window coordinates<])

See Also: READ ACHOICE MEMOEDIT
This page created by ng2html v1.05, the Norton guide to HTML conversion utility. Written by Dave Pearson