3. Embedded QUEL for COBOL : Sample Applications : UNIX and VMS—The Professor-Student Mixed Form Application
 
Share this page                  
UNIX and VMS—The Professor-Student Mixed Form Application
This EQUEL/FORMS application lets the user browse and update information about graduate students who report to a specific professor. The program is structured in a master/detail fashion, with the professor being the master entry, and the students the detail entries. The application uses two forms—one to contain general professor information and another for detailed student information.
The application uses the following objects:
Object
Description
personnel
The program's database environment.
professor
A database table with two columns:
pname (c25)
pdept (c10).
See its create statement below for a full description.
student
A database table with seven columns:
sname (c25)
sage (i1)
sbdate (c25)
sgpa (f4)
sidno (i1)
scomment (text(200))
sadvisor (c25).
See the create statement below for a full description. The sadvisor columnm is the join field with the pname column in the Professor table.
masterfrm
The main form has the pname and pdept fields that correspond to the information in the Professor table, and the studenttbl table field. The pdept field is display-only. Masterfrm is a compiled form.
studenttbl
A table field in masterfrm with two columns, sname and sage. When initialized, it also has five more hidden columns corresponding to information in the Student table.
studentfrm
The detail form, with seven fields, which correspond to information in the Student table. Only the sgpa, scomment and sadvisor fields are updatable. All other fields are display-only. Studentfrm is a compiled form.
grad
A global structure, whose members correspond in name and type to the columns of the Student database table, the studentfrm form and the studenttbl table field.
The program uses the masterfrm as the general-level master entry, in which data can only be retrieved and browsed, and the studentfrm as the detailed screen, in which specific student information can be updated.
The runtime user enters a name in the pname (professor name) field and then selects the Students menu operation. The operation fills the displayed and hidden columns of the studenttbl table field with detailed information of the students reporting to the named professor. The user may then browse the table field (in read mode), which displays only the names and ages of the students. More information about a specific student may be requested by selecting the Zoom menu operation. This operation displays the studentfrm form. The fields of studentfrm are filled with values stored in the hidden columns of studenttbl. The user may make changes to three fields (sgpa, scomment, and sadvisor). If validated, these changes will be written back to the database table (based on the unique student id), and to the table field's data set. This process can be repeated for different professor names.
For readability, all EQUEL reserved words are in uppercase.
UNIX: The following two create statements describe the Professor and Student database tables:
##   CREATE student   /* Graduate student table */
##    (sname     = c25,       /* Name */
##     sage      = i1,        /* Age */
##     sbdate    = c25,       /* Birth date */
##     sgpa      = f4,        /* Grade point average */
##     sidno     = i4,        /* Unique student number */
##     scomment  = text(200), /* General comments */
##     sadvisor  = c25)       /* Advisor's name */

##   CREATE professor    /* Professor table */
##    (pname     = c25,       /* Professor's name */
##     pdept     = c10)       /* Department */

        IDENTIFICATION DIVISION.
        PROGRAM-ID. STUDENT-ADMINISTRATOR.

        ENVIRONMENT DIVISION.

        DATA DIVISION.
        WORKING-STORAGE SECTION.
##      DECLARE
*       Global grad student record maps to database table
##      01    GRAD.
##             02 SNAME           PIC X(25).
##             02 SAGE            PIC S9(4) USAGE COMP.
##             02 SBDATE          PIC X(25).
##             02 SGPA            PIC S9(3)V9(2) USAGE COMP.
##             02 SIDNO           PIC S9(9) USAGE COMP.
##             02 SCOMMENT        PIC X(200).
##             02 SADVISOR        PIC X(25).

*       Professor info maps to database table
##      01     PROF.
##              02 PNAME          PIC X(25).
##              02 PDEPT          PIC X(10).

*       Row number of last row in student table field
##      01     LASTROW            PIC S9(9) USAGE COMP.

*       Is user on a table field?
##      01     ISTABLE            PIC S9 USAGE COMP.

*       Were changes made to data in student form?
##      01     CHANGED-DATA       PIC S9 USAGE COMP.

*       Did user enter a valid advisor name?
##      01     VALID-ADVISOR      PIC S9 USAGE COMP.

*       Studentfrm loaded?
##      01     LOADFORM           PIC S9 USAGE COMP VALUE IS 0.

*       Local utility buffers
##      01     MSGBUF             PIC X(100).
##      01     RESPBUF            PIC X.
##      01     OLD-ADVISOR        PIC X(25).
*       Compiled forms are not yet accepted as EXTERNAL due
*       to restrictions noted in the chapter that 
*       describes how to link the RTS with compiled forms. 
*       Consequently the declarations of external form
*       objects and the corresponding ADDFORM statement
*       have been commented out and replaced by a CALL 
*       "add_formname" statement.
* ##    01    masterfrm      PIC S9(9) USAGE COMP-5 IS EXTERNAL.
* ##    01    studentfrm     PIC S9(9) USAGE COMP-5 IS EXTERNAL.

**
*       Procedure Division: STUDENT-ADMINISTRATOR
*
*       Start up program, Ingres, and the FORMS system and *       call Master driver.
**

        PROCEDURE DIVISION.
        EXAMPLE SECTION.
        XBEGIN.

##      FORMS

##      MESSAGE "Initializing Student Administrator . . ."

##      INGRES "personnel"
##      RANGE OF p IS professor, s IS student

        PERFORM MASTER THROUGH END-MASTER.

##      CLEAR SCREEN
##      ENDFORMS
##      EXIT
        STOP RUN.
**
*       Paragraph: MASTER
*
*           Drive the application, by running "masterfrm", and
*           allowing the user to "zoom" into a selected student.
**

        MASTER.

* ##    ADDFORM masterfrm
        CALL "add_masterfrm".

*       Initialize "studenttbl" with a data set in READ mode. 
*       Declare hidden  columns for all the extra fields that 
*       the program will display when   more information is 
*       requested about a student.
*       Columns "sname" and  "sage" are displayed, all other
*       columns are hidden, to be used in  the student 
*       information form.

##      INITTABLE #masterfrm studenttbl READ
##          (#SBDATE = CHAR(25),
##          #SGPA = FLOAT,
##          #SIDNO = INTEGER,
##          #SCOMMENT = CHAR(200),
##          #SADVISOR = CHAR(20))

##     DISPLAY #masterfrm UPDATE

##     INITIALIZE
##     {
##            MESSAGE "Enter an Advisor name . . ."
##            SLEEP 2
##     }

##     ACTIVATE MENUITEM "Students", FIELD "pname"
##     {
*          Load the students of the specified professor
##          GETFORM (PNAME = #pname)

*          If no professor name is given then resume
          IF PNAME = SPACES THEN
##                   RESUME FIELD #pname
          END-IF.

*          Verify the professor exists. Local error handling just
*          prints the message, and continues. We assume that each
*          professor has exactly one department.

          MOVE SPACES TO PDEPT.

##          RETRIEVE (PDEPT = p.#pdept, PNAME = p.#pname)
##                WHERE p.#pname = PNAME

          IF PDEPT = SPACES THEN
                MOVE SPACES TO MSGBUF
                STRING "No professor with name """
                       DELIMITED BY SIZE,
                       PNAME DELIMITED BY " ",
                       """ [RETURN]" DELIMITED BY SIZE
                       INTO MSGBUF
##                       PROMPT NOECHO (MSGBUF, RESPBUF)
##                       RESUME FIELD #pname
           END-IF.

*          Fill the department field and load students
##          PUTFORM (#pdept = PDEPT, #pname = PNAME)

*          Refresh for query
##          REDISPLAY

          PERFORM LOAD-STUDENTS THROUGH END-LOAD.

##          RESUME FIELD studenttbl

##        }

##       ACTIVATE MENUITEM "Zoom"
##       {
*           Confirm that user is on "studenttbl", and that the
*           table field is not empty. Collect data from the 
*           row and zoom for browsing and updating.

##          INQUIRE_FRS FIELD #masterfrm (ISTABLE = table)

         IF ISTABLE = 0 THEN
##              PROMPT NOECHO
##                     ("Select from the student table [RETURN]",
##                       RESPBUF)
##              RESUME FIELD studenttbl
         END-IF.

##       INQUIRE_FRS TABLE #masterfrm (LASTROW = lastrow)

         IF LASTROW = 0 THEN
##              PROMPT NOECHO ("There are no students [RETURN]",
##                              RESPBUF)
##              RESUME FIELD #pname
         END-IF.

*        Collect all data on student into global record
##       GETROW #masterfrm studenttbl
##              (SNAME = #sname,
##               SAGE = #sage,
##               SBDATE = #sbdate,
##               SGPA = #sgpa,
##               SIDNO = #sidno,
##               SCOMMENT = #scomment,
##               SADVISOR = #sadvisor)
*        Display "studentfrm", and if any changes were made make
*        the updates to the local table field row. Only make
*        updates to the columns corresponding to writable fields
*        in "studentfrm". If the student changed advisors, then
*        delete this row from the display.

         MOVE SADVISOR TO OLD-ADVISOR.

         PERFORM STUDENT-INFO-CHANGED THROUGH END-STUDENT.

         IF CHANGED-DATA = 1 THEN
                IF OLD-ADVISOR NOT = SADVISOR THEN
##                     DELETEROW #masterfrm studenttbl
                ELSE
##                     PUTROW #masterfrm studenttbl
##                            (#sgpa = SGPA,
##                             #scomment = SCOMMENT,
##                             #sadvisor = SADVISOR)
                END-IF
         END-IF.

##       }

##       ACTIVATE MENUITEM "Quit", FRSKEY2
##       {
##              BREAKDISPLAY
##       }
##       FINALIZE 

         END-MASTER.
                EXIT.
**
*        Paragraph: LOAD-STUDENTS
*
*          For the current professor name, this paragraph loads
*          into the "studenttbl" table field all the students 
*          whose advisor is the professor with that name.
**

         LOAD-STUDENTS.

##       MESSAGE "Retrieving Student Information . . ."
##       CLEAR FIELD studenttbl

##       RETRIEVE (SNAME = s.#sname,
##                 SAGE = s.#sage,
##                 SBDATE = s.#sbdate,
##                 SGPA = s.#sgpa,
##                 SIDNO = s.#sidno,
##                 SCOMMENT = s.#scomment,
##                 SADVISOR = s.#sadvisor)
##       WHERE s.#sadvisor = PNAME
##       {
##          LOADTABLE #masterfrm studenttbl
##                    (#sname = SNAME,
##                     #sage = SAGE,
##                     #sbdate = SBDATE,
##                     #sgpa = SGPA,
##                     #sidno = SIDNO,
##                     #scomment = SCOMMENT,
##                     #sadvisor = SADVISOR)
##       }

         END-LOAD.
           EXIT.
**
*    Paragraph: STUDENT-INFO-CHANGED
*
*          Allow the user to zoom into the details of a selected
*          student. Some of the data can be updated by the user.
*          If any updates were made, then reflect these back into
*          the database table. The paragraph records whether or not
*          changes were made via the CHANGED-DATA variable. **

      STUDENT-INFO-CHANGED.

*     Control ADDFORM to only initialize once

      IF LOADFORM = 0 THEN
##           MESSAGE "Loading Student form . . ."
* ##         ADDFORM studentfrm
              CALL "add_studentfrm"
              MOVE 1 TO LOADFORM
      END-IF.

##    DISPLAY #studentfrm FILL
##    INITIALIZE (#sname = SNAME,
##                  #sage = SAGE,
##                  #sbdate = SBDATE,
##                  #sgpa = SGPA,
##                  #sidno = SIDNO,
##                  #scomment = SCOMMENT,
##                  #sadvisor = SADVISOR) 

##    ACTIVATE MENUITEM "Write", FRSKEY4
##    {
*         If changes were made then update the database table.
*         Only bother with the fields that are not read-only.

##        INQUIRE_FRS form (CHANGED-DATA = change)
          IF CHANGED-DATA = 0 THEN
##            BREAKDISPLAY
          END-IF.
##        VALIDATE
##        MESSAGE "Writing changes to database. . ." 

##        GETFORM (SGPA = #sgpa,
##                 SCOMMENT = #scomment,
##                 SADVISOR = #sadvisor) 

*         Enforce integrity of professor name.
          MOVE 0 TO VALID-ADVISOR
##        RETRIEVE (VALID-ADVISOR = 1)
##              WHERE p.#pname = SADVISOR

          IF VALID-ADVISOR = 0 THEN
##                MESSAGE "Not a valid advisor name"
##                SLEEP 2
##                RESUME FIELD #sadvisor
          ELSE
##                REPLACE s (#sgpa = SGPA, #scomment = SCOMMENT,
##                           #sadvisor = SADVISOR)
##                WHERE s.#sidno = SIDNO
##              BREAKDISPLAY
          END-IF.

##    }

##    ACTIVATE MENUITEM "End", FRSKEY3
##    {

*         Quit without submitting changes
          MOVE 0 TO CHANGED-DATA.
##        BREAKDISPLAY 

##    }
##    FINALIZE 

      END-STUDENT.
      EXIT. 

VMS: The following two create statements describe the Professor and Student database tables.
##      CREATE student            /* Graduate student table */
##            (sname     = c25,       /* Name */
##             sage      = i1,        /* Age */
##             sbdate    = c25,       /* Birth date */
##             sgpa      = f4,        /* Grade point average */
##             sidno     = i4,        /* Unique student number */
##             scomment  = text(200), /* General comments */
##             sadvisor  = c25)       /* Advisor's name */

##        CREATE professor        /* Professor table */
##            (pname = c25,           /* Professor's name */
##             pdept = c10)           /* Department */

IDENTIFICATION DIVISION. 
PROGRAM-ID. STUDENT-ADMINISTRATOR.

ENVIRONMENT DIVISION.

DATA DIVISION.
WORKING-STORAGE SECTION.
##      DECLARE

* Global grad student record maps to database table
##       01 GRAD.
##           02 SNAME         PIC X(25).
##           02 SAGE          PIC S9(4) USAGE COMP.
##           02 SBDATE        PIC X(25).
##           02 SGPA          USAGE COMP-1.
##           02 SIDNO         PIC S9(9) USAGE COMP.
##           02 SCOMMENT      PIC X(200).
##           02 SADVISOR      PIC X(25).

* Professor info maps to database table
##       01 PROF.
##          02 PNAME          PIC X(25).
##          02 PDEPT          PIC X(10).
* Row number of last row in student table field
##       01 LASTROW           PIC S9(9) USAGE COMP.

* Is user on a table field?
##       01 ISTABLE           PIC S9 USAGE COMP.

* Were changes made to data in student form?
##       01 CHANGED           PIC S9 USAGE COMP.

* Did user enter a valid advisor name? 
##       01 VALID-ADVISOR     PIC S9 USAGE COMP.

* Studentfrm loaded?
##       01 LOADFORM          PIC S9 USAGE COMP VALUE IS 0.

* Local utility buffers
##       01 MSGBUF            PIC X(100).
##       01 RESPBUF           PIC X.
##       01 OLD-ADVISOR       PIC X(25).

* Externally compiled forms
##    01 MASTERF    PIC S9(9) USAGE COMP VALUE EXTERNAL Masterfrm.
##    01 STUDENTF   PIC S9(9) USAGE COMP VALUE EXTERNAL Studentfrm.
**
* Procedure Division: STUDENT-ADMINISTRATOR
*
*        Start up program, Ingres, and the FORMS system and
*        call Master driver.
**

PROCEDURE DIVISION.
SBEGIN.

##       FORMS

##       MESSAGE "Initializing Student Administrator . . ."

##       INGRES "personnel"
##       RANGE OF p IS professor, s IS student

         PERFORM MASTER THROUGH END-MASTER.

##       CLEAR SCREEN
##       ENDFORMS
##       EXIT
         STOP RUN.
**
* Paragraph: MASTER
*
*        Drive the application, by running "masterfrm", and
*        allowing the user to "zoom" into a selected student.
**
MASTER.

##       ADDFORM MASTERF

* Initialize "studenttbl" with a data set in READ mode. 
* Declare hidden columns for all the extra fields that the 
* program will display when more information is requested about 
* a student. Columns "sname" and "sage" are displayed, all 
* other columns are hidden, to be used in the student information
* form.

##       INITTABLE #masterfrm studenttbl READ
##              (#SBDATE = CHAR(25),
##               #SGPA = FLOAT,
##               #SIDNO = INTEGER,
##               #SCOMMENT = CHAR(200),
##               #SADVISOR = CHAR(20))

##       DISPLAY #masterfrm UPDATE

##       INITIALIZE
##       {
##          MESSAGE "Enter an Advisor name . . ."
##               SLEEP 2
##       }

##       ACTIVATE MENUITEM "Students", FIELD "pname"
##       {
* Load the students of the specified professor

##          GETFORM (PNAME = #pname)

* If no professor name is given then resume

            IF PNAME = "" THEN
##                  RESUME FIELD #pname
            END-IF.

* Verify the professor exists. Local error handling just prints 
* the message, and continues. We assume that each professor has
* exactly one department.

            MOVE "" TO PDEPT.

##          RETRIEVE (PDEPT = p.#pdept, PNAME = p.#pname)
##                  WHERE p.#pname = PNAME

            IF PDEPT = "" THEN
               MOVE "" TO MSGBUF
               STRING "No professor with name """ DELIMITED BY SIZE,
               PNAME DELIMITED BY " ",
               """ [RETURN]" DELIMITED BY SIZE
               INTO MSGBUF
##             PROMPT NOECHO (MSGBUF, RESPBUF)
##             CLEAR FIELD ALL
##             RESUME FIELD #pname
            END-IF.

* Fill the department field and load students

##          PUTFORM (#pdept = PDEPT, #pname = PNAME)
* Refresh for query

##          REDISPLAY

            PERFORM LOAD-STUDENTS THROUGH END-LOAD.

##          RESUME FIELD studenttbl

##       }

##       ACTIVATE MENUITEM "Zoom"
##       {

* Confirm that user is on "studenttbl", and that the table 

* field is not empty. Collect data from the row and zoom 
* for browsing and updating.

##       INQUIRE_FRS FIELD #masterfrm (ISTABLE = table)

         IF ISTABLE = 0 THEN
##             PROMPT NOECHO 
##                ("Select from the student table [RETURN]",
##                  RESPBUF)
##             RESUME FIELD studenttbl
         END-IF.

##       INQUIRE_FRS TABLE #masterfrm (LASTROW = lastrow)

         IF LASTROW = 0 THEN

##             PROMPT NOECHO ("There are no students [RETURN]",
##                             RESPBUF)
##             RESUME FIELD #pname

         END-IF.
* Collect all data on student into global record

##       GETROW #masterfrm studenttbl
##              (SNAME         = #sname,
##               SAGE          = #sage,
##               SBDATE        = #sbdate,
##               SGPA          = #sgpa,
##               SIDNO         = #sidno,
##               SCOMMENT      = #scomment,
##               SADVISOR      = #sadvisor)

* Display "studentfrm", and if any changes were made make the 
* updates to the local table field row. Only make updates to the
* columns corresponding to writable fields in "studentfrm". If 
* the student changed advisors, then delete this row from
* the display.

         MOVE SADVISOR TO OLD-ADVISOR.

         PERFORM STUDENT-INFO-CHANGED THROUGH END-STUDENT.

         IF CHANGED = 1 THEN
               IF OLD-ADVISOR NOT = SADVISOR THEN
##                    DELETEROW #masterfrm studenttbl 
               ELSE
##                    PUTROW #masterfrm studenttbl
##                           (#sgpa = SGPA,
##                            #scomment = SCOMMENT,
##                            #sadvisor = SADVISOR) 
              END-IF
           END-IF.

##      }

##        ACTIVATE MENUITEM "Quit", FRSKEY2
##        {
##              BREAKDISPLAY 
##        }
##        FINALIZE

END-MASTER.
**
* Paragraph: LOAD-STUDENTS
*
*     For the current professor name, this paragraph loads into the
*     "studenttbl" table field all the students whose advisor is
*     the professor with that name.
**

LOAD-STUDENTS.

##     MESSAGE "Retrieving Student Information . . ."
##     CLEAR FIELD studenttbl

##     RETRIEVE (
##                SNAME      = s.#sname,
##                SAGE       = s.#sage,
##                SBDATE     = s.#sbdate,
##                SGPA       = s.#sgpa,
##                SIDNO      = s.#sidno,
##                SCOMMENT   = s.#scomment,
##                SADVISOR   = s.#sadvisor)
##     WHERE s.#sadvisor     = PNAME
##     {
##              LOADTABLE #masterfrm studenttbl
##                            (#sname        = SNAME,
##                             #sage         = SAGE,
##                             #sbdate       = SBDATE,
##                             #sgpa         = SGPA,
##                             #sidno        = SIDNO,
##                             #scomment     = SCOMMENT,
##                             #sadvisor     = SADVISOR) 
##     }

END-LOAD.
**
* Paragraph: STUDENT-INFO-CHANGED
*
*        Allow the user to zoom into the details of a selected
*        student. Some of the data can be updated by the user. 
*        If any updates were made, then reflect these back into 
*        the database table. The paragraph records whether or not 
*        changes were made via the CHANGED variable.
**

STUDENT-INFO-CHANGED.

* Control ADDFORM to only initialize once

        IF LOADFORM = 0 THEN
##                MESSAGE "Loading Student form . . ."
##                ADDFORM STUDENTF 
                MOVE 1 TO LOADFORM
        END-IF.

##      DISPLAY #studentfrm FILL 
##      INITIALIZE
##                    (#sname      = SNAME,
##                     #sage       = SAGE,
##                     #sbdate     = SBDATE,
##                     #sgpa       = SGPA,
##                     #sidno      = SIDNO,
##                     #scomment   = SCOMMENT,
##                     #sadvisor   = SADVISOR)

##      ACTIVATE MENUITEM "Write", FRSKEY4
##      {
* If changes were made then update the database table. Only
* bother with the fields that are not read-only.

##                     INQUIRE_FRS form (CHANGED = change)

                       IF CHANGED = 0 THEN 
##                           BREAKDISPLAY
                       END-IF.

##                     VALIDATE 
##                     MESSAGE "Writing changes to database. . ."

##                     GETFORM
##                              (SGPA = #sgpa,
##                              SCOMMENT = #scomment,
##                              SADVISOR = #sadvisor)
* Enforce integrity of professor name.

                       MOVE 0 TO VALID-ADVISOR
##                     RETRIEVE (VALID-ADVISOR = 1)
##                        WHERE p.#pname = SADVISOR

                       IF VALID-ADVISOR = 0 THEN
##                        MESSAGE "Not a valid advisor name"
##                        SLEEP 2 
##                        RESUME FIELD #sadvisor 
                       ELSE
##                   REPLACE s (#sgpa = SGPA, #scomment = SCOMMENT,
##                                   #sadvisor = SADVISOR)
##                                   WHERE s.#sidno = SIDNO 
##                      BREAKDISPLAY 
                      END-IF.

##      }

##      ACTIVATE MENUITEM "End", FRSKEY3
##      {

* Quit without submitting changes

                 MOVE 0 TO CHANGED.
##               BREAKDISPLAY

##      }
##      FINALIZE

END-STUDENT.