ILE COBOL
Looping Statements
Perform Looping Statements
Iterative programming uses loops to make a set of statements run repeatedly. The statements keep executing until a specified condition is met.
In COBOL, the PERFORM statement is used for this kind of repetitive execution.
PERFORM Types based on lines
There are 2 types of the PERFORM statements based on lines:
- Inline PERFORM
- Outline PERFORM
PERFORM Types based on formats
There are four types of PERFORM statements based on formats:
Format 1 – Basic PERFORM
Simple PERFORM is a way to execute a given paragraph or section once, and control is passed to the next statement in the flow. It is both inline and outline.
- Example1 for Inline PERFORM:
Output:
- Example 2 for Outline PERFORM:
Output:
- Example for Outline PERFORM with THRU:
Output:
Format 2 – PERFORM with TIMES Phrase
- Example for Inline PERFORM with TIMES:
Output:
- Example for Outline PERFORM with TIMES:
Output:
Format 3 – PERFORM with UNTIL Phrase
- Example for Inline PERFORM with UNTIL:
Output:
- Example for Outline PERFORM with UNTIL:
Output:
Format 4 – PERFORM with VARYING Phrase
PERFORM with VARYING executes a specific paragraph or section repetitively while varying the values of the variables until the condition is satisfied. The PERFORM with VARYING is similar to PERFORM UNTIL, but it handles the variable’s initialization, increment, or decrement. This structure provides a “for loop” functionality found in many other programming languages.
- Example for Inline PERFORM with VARYING:
Output:
- Example for Outline PERFORM with VARYING:
Output:
String Handling
String Handling
String handling commands are essential tools for working with and changing text (like characters and strings) in a program. It performs various operations, such as combining or separating strings, and finding or working with specific parts of a string. Programmers can also use them to count, replace, or convert characters. For example, changing text to uppercase or lowercase, or checking its total length.
In COBOL programming, three main commands handle these tasks:
- STRING
- UNSTRING
- INSPECT
STRING Verb
The STRING statement strings together the partial or complete contents of two or more data items into one single data item. Also, single STRING statement can be written instead of a series of MOVE statements.
Syntax:
Example 1:
Output:
Example 2:
Output:
Example 3:
Output:
UNSTRING Verb
The UNSTRING statement causes contiguous data in a sending field to be separated and placed into multiple receiving fields. Also, single UNSTRING statement can be written instead of a series of MOVE statements.
Syntax:
Example 1:
Output:
Example 2:
Output:
Example 3:
Output:
Example 4:
Output:
INSPECT Verb
The INSPECT statement specifies that characters in a data item are to be counted (tallied), or replaced (or both).
- It will count the occurrence of a specific character (alphabetic, numeric, or special character) in a data item.
- It will fill all or portions of a data item with spaces or zeros.
- It will translate characters from one collating sequence to another.
The INSPECT statement has four formats:
- INSPECT TALLYING
- INSPECT REPLACING
- INSPECT TALLYING REPLACING
- INSPECT CONVERTING
Syntax for Format 1: INSPECT TALLYING
Example 1:
Output:
Syntax for Format 2: INSPECT REPLACING
Example 1:
Output:
Syntax for Format 3: INSPECT TALLYING REPLACING
Example 1:
Output:
Syntax for Format 4: INSPECT CONVERTING
Example 1:
Output:
COBOL400 – Introduction
Introduction
COBOL400: This is the COBOL programming language used on IBM’s AS/400 (now IBM i) platform. It is a foundational, rules-based language that has been used for decades.
ILE COBOL: This is the Integrated Language Environment version of COBOL for the IBM i. It is a more modern form of COBOL that works with other languages like RPG and C++ in one environment.
Source Types in COBOL400 or ILE COBOL
There are 4 types of source types available for COBOL programs in IBM i-Series
- CBL
- CBLLE
- SQLCBL
- SQLCLBLLE
Source Types brief description
Each source type of COBOL contains different features as shown below:
- CBL – Native COBOL + Features available in IBM i-Series
- CBLLE – Native COBOL + Features available in IBM i-Series + ILE features of IBM i-Series
- SQLCBL – Native COBOL + Features available in IBM i-Series + Embedded DB2 programming
- SQLCBLLE – Native COBOL + Features available in IBM i-Series + Embedded DB2 programming + ILE features of IBM i-Series
COBOL Program objects
-
Compilation of CBL Source using the CRTCBLPGM CL Command.
When CBL source is compiled, it generates program object – *PGM with attribute CBL.
-
Compilation of CBLLE Source using the CRTBNDCBL CL Command
When CBLLE source is compiled, it generates program object – *PGM with attribute CBLLE.
-
Compilation of SQLCBL Source using the CRTSQLCBL CL Command.
When SQLCBL source is compiled, it generates program object – *PGM with attribute CBL.
-
Compilation of SQLCBLLE Source using the CRTSQLCBLI CL Command.
When SQLCBLLE source is compiled, it generates program object – *PGM with attribute CBLLE
Table Handling
In ILE COBOL, a table is the equivalent of an array in other programming languages. It is a collection of logically consecutive data items that share the same description and are defined in the DATA DIVISION using the OCCURS clause.
Table Declaration
A table is a group of repeated data items stored together under one name. It helps to store multiple values of the same type — like names, prices, or marks — using a single variable name with positions (1, 2, 3…).
Key Points:
- The tables are declared in the DATA DIVISION.
- The OCCURS clause defines repetition of data items.
- It tells COBOL how many times a field or group repeats.
- We can use OCCURS with level numbers from 02 to 49.
- OCCURS clause does not work with REDEFINES in the same declaration.
- Programmers can also define INDEXED BY to create an index for faster access.
One-Dimensional Table
A one-dimensional table is like a single row or list.
It has elements arranged in a single line and can be accessed by position (1, 2, 3, …).
Syntax:
01 WS-TABLE.
05 WS-A PIC A (10) OCCURS 10 TIMES.
Program:
IDENTIFICATION DIVISION.
*-------------------------*
PROGRAM-ID. PGM5.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM1-Series.
OBJECT-COMPUTER. IBM1-Series.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TABLE.
05 WS-A PIC A(20) VALUE 'Programmers.ai' OCCURS 5 TIMES.
PROCEDURE DIVISION.
DISPLAY "ONE-D TABLE : " WS-TABLE.
STOP RUN.
Output:
ONE-D TABLE: Programmers.ai Programmers.ai Programmers.ai Programmers.ai Programmers.ai Programmers.ai
Explanation:
- The table WS-TABLE contains 5 elements.
- Each element WS-A can hold 10 characters.
- All elements are initialized with ‘Programmers.ai’.
- The DISPLAY statement shows all 5 values on the screen.
Two-Dimensional Table
A two-dimensional table is like a matrix or grid.
It stores data in rows and columns, such as marks of students in subjects.
Syntax:
01 WS-MARKS.
05 STUDENT OCCURS 3 TIMES.
10 SUBJECT OCCURS 2 TIMES.
15 WS-MARK PIC 9(3).
Program:
IDENTIFICATION DIVISION.
*-------------------------*
PROGRAM-ID. PGM1.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM1-Series.
OBJECT-COMPUTER. IBM1-Series.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TABLE.
05 WS-A OCCURS 2 TIMES.
10 WS-B PIC A(10) VALUE 'User'.
10 WS-C OCCURS 2 TIMES.
15 WS-D PIC X(6) VALUE 'COBOL'.
PROCEDURE DIVISION.
DISPLAY "TWO-D TABLE : " WS-TABLE.
STOP RUN.
Output:
TWO-D TABLE : User COBOL COBOL User COBOL COBOL
Explanation:
- The outer OCCURS (2 TIMES) means 2 main branches.
- The inner OCCURS (2 TIMES) means 2 sub-branches.
Subscript
A subscript is a simple number that identifies which element of the table you want to use.
- Subscripts always start from 1.
- You write it inside parentheses () after the table name.
- You can use a variable to hold the subscript number.
Program:
IDENTIFICATION DIVISION.
*-------------------------*
PROGRAM-ID. PGM3.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM1-Series.
OBJECT-COMPUTER. IBM1-Series.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NAME.
05 WS-STUDENT PIC A(15) OCCURS 3 TIMES.
77 I PIC 9 VALUE 1.
PROCEDURE DIVISION.
MOVE "Amitabh" TO WS-STUDENT(1)
MOVE "Mithun" TO WS-STUDENT(2)
MOVE "Harshit" TO WS-STUDENT(3)
DISPLAY "STUDENT NAME: " WS-STUDENT(I)
STOP RUN.
Output:
STUDENT NAME: Amitabh
Explanation:
- Subscript(I) choose which element to display.
- We have entered 1, program shows ‘Amitabh’.
INDEXED BY
An index is a special internal counter COBOL uses to track the current element’s position in a table.
- It is faster than a subscript.
- It is defined using INDEXED BY in the table declaration.
- The index value can only be changed using the SET statement.
Syntax:
01 WS-CLASS
03 WS-STUDENT OCCURS 2 TIMES INDEXED BY WS-IDX.
05 WS-ROLLNO PIC X(04).
05 WS-NAME PIC X(15).
Program:
IDENTIFICATION DIVISION.
*-------------------------*
PROGRAM-ID. PGM6.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM1-Series.
OBJECT-COMPUTER. IBM1-Series.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CLASS.
03 WS-STUDENT OCCURS 2 TIMES INDEXED BY IDX-ONE.
05 WS-ROLL-NO PIC X(03).
05 WS-NAME PIC X(12).
PROCEDURE DIVISION.
MOVE "001Harshit Y" TO WS-STUDENT(1).
MOVE "002Ranbir Y" TO WS-STUDENT(2).
DISPLAY "Class Information: " WS-CLASS.
DISPLAY " ".
SET IDX-ONE TO 1.
DISPLAY "Students Information => ".
PERFORM UNTIL IDX-ONE > 2
DISPLAY "Roll No: " WS-ROLL-NO(IDX-ONE)
DISPLAY "Name: " WS-NAME(IDX-ONE)
SET IDX-ONE UP BY 1
END-PERFORM.
STOP RUN.
Output:
Class Information: 001Harshit Y 002Ranbir Y Students Information => Roll No: 001 Name: Harshit Y Roll No: 002 Name: Ranbir Y
Explanation:
Array Setup: Defines WS-CLASS with 2 student entries, each having Roll No and Name, accessed using an index IDX-ONE.
Data Loading: Moves two student details into the array and displays the entire class data.
Loop & Display: Starts index at 1, loops until 2, prints each student’s roll number and name, then increments the index.
SET Statement
The SET statement is used to move or change the position of an index. Set verb is used to initialize, increment, or decrement the index value.
Syntax:
SET index-name TO n SET index-name UP BY n SET index-name DOWN BY n
Program:
IDENTIFICATION DIVISION.
*-------------------------*
PROGRAM-ID. PGM6.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM1-Series.
OBJECT-COMPUTER. IBM1-Series.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TABLE.
05 WS-A OCCURS 3 TIMES INDEXED BY I.
10 WS-B PIC A(2).
10 WS-C OCCURS 2 TIMES INDEXED BY J.
15 WS-D PIC X(3).
PROCEDURE DIVISION.
MOVE '12ABCDEF34GHIJKL56MNOPQR' TO WS-TABLE.
SET I J TO 1.
DISPLAY WS-C(I, J).
SET J UP BY 1.
DISPLAY WS-C(I, J).
STOP RUN.
Output:
ABC JKL
Explanation:
- Set the value to the positions and display that element.
FORMAT Clause
The IBM i series, specifically ILE COBOL or COBOL400, has several features that differentiate it from mainframe, Micro Focus, and other COBOL environments. One of these is the FORMAT clause, which is used to declare DATE, TIME, and TIMESTAMP fields in the DATA DIVISION.
Use of FORMAT Clause
The FORMAT clause is used to specify a default format for a DATA DIVISION date, time or timestamp item.
Example: (For FORMAT DATE)
IDENTIFICATION DIVISION.
*-----------------------*
PROGRAM-ID. DATFUNC02.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBMi-Series.
OBJECT-COMPUTER. IBMi-Series.
DATA DIVISION.
*---------------------*
WORKING-STORAGE SECTION.
01 POLICY-EFF-DATE FORMAT DATE '@Y-%m-%d' VALUE '2021-11-12'.
01 POLICY-EXP-DATE FORMAT DATE '@Y/%m/%d' VALUE '2029/12/31'.
01 POLICY-MAT-DATE FORMAT DATE '@Y%m%d' VALUE '20261112'.
01 NEXT-DUE-DATE FORMAT DATE '%m%d%y' VALUE '070125'.
01 EUR-FORMAT-DATE FORMAT DATE '%d.%m.@Y' VALUE '01.12.2025'.
01 USA-FORMAT-DATE FORMAT DATE '%m/%d/@Y' VALUE '12/01/2025'.
PROCEDURE DIVISION.
MAIN-LOGIC.
DISPLAY 'Policy-Effective-Date:' POLICY-EFF-DATE
DISPLAY 'Policy-Expiry-Date :' POLICY-EXP-DATE
DISPLAY 'Policy-Maturity-Date :' POLICY-MAT-DATE
DISPLAY 'Payment-Next-Due-Date:' NEXT-DUE-DATE
DISPLAY 'EUR-Format-Date :' EUR-FORMAT-DATE
DISPLAY 'USA-Format-Date :' USA-FORMAT-DATE
STOP RUN.
Output:
Policy-Effective-Date:2021-11-12 Policy-Expiry-Date :2029/12/31 Policy-Maturity-Date :20261112 Payment-Next-Due-Date:070125 EUR-Format-Date :01.12.2025 USA-Format-Date :12/01/2025
Example: (For FORMAT DATE & MOVE)
IDENTIFICATION DIVISION.
*-----------------------*
PROGRAM-ID. DATFUNC03.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBMi-Series.
OBJECT-COMPUTER. IBMi-Series.
DATA DIVISION.
*---------------------*
WORKING-STORAGE SECTION.
01 POLICY-EFF-DATE FORMAT DATE '@Y-%m-%d' VALUE '2021-11-12'.
01 WS-POLICY-EFF FORMAT DATE '%m%d%y'.
PROCEDURE DIVISION.
MAIN-LOGIC.
MOVE POLICY-EFF-DATE TO WS-POLICY-EFF.
MOVE POLICY-EFF-DATE TO WS-POLICY-EFF.
DISPLAY 'WS-POLICY-EFF:' WS-POLICY-EFF.
STOP RUN.
Output:
WS-POLICY-EFF:111221
Example: (For FORMAT TIME & MOVE)
IDENTIFICATION DIVISION.
*-----------------------*
PROGRAM-ID. DATFUNC04.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBMi-Series.
OBJECT-COMPUTER. IBMi-Series.
DATA DIVISION.
*---------------------*
WORKING-STORAGE SECTION.
01 WS-TIME-A1 FORMAT TIME '%I:%M @p' VALUE '06:20 am'.
01 WS-TIME-A2 LIKE WS-TIME-A1.
PROCEDURE DIVISION.
MAIN-LOGIC.
MOVE WS-TIME-A1 TO WS-TIME-A2.
DISPLAY 'WS-TIME-A1:' WS-TIME-A1.
DISPLAY 'WS-TIME-A2:' WS-TIME-A2.
STOP RUN.
Output:
WS-TIME-A1:06:20 am WS-TIME-A2:06:20 AM
Example: (For FORMAT TIMESTAMP)
IDENTIFICATION DIVISION.
*-----------------------*
PROGRAM-ID. DATFUNC05.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBMi-Series.
OBJECT-COMPUTER. IBMi-Series.
DATA DIVISION.
*---------------------*
WORKING-STORAGE SECTION.
01 CARD-NEW-TIMESTAMP FORMAT TIMESTAMP VALUE
'2020-01-01-00.00.01.000001'.
01 CARD-EXP-TIMESTAMP LIKE CARD-NEW-TIMESTAMP.
PROCEDURE DIVISION.
MAIN-LOGIC.
MOVE FUNCTION ADD-DURATION(CARD-NEW-TIMESTAMP YEARS 5)
TO CARD-EXP-TIMESTAMP.
DISPLAY 'CARD-NEW-TIMESTAMP:' CARD-NEW-TIMESTAMP.
DISPLAY 'CARD-EXP-TIMESTAMP:' CARD-EXP-TIMESTAMP.
STOP RUN.
Output:
CARD-NEW-TIMESTAMP:2020-01-01-00.00.01.000001 CARD-EXP-TIMESTAMP:2025-01-01-00.00.01.000001
LIKE Clause
The IBM i series, with ILE COBOL or COBOL400, offers several features that differentiate it from mainframe, Micro Focus, and other COBOL environments. One among these is the LIKE clause used in the DATA DIVISION.
Use of LIKE Clause
The LIKE clause acts like a “data type template”. It is a shortcut command that instructs the compiler to create a new data variable with the exact same type and size as the referenced variable. In ILE COBOL, this LIKE clause is similar to the LIKE keyword used in the D-SPEC of RPGLE programming.
Example:
IDENTIFICATION DIVISION.
*-----------------------*
PROGRAM-ID. DATATYP01.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. Programmers-Lab.
OBJECT-COMPUTER. Programmers-Lab.
DATA DIVISION.
*---------------------*
WORKING-STORAGE SECTION.
01 WS-PGM-VAR1 PIC A(20) VALUE 'QWERTYASDF'.
01 WS-PGM-VAR2 PIC S9(3)V9(2) COMP-3 VALUE 17.22.
01 WS-PGM-DAT3 PIC 9(08) VALUE 29022024.
* == Use of LIKE Clause. ==
01 WS-LIK-VAR1 LIKE WS-PGM-VAR1.
01 WS-LIK-VAR2 LIKE WS-PGM-VAR2.
01 WS-LIK-DAT3 LIKE WS-PGM-DAT3.
PROCEDURE DIVISION.
MAIN.
MOVE WS-PGM-VAR1 TO WS-LIK-VAR1.
MOVE WS-PGM-VAR2 TO WS-LIK-VAR2.
MOVE WS-PGM-DAT3 TO WS-LIK-DAT3.
DISPLAY "Like Variable 1:" WS-LIK-VAR1.
DISPLAY "Like Variable 2:" WS-LIK-VAR2.
DISPLAY "Like Variable 3:" WS-LIK-DAT3.
STOP RUN.
Output:
Like Variable 1:QWERTYASDF Like Variable 2:01722 Like Variable 3:29022024
Snippet during debug:
When attribute of WS-LIK-VAR1, WS-LIK-VAR2, WS-LIK-DAT3 was requested, the compiler returned below statement.
> ATTR WS-PGM-VAR1 TYPE = FIXED LENGTH STRING, LENGTH = 20 BYTES > ATTR WS-LIK-VAR1 TYPE = FIXED LENGTH STRING, LENGTH = 20 BYTES > ATTR WS-PGM-VAR2 TYPE = PACKED(5,2), LENGTH = 3 BYTES > ATTR WS-LIK-VAR2 TYPE = PACKED(5,2), LENGTH = 3 BYTES > ATTR WS-PGM-DAT3 TYPE = ZONED(8,0), LENGTH = 8 BYTES > ATTR WS-LIK-DAT3 TYPE = ZONED(8,0), LENGTH = 8 BYTES
Note: LIKE clause does not work with REDEFINES, SIGN, USAGE, PICTURE, FORMAT, TYPE and TYPEDEF clause.
CONSTANT Clause
The IBM i series, with ILE COBOL or COBOL400, offers several features that differ from mainframes and other COBOL environments. One of these is the CONSTANT clause used in the DATA DIVISION.
Use of CONSTANT Clause
The CONSTANT clause creates a constant field that cannot be changed during the program cycle. Programmers use the CONSTANT clause to introduce numeric, alphanumeric, and hexadecimal constants in ILE programs, such as single quotes, double quotes, commas, the ENTER key, etc. In ILE COBOL, this CONSTANT clause is similar to the CONST keyword used in the D-SPEC of RPGLE programming.
Example:
IDENTIFICATION DIVISION.
*-----------------------*
PROGRAM-ID. DATATYP01A.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBMi-Series.
OBJECT-COMPUTER. IBMi-Series.
DATA DIVISION.
*---------------------*
WORKING-STORAGE SECTION.
01 WS-VAR1 PIC 9(02) VALUE 20.
01 WS-VAR3 PIC 9(02).
01 WS-STR1 PIC X(30).
* ==Use of Numeric,Character, Hexadecimal Constant==*
01 WS-VAR2 CONSTANT 10.
01 WS-VAR2 CONSTANT 10.
01 WS-CHRX CONSTANT 'CONST'.
01 WS-SQUOTE CONSTANT x'7D'.
PROCEDURE DIVISION.
MAIN.
COMPUTE WS-VAR3 = WS-VAR1 + WS-VAR2.
STRING 'McDonald DELIMITED BY SIZE
WS-SQUOTE DELIMITED BY SPACE
's Burger' DELIMITED BY SIZE
INTO WS-STR1
END-STRING.
DISPLAY "Numeric Constant :" WS-VAR3.
DISPLAY "Character Constant :" WS-CHRX.
DISPLAY "Hexadecimal Constant:" WS-STR1.
STOP RUN.
Output:
Numeric Constant :30 Character Constant :CONST Hexadecimal Constant:McDonald's Burger
Note: The CONSTANT clause can only be specified for level 01 entries for elementary constant name.
TYPE & TYPEDEF Clauses
The IBM i series, with ILE COBOL or COBOL400, offers several features that distinguish it from mainframes and other COBOL environments. One of them is the usage of TYPE and TYPEDEF clause in the DATA DIVISION.
Use of TYPEDEF & TYPE Clause
In ILE COBOL, programmers can use the TYPEDEF clause to create user-defined data types. User-defined data types are not added to the existing ILE COBOL data types, such as alphanumeric, numeric, boolean, etc. These type definitions act as templates that can then be used to define new data items using the TYPE clause.
This TYPEDEF and TYPE clause combination has a similar effect to the TEMPLATE keyword in RPGLE programs.
Example:
IDENTIFICATION DIVISION.
*------------------------*
PROGRAM-ID. DATATYP05.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
*---------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. ProgrammersIO-Lab.
OBJECT-COMPUTER. ProgrammersIO-Lab.
DATA DIVISION.
*--------------*
WORKING-STORAGE SECTION.
*=== Define TYPEDEF Clause ===*
01 CUSTOMER-REC-TYPE TYPEDEF.
05 CUSTOMER-ID PIC X(10).
05 CUSTOMER-NAME PIC X(30).
05 CUSTOMER-BALANCE PIC S9(7)V99.
*=== Utilize TYPEDEF fields from TYPE Clause ===*
01 CUSTOMER-A TYPE CUSTOMER-REC-TYPE.
01 CUSTOMER-B TYPE CUSTOMER-REC-TYPE.
PROCEDURE DIVISION.
MOVE 'CUST001' TO CUSTOMER-ID OF CUSTOMER-A.
MOVE 'John Doe' TO CUSTOMER-NAME OF CUSTOMER-A.
MOVE 123.45 TO CUSTOMER-BALANCE OF CUSTOMER-A.
MOVE 'CUST002' TO CUSTOMER-ID OF CUSTOMER-B.
MOVE 'Jane Smith' TO CUSTOMER-NAME OF CUSTOMER-B.
MOVE 543.21 TO CUSTOMER-BALANCE OF CUSTOMER-B.
DISPLAY 'Customer A ID : ' CUSTOMER-ID OF CUSTOMER-A.
DISPLAY 'Customer A Name : ' CUSTOMER-NAME OF CUSTOMER-A.
DISPLAY 'Customer A Balance: ' CUSTOMER-BALANCE
OF CUSTOMER-A.
DISPLAY 'Customer B ID : ' CUSTOMER-ID OF CUSTOMER-B.
DISPLAY 'Customer B Name : ' CUSTOMER-NAME OF CUSTOMER-B.
DISPLAY 'Customer B Balance: ' CUSTOMER-BALANCE
OF CUSTOMER-B.
STOP RUN.
Output:
Customer A ID : CUST001 Customer A Name : John Doe Customer A Balance: 000012345 Customer B ID : CUST002 Customer B Name : Jane Smith Customer B Balance: 000054321
PROGRAM STATUS Clause
IBM i series offers several environment features in ILE COBOL or COBOL400 that differ from mainframe, Micro Focus, and other COBOL environments. One among them is the PROGRAM STATUS clause.
PROGRAM STATUS Clause
RPG programs when using program status data structure, its subfields give details of running program at runtime. In COBOL400 or ILE COBOL programs limited but similar information can be achieved via the PROGRAM STATUS clause of the SPECIAL-NAMES paragraph of the CONFIGURATION SECTION.
Programmers need to declare program status group variable which consists of 94 characters only.
Example:
IDENTIFICATION DIVISION.
* -----------------------*
PROGRAM-ID. COBOL12.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
* --------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-ISERIES.
OBJECT-COMPUTER. IBM-ISERIES.
SPECIAL-NAMES. PROGRAM STATUS IS WS-PGM-STATUS1.
DATA DIVISION.
* ------------*
WORKING-STORAGE SECTION.
01 WS-RESULT PIC 9(01)V9(02).
01 WS-PGM-STATUS1 PIC X(94).
05 WS-PGM-NAM PIC X(10).
05 WS-PGM-LIB PIC X(10).
05 WS-MOD-NAM PIC X(10).
05 WS-STM-NBR PIC X(10).
05 WS-OPT-LVL PIC X(06).
05 WS-ECP-MSG PIC X(07).
05 WS-JOB-NAM PIC X(10).
05 WS-JOB-NBR PIC X(06).
05 WS-JOB-TYP PIC X(01).
05 WS-USR-PRF PIC X(10).
05 WS-TIM-STAMP PIC X(14).
PROCEDURE DIVISION.
000-MAINLINE-PARA.
* DIVIDE BY ZERO ERROR
DIVIDE 100 BY 0
GIVING WS-RESULT
ON SIZE ERROR PERFORM 011-HANDLE-ERROR-PARA
THRU 011-HANDLE-ERROR-PARA-EXIT
NOT ON SIZE ERROR DISPLAY 'WS-RESULT:' WS-RESULT.
* CALL PROGRAM OBJECT NOT FOUND
CALL "ABC001"
ON EXCEPTION PERFORM 011-HANDLE-ERROR-PARA
THRU 011-HANDLE-ERROR-PARA-EXIT.
STOP RUN.
*
011-HANDLE-ERROR-PARA.
DISPLAY 'WS-PGM-NAM :' WS-PGM-NAM.
DISPLAY 'WS-PGM-LIB :' WS-PGM-LIB.
DISPLAY 'WS-MOD-NAM :' WS-MOD-NAM.
DISPLAY 'WS-STM-NBR :' WS-STM-NBR.
DISPLAY 'WS-OPT-LVL :' WS-OPT-LVL.
DISPLAY 'WS-ECP-MSG :' WS-ECP-MSG.
DISPLAY 'WS-JOB-NAM :' WS-JOB-NAM.
DISPLAY 'WS-JOB-NBR :' WS-JOB-NBR.
DISPLAY 'WS-JOB-TYP :' WS-JOB-TYP.
DISPLAY 'WS-USR-PRF :' WS-USR-PRF.
DISPLAY 'WS-TIM-STAMP:' WS-TIM-STAMP.
011-HANDLE-ERROR-PARA-EXIT.
EXIT.
Output for Divide by zero: (MCH1211)
WS-PGM-NAM :COBOL12 WS-PGM-LIB :PIOLIB WS-MOD-NAM :COBOL12 WS-STM-NBR :26 WS-OPT-LVL :*NONE WS-ECP-MSG :MCH1211 WS-JOB-NAM :QPADEV000K WS-JOB-NBR :847831 WS-JOB-TYP :I WS-USR-PRF :PIOASH WS-TIM-STAMP:20251126012339
Output for Program object not found: (MCH3401)
WS-PGM-NAM :COBOL12 WS-PGM-LIB :PIOLIB WS-MOD-NAM :COBOL12 WS-STM-NBR :29 WS-OPT-LVL :*NONE WS-ECP-MSG :MCH3401 WS-JOB-NAM :QPADEV000K WS-JOB-NBR :847831 WS-JOB-TYP :I WS-USR-PRF :PIOASH WS-TIM-STAMP:20251126012350
Programmers must use program status group variable for getting the following details at run time:
- Program Name
- Program Library Name
- Module Name
- Last statement number
- Module in Library
- Escape MONMSG ID if error occurred.
- Job Name
- Job Number
- Job type (I- for Interactive and B- Batch)
- Timestamp during abend or error
DATA AREA Handling
Data inside a DATA AREA (LDA or User defined data area) can be fetched and modified in ILE COBOL programs. Programmers need to use either the ‘LOCAL-DATA’ or ‘DATA-AREA’ clause of the SPECIAL-NAMES paragraph in the CONFIGURATION SECTION.
LOCAL-DATA and DATA-AREA represent *LDA and user defined data area respectively.
Example:
IDENTIFICATION DIVISION.
* -----------------------*
PROGRAM-ID. DATAAREA01.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
* --------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. PROGRAMMERIO-LAB.
OBJECT-COMPUTER. PROGRAMMERIO-LAB.
SPECIAL-NAMES. LOCAL-DATA IS LOCAL-DATA-AREA
DATA-AREA IS USER-DATA-AREA.
DATA DIVISION.
* -------------*
WORKING-STORAGE SECTION.
01 WS-LDA PIC X(10).
01 WS-LDA1 PIC X(10).
01 WS-AKTEST PIC X(100).
01 WS-AKTEST1 PIC X(100).
PROCEDURE DIVISION.
* ------------------*
000-MAINLINE-PARA.
* ----------------*
* Working with LDA
* ----------------*
MOVE 'A' TO WS-LDA(1:1).
MOVE 'B' TO WS-LDA(2:1).
MOVE 'C' TO WS-LDA(3:1).
MOVE 'D' TO WS-LDA(4:1).
MOVE 'E' TO WS-LDA(5:1).
MOVE 'F' TO WS-LDA(6:1).
* Write into Local Data Area
DISPLAY WS-LDA UPON LOCAL-DATA-AREA.
* Read Local Data Area
ACCEPT WS-LDA1 FROM LOCAL-DATA-AREA.
DISPLAY WS-LDA1.
* ---------------------------*
* Working with User Data Area
* ---------------------------*
* Read User Data Area
ACCEPT WS-AKTEST FROM USER-DATA-AREA
FOR "AKTEST"
LIBRARY "ASHWANI".
DISPLAY WS-AKTEST(01:10).
DISPLAY WS-AKTEST(11:10).
DISPLAY WS-AKTEST(21:10).
DISPLAY WS-AKTEST(31:10).
MOVE WS-AKTEST TO WS-AKTEST1.
MOVE 'NEWLIB' TO WS-AKTEST1(31:10).
* Write into User Data Area
DISPLAY WS-AKTEST1 UPON USER-DATA-AREA
FOR "AKTEST"
LIBRARY "ASHWANI".
* Read User Data Area
ACCEPT WS-AKTEST FROM USER-DATA-AREA
FOR "AKTEST"
LIBRARY "ASHWANI".
DISPLAY WS-AKTEST(01:10).
DISPLAY WS-AKTEST(11:10).
DISPLAY WS-AKTEST(21:10).
DISPLAY WS-AKTEST(31:10).
STOP RUN.
Output for LDA:
ABCDEF
Output for User Data Area: (Before Change)
LIBRARY1 LIBRARY2 LIBRARY3 LIBRARY4
Output for User Data Area: (After Change)
LIBRARY1 LIBRARY2 LIBRARY3 NEWLIB
Switch Handling
SWITCH is completely an IBM i-Series platform environment feature.
IBM i system provides some auto generated features passed from job or program level that changes the course of program flow if used by programmers.
Few auto-generated features are:
- Local Data Area (*LDA) – LDA have 1024 bytes memory area. Local data area is auto generated in each program and data area details can be passed from the called interactive programs.
- *INZSR is a special initialization subroutine in RPG programs that runs automatically at the beginning of the program.
- Switch – are similar to the indicators or Boolean data. There are 8 switches provided by IBM i systems. These switches can be passed from interactive or batch jobs.
SWITCH can have 3 possible values as shown below:
- ‘1’ as True
- ‘0’ as False
- ‘X’ as masked meaning ignore during comparison.
SWITCH in IBM i System
There are 4 CL commands CRTJOBD, SBMJOB, CHGJOB and RTVJOBA that are associated with parameter Job switches (SWS).
CRTJOBD:
The initial values of the switches for the job are determined first by the CRTJOBD command; the default value is 00000000.
Create Job Description (CRTJOBD)
Type choices, press Enter.
End severity . . . . . . . . . . ENDSEV 30
Inquiry message reply . . . . . INQMSGRPY *RQD
Hold on job queue . . . . . . . HOLD *NO
Job date . . . . . . . . . . . . DATE *SYSVAL
Job switches . . . . . . . . . . SWS 00000000
SBMJOB:
Programmers can change this if necessary, using the SWS parameter on the Submit SBMJOB and CHGJOB.
Submit Job (SBMJOB)
Type choices, press Enter.
Schedule date . . . . . . . . . SCDDATE *CURRENT
Schedule time . . . . . . . . . SCDTIME *CURRENT
Job date . . . . . . . . . . . . DATE *JOBD
Job switches . . . . . . . . . . SWS 10100000
CHGJOB:
Change Job (CHGJOB)
Type choices, press Enter.
Time separator . . . . . . . . . TIMSEP ':'
Job switches . . . . . . . . . . SWS 00000000
SWITCH in CL programs
CL and other high-level languages working in IBM i system can also set job switches or check switch value.
RTVJOBA:
Retrieve Job Attributes (RTVJOBA)
Type choices, press Enter.
CL var for YEAROFS (3 0) . . YEAROFS _______
CL var for ACGCDE (15) . . ACGCDE _______
CL var for SWS (8) . . SWS _______
SWITCH in ILE COBOL programs
ILE COBOL job switches are handled by SPECIAL-NAMES paragraph of CONFIGURATION SECTION in ENVIRONMENT DIVISION. These indicators are also called external indicators. Their special names are – UPSI-0, UPSI-1, UPSI-2, UPSI-3, UPSI-4, UPSI-5, UPSI-6, UPSI-7. These are similar to *INU1 to *INU8 in RPGLE programming.
Example: (A CL program SWITCH02 – setting job switches for COBOL program ORDERRPT)
PGM
DCL:
DCL VAR(&SWS) TYPE(*CHAR) LEN(8)
START:
/* Retrieve default job switches */
RTVJOBA SWS(&SWS)
/* Set job switches for ORDERRPT program */
CHGJOB SWS(10100000)
CALL PGM(ORDERRPT)
/* Reset Switches to default */
CHGJOB SWS(&SWS)
END:
ENDPGM
COBOL program – ORDERRPT
IDENTIFICATION DIVISION.
* -----------------------*
PROGRAM-ID. ORDERRPT.
AUTHOR. PROGRAMMERS.
ENVIRONMENT DIVISION.
* --------------------*
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-ISERIES.
OBJECT-COMPUTER. IBM-ISERIES.
SPECIAL-NAMES.
* All Switches declarations used in the program
UPSI-0 IS UPSI-SWITCH-0
ON STATUS IS U0-ON
OFF STATUS IS U0-OFF
UPSI-1 IS UPSI-SWITCH-1
ON STATUS IS U1-ON
OFF STATUS IS U1-OFF
UPSI-2 IS UPSI-SWITCH-2
ON STATUS IS U2-ON
OFF STATUS IS U2-OFF
UPSI-3 IS UPSI-SWITCH-3
ON STATUS IS U3-ON
OFF STATUS IS U3-OFF
UPSI-4 IS UPSI-SWITCH-4
ON STATUS IS U4-ON
OFF STATUS IS U4-OFF
UPSI-5 IS UPSI-SWITCH-5
ON STATUS IS U5-ON
OFF STATUS IS U5-OFF.
INPUT-OUTPUT SECTION.
* --------------------*
FILE-CONTROL.
* All file declarations
SELECT ORDER-FILE
ASSIGN TO DATABASE-ORDER
ORGANIZATION IS INDEXED
ACCESS MODE IS DYNAMIC
RECORD KEY IS EXTERNALLY-DESCRIBED-KEY
WITH DUPLICATES
FILE STATUS IS ORDER-FS.
SELECT REPORT-FILE
ASSIGN TO PRINTER-QSYSPRT
FILE STATUS IS REPORT-FS.
* ------------*
DATA DIVISION.
* ------------*
FILE SECTION.
* ORDER file external record format declaration.
FD ORDER-FILE
LABEL RECORDS ARE STANDARD.
01 ORDER-RCD.
COPY DD-ORDERR OF ORDER.
* REPORT file program described record format declaration.
FD REPORT-FILE
LABEL RECORDS ARE OMITTED.
01 REPORT-LINE PIC X(132).
WORKING-STORAGE SECTION.
* -----------------------*
* REPORT-FILE header record format.
01 HEADER01.
05 FILLER PIC X(10) VALUE SPACES.
05 H1-HEADER-DESC PIC X(40).
01 HEADER02.
05 FILLER PIC X(02) VALUE '| '.
05 FILLER PIC X(10) VALUE 'ORDER DATE'.
05 FILLER PIC X(03) VALUE ' | '.
05 FILLER PIC X(10) VALUE 'ORDER ID'.
05 FILLER PIC X(03) VALUE ' | '.
05 FILLER PIC X(25) VALUE 'CUSTOMER NAME'.
05 FILLER PIC X(03) VALUE ' | '.
05 FILLER PIC X(20) VALUE 'CUSTOMER CITY'.
* REPORT-FILE detail record format.
01 DETAIL01.
05 FILLER PIC X(02) VALUE '| '.
05 D1-ORDERDT PIC X(10).
05 FILLER PIC X(03) VALUE ' | '.
05 D1-ORDERID PIC X(10).
05 FILLER PIC X(03) VALUE ' | '.
05 D1-CUSTNAM PIC X(25).
05 FILLER PIC X(03) VALUE ' | '.
05 D1-CUSTCTY PIC X(20).
* Program variable declarations
01 START-DATE LIKE ORDERDT.
01 END-DATE LIKE ORDERDT.
01 TODAYSDATE FORMAT DATE '@Y%m%d'.
01 FIRST-RECORD PIC 9(01) VALUE 1.
01 PAGE-COUNT PIC 9(04) VALUE 0.
01 LINE-COUNT PIC 9(02) VALUE 0.
* All file status variable declarations
77 ORDER-FS PIC X(02).
88 88-ORDER-EOF VALUE '10'.
88 88-ORDER-NFND VALUE '23'.
77 REPORT-FS LIKE ORDER-FS.
88 88-REPORT-EOP VALUE '10'.
PROCEDURE DIVISION.
* ------------------*
MAINLINE-PARA.
* First check switch and corresponding switch activities.
PERFORM INITIALIZE-PARA
THRU INITIALIZE-EXIT.
* End Program!.
STOP RUN.
* ------------------------------------------------------------*
* Initialize paragraph to check on switches and initialize all*
* required variables *
* ------------------------------------------------------------*
INITIALIZE-PARA.
* Get Today's date in ISO format.
MOVE FUNCTION CURRENT-DATE(1:8)
TO TODAYSDATE.
* Prepare Daily Order report for previous date
IF U0-ON
MOVE FUNCTION SUBTRACT-DURATION(TODAYSDATE DAYS 1)
TO START-DATE
MOVE TODAYSDATE TO END-DATE
MOVE 'DAILY ORDER REPORT'
TO H1-HEADER-DESC
PERFORM GENERATE-REPORT-PARA
THRU GENERATE-REPORT-EXIT
END-IF.
* Prepare Weekly Order report for last 7 days
IF U1-ON
MOVE FUNCTION SUBTRACT-DURATION(TODAYSDATE DAYS 7)
TO START-DATE
MOVE TODAYSDATE TO END-DATE
MOVE 1 TO FIRST-RECORD
MOVE 'WEEKLY ORDER REPORT'
TO H1-HEADER-DESC
PERFORM GENERATE-REPORT-PARA
THRU GENERATE-REPORT-EXIT
END-IF.
* Prepare Monthly Order report for last 30 days
IF U2-ON
MOVE FUNCTION SUBTRACT-DURATION(TODAYSDATE DAYS 30)
TO START-DATE
MOVE TODAYSDATE TO END-DATE
MOVE 1 TO FIRST-RECORD
MOVE 'MONTHLY ORDER REPORT'
TO H1-HEADER-DESC
PERFORM GENERATE-REPORT-PARA
THRU GENERATE-REPORT-EXIT
END-IF.
* Prepare Quarterly Order report for last 90 days
IF U3-ON
MOVE FUNCTION SUBTRACT-DURATION(TODAYSDATE DAYS 90)
TO START-DATE
MOVE TODAYSDATE TO END-DATE
MOVE 1 TO FIRST-RECORD
MOVE 'QUATERLY ORDER REPORT'
TO H1-HEADER-DESC
PERFORM GENERATE-REPORT-PARA
THRU GENERATE-REPORT-EXIT
END-IF.
* Prepare half yearly Order report for last 180 days
IF U4-ON
MOVE FUNCTION SUBTRACT-DURATION(TODAYSDATE DAYS 180)
TO START-DATE
MOVE TODAYSDATE TO END-DATE
MOVE 1 TO FIRST-RECORD
MOVE 'HALF YEARLY ORDER REPORT'
TO H1-HEADER-DESC
PERFORM GENERATE-REPORT-PARA
THRU GENERATE-REPORT-EXIT
END-IF.
* Prepare yearly Order report for last 365 days
IF U5-ON
MOVE FUNCTION SUBTRACT-DURATION(TODAYSDATE DAYS 365)
TO START-DATE
MOVE TODAYSDATE TO END-DATE
MOVE 1 TO FIRST-RECORD
MOVE 'YEARLY ORDER REPORT'
TO H1-HEADER-DESC
PERFORM GENERATE-REPORT-PARA
THRU GENERATE-REPORT-EXIT
END-IF.
INITIALIZE-EXIT. EXIT.
* ------------------------------------------------------------*
* Generate order report paragraph *
* ------------------------------------------------------------*
GENERATE-REPORT-PARA.
* Open all required files
OPEN INPUT ORDER-FILE
OUTPUT REPORT-FILE.
* Process all required records
PERFORM PROCESS-PARA
THRU PROCESS-EXIT
* Close all files
CLOSE ORDER-FILE
REPORT-FILE.
GENERATE-REPORT-EXIT. EXIT.
* ------------------------------------------------------------*
* Process input file and generate report *
* ------------------------------------------------------------*
PROCESS-PARA.
* Set the pointer to the ORDER file.
MOVE START-DATE TO ORDERDT.
MOVE ZEROS TO ORDERID.
START ORDER-FILE KEY >= EXTERNALLY-DESCRIBED-KEY
INVALID KEY
* Handle record not found.
SET 88-ORDER-EOF TO TRUE
GO TO PROCESS-EXIT.
PROCESS-LOOP.
* If pointer set successfully, read next equivalent record.
READ ORDER-FILE NEXT RECORD
AT END
* Handle end of file.
SET 88-ORDER-EOF TO TRUE
GO TO PROCESS-EXIT
END-READ.
* If ORDERDT is greater than END-DATE, then end read loop.
IF ORDERDT > END-DATE
SET 88-ORDER-EOF TO TRUE
GO TO PROCESS-EXIT
END-IF.
* Check EOP and Write header record
IF FIRST-RECORD = 1
ADD 1 TO FIRST-RECORD
MOVE 1 TO PAGE-COUNT
WRITE REPORT-LINE FROM HEADER01
AFTER ADVANCING PAGE
WRITE REPORT-LINE FROM HEADER02
AFTER ADVANCING 1 LINE
ELSE
IF 88-REPORT-EOP
WRITE REPORT-LINE FROM HEADER01
AFTER ADVANCING PAGE
WRITE REPORT-LINE FROM HEADER02
AFTER ADVANCING 1 LINE
END-IF
END-IF.
* Populate fields of Detail record.
MOVE ORDERDT TO D1-ORDERDT.
MOVE ORDERID TO D1-ORDERID.
MOVE CUSTNAM TO D1-CUSTNAM.
MOVE CUSTCTY TO D1-CUSTCTY.
* Write Detail record.
WRITE REPORT-LINE FROM DETAIL01
AFTER ADVANCING 1 LINE.
GO TO PROCESS-LOOP.
PROCESS-EXIT. EXIT.
When CL program is invoked, then two reports get generated.
CALL SWITCH02
Device or Total Cur
Opt File User Queue User Data Sts Pages Page Copy
QSYSPRT PIOASH PRT01 ORDERRPT RDY 2 1
QSYSPRT PIOASH PRT01 ORDERRPT RDY 2 1
It generated – Daily Order Report.
DAILY ORDER REPORT | ORDER DATE | ORDER ID | CUSTOMER NAME | CUSTOMER CITY | 20251130 | 4021 | JACK CITY | FL | 20251130 | 4021 | JOHN BROWN | FL | 20251130 | 4021 | MANDY MOORE | FL
It generated – Monthly Order Report.
MONTHLY ORDER REPORT | ORDER DATE | ORDER ID | CUSTOMER NAME | CUSTOMER CITY | 20251101 | 1031 | Peter Jones | FL | 20251101 | 3013 | Peter Master | FL | 20251113 | 2019 | Flex Brown | FL | 20251114 | 2012 | Steve Jobs | FL | 20251114 | 2013 | Neil ArmsStrong | FL | 20251114 | 2020 | James Bond | FL | 20251117 | 1212 | Brad Pitt | IL | 20251117 | 1212 | Anne Hathway | IL | 20251117 | 4444 | Leo Caprio | CA | 20251117 | 4444 | Kate Wins | CA | 20251117 | 5505 | Robert Downey Jr. | TX | 20251117 | 5505 | George Clooney | NY | 20251117 | 7212 | Tom Hanks | TX | 20251117 | 7212 | Scarlet Johnson | NJ | 20251130 | 4021 | JACK CITY | FL | 20251130 | 4021 | JOHN BROWN | FL | 20251130 | 4021 | MANDY MOORE | FL
When COBOL program ORDERRPT is called either directly via command line or CL program where SBMJOB contains SWS(00010000), it generates single report with weekly order report
SBMJOB CMD(CALL PGM(ORDERRPT)) SWS(00010000)
QUATERLY ORDER REPORT | ORDER DATE | ORDER ID | CUSTOMER NAME | CUSTOMER CITY | 20251101 | 1031 | Peter Jones | FL | 20251101 | 3013 | Peter Master | FL | 20251113 | 2019 | Flex Brown | FL | 20251114 | 2012 | Steve Jobs | FL | 20251114 | 2013 | Neil ArmsStrong | FL | 20251114 | 2020 | James Bond | FL | 20251117 | 1212 | Brad Pitt | IL | 20251117 | 1212 | Anne Hathway | IL | 20251117 | 4444 | Leo Caprio | CA | 20251117 | 4444 | Kate Wins | CA | 20251117 | 5505 | Robert Downey Jr. | TX | 20251117 | 5505 | George Clooney | NY | 20251117 | 7212 | Tom Hanks | TX | 20251117 | 7212 | Scarlet Johnson | NJ | 20251130 | 4021 | JACK CITY | FL | 20251130 | 4021 | JOHN BROWN | FL | 20251130 | 4021 | MANDY MOORE | FL