# Compaq ACMS for OpenVMS
Writing Applications

Previous | Contents | Index

#### 2.2.5.1.3 Additional Workspace Definitions

Because the error handling described in the preceding sections named new workspaces, you must enter these definitions into the dictionary. In the first exchange step, the CONTROL FIELD clause tests the QUIT_KEY field of the QUIT_CTRL_WKSP workspace.

In the processing step, the IF THEN ELSE clause uses an ACMS system workspace and the MSG_WKSP workspace. You do not need to do anything with the system workspace, but you have to enter the MSG_WKSP definition into the dictionary.

In your task definition, you must include QUIT_CTRL_WKSP and MSG_WKSP in the WORKSPACES clause.

### 2.2.5.2 Repeating the Task Automatically

In a data entry task, you frequently do not want to redisplay the menu each time the user adds a reservation record or encounters an error. Instead, you want to repeat the task automatically, letting the user return to the menu by pressing a function key such as PF4.

You can describe this characteristic by using the REPEAT TASK clause when you define the actions for the block step. You can include the optional ACTION keyword to distinguish the action part of the block definition from the work part of the definition.

Example 2-3 shows the complete definition for the new version of the Add Car Reservation task.

Example 2-3 Complete Definition for the Add Car Reservation Task

    REPLACE TASK ADD_CAR_RESERVATION_TASK
    WORKSPACES ARE ADD_RESERVE_WKSP, QUIT_CTRL_WKSP, MSG_WKSP;

    BLOCK WORK WITH FORM I/O IS

     GET_RENTAL_INFORMATION:
      EXCHANGE WORK IS
       TRANSCEIVE FORM RECORD ADD_RESERVE_FORM_REC,
                              ADD_RESERVE_FORM_REC_LIS
        SENDING ADD_RESERVE_WKSP
        RECEIVING ADD_RESERVE_WKSP, QUIT_CTRL_WKSP;
      ACTION IS
       CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY
       "QUIT"  :  EXIT TASK;
       END CONTROL FIELD;

     WRITE_RESERVATION_INFORMATION:
      PROCESSING WORK IS
       CALL WRITE_RESERVE_PROC IN RESERVE_SERVER
       USING ADD_RESERVE_WKSP;
      ACTION IS
       IF (ACMS$T_STATUS_TYPE EQ "B")
       THEN GET ERROR MESSAGE;
            MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL;
            GOTO NEXT EXCHANGE;
       ELSE GOTO PREVIOUS EXCHANGE;
       END IF;

     ERROR_PROCESS_MSG:
      EXCHANGE WORK IS
       SEND FORM RECORD MSG_FORM_REC
       SENDING MSG_WKSP;

    END BLOCK WORK;
    ACTION IS
     REPEAT TASK;

    END DEFINITION;

# 2.3 Defining an Inquiry Task

A task displaying information from a file has many of the same characteristics as one adding information to a file. This section presents an inquiry task, the Review Car Rates task, that displays rental rates for particular types of cars. Table 2-3 lists the steps that an inquiry task performs.

Table 2-3 Inquiry Task
Step | Type
--- | ---
Display a form to get information | Exchange step
Read information from a file | Processing step
Display an error message if necessary | Exchange step
Display a form with information | Exchange step

## 2.3.1 Getting Information from the User

The first step of both data entry and inquiry tasks involves getting information from the user. In the Review Car Rates task, the terminal user types in a code indicating the class of car (compact, midsize, and so on) that the customer wants to rent and presses `[Return]` or `[Enter]` to proceed to the next step. Otherwise, the terminal user can press `[PF4]` to exit from the task and return to the menu.

The first step of the Review History inquiry task looks like this:

    DETERMINE_RENTAL_CLASS:
      EXCHANGE
       TRANSCEIVE FORM RECORD RENTAL_CLASSES_FORM_REC,
                              RENTAL_CLASSES_FORM_REC_LIS
        SENDING RENTAL_CLASSES_WKSP
        RECEIVING RENTAL_CLASSES_WKSP, QUIT_CTRL_WKSP;
      ACTION
       CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY
       "QUIT"  :  EXIT TASK;
       END CONTROL FIELD;

Because both the DETERMINE_RENTAL_CLASS step and the first step in the data entry task get information from the user, their definitions are almost identical. Both steps do the following:

- Use a TRANSCEIVE clause to display a form asking for information
- Let the user exit directly from the step
- Use workspaces to pass control information and data

The definitions of the workspaces for the data entry and inquiry tasks are similar also. Example 2-4 shows the definition for RENTAL_CLASSES_WKSP that the first step of the Review Car Rates task uses.

Example 2-4 Definition for RENTAL_CLASSES_WKSP

    Definition of record RENTAL_CLASSES_WKSP
    |   Contains field          COUNTRY_ID
    |   |  Datatype                 signed longword
    |   Contains field          REQUESTED_RENTAL_CLASS_ID
    |   |  Datatype                 text size is 2 characters
    |   Contains field          DAY_RENTAL_RATE_AMT
    |   |  Datatype                 text size is 5 characters
    |   Contains field          WEEK_RENTAL_RATE_AMT
    |   |  Datatype                 text size is 7 characters
    |   Contains field          MONTH_RENTAL_RATE_AMT
    |   |  Datatype                 text size is 7 characters

As in the data entry task, you can use the DECforms COPY statement in the RENTAL_CLASSES_FORM IFDL code to create the RENTAL_CLASSES_FORM_REC form record that corresponds to the application workspace.

## 2.3.2 Retrieving Information from a File

The second part of data entry and inquiry involves interaction with a file. You accomplish this interaction by using a procedure in a processing step. In a data entry task, a procedure writes data to a file; in an inquiry task, a procedure reads data from a file.

You must consider errors that can occur when a procedure tries to read from a file. In the Review Car Rates task, a procedure reads from the Rates file, using the rental class code as a key in RENTAL_CLASSES_WKSP. The procedure can encounter the following errors:

- The record does not exist.
- The record is locked by another user.

Both of these errors are recoverable; the user can type a new number if the record did not exist or can retry the inquiry if the record was locked. Any other errors in reading the record are treated as nonrecoverable, and the procedure cancels the task.

Both recoverable errors cause the procedure to return an error code with a severity level of WARNING or ERROR. Both of these severity levels are handled by the value B (BAD) in the ACMS$T_STATUS_TYPE field in the workspace ACMS$PROCESSING_STATUS. Therefore, you can use the IF THEN ELSE clause to test the contents of that field and handle errors for the task.

Because the second step of an inquiry task and the second step of a data entry task perform processing, both steps are very similar.

    GET_RENTAL_RATES:
      PROCESSING
        CALL GET_RATES_PROC IN RENTAL_SERVER
          USING RENTAL_CLASSES_WKSP;
      ACTION IS
        IF (ACMS$T_STATUS_TYPE EQ "B")
        THEN GET ERROR MESSAGE;
             MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL;
             GOTO NEXT EXCHANGE;
        ELSE GOTO STEP DISPLAY_RENTAL_RATES;
        END IF;

Both steps do the following:

- Call a procedure to read from or write to a file
- Use information stored in a workspace
- Test the ACMS$T_STATUS_TYPE field of the ACMS$PROCESSING_STATUS system workspace for the severity level of errors returned by the procedure
- Go to an exchange step that displays an error message, if the value of ACMS$T_STATUS_TYPE is B

If ACMS evaluates the Boolean expression in the IF THEN ELSE clause to be false, it performs the action associated with the ELSE keyword. In this case, it passes control to the DISPLAY_RENTAL_RATES exchange step.

For the processing step of the Review Car Rates task, the procedure GET_RATES_PROC in RENTAL_SERVER uses the rental class code stored in RENTAL_CLASSES_WKSP to read a record from the Rates file. The procedure returns a status value to the ACMS$PROCESSING_STATUS system workspace. ACMS uses the severity level of the status to return either a B or G to the ACMS$T_STATUS_TYPE field. If the value in that field is B, ACMS retrieves an error message from an error message file and passes control to the NO_RC_MSG exchange step, which displays the error message on the terminal screen.

    NO_RC_MSG:
      EXCHANGE
        TRANSCEIVE FORM RECORD MSG_FORM_REC, QUIT_CTRL_FORM_REC
         SENDING MSG_WKSP
         RECEIVING QUIT_CTRL_WKSP;
      ACTION IS
        IF (QUIT_CTRL_WKSP.QUIT_KEY EQ "QUIT")
        THEN EXIT TASK;
        ELSE GOTO STEP DETERMINE_RENTAL_CLASS;
        END IF;

As in the data entry task, you must define the additional workspaces that you use for error handling, QUIT_CTRL_WKSP and MSG_WKSP. Because the NO_RC_MSG exchange step sends the error message from MSG_WKSP to the form, you also need to include the form record definition for MSG_FORM_REC in the IFDL code. QUIT_CTRL_FORM_REC is the form record that corresponds to the QUIT_CTRL_WKSP workspace.

The NO_RC_MSG exchange step uses an IF THEN ELSE clause in the action part of the step to test whether or not the terminal user wants to exit from the task. If the user does not want to exit, ACMS passes control to the DETERMINE_RENTAL_CLASS exchange step so that the user can enter another rental class code.

## 2.3.3 Displaying Information

In a data entry task, once a procedure has written the information to a file, the task is complete. For an inquiry task, however, once the procedure has read information from a file, you must display that information to the terminal user.

As in the first exchange step of both the data entry and inquiry tasks, you can let the user press a function key to exit the task.

    DISPLAY_RENTAL_RATES:
      EXCHANGE WORK IS
       TRANSCEIVE FORM RECORD RENTAL_CLASSES_FORM_REC, QUIT_CTRL_FORM_REC
        SENDING RENTAL_CLASSES_WKSP
        RECEIVING QUIT_CTRL_WKSP;
      ACTION
       CONTROL FIELD QUIT_CTRL_WKSP.QUIT_KEY
       "QUIT"   :   EXIT TASK;
       END CONTROL FIELD;

This step:

- Displays the rates for cars in the requested rental class
- Ends the task, if the user presses a function key

Once the DISPLAY_RENTAL_RATES step has displayed the car rates, ACMS returns control to the block step part of the definition.

## 2.3.4 Completing the Task Definition

Like the Add Car Reservation task, the Review Car Rates task uses DECforms to communicate with the terminal user. Therefore, you need to assign the FORM I/O attribute to the block step.

You define the start of the block step with the BLOCK WORK keywords. You use the END BLOCK WORK keywords to signal the end of the work done in the block and to separate the block work from the block action.

For inquiry tasks, terminal users are likely to want to look at more than one record without having to reselect the task from a menu. You can let them do this by using the REPEAT TASK clause in the action part of the block step definition.

Finally, you must identify the workspaces used by steps in the task. Here is the task part of the definition for the Review Car Rates task:

    WORKSPACES ARE RENTAL_CLASSES_WKSP, QUIT_CTRL_WKSP, MSG_WKSP;

The task automatically uses the ACMS$PROCESSING_STATUS workspace; do not name that workspace in the WORKSPACES clause. Example 2-5 shows the complete definition for the Review Car Rates task.

Example 2-5 Complete Definition of the Review Car Rates Task

    REPLACE TASK REVIEW_CAR_RATES_TASK /LIST=CARRTRV.LIS

    WORKSPACES ARE RENTAL_CLASSES_WKSP, QUIT_CTRL_WKSP, MSG_WKSP;
    BLOCK WORK WITH FORM I/O

    DETERMINE_RENTAL_CLASS:
      EXCHANGE
       TRANSCEIVE FORM RECORD RENTAL_CLASSES_FORM_REC,
                              RENTAL_CLASSES_FORM_REC_LIS
        SENDING RENTAL_CLASSES_WKSP
        RECEIVING RENTAL_CLASSES_WKSP, QUIT_CTRL_WKSP;
      ACTION
       CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY
       "QUIT"  :  EXIT TASK;
       END CONTROL FIELD;

    GET_RENTAL_RATES:
      PROCESSING
        CALL GET_RATES_PROC IN RENTAL_SERVER
          USING RENTAL_CLASSES_WKSP;
      ACTION IS
        IF (ACMS$T_STATUS_TYPE EQ "B")
        THEN GET ERROR MESSAGE;
             MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL;
             GOTO NEXT EXCHANGE;
        ELSE GOTO STEP DISPLAY_RENTAL_RATES;
        END IF;

    NO_RC_MSG:
      EXCHANGE
        TRANSCEIVE FORM RECORD MSG_FORM_REC, QUIT_CTRL_FORM_REC
         SENDING MSG_WKSP
         RECEIVING QUIT_CTRL_WKSP;
      ACTION IS
        IF (QUIT_CTRL_WKSP.QUIT_KEY EQ "QUIT")
        THEN EXIT TASK;
        ELSE GOTO STEP DETERMINE_RENTAL_CLASS;
        END IF;

    DISPLAY_RENTAL_RATES:
      EXCHANGE WORK IS
       TRANSCEIVE FORM RECORD RENTAL_CLASSES_FORM_REC, QUIT_CTRL_FROM_REC
        SENDING RENTAL_CLASSES_WKSP
        RECEIVING QUIT_CTRL_WKSP;
      ACTION
       CONTROL FIELD QUIT_CTRL_WKSP.QUIT_KEY
       "QUIT"   :   EXIT TASK;
       END CONTROL FIELD;
    END BLOCK WORK;

    ACTION
      REPEAT TASK;

    END DEFINITION;

When making changes to the definition, use the REPLACE command on the first line in the file to minimize the changes that you have to make to the file later. If you want to produce a listing file when submitting the file to ADU, you must include the /LIST qualifier in the file itself, because you cannot use it with the at sign character (@). The listing file shows you the source definition file and errors encountered by ADU when that definition was processed with the CREATE or REPLACE command.

To submit the definition file REVIEW_CAR_RATES_TASK.COM to ADU, type:

    ADU> @REVIEW_CAR_RATES_TASK.COM

If there are no syntax errors in the definition, ADU stores it in the dictionary. If there are errors in the definition, you can edit the source definition file and resubmit it to ADU as a command file.

## 2.3.5 Additional Considerations: Displaying Multiple Records

The previous sections show how to define a simple inquiry task, Review Car Rates. That task displayed a single record from a file. However, you might want to define a task that lets a user display many records at the same time. Also, all the records requested by the user might not fit on a single screen.

For example, a car rental agency that handles many corporate car rentals needs to be able to review all the current reservation records for a particular company's employees. The Review Reservation task lets a terminal user display the reservation records for employees in a particular company. The task displays only five records at a time. However, it lets the terminal user display five more records without redisplaying the initial panel.

Because the Review Reservation task is still an inquiry task, its basic structure is the same as before. However, although the basic parts of the problem are the same, the action taken at the end of the second and fourth steps is affected by the following:

- Whether or not there are more records available for display
- Whether or not the terminal user wants to see more records

The steps for the Review Reservation task follow:

1. Display a panel requesting the identification number of the company whose employee reservations the terminal user wants to see.
2. Read information from the Reservation file.
3. Display error message if necessary.
4. Display records for the terminal user. If the user wants to see more records, repeat the second and fourth parts. Otherwise, end the task.

### 2.3.5.1 Getting Information from the User

The exchange step you define to get information is virtually the same in the Review Reservation task as in the Review Car Rates task:

    GET_COMPANY_ID:
      EXCHANGE
        TRANSCEIVE FROM RECORD CO_RESERVE_FORM_REC,
                               CO_RESERVE_FORM_REC_LIS
         SENDING CO_RESERVE_WKSP
         RECEIVING CO_RESERVE_WKSP, QUIT_CTRL_WKSP;
      ACTION IS
        CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY
          "QUIT"     : EXIT TASK;
        END CONTROL FIELD;

Like the Review Car Rates task, the Review Reservation task uses one workspace for storing data returned by the form and another workspace for testing whether or not the terminal user wants to exit from the task. Example 2-6 shows the record description of CO_RESERVE_WKSP.

Example 2-6 Record Description for REVIEW_RESERVATION_WORKSPACE

    Definition of record CO_RESERVE_WKSP
    |   Contains field           COMP_ID
    |   |  Datatype                  text size is 5 characters
    |   Contains field           COMP_NAME
    |   |  Datatype                  text size is 20 characters
    |   Contains field           WK_ERR_MSG
    |   |  Datatype                  text size is 4 characters
    |   Contains field           WK_SAVE_NUMBER
    |   |  Datatype                  signed longword
    |   Contains record          EMPL
    |   |  Row_major array           1:5
    |   |  Contains field            EMPL_NAME
    |   |  |  Datatype                   text size is 30 characters
    |   |  Contains field            EMPL_PHONE
    |   |  |  Datatype                   text size is 10 characters
    |   |  Contains field            CAR_TYPE
    |   |  |  Datatype                   text size is 3 characters
    |   |  Contains field            RENTAL_DATE
    |   |  |  Datatype                   text size is 6 characters
    |   |  Contains field            RETURN_DATE
    |   |  |  Datatype                   text size is 6 characters

### 2.3.5.2 Retrieving Information

The definition of the processing step for the Review Reservation inquiry task is very similar to that for the Review Car Rates inquiry task. It calls a procedure and handles recoverable errors.

    GET_FIVE_RESERVATIONS:
      PROCESSING
        CALL REVIEW_RESERVATION_PROC IN RESERVATION_SERVER
          USING CO_RESERVE_WKSP;
      ACTION IS
        IF (ACMS$STATUS_TYPE EQ "B")
        THEN GET ERROR MESSAGE;
             MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL;
             GOTO NEXT EXCHANGE;
        ELSE GOTO STEP DISPLAY_RESERVATIONS;
        END IF;

However, the REVIEW_RESERVATION_PROC procedure, after reading as many records as fit on the terminal screen, must tell the form whether or not there are more records available for display.

The REVIEW_RESERVATION_PROC procedure writes either MORE or STOP to the WK_ERR_MSG field of CO_RESERVE_WKSP. You must code your IFDL form file to test that field to tell the terminal user whether or not there are more records to see.

As in the previous task definitions, you need to add code to handle possible processing errors. The processing step tests the ACMS$T_STATUS_TYPE field, and if the field indicates that an error occurred, ACMS moves the error message to the MSG_WKSP workspace and passes control to the DISPLAY_ERROR exchange step.

    DISPLAY_ERROR:
       EXCHANGE
        TRANSCEIVE FORM RECORD MSG_FORM_REC, QUIT_CTRL_FORM_REC
         SENDING MSG_WKSP
         RECEIVING QUIT_CTRL_WKSP.QUIT_KEY;
        ACTION
         IF (QUIT_CTRL_WKSP.QUIT_KEY EQ "QUIT")
         THEN EXIT TASK;
         ELSE GOTO STEP GET_COMPANY_ID;
         END IF;

This exchange step is identical to that used in the Review Car Rates task. After it displays the error message to the terminal user, it checks to see whether or not the user wants to exit from the task. If the user does not want to exit, ACMS returns control to the first exchange step.

### 2.3.5.3 Displaying Information to the User

As in any exchange step, when you use a form to display information, you can let the terminal user press a function key to exit the task. In this type of inquiry task, you also want to do the following:

- Use the form to tell the user whether or not there are more records available for display
- Let the user press a function key to see more records
- Retrieve and display the next five records if the user wants to see more records

Here is the definition of the final exchange step of the Review Reservation task:

    DISPLAY_RESERVATION:
      EXCHANGE
       TRANSCEIVE FORM RECORD CO_RESERVE_FORM_REC, QUIT_CTRL_FORM_REC
        SENDING CO_RESERVE_WKSP
        RECEIVING QUIT_CTRL_WKSP;
       ACTION IS
        CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY
        "QUIT"   :   EXIT TASK;
        "MORE"   :   GOTO PREVIOUS PROCESSING;
        END CONTROL FIELD;

Just as you declared the PF4 function key to be the QUIT_KEY in the Add Car Reservation task, you must declare a function key and function response in your IFDL file so that the terminal user can press that key to see five more records. When the terminal user presses that key, DECforms passes the "MORE" value into the QUIT_KEY field of the QUIT_CTRL_WKSP workspace. When ACMS processes the DISPLAY_RESERVATION step, if that field contains "MORE", ACMS repeats the GET_FIVE_RESERVATIONS processing step. The user avoids returning to the first step to retype the company identification number.

Previous | Next | Contents | Index