# Compaq ACMS for OpenVMS
Getting Started

Previous | Contents | Index

## 7.4.2 Defining the Processing Step

You begin a processing step by identifying it with the keyword PROCESSING. This processing step calls a procedure that adds information to an RMS file.

The processing step is located after the exchange step. Add the processing step as follows:

1. Add these clauses as the first part of your processing step:

       PROCESS_EMPL_INFO:
         PROCESSING
           CALL ADD_EMPL_INFO IN EMPL_SERVER
             USING EMPLOYEE_INFO_WKSP, CONTROL_WORKSPACE;

   As mentioned previously, when ACMS starts a processing step, it allocates a server process to handle the procedure in that step. A server process is a specialized OpenVMS process with a user name, privileges, and quotas, just like your own OpenVMS process. (This manual often refers to a server process simply as a server.)
   In the CALL clause, you specify the procedure name and the name of the server in which the procedure executes. The server process (named EMPL_SERVER here) can have any name you choose. The procedure (named ADD_EMPL_INFO here) must correspond to the PROGRAM-ID name that you specify in the COBOL procedure later in this chapter.
   The CALL clause also includes a USING phrase that names the two workspaces that this procedure uses: EMPLOYEE_INFO_WKSP, which stores the user input to be passed to the procedure for processing; and CONTROL_WORKSPACE, which holds status values and error messages.
2. Add these clauses to your processing step to handle duplicate employee number errors:

       IF (CONTROL_WORKSPACE.ERROR_STATUS_FIELD EQ "DUPL")
         THEN
          MOVE "Employee number already exists. Ctrl/Z to repeat, PF4 to quit."
                  TO CONTROL_WORKSPACE.MESSAGEPANEL;
         ELSE
          EXIT TASK;
       END IF;

   In the data entry task, you need to include a method for reporting any errors that can occur when the processing step attempts to write the new information to the RMS file. When the ADD_EMPL_INFO procedure finishes executing, it returns a status value that indicates whether or not the procedure completed successfully.
   A common error in a data entry task occurs when the user tries to enter information for a primary key that already exists. For example, in this tutorial application, every employee is uniquely identified by an employee number (the EMPL_NUMBER field of EMPLOYEE_INFO_WKSP). If a user tries to write a new record to the RMS file with an employee number that already exists, the user receives an error message on the terminal screen.
   The ADD_EMPL_INFO procedure tests the return status value of the write operation. If the status value corresponds to the COBOL code for the duplicate primary key error, the procedure stores the value DUPL in a workspace field.
   The processing step in this task tests the field ERROR_STATUS_FIELD, using an IF clause. If that field contains DUPL, the processing step directs ACMS to move an error message to the field MESSAGEPANEL, and the task continues to a second exchange step to display the message. Otherwise, if the DUPL value is not in the workspace field, control passes to the ELSE statement, and the task ends successfully.

## 7.4.3 Defining the Second Exchange Step

The purpose of the second exchange step is to display an error message if the user tries to enter an employee number that already exists in the RMS file (DUPL error). Add the second exchange step as follows:

1. The SEND statement specifies the name of the form record (CONTROL_WORKSPACE):

       DISPLAY_ERROR_MESSAGE:
         EXCHANGE
           SEND FORM RECORD CONTROL_WORKSPACE

2. The SENDING statement specifies the name of the workspace that ACMS uses to pass the error message to the form. The RECEIVE CONTROL clause specifies the name of the record that contains the QUIT_KEY field:

           SENDING CONTROL_WORKSPACE
           WITH RECEIVE CONTROL QUIT_WORKSPACE;

   The record CONTROL_WORKSPACE contains the field MESSAGEPANEL, which stores the error message corresponding to the DUPL error. DECforms receives the message from ACMS, displays the message in its default message panel, and waits for the user to take some action.
3. Enter the following ACTION clause to complete the exchange step:

         ACTION IS
           IF (QUIT_WORKSPACE.QUIT_KEY EQ " FQUT")
           THEN EXIT TASK;
           ELSE REPEAT TASK;
           END IF;

   The IF clause tests the value of the field QUIT_KEY. If the value is FQUT (that is, if the user presses `[PF4]` ), the action is to exit the task. Otherwise, if the user executes the transmit function (presses `[Ctrl/Z]` ), the action is to repeat the task, sending control back to the first exchange step. In this way, the user can read the error message and choose one of two actions: to end the task or to repeat it.

## 7.4.4 Defining the Block Step and Workspaces

After defining the exchange and processing steps of a task, you use a block step to place those steps in a group. A block step can have three parts:

- Attributes, an optional part of the block that describes the characteristics of the steps in a block
- Work, a required part of the block that comprises the exchange and processing steps of the task
- Actions, an optional part of the block that describes the action to be taken after the work is done

To define the block step and the remaining elements of this task definition, you need to add some lines at the beginning of your file and at the end of your file.

1. Enter the following lines at the beginning of your file:

       REPLACE TASK EMPLOYEE_INFO_ADD_TASK
       DEFAULT FORM IS EMPLOYEE_INFO_LABEL;
       USE WORKSPACES
        EMPLOYEE_INFO_WKSP,
        QUIT_WORKSPACE,
        CONTROL_WORKSPACE;

       BLOCK WORK WITH FORM I/O

   REPLACE is an ADU command that stores a new task definition in CDD (creating a new definition or replacing an old one). Placing this command inside the task definition allows you to run this task definition (EMPLOYEE_INFO_ADD_TASK) as a command file in ADU (see Section 7.5).
   The DEFAULT FORM clause is an option that specifies a label name used within ACMS to refer to a DECforms form. EMPLOYEE_INFO_LABEL is mapped to the actual form name (EMPLOYEE_INFO_FORM) through the FORMS clause in the task group definition. This label name can be identical to the form name. If you do not enter the DEFAULT FORM clause at the beginning of a task definition, you need to include the form label name as part of each SEND, RECEIVE, and TRANCEIVE clause in the task definition. For example, RECEIVE FORM RECORD EMPLOYEE_INFO_RECORD IN EMPLOYEE_INFO_LABEL.
   Those steps that you include in the block step share some characteristics such as the list of the workspaces used in the task to pass information between the task and exchange steps, and between the task and processing steps.
   The BLOCK WORK clause marks the beginning of the work that takes place within the block step. Because the task communicates with DECforms for terminal I/O operations, include the words WITH FORM I/O.
2. Enter the following lines at the end of your file:

       END BLOCK WORK;

       END DEFINITION;

   The END BLOCK WORK clause ends the work done within the block step.
3. Your task definition for the Data Entry Task, EMPLOYEE_INFO_ADD_TASK.TDF, is now complete. Save your file and exit the editor.

# 7.5 Compiling the Task Definition in ADU

Compiling the task definition in ADU allows ADU to check for syntax errors in the source file EMPLOYEE_INFO_ADD_TASK.TDF. If there are no errors, ADU inserts your task definition into CDD. To do this, perform the following steps:

1. Edit your login command file to define ADU as a global symbol. Then exit the editor and reinitialize your edited login command file:

       $ ADU :== $ACMSADU

       $ @LOGIN.COM

2. Invoke ADU:

       $ ADU

3. Type the SET LOG and SET VERIFY commands at the ADU> prompt:

       ADU> SET LOG
       ADU> SET VERIFY

   SET LOG causes ADU to write the task definition to the ADULOG.LOG file as ADU compiles it, including any error messages. Each time you issue an ADU command, ADU appends log information to this file.
   SET VERIFY causes ADU to display the task definition on your terminal screen as ADU compiles it. If your task definition compiles successfully (no error messages), ADU inserts it into your default CDD directory. If there are errors, messages appear in the text of the definition as ADU displays it on your terminal screen.
4. Submit the file EMPLOYEE_INFO_ADD_TASK.TDF, as follows:

       ADU> @EMPLOYEE_INFO_ADD_TASK.TDF

   If ADU detects syntax errors in your task definition, exit ADU and edit the source file to correct the errors. Then reenter ADU and resubmit the file. Repeat editing the source file and resubmitting it to ADU until the file processes without errors. If you get error messages, make sure you typed the definition exactly as shown. In particular, check that you used the appropriate punctuation.
5. Exit from ADU:

       ADU> EXIT
       $

6. Check that your task definition is now located in your default CDD directory. (In Section 7.1, step 6, you defined CDD$DEFAULT in your login command file.) Enter CDO and issue the CDO DIRECTORY command:

       $ CDO
       CDO> DIRECTORY

        Directory disk:[cdd_directory]d_name
        .
        .
        .
        EMPLOYEE_INFO_ADD_TASK;1                     ACMS$TASK
       CDO>

# 7.6 Defining a System Logical for Your Tutorial Directory

To complete the data entry task, you need to create a procedure that writes a new record to an RMS master file. In this tutorial, the name of this RMS file is EMPLOYEE.DAT.

So that ACMS can find this file, your COBOL procedures need to specify where EMPLOYEE.DAT is located. The easiest way to do this is to define a system logical that points to its location (your OpenVMS directory of source files). Your system logical must be unique so that it does not conflict with logicals used by others who may be entering this same tutorial on your system.

Define the system logical as follows, substituting your initials or other unique characters for xxx. (Remember that udisk and uname represent the disk and user-name directory where your application files are located.)

    $ DEFINE/SYSTEM xxx_FILES udisk:[uname]

If you do not have the necessary privileges to define a system logical, you receive an "insufficient privileges" message here. If so, see your system manager about defining your system logical.

If your account is on an OpenVMS Cluster system, you can be logged in to any of several nodes. In this case, define your logical on each node in the cluster.

You can verify your system logical by issuing the following command:

    $ SHOW LOGICAL xxx_FILES

By defining the system logical xxx_FILES, you can use it whenever your procedures and definitions refer to the location of EMPLOYEE.DAT and other files used in this tutorial application (substituting your unique logical wherever xxx_FILES occurs). For example, in your COBOL procedures:

    ASSIGN TO "xxx_FILES:EMPLOYEE.DAT".

Note If you copied the online source files to your default directory before starting this tutorial, edit each file that contains the logical xxx_FILES and substitute your unique logical. Section B.2 lists those files that contain the term xxx_FILES.

# 7.7 Defining the Data Entry Procedure

This section describes how to define the COBOL procedure that, when called by the data entry task, writes a new record to the RMS master file.

Create the Data Entry COBOL procedure as follows:

1. Example 7-1 contains the COBOL procedure. Create a source file named EMPLOYEE_INFO_ADD.COB and type in the procedure as shown in this example.

   Note If you copied this file from the online source files, edit the file and substitute your unique logical for the xxx_FILES logical in the file. Section B.2 lists other files that contain the logical xxx_FILES.

2. Save the file and exit the editor.

Example 7-1 COBOL Data Entry Procedure

    IDENTIFICATION DIVISION.
    PROGRAM-ID. ADD_EMPL_INFO.

    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
    SOURCE-COMPUTER.  VAX-11.
    OBJECT-COMPUTER.  VAX-11.
    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
    SELECT  EMPLOYEE-FILE
            ORGANIZATION INDEXED
            ACCESS RANDOM
            FILE STATUS IS FILE-STAT
            ASSIGN TO "xxx_FILES:EMPLOYEE.DAT".
    I-O-CONTROL.
            APPLY LOCK-HOLDING ON EMPLOYEE-FILE.

    DATA DIVISION.
    FILE SECTION.
    FD      EMPLOYEE-FILE EXTERNAL
            DATA RECORD IS EMPLOYEE_INFO_WKSP
            RECORD KEY EMPL_NUMBER OF EMPLOYEE_INFO_WKSP.

    COPY "EMPLOYEE_INFO_WKSP" FROM DICTIONARY.

    WORKING-STORAGE SECTION.
    01  FILE-STAT                        PIC XX IS EXTERNAL.
        88 OK                              VALUE "00".
        88 DUPL-PRIMARY                    VALUE "22".
        88 REC-LOCK                        VALUE "92".

    LINKAGE SECTION.
    COPY "EMPLOYEE_INFO_WKSP" FROM DICTIONARY REPLACING
        ==EMPLOYEE_INFO_WKSP. == BY ==EMPLOYEE_INFO_LINKAGE_WKSP. ==.
    COPY "CONTROL_WORKSPACE" FROM DICTIONARY.

    PROCEDURE DIVISION USING EMPLOYEE_INFO_LINKAGE_WKSP, CONTROL_WORKSPACE.
    DECLARATIVES.
    EMPLOYEE-USE SECTION.
        USE AFTER STANDARD ERROR PROCEDURE ON EMPLOYEE-FILE.
    EMPLOYEE-CHECKING.
        EVALUATE TRUE
            WHEN DUPL-PRIMARY
              MOVE "DUPL" TO ERROR_STATUS_FIELD
            WHEN OTHER
              CALL "ACMS$RAISE_NONREC_EXCEPTION" USING
              BY REFERENCE RMS-STS OF EMPLOYEE-FILE
        END-EVALUATE.
    END DECLARATIVES.

    MAIN SECTION.
    000-SET-STATUS.
        MOVE SPACES TO ERROR_STATUS_FIELD.

    010-WRITE-RECORD.
        WRITE EMPLOYEE_INFO_WKSP FROM EMPLOYEE_INFO_LINKAGE_WKSP
           ALLOWING NO OTHERS.

    100-EXIT-PROGRAM.
        UNLOCK EMPLOYEE-FILE.
        EXIT PROGRAM.

The following sections discuss various elements in this COBOL program. For complete reference information on VAX COBOL, see VAX COBOL Reference Manual.

## 7.7.1 Identification Division

In the Identification Division of this program, you give the COBOL procedure a name to complete the PROGRAM-ID statement. This name must be unique among all the procedures that run in the same server, and it must be the same name that you specified previously in your task definition's CALL statement to this procedure.

In this tutorial, the name of the COBOL procedure is ADD_EMPL_INFO.

## 7.7.2 Environment Division

The Environment Division defines the RMS file named EMPLOYEE.DAT and specifies its location. EMPLOYEE-FILE is the procedure's internal name for referencing the external file EMPLOYEE.DAT, where the procedure stores the information that the user enters. (The file EMPLOYEE.DAT is created by the COBOL initialization procedure defined in Chapter 9.)

You use the SELECT clause to assign the internal name to the RMS file, describe the organization and access of the file, provide a FILE STATUS buffer, and assign the OpenVMS file specification for the RMS file.

The FILE STATUS clause identifies the FILE-STAT data item, where the status value of the write operation is stored. In the I-O-CONTROL section, the APPLY statement enables record locking for EMPLOYEE-FILE.

## 7.7.3 Data Division

In the Data Division, you define the personnel records that make up the RMS file, naming one field as the primary key. An RMS file in an ACMS application contains records whose definitions reside in CDD. Therefore, the Data Division need not list every field in the record, but can instead include a COPY ... FROM DICTIONARY clause for the record definition.

This procedure identifies EMPLOYEE-FILE as EXTERNAL because the file is accessed externally. The RECORD KEY clause establishes the employee number field, EMPL_NUMBER, as the primary key of the record. The COPY statement directs the procedure to find the definition of EMPLOYEE_INFO_WKSP in the CDD dictionary when you compile this COBOL program.

The Data Division also sets up condition values for you to use in error handling. A user might try to add a new record to the file using an employee number that already exists. The COBOL condition code for the duplicate key error is 22. In the Data Division, you declare the FILE-STAT data item and associate it with the names of the condition values (DUPL_PRIMARY, for example) that your procedure tests during its execution.

Another possible error is when a second user tries to access the record while the procedure is processing the record for the first user. Because the procedure locks the record during I/O processing, the second user encounters a locked-record condition. The COBOL condition code for the locked-record error is 92. You must also associate FILE-STAT with the REC-LOCK condition.

The Linkage Section of this procedure lists the workspaces passed between the task and the procedure. COPY statements describe which CDD record definitions correspond to the workspaces you need. Because the linkage record and the file record must have different names, the COPY statement for EMPLOYEE_INFO_WKSP must use a REPLACING clause to assign a different name to the workspace. This new name is used only in the Procedure Division of the procedure.

## 7.7.4 Procedure Division

The main action of the Procedure Division is to write a new record to the RMS file. ACMS passes the user input to the procedure in the EMPLOYEE_INFO_WKSP workspace, renamed to EMPLOYEE_INFO_LINKAGE_WKSP in the Linkage Section. The procedure uses CONTROL_WORKSPACE to report any errors. As required, the USING clause lists both workspaces in the same order as the CALL clause listed them in the task definition.

The Declaratives Section handles any errors in the procedure. If a duplicate primary key error occurs when the procedure tries to write a new record to the file, FILE-STAT is assigned the condition value DUPL-PRIMARY. The EVALUATE statement tests whether the DUPL-PRIMARY condition is true. If true, the value DUPL is moved to the field ERROR_STATUS_FIELD in the record CONTROL_WORKSPACE, and the ACMS task definition takes some action (sends an error message) based on finding the DUPL value. If any other error condition is true, the procedure cancels the task with the ACMS$RAISE_NONREC_EXCEPTION service. See Compaq ACMS for OpenVMS Writing Applications for information about recoverable and nonrecoverable exceptions.

The Main Section of this procedure performs these simple actions:

- Initializes the field ERROR_STATUS_FIELD to spaces (some value other than DUPL)
- Writes the new record to the file, locking it to prevent any access by other users while the write action is occurring
- Unlocks the record before exiting the program

This procedure does not create the RMS file, nor does it open the file once it exists. A separate initialization procedure (described in Chapter 9) performs these operations. Also, this procedure does not handle the user's interactions with the terminal; DECforms does this.

## 7.7.5 Compiling the COBOL Procedure

Use the COBOL command to compile this procedure. By appending the /DEBUG qualifier to this command, you create the capability to debug the procedure later with the OpenVMS Debugger. By appending the /LIST qualifier, you generate a listing of your program showing any errors. (The listing file has the file type .LIS.)

Compile the source file EMPLOYEE_INFO_ADD.COB as follows:

    $ COBOL/DEBUG/LIST EMPLOYEE_INFO_ADD

If the source file contains syntax errors, you must edit the file and recompile it until the COBOL compiler signifies that the program compiles successfully by returning to the $ prompt without any error messages. If you get error messages, make sure you typed the definition exactly as shown in Example 7-1. In particular, check that you used the appropriate punctuation.

See the COBOL documentation for information on compiling COBOL programs and interpreting COBOL error messages.

Previous | Next | Contents | Index