Case Logic

In this section:

How to:

Case Logic allows you to branch to different parts of MODIFY requests during execution. This enables you to construct more complex MODIFY requests. For example, Case Logic requests can offer the terminal operator the choice of different procedures, process different transaction records differently, or update multiple segment instances with a single transaction.

Case Logic also extends the use of the NEXT statement to process segment chains and facilitates modifying multiple unique child segments.

To prepare a request using Case Logic, you divide the request into sections called cases. Each case is labeled, allowing you to branch to the case from elsewhere in the request.

Syntax: How to Use a Case Statement

Each case begins with the statement

CASE {AT START|casename}

where:

AT START

Indicates that the case is to be executed only at the beginning of the request. This case is called the START case.

casename

Is a label of up to 12 characters that does not contain embedded blanks or the characters:

+ - * / & $ ' " 

Each case ends with the statement:

ENDCASE

The CASE and ENDCASE statements must both be on lines by themselves.

The first case in the request, the one immediately following the MODIFY command, needs neither a beginning nor an ending statement. It is automatically assigned the label TOP. Note, however, that if the request contains only one case, you may want to begin the case with the statement CASE TOP and end it with ENDCASE. This allows you to branch to the beginning of the request from its middle.

The following request updates employee salaries in the EMPLOYEE data source. If the salary is above $50,000, the request has the user retype the value to confirm it:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID CURR_SAL
IF CURR_SAL GT 50000 GOTO CONFIRM ELSE GOTO NEWSAL;
CASE NEWSAL
MATCH EMP_ID
  ON MATCH UPDATE CURR_SAL
  ON NOMATCH REJECT
ENDCASE
CASE CONFIRM
TYPE
  "THE SALARY YOU ENTERED EXCEEDS $50,000"
  "PLEASE REENTER THE SALARY TO CONFIRM IT"
  "OR ENTER A NEW SALARY"
PROMPT CURR_SAL
GOTO NEWSAL
ENDCASE
DATA

This request consists of three cases: the TOP case, the NEWSAL case, and the CONFIRM case. (The blank lines between cases are there to enhance readability and are not required.)

The TOP case contains the first two statements in the request:

PROMPT EMP_ID CURR_SAL
IF CURR_SAL GT 50000 GOTO CONFIRM

The TOP case prompts you for an employee ID and new salary. It then tests the salary value you entered. If the salary is more than $50,000, it branches to the CONFIRM case. Otherwise, the request proceeds with the next case.

The next case is the NEWSAL case. This case updates the employee salaries. After the update, the request automatically returns to the beginning of the TOP case to prompt for the next employee ID and salary.

The third case is the CONFIRM case. This is where the request branches if you enter a salary higher than $50,000. The case asks you to reenter the salary. It then branches to the NEWSAL case to enter the salary into the data source.

This is the order of cases executed if you enter a salary lower than $50,000:

  1. The TOP case.
  2. The NEWSAL case.
  3. Back to the TOP case.

This is the order of cases executed if you enter a salary higher than $50,000:

  1. The TOP case.
  2. The CONFIRM case.
  3. The NEWSAL case.
  4. Back to the TOP case.

Rules Governing Cases

The following rules apply to cases:

Executing a Case at the Beginning of a Request Only: The START Case

You can have your request begin execution with an initial case that is never executed afterwards. This case is called the START case and begins with the label:

CASE AT START

You cannot branch from other cases to the START case, but you can branch from the START case to other cases. If you do not branch to another case, the START case passes control to the TOP case. Note that the START case comes after the TOP case in the text of the request.

The following request counts how many employee salaries it updates. However, it starts counting from three:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID CURR_SAL
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH COMPUTE
     SALCOUNT/I4 = SALCOUNT + 1;
  ON MATCH UPDATE CURR_SAL
TYPE AT END
  "<SALCOUNT SALARIES PROCESSED"
CASE AT START
COMPUTE
  SALCOUNT = 3;
ENDCASE
DATA

The START case initializes the SALCOUNT counter to 3. After that, the request does not need to refer to the case again.

Note that temporary fields used in the START case that appear earlier in the request must have their formats defined there.

Branching to Different Cases: The GOTO, PERFORM, and IF Statements

How to:

Reference:

Three statements branch to other cases:

Syntax: How to Branch to Another Case With GOTO

GOTO statements unconditionally branch to another case. The syntax is

GOTO location

where:

location

Is one of the following:

TOP branches to the beginning of the TOP case.

ENDCASE branches to the end of the case. If the case was called by a PERFORM statement either directly or indirectly (for example, a PERFORM statement called a case that branched to this case), then control returns to the statement after the most recently executed PERFORM statement. Otherwise, the request branches back to the TOP case.

casename branches to the beginning of the specified case.

variable branches to the beginning of the case whose name is the value of the temporary field variable. The temporary field must have a format of A12.

EXIT terminates the request. This is useful when you want to halt execution before the last transaction in a data source or the transaction specified by the STOP command. Note that the statement GOTO EXIT is legal even in MODIFY requests without cases.

If a case does not have a GOTO statement, it branches to the TOP case upon completion unless a PERFORM or IF statement branches somewhere else.

Syntax: How to Use a PERFORM Statement

The PERFORM statement causes the request to branch to another case, executes that case, then returns control to the statement after the most recently executed PERFORM statement. The syntax is

PERFORM  location

where:

location

Is one of the following:

TOP branches to the beginning of the TOP case. All return points are cleared and the procedure continues as if no PERFORM statement had executed.

ENDCASE branches to the end of the case. If the case was called by another PERFORM statement, either directly or indirectly (for example, a PERFORM statement called a case that branched to this case), then control returns to the statement after the most recently executed PERFORM statement. Otherwise, the request branches back to the TOP case.

casename branches to the beginning of a specified case.

variable branches to the beginning of the case whose name is the value of the temporary field variable. The temporary field must have a format of A12.

EXIT terminates the request.

A PERFORM statement can branch to a case containing a GOTO or IF statement that branches to a second case. The second case can branch to a third case, and so on until the request encounters an ENDCASE statement at the end of a case. Control then returns to the statement after the most recently executed PERFORM statement.

A PERFORM statement can branch to a case containing a PERFORM statement that leads to other cases. When the request encounters an ENDCASE statement at the end of a case, control returns to the statement after the most recently executed PERFORM statement. Control eventually returns to the original PERFORM.

If a case branches to the TOP case, control does not return to the last PERFORM. Rather, the request begins a new cycle starting from the TOP case. All PERFORM return points are cleared.

Example: Using the PERFORM Statement

This sample request updates employee salaries. If a user enters a salary greater than $50,000, the request checks the employee ID against a list of IDs in the sequential data source EMPLIST. If the employee is listed, the request updates the salary; otherwise, it asks the user to re-enter the information. The request is:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID CURR_SAL
PERFORM EMPCHECK
PERFORM UPSAL
TYPE
  "SALARY OF EMPLOYEE <EMP_ID UPDATED"
CASE EMPCHECK
IF CURR_SAL LE 50000 GOTO ENDCASE;
COMPUTE
  RAISE_OK/A3 = DECODE EMP_ID (EMPLIST ELSE 'NO');
IF RAISE_OK IS 'NO' THEN PERFORM TOP;
ENDCASE
CASE UPSAL
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH UPDATE CURR_SAL
ENDCASE
DATA

Supposing the data source EMPLIST contained the following data:

071382660 YES
451123478 YES

A sample execution might go as follows:

  1. The request prompts you for an employee ID and a salary. You enter ID 818692173 and a salary of $35,000.
  2. The PERFORM EMPCHECK statement branches to the EMPCHECK case.
  3. Since the salary is less than $50,000, the PERFORM ENDCASE phrase returns control to the statement after the PERFORM EMPCHECK statement (PERFORM UPSAL).
  4. The PERFORM UPSAL statement branches to the UPSAL case.
  5. The case updates the salary and passes control to the TYPE statement (the statement after the most recently executed PERFORM statement).
  6. The TYPE statement displays the message:
    SALARY FOR EMPLOYEE 8188692173 UPDATED
  7. Control goes to the beginning of the TOP case.
  8. The TOP case prompts you for an employee ID and a salary.
  9. You enter an ID Of 119329144 and a salary of $65,000.
  10. The PERFORM EMPCHECK statement branches to the EMPCHECK case. Since employee 119329144 is not listed in the EMPLIST data source, the IF...GOTO TOP phrase branches to the TOP case.
  11. The TOP case prompts you for an employee ID and a salary. You enter an ID of 071382660 and a salary of $65,000.
  12. The PERFORM EMPCHECK statement branches to the EMPCHECK case. Since employee 071382660 is listed in the EMPLIST data source, control returns to the statement after the most recently executed PERFORM statement (PERFORM UPSAL).
  13. The PERFORM UPSAL statement branches to the UPSAL case, which updated the salary. Control then passes to the TYPE statement (the statement after the most recently executed PERFORM statement).
  14. The TYPE statement displays a message:
    SALARY FOR EMPLOYEE 071382660 UPDATED
  15. Control goes to the beginning of the TOP case.

Reference: Rules for PERFORM Statements

  • PERFORM statements can be nested; that is, one PERFORM statement can call a case containing a second PERFORM statement. PERFORM statements can be nested to any depth, limited only by available memory. If memory runs out, FOCUS displays the message:
    (FOC187) PERFORMS NESTED TOO DEEPLY
  • REPEAT statements can contain PERFORM statements. When control returns to the statement after the most recently executed PERFORM statement, the REPEAT statement resumes execution. For example:
    REPEAT 5 TIMES
      PERFORM ANALYSIS
      COMPUTE AMOUNT/D8.2 = RECEIPTS + AWARDS;
    ENDREPEAT

    Each pass of this REPEAT statement executes the ANALYSIS case, then computes the value of the AMOUNT field.

  • When a PERFORM statement branches to a case, you can return control to the PERFORM before the end of the case by including the GOTO ENDCASE or PERFORM ENDCASE statement in the case.

Syntax: How to Branch to Another Case With IF

The IF statement branches to another case depending on how an expression is evaluated. The syntax is

IF expr [THEN] {GOTO|PERFORM} location1 [ELSE {GOTO|PERFORM} location2]

where:

expr

Is any logical expression legal in a DEFINE or COMPUTE IF statement (see the Creating Reports manual). For example:

IF CURR_SAL GT 50000
IF SALARY/12 LT GROSS
IF LAST_NAME CONTAINS 'BLACK'
IF (CURR_SAL GT SALARY) OR
     (CURR_JOB CONTAINS 'B')

Note that literals must be enclosed in single quotation marks. Parentheses are necessary if the expression is compound.

IF expressions cannot compare data source fields unless they are used in or following MATCH or NEXT statements (see Branching to Different Cases: The GOTO, PERFORM, and IF Statements).

location1, location2

The options are:

TOP branches to the TOP case.

ENDCASE branches to the end of the case (the request then branches to the TOP case or to the statement after the most recently executed PERFORM statement).

case1 branches to the case named case1.

var branches to the case whose name is contained in the temporary field var.

EXIT terminates the request.

The word THEN is optional and is there to enhance readability.

An IF statement can extend over several lines, but must end with a semicolon (;).

Like IF statements in TABLE requests and Dialogue Manager control statements, Case Logic IF statements can be nested. You can nest IF statements so that if the outer IF expression is true, the inner IF is executed. Place the inner IF phrase within parentheses following the THEN phrase.

Example: IF Statement

IF expression1 
THEN (IF expression2 
THEN (IF expression3 GOTO case4 ELSE GOTO case3)
ELSE GOTO case2)
ELSE GOTO case1;

You can also nest IF statements so that if the outer IF expression is false, the inner IF is executed. You place the inner IF statement after the ELSE phrase. The inner IF does not need parentheses:

     IF expression1 THEN GOTO case1 
ELSE IF expression2 THEN GOTO case2 
ELSE IF expression3 THEN GOTO case3 
ELSE...;

The following request offers the user a choice between deleting a segment instance and including a new one:

MODIFY FILE EMPLOYEE
COMPUTE CHOICE/A6=;
TYPE
  "ENTER 'UPDATE' TO UPDATE A SALARY"
  "ENTER 'DELETE' TO DELETE AN EMPLOYEE"
PROMPT CHOICE
      IF CHOICE IS 'UPDATE' THEN GOTO UPDSEG
ELSE  IF CHOICE IS 'DELETE' THEN GOTO DELSEG
ELSE GOTO TOP;
CASE UPDSEG
PROMPT EMP_ID CURR_SAL
MATCH EMP_ID
  ON MATCH UPDATE CURR_SAL
  ON NOMATCH REJECT
ENDCASE
CASE DELSEG
PROMPT EMP_ID
MATCH EMP_ID
  ON MATCH DELETE
  ON NOMATCH REJECT
ENDCASE
DATA

This request has three cases:

  • The TOP case defines a variable called CHOICE, which will contain your response to its menu:

    If you enter UPDATE, the request branches to the UPDSEG case.

    If you enter DELETE, the request branches to the DELSEG case.

    If you enter neither, it reprompts you for another response by branching back to the beginning of the case.

  • The UPDSEG case prompts you for the employee ID and new salary, and updates the employee's salary.
  • The DELSEG case prompts you for the employee ID, and deletes that ID from the data source.

Rules Governing Branching

The following rules govern the sequence of case execution and branching:

The second case, NEWPAY, modifies the segment chain descended from the segment instance selected in the TOP case.

GOTO, PERFORM, and IF Phrases in MATCH Statements

You can use GOTO, PERFORM, and IF statements in MATCH and NEXT statements, where they form part of ON MATCH, ON NOMATCH, ON NEXT, or ON NONEXT phrases. IF phrases in MATCH and NEXT statements can use data source fields in expressions. To do this, affix the D. prefix to the field name. For example, the phrase

ON MATCH IF CURR_SAL LT D.CURR_SAL ...

tests whether the incoming value of CURR_SAL is less than the data source value of CURR_SAL. The data source value must either be in the segment instance that the MATCH or NEXT statement is processing or in a parent instance along the segment path (the parent, the parent's parent, and so on, up to the root segment).

For example, this request does not accept a new salary for an employee if it is less than the employee's present salary:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID CURR_SAL
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH IF CURR_SAL LT D.CURR_SAL GOTO ERROR;
  ON MATCH UPDATE CURR_SAL
CASE ERROR
TYPE
  "YOU ENTERED A NEW SALARY"
  "LESS THAN THE EMPLOYEE'S PRESENT SALARY"
  "PLEASE REENTER DATA"
ENDCASE
DATA

This request consists of two cases:

If the MATCH statement specifies fields in multiple segments (the technique of matching across segments, described in Modifying Segments in FOCUS Structures), the GOTO, PERFORM and IF phrases in the statement are only executed when the MATCH statement modifies the last segment. For example, this request adds instances to the EMPINFO, SALINFO, and DEDUCT segments:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID PAY_DATE DED_CODE
GOTO ADD
CASE ADD
MATCH EMP_ID PAY_DATE DED_CODE
  ON MATCH REJECT
  ON NOMATCH INCLUDE
  ON NOMATCH GOTO MESSAGE
ENDCASE
CASE MESSAGE
TYPE
  "NEW INSTANCE ADDED"
ENDCASE
DATA

The ADD case branches to the MESSAGE case only when it includes a new instance in the segment containing the DED_CODE field. If you want the case to branch to the MESSAGE case when it includes a new instance in any of the segments, then write the case with a separate MATCH statement for each segment it searches:

CASE ADD
MATCH EMP_ID
  ON MATCH CONTINUE
  ON NOMATCH INCLUDE
  ON NOMATCH GOTO MESSAGE
MATCH PAY_DATE
  ON MATCH CONTINUE
  ON NOMATCH INCLUDE
  ON NOMATCH GOTO MESSAGE
MATCH DED_CODE
  ON MATCH REJECT
  ON NOMATCH INCLUDE
  ON NOMATCH GOTO MESSAGE
ENDCASE

Example: Using Case Logic and Validation Tests

You can also branch to other cases when an incoming field value fails a validation test. Do this by including GOTO, PERFORM, and IF statements as part of the ON INVALID phrase. For example, this request processes transactions with salaries higher than $50,000 in a separate case:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID
GOTO NEWSAL
CASE NEWSAL
PROMPT CURR_SAL
VALIDATE
  SALTEST = IF CURR_SAL GT 50000 THEN 0 ELSE 1;
  ON INVALID GOTO HIGHSAL
MATCH EMP_ID
  ON MATCH UPDATE CURR_SAL
  ON NOMATCH REJECT
ENDCASE
CASE HIGHSAL
TYPE
  "SALARY ABOVE $50,000 NOT ALLOWED"
  "RETYPE SALARY BELOW"
GOTO NEWSAL
ENDCASE
DATA

Case Logic Applications

How to:

This section discusses some examples of applications for Case Logic that extend the capabilities of MODIFY requests. The applications are:

Syntax: How to Loop Through a Segment Chain With the NEXT Statement

The NEXT statement, discussed in Selecting the Instance After the Current Position: The NEXT Statement, modifies or displays the next segment instance after the current position in the data source. Using Case Logic, you can use NEXT statements to process entire segment chains.

For an entire segment chain to be displayed, the request must branch back to the beginning of the NEXT statement. Put the NEXT statement in a separate case, as shown below:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH TYPE
     "WAGES PAID TO EMPLOYEE #<EMP_ID"
  ON MATCH GOTO SALHIST
 
CASE SALHIST
NEXT DAT_INC
  ON NEXT TYPE "<D.DAT_INC <D.SALARY"
  ON NEXT GOTO SALHIST
  ON NONEXT GOTO TOP
ENDCASE
DATA

This request consists of two cases:

  • The TOP case prompts you for an employee ID and branches to the SALHIST case.
  • The SALHIST case contains one NEXT statement that displays the next instance of the employee's salary chain. The case then branches back to the its beginning to display the next instance. When it reaches the end of the chain, it branches back to the TOP case.

To return to the beginning of a segment chain, use the REPOSITION statement. The syntax is

REPOSITION field

where field is any field of the segment. The REPOSITION statement allows you to return to the beginning of the segment chain you are now modifying, or to the beginning of the chain of any of the parent instances along the segment path (that is, the parent instance, the parent's parent, and so on to the root segment). You can then search the segment chain from the beginning.

The following request allows you to allocate a new monthly pay for a selected employee for each pay date. The request accumulates each pay in a total. If this total pay exceeds the employee's yearly salary, the request returns to the first pay date to permit you to enter new values for the entire chain:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH GOTO PAYLOOP
CASE PAYLOOP
NEXT PAY_DATE
  ON NONEXT GOTO TOP
  ON NEXT TYPE
     "EMPLOYEE ID: <EMP_ID"
     "PAY DATE: <D.PAY_DATE MONTHLY PAY: <D.GROSS"
  ON NEXT PROMPT GROSS.ENTER MONTHLY PAY:.
  ON NEXT COMPUTE
     TOTAL_PAY/D10.2 = TOTAL_PAY + GROSS;
  ON NEXT IF TOTAL_PAY GT D.CURR_SAL GOTO ERROR;
  ON NEXT UPDATE GROSS
  ON NEXT GOTO PAYLOOP
ENDCASE
CASE ERROR
TYPE
  "TOTAL MONTHLY PAY EXCEEDS YEARLY SALARY"
  "REENTER PROPOSED PAY STARTING FROM"
  "THE FIRST PAY DATE"
REPOSITION PAY_DATE
COMPUTE TOTAL_PAY = 0;
GOTO PAYLOOP
ENDCASE
DATA

Note that the ERROR case in the example warns you that the sum of the figures you entered exceeds the employee's yearly salary. It then repositions the current position of the PAY_DATE field at the beginning of the segment chain and branches back to the PAYLOOP case, allowing you to reenter pay figures for the entire chain.

When you use INCLUDE, UPDATE, and DELETE actions in looping NEXT statements, note the following:

  • Use the ON NEXT INCLUDE and ON NONEXT INCLUDE phrases only to add instances to segments of type S0 or blank. If you use these phrases to modify other segments, you will duplicate what is already there. The difference between the two phrases is:

    ON NEXT INCLUDE adds a new segment instance after the current position.

    ON NONEXT INCLUDE adds a new instance at the end of the segment chain.

  • Use the ON NEXT UPDATE phrase without restriction. The phrase updates the segment instance at the current position. If you are looping with the NEXT statement, the phrase updates the entire chain.
  • Use the ON NEXT DELETE phrase to delete entire segment chains. This phrase deletes the segment instance at the current position. If you are looping with the NEXT statement, the phrase deletes the entire chain, but only if you start at the beginning of a chain. Otherwise, the phrase deletes every second instance.

Note that the phrases ON NONEXT UPDATE and ON NONEXT DELETE are illegal and will generate error messages.

Example: Modifying Multiple Unique Segments

Modifying unique segments is described in Modifying Segments in FOCUS Structures. This section describes how to modify several unique segments descended from one parent using the CONTINUE TO method.

To modify multiple unique segments, prepare separate cases containing a MATCH or NEXT statement for each segment you are modifying. The sample request below illustrates this. The request loads data into the SUBSCRIBE data source, which records magazine subscribers, their mailing addresses, and expiration dates. The Master File is:

FILE=SUBSCRIB ,SUFFIX=FOC,$
SEGMENT=SUBSEG ,$
 FIELD=SUBSCRIBER      ,ALIAS=NAME    ,FORMAT=A35     ,$
SEGMENT=ADDRSEG,SEGTYPE=U,PARENT=SUBSEG               ,$
 FIELD=ADDRESS    ,ALIAS=ADDR  ,FORMAT=A40            ,$
SEGMENT=EXPRSEG,SEGTYPE=U,PARENT=SUBSEG               ,$
 FIELD=EXPR_DATE       ,ALIAS=EXDATE  ,FORMAT=I6DMYT  ,$

The following MODIFY request loads the data:

MODIFY FILE SUBSCRIB
PROMPT SUBSCRIBER
MATCH SUBSCRIBER
  ON NOMATCH INCLUDE
  ON MATCH CONTINUE
GOTO NEWADDR
 
CASE NEWADDR
PROMPT ADDRESS
MATCH SUBSCRIBER
  ON NOMATCH REJECT
  ON MATCH CONTINUE TO ADDRESS
     ON MATCH REJECT
     ON MATCH GOTO NEWDATE
     ON NOMATCH INCLUDE
     ON NOMATCH GOTO NEWDATE
ENDCASE
 
CASE NEWDATE
PROMPT EXPR_DATE
MATCH SUBSCRIBER
  ON NOMATCH REJECT
  ON MATCH CONTINUE TO EXPR_DATE
     ON MATCH REJECT
     ON NOMATCH INCLUDE
ENDCASE
DATA

Note the last two cases in the request:

  • The NEWADDR case loads subscriber addresses into the unique segment ADDRSEG. The case examines the ADDRSEG segment. Does the subscriber have a mailing address listed? If not, the request includes the new address. In either event, the request continues to the NEWDATE case.
  • The NEWDATE case loads expiration dates into the sibling unique segment EXPRSEG. It examines the EXPRSEG segment with the EXPR_DATE field. Does the subscriber have a magazine expiration date? If not, the request includes the new expiration date. If the subscriber has an expiration date, the request checks to determine whether it gave the subscriber a new address.

    If the request gave the subscriber a new address, the request does not reject the transaction.

    If the request did not give the subscriber a new address, the request rejects the transaction.

If you were to include the MATCH statements in one case, the request would reject a transaction if the subscriber already had either an address or an expiration date. Since you want the transaction rejected only if the subscriber already has both, separate the MATCH statements into separate cases.

Procedure: How to Use Case Logic to Offer User Selections

You can use Case Logic to offer users a selection of options. The request below offers a choice between updating employee salaries, monthly pay, or addresses:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH GOTO MENU
 
CASE MENU
TYPE
"TO UPDATE THE EMPLOYEE'S SALARY, TYPE 'SALARY' "
"TO UPDATE THE EMPLOYEE'S MONTHLY PAY, TYPE 'PAY' "
"TO UPDATE THE EMPLOYEE'S ADDRESS, TYPE 'ADDRESS' "
COMPUTE CHOICE/A7=;
PROMPT CHOICE
       IF CHOICE IS 'SALARY' THEN GOTO SALARY
 ELSE  IF CHOICE IS 'PAY'THEN GOTO PAY
 ELSE  IF CHOICE IS 'ADDRESS'THEN GOTO ADDRESS;
TYPE "ILLEGAL CHOICE, PLEASE TYPE ENTRY AGAIN"
GOTO MENU
ENDCASE
CASE SALARY
PROMPT CURR_SAL
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH UPDATE CURR_SAL
ENDCASE
CASE PAY
PROMPT PAY_DATE GROSS
MATCH PAY_DATE
  ON NOMATCH REJECT
  ON MATCH UPDATE GROSS
ENDCASE
CASE ADDRESS
PROMPT TYPE ADDRESS_LN1 ADDRESS_LN2
MATCH TYPE
  ON NOMATCH REJECT
  ON MATCH UPDATE ADDRESS_LN1 ADDRESS_LN2
ENDCASE
DATA

Procedure: How to Use Case Logic to Process Transaction Data Sources

You can use Case Logic to process records in a transaction data source in different ways. For example, each transaction record contains a field that defines what type of record it is. The MODIFY request can use these record types to branch to the appropriate case and process the transaction.

The following request processes two record types: type A updates employee department assignments and job codes; type B updates salaries and classroom hours. The record type field (called RTYPE) is the last field in each record. It contains either the letter A or B, depending on the record type.

MODIFY FILE EMPLOYEE
COMPUTE RTYPE/A1=;
FIXFORM  X26 RTYPE/1
      IF RTYPE IS 'A' THEN GOTO TYPE_A
 ELSE IF RTYPE IS 'B'THEN GOTO TYPE_B;
TYPE "BAD RECTYPE VALUE"
GOTO TOP
 
CASE TYPE_A
FIXFORM X-27 EMP_ID/9 X1 DEPARTMENT/10
FIXFORM X1 CURR_JOBCODE/3 X3
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH UPDATE DEPARTMENT CURR_JOBCODE
ENDCASE
 
CASE TYPE_B
FIXFORM X-27 EMP_ID/9 X1 CURR_SAL/8 X1 ED_HRS/6 X2
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH UPDATE CURR_SAL ED_HRS
ENDCASE
DATA ON FIXTYPE
END

Notice the three FIXFORM statements: one in each of the cases. Only the statement in the TOP case reads a record from disk or tape. The other two statements redefine the record for the case.

Also note that each of these two statements begins with X-27, which allows the case to redefine the 27-byte record from the beginning. Always place the notation X-n at the beginning of the FIXFORM statement that is redefining the record, not at the end of the previous FIXFORM statement.

A FIXFORM statement reads a new record from disk or tape if one of these conditions are met:

  • The statement is the first FIXFORM statement in the request.
  • The statement defines records to be longer than they were defined before. For instance, if one FIXFORM statement defines a record of 80 bytes, and the next FIXFORM statement defines a record from the same data source as being 90 bytes, the second FIXFORM statement reads a new record.
  • The statement reads records from a different data source than the one read previously. This is possible if the statement has the form
    FIXFORM ON ddname

    where ddname is the ddname of the second transaction data source. If the next FIXFORM statement does not have the ON ddname option, it too reads another record.

Procedure: How to Use Case Logic to Process Transactions Based on the Values of Their Fields

You can use Case Logic to process transactions depending on their field values. The following request updates employee salaries. If the user enters a salary higher than $50,000, the request checks the employee ID against a list of employees authorized for large salaries:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID
GOTO NEWSAL
 
CASE NEWSAL
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH PROMPT CURR_SAL
  ON MATCH IF CURR_SAL GT 50000 THEN GOTO HIGHSAL;
  ON MATCH UPDATE CURR_SAL
ENDCASE
 
CASE HIGHSAL
COMPUTE
  SALTEST = DECODE EMP_ID (HIGHPAY);
IF SALTEST NE 1 THEN GOTO WRONGSAL;
MATCH EMP_ID
  ON NOMATCH REJECT
  ON MATCH UPDATE CURR_SAL
ENDCASE
 
CASE WRONGSAL
TYPE
  "EMPLOYEE NOT AUTHORIZED FOR SALARY INCREASE"
  "PLEASE REENTER THE DATA"
ENDCASE
DATA

Procedure: How to Use Case Logic to Process Transactions With Bad Values

You can use Case Logic to process transactions with values that would otherwise cause the transactions to be rejected. You do this by combining GOTO and IF phrases with:

  • The ON MATCH phrase, if you are adding new segment instances.
  • The ON NOMATCH phrase, if you are updating or deleting instances.
  • The ON INVALID phrase, if you are validating incoming data fields.

This request updates employee salaries. If it cannot find an employee record, it queries the user whether to include the transaction as a new employee record:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID CURR_SAL
MATCH EMP_ID
  ON MATCH UPDATE CURR_SAL
  ON NOMATCH GOTO QUERY
 
CASE QUERY
COMPUTE CHOICE/A1=;
TYPE
  "EMPLOYEE ID NOT FOUND IN THE DATABASE"
  "INCLUDE THE TRANSACTION ANYWAY (Y/N)?"
PROMPT CHOICE
      IF CHOICE IS 'Y' THEN GOTO INCLUDE
 ELSE IF CHOICE IS 'N'THEN GOTO REJECT;
TYPE "PLEASE TYPE EITHER Y OR N"
GOTO QUERY
ENDCASE
 
CASE INCLUDE
MATCH EMP_ID
  ON MATCH REJECT
  ON NOMATCH INCLUDE
ENDCASE
 
CASE REJECT
MATCH EMP_ID
  ON MATCH REJECT
  ON NOMATCH REJECT
ENDCASE
DATA

Tracing Case Logic: The TRACE Facility

The TRACE facility displays the name of each case that is entered during the execution of a MODIFY request. This is a useful tool for debugging large Case Logic requests.

You can allocate the output to a file or to your terminal. Then, add the word TRACE to the end of the MODIFY command line

MODIFY FILE filename TRACE

where:

filename

is the name of the FOCUS data source you are modifying.

When the TRACE facility is on, it lists in the HLIPRINT file the name of the case about to run

TRACE ===> AT CASE case

where:

case

Is the name of the case.

Note that if you are using FIDEL and displaying the TRACE output on the terminal, the following happens. When you enter a CRTFORM screen, the screen clears and displays the name of the next case. Clear the screen, and the next CRTFORM screen appears.

The request and sample execution below illustrate the use of the TRACE facility:

MODIFY FILE EMPLOYEE TRACE
PROMPT EMP_ID CURR_SAL
IF CURR_SAL GT 50000 GOTO HIGHSAL
ELSE GOTO UPDATE;
 
CASE UPDATE
MATCH EMP_ID
  ON MATCH UPDATE CURR_SAL
  ON NOMATCH REJECT
ENDCASE
 
CASE HIGHSAL
TYPE
  " "
  "YOU ENTERED A SALARY ABOVE $50,000"
  " "
PROMPT CURR_SAL.PLEASE REENTER THE SALARY.
IF CURR_SAL GT 50000 GOTO HIGHSAL
ELSE GOTO UPDATE;
ENDCASE
DATA

The following is a sample execution of the previous request:

> EMPLOYEE     ON 10/04/98 AT 14.02.33
**** START OF TRACE ****
TRACE ===> AT CASE TOP
DATA FOR TRANSACTION  1
 
EMP_ID  = > 112847612
CURR_SAL  = > 67000
TRACE ===> AT CASE HIGHSAL
 
YOU ENTERED A SALARY ABOVE $50,000
 
PLEASE REENTER THE SALARY > 27000
TRACE ===> AT CASE UPDATE
TRACE ===> AT CASE TOP
DATA FOR TRANSACTION 2
 
EMP_ID = 0

Information Builders