MainframeMaster

COBOL Tutorial

COBOL BY Clause

The BY clause in COBOL is a fundamental control structure used to specify the increment or step value in PERFORM VARYING statements and other iterative operations. This clause determines how loop counters are modified with each iteration, enabling precise control over repetitive processing, array manipulation, table processing, and complex iteration patterns essential for data processing applications, mathematical calculations, and systematic data traversal operations.

Understanding BY Clause

The BY clause specifies the increment value for loop variables in PERFORM VARYING statements. It controls how the variable changes with each iteration, allowing for forward counting, backward counting, and custom step values for flexible loop control.

Key Applications:

  • Loop counter increment control
  • Array and table processing
  • Mathematical sequence generation
  • Data stepping and sampling
  • Custom iteration patterns
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
*> Basic BY clause usage in PERFORM VARYING DATA DIVISION. WORKING-STORAGE SECTION. 01 LOOP-CONTROLS. 05 COUNTER PIC 9(3) VALUE ZERO. 05 INDEX-VAR PIC 9(3) VALUE 1. 05 STEP-SIZE PIC 9(2) VALUE 5. 01 ARRAY-DATA. 05 DATA-TABLE OCCURS 100 TIMES. 10 TABLE-ITEM PIC X(20). PROCEDURE DIVISION. BASIC-BY-EXAMPLES. *> Count by 1 (default) PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER > 10 DISPLAY "Counter: " COUNTER END-PERFORM *> Count by 2 PERFORM VARYING INDEX-VAR FROM 2 BY 2 UNTIL INDEX-VAR > 20 DISPLAY "Even number: " INDEX-VAR END-PERFORM *> Count by variable step PERFORM VARYING COUNTER FROM 5 BY STEP-SIZE UNTIL COUNTER > 50 DISPLAY "Step count: " COUNTER END-PERFORM.

Advanced Loop Control

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
*> Advanced BY clause patterns and techniques DATA DIVISION. WORKING-STORAGE SECTION. 01 ADVANCED-CONTROLS. 05 MAIN-INDEX PIC 9(4) VALUE 1. 05 SUB-INDEX PIC 9(3) VALUE 1. 05 DYNAMIC-STEP PIC S9(3) VALUE 1. 05 REVERSE-COUNTER PIC 9(3) VALUE 100. 01 PROCESSING-FLAGS. 05 DIRECTION-FLAG PIC X VALUE 'F'. 88 FORWARD VALUE 'F'. 88 BACKWARD VALUE 'B'. 05 STEP-MODE PIC X VALUE 'N'. 88 NORMAL-STEP VALUE 'N'. 88 DOUBLE-STEP VALUE 'D'. 88 CUSTOM-STEP VALUE 'C'. 01 DATA-ARRAYS. 05 MAIN-ARRAY OCCURS 1000 TIMES. 10 ARRAY-VALUE PIC S9(7)V99 COMP-3. 10 ARRAY-FLAG PIC X. 05 SUMMARY-ARRAY OCCURS 50 TIMES. 10 SUMMARY-TOTAL PIC S9(9)V99 COMP-3. PROCEDURE DIVISION. ADVANCED-BY-PROCESSING. PERFORM DETERMINE-STEP-SIZE PERFORM PROCESS-WITH-DYNAMIC-STEP PERFORM REVERSE-PROCESSING PERFORM NESTED-VARYING-LOOPS. DETERMINE-STEP-SIZE. EVALUATE TRUE WHEN NORMAL-STEP MOVE 1 TO DYNAMIC-STEP WHEN DOUBLE-STEP MOVE 2 TO DYNAMIC-STEP WHEN CUSTOM-STEP COMPUTE DYNAMIC-STEP = WS-RECORD-COUNT / 10 END-EVALUATE. PROCESS-WITH-DYNAMIC-STEP. PERFORM VARYING MAIN-INDEX FROM 1 BY DYNAMIC-STEP UNTIL MAIN-INDEX > 1000 *> Process array element COMPUTE ARRAY-VALUE(MAIN-INDEX) = ARRAY-VALUE(MAIN-INDEX) * 1.05 *> Mark as processed MOVE 'Y' TO ARRAY-FLAG(MAIN-INDEX) DISPLAY "Processed index: " MAIN-INDEX END-PERFORM. REVERSE-PROCESSING. *> Backward iteration using negative BY value PERFORM VARYING REVERSE-COUNTER FROM 100 BY -1 UNTIL REVERSE-COUNTER < 1 IF ARRAY-FLAG(REVERSE-COUNTER) = 'Y' PERFORM VALIDATE-PROCESSED-ITEM END-IF END-PERFORM. NESTED-VARYING-LOOPS. *> Complex nested loops with different BY values PERFORM VARYING MAIN-INDEX FROM 1 BY 10 UNTIL MAIN-INDEX > 1000 PERFORM VARYING SUB-INDEX FROM MAIN-INDEX BY 1 UNTIL SUB-INDEX > (MAIN-INDEX + 9) OR SUB-INDEX > 1000 *> Process sub-range ADD ARRAY-VALUE(SUB-INDEX) TO SUMMARY-TOTAL((MAIN-INDEX + 9) / 10) END-PERFORM END-PERFORM.

Table Processing Applications

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
*> Table processing with BY clause optimization DATA DIVISION. WORKING-STORAGE SECTION. 01 TABLE-PROCESSING-CONTROLS. 05 BATCH-SIZE PIC 9(3) VALUE 50. 05 CURRENT-BATCH PIC 9(3) VALUE 1. 05 TOTAL-RECORDS PIC 9(6) VALUE 10000. 05 PROCESSING-INDEX PIC 9(6). 01 CUSTOMER-TABLE. 05 CUSTOMER-RECORD OCCURS 10000 TIMES INDEXED BY CUST-IDX. 10 CUST-ID PIC 9(8). 10 CUST-NAME PIC X(30). 10 CUST-BALANCE PIC S9(7)V99 COMP-3. 10 CUST-STATUS PIC X. 01 BATCH-TOTALS. 05 BATCH-COUNT PIC 9(4) VALUE ZERO. 05 BATCH-AMOUNT PIC S9(9)V99 COMP-3 VALUE ZERO. 05 GRAND-TOTAL PIC S9(11)V99 COMP-3 VALUE ZERO. PROCEDURE DIVISION. PROCESS-CUSTOMER-TABLE. PERFORM BATCH-PROCESSING-LOOP PERFORM DISPLAY-FINAL-TOTALS. BATCH-PROCESSING-LOOP. PERFORM VARYING PROCESSING-INDEX FROM 1 BY BATCH-SIZE UNTIL PROCESSING-INDEX > TOTAL-RECORDS PERFORM RESET-BATCH-TOTALS PERFORM PROCESS-CURRENT-BATCH PERFORM DISPLAY-BATCH-SUMMARY ADD 1 TO CURRENT-BATCH END-PERFORM. PROCESS-CURRENT-BATCH. PERFORM VARYING CUST-IDX FROM PROCESSING-INDEX BY 1 UNTIL CUST-IDX > (PROCESSING-INDEX + BATCH-SIZE - 1) OR CUST-IDX > TOTAL-RECORDS IF CUST-STATUS(CUST-IDX) = 'A' *> Active customers ADD 1 TO BATCH-COUNT ADD CUST-BALANCE(CUST-IDX) TO BATCH-AMOUNT *> Apply interest calculation COMPUTE CUST-BALANCE(CUST-IDX) = CUST-BALANCE(CUST-IDX) * 1.002 END-IF END-PERFORM. RESET-BATCH-TOTALS. MOVE ZERO TO BATCH-COUNT BATCH-AMOUNT. DISPLAY-BATCH-SUMMARY. DISPLAY "Batch " CURRENT-BATCH ": " BATCH-COUNT " customers, Amount: $" BATCH-AMOUNT ADD BATCH-AMOUNT TO GRAND-TOTAL.

Mathematical and Statistical Processing

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
*> Mathematical applications using BY clause DATA DIVISION. WORKING-STORAGE SECTION. 01 MATH-PROCESSING. 05 NUMBER-SEQUENCE PIC 9(6) VALUE 1. 05 FIBONACCI-A PIC 9(10) VALUE 1. 05 FIBONACCI-B PIC 9(10) VALUE 1. 05 FIBONACCI-TEMP PIC 9(10). 05 PRIME-CANDIDATE PIC 9(6). 05 DIVISOR PIC 9(6). 05 IS-PRIME-FLAG PIC X VALUE 'Y'. 01 STATISTICAL-DATA. 05 DATA-POINTS OCCURS 1000 TIMES. 10 DATA-VALUE PIC S9(5)V99 COMP-3. 05 SAMPLE-SIZE PIC 9(4) VALUE 100. 05 SAMPLE-INTERVAL PIC 9(3) VALUE 10. 05 MEAN-VALUE PIC S9(7)V99 COMP-3. 05 VARIANCE PIC S9(9)V99 COMP-3. PROCEDURE DIVISION. MATHEMATICAL-PROCESSING. PERFORM GENERATE-NUMBER-SEQUENCES PERFORM FIND-PRIME-NUMBERS PERFORM STATISTICAL-SAMPLING. GENERATE-NUMBER-SEQUENCES. *> Generate Fibonacci sequence DISPLAY "Fibonacci sequence:" DISPLAY FIBONACCI-A DISPLAY FIBONACCI-B PERFORM VARYING NUMBER-SEQUENCE FROM 3 BY 1 UNTIL NUMBER-SEQUENCE > 20 COMPUTE FIBONACCI-TEMP = FIBONACCI-A + FIBONACCI-B MOVE FIBONACCI-B TO FIBONACCI-A MOVE FIBONACCI-TEMP TO FIBONACCI-B DISPLAY FIBONACCI-B END-PERFORM. FIND-PRIME-NUMBERS. DISPLAY "Prime numbers up to 1000:" PERFORM VARYING PRIME-CANDIDATE FROM 2 BY 1 UNTIL PRIME-CANDIDATE > 1000 MOVE 'Y' TO IS-PRIME-FLAG *> Check for factors PERFORM VARYING DIVISOR FROM 2 BY 1 UNTIL DIVISOR > (PRIME-CANDIDATE / 2) OR IS-PRIME-FLAG = 'N' IF FUNCTION MOD(PRIME-CANDIDATE, DIVISOR) = 0 MOVE 'N' TO IS-PRIME-FLAG END-IF END-PERFORM IF IS-PRIME-FLAG = 'Y' DISPLAY PRIME-CANDIDATE END-IF END-PERFORM. STATISTICAL-SAMPLING. *> Sample every nth data point MOVE ZERO TO MEAN-VALUE MOVE ZERO TO WS-SAMPLE-COUNT PERFORM VARYING WS-INDEX FROM 1 BY SAMPLE-INTERVAL UNTIL WS-INDEX > 1000 ADD DATA-VALUE(WS-INDEX) TO MEAN-VALUE ADD 1 TO WS-SAMPLE-COUNT END-PERFORM COMPUTE MEAN-VALUE = MEAN-VALUE / WS-SAMPLE-COUNT DISPLAY "Sample mean: " MEAN-VALUE.

Best Practices

BY Clause Guidelines:

  • Use positive values for forward iteration, negative for backward
  • Ensure BY value doesn't cause infinite loops
  • Consider performance impact of large step values
  • Validate that step size doesn't skip critical data
  • Use variables for dynamic step control when needed
  • Test loop boundaries thoroughly
  • Document complex iteration patterns clearly