OPTIONAL

Overview

The OPTIONAL keyword in COBOL is used to indicate that a file or parameter may or may not be present during program execution. For files, it allows the program to handle missing files gracefully without terminating. For parameters, it enables flexible subprogram interfaces where some arguments may be omitted.

Primary Uses

Optional Files

Files that may not exist without causing program failure

Configuration Files

Settings files that use defaults when missing

Log Files

Logging that can be disabled when file is absent

Input Validation

Reference files that may not always be required

Optional File Declaration

Basic Optional File Syntax

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.DAT"
        ORGANIZATION IS SEQUENTIAL
        ACCESS MODE IS SEQUENTIAL
        FILE STATUS IS WS-CUSTOMER-STATUS.
        
    SELECT OPTIONAL CONFIG-FILE ASSIGN TO "CONFIG.INI"
        ORGANIZATION IS SEQUENTIAL
        ACCESS MODE IS SEQUENTIAL
        FILE STATUS IS WS-CONFIG-STATUS.
        
    SELECT OPTIONAL AUDIT-LOG ASSIGN TO "AUDIT.LOG"
        ORGANIZATION IS SEQUENTIAL
        ACCESS MODE IS SEQUENTIAL
        FILE STATUS IS WS-AUDIT-STATUS.

DATA DIVISION.
FILE SECTION.
FD  CUSTOMER-FILE.
01  CUSTOMER-RECORD.
    05  CUST-ID         PIC X(8).
    05  CUST-NAME       PIC X(30).
    05  CUST-BALANCE    PIC S9(8)V99.

FD  CONFIG-FILE.
01  CONFIG-RECORD      PIC X(80).

FD  AUDIT-LOG.
01  AUDIT-RECORD       PIC X(120).

WORKING-STORAGE SECTION.
01  WS-FILE-STATUS.
    05  WS-CUSTOMER-STATUS  PIC XX.
    05  WS-CONFIG-STATUS    PIC XX.
    05  WS-AUDIT-STATUS     PIC XX.

Declaring files as optional using the OPTIONAL keyword.

Optional File Processing

Configuration File Handling

WORKING-STORAGE SECTION.
01  WS-CONFIG-SETTINGS.
    05  WS-DEBUG-MODE       PIC X VALUE 'N'.
    05  WS-LOG-LEVEL        PIC 9 VALUE 1.
    05  WS-MAX-RECORDS      PIC 9(6) VALUE 10000.
    05  WS-TIMEOUT-SECONDS  PIC 9(3) VALUE 30.
    05  WS-CONFIG-LOADED    PIC X VALUE 'N'.

PROCEDURE DIVISION.
LOAD-CONFIGURATION.
    *> Set default values first
    MOVE 'N' TO WS-DEBUG-MODE.
    MOVE 1 TO WS-LOG-LEVEL.
    MOVE 10000 TO WS-MAX-RECORDS.
    MOVE 30 TO WS-TIMEOUT-SECONDS.
    MOVE 'N' TO WS-CONFIG-LOADED.
    
    *> Try to open optional configuration file
    OPEN INPUT CONFIG-FILE.
    
    EVALUATE WS-CONFIG-STATUS
        WHEN "00"
            *> File exists and opened successfully
            DISPLAY "CONFIGURATION FILE FOUND"
            PERFORM READ-CONFIG-SETTINGS
            MOVE 'Y' TO WS-CONFIG-LOADED
            CLOSE CONFIG-FILE
            
        WHEN "05"
            *> File is optional and not present
            DISPLAY "CONFIGURATION FILE NOT FOUND - USING DEFAULTS"
            MOVE 'N' TO WS-CONFIG-LOADED
            
        WHEN "35"
            *> File exists but cannot be opened
            DISPLAY "CONFIGURATION FILE EXISTS BUT CANNOT BE OPENED"
            DISPLAY "USING DEFAULT SETTINGS"
            MOVE 'N' TO WS-CONFIG-LOADED
            
        WHEN OTHER
            DISPLAY "ERROR ACCESSING CONFIGURATION FILE: " WS-CONFIG-STATUS
            DISPLAY "USING DEFAULT SETTINGS"
            MOVE 'N' TO WS-CONFIG-LOADED
    END-EVALUATE.
    
    PERFORM DISPLAY-CURRENT-SETTINGS.

READ-CONFIG-SETTINGS.
    PERFORM UNTIL WS-CONFIG-STATUS NOT = "00"
        READ CONFIG-FILE
            AT END
                EXIT PERFORM
            NOT AT END
                PERFORM PARSE-CONFIG-LINE
        END-READ
    END-PERFORM.

PARSE-CONFIG-LINE.
    IF CONFIG-RECORD(1:12) = "DEBUG_MODE="
        MOVE CONFIG-RECORD(13:1) TO WS-DEBUG-MODE
        DISPLAY "LOADED: DEBUG_MODE=" WS-DEBUG-MODE
    END-IF.
    
    IF CONFIG-RECORD(1:11) = "LOG_LEVEL="
        MOVE CONFIG-RECORD(12:1) TO WS-LOG-LEVEL
        DISPLAY "LOADED: LOG_LEVEL=" WS-LOG-LEVEL
    END-IF.
    
    IF CONFIG-RECORD(1:12) = "MAX_RECORDS="
        MOVE CONFIG-RECORD(13:6) TO WS-MAX-RECORDS
        DISPLAY "LOADED: MAX_RECORDS=" WS-MAX-RECORDS
    END-IF.
    
    IF CONFIG-RECORD(1:16) = "TIMEOUT_SECONDS="
        MOVE CONFIG-RECORD(17:3) TO WS-TIMEOUT-SECONDS
        DISPLAY "LOADED: TIMEOUT_SECONDS=" WS-TIMEOUT-SECONDS
    END-IF.

DISPLAY-CURRENT-SETTINGS.
    DISPLAY "CURRENT CONFIGURATION:".
    DISPLAY "  DEBUG MODE: " WS-DEBUG-MODE.
    DISPLAY "  LOG LEVEL: " WS-LOG-LEVEL.
    DISPLAY "  MAX RECORDS: " WS-MAX-RECORDS.
    DISPLAY "  TIMEOUT: " WS-TIMEOUT-SECONDS " SECONDS".
    IF WS-CONFIG-LOADED = 'Y'
        DISPLAY "  SOURCE: CONFIGURATION FILE"
    ELSE
        DISPLAY "  SOURCE: DEFAULT VALUES"
    END-IF.

Loading configuration from optional file with defaults.

Optional Audit Logging

WORKING-STORAGE SECTION.
01  WS-AUDIT-CONTROL.
    05  WS-AUDIT-ENABLED   PIC X VALUE 'N'.
    05  WS-AUDIT-ENTRIES   PIC 9(6) VALUE 0.

PROCEDURE DIVISION.
INITIALIZE-AUDIT-LOGGING.
    OPEN EXTEND AUDIT-LOG.
    
    EVALUATE WS-AUDIT-STATUS
        WHEN "00"
            MOVE 'Y' TO WS-AUDIT-ENABLED
            DISPLAY "AUDIT LOGGING ENABLED"
            PERFORM WRITE-AUDIT-STARTUP
            
        WHEN "05"
            MOVE 'N' TO WS-AUDIT-ENABLED
            DISPLAY "AUDIT LOGGING DISABLED - LOG FILE NOT CONFIGURED"
            
        WHEN OTHER
            MOVE 'N' TO WS-AUDIT-ENABLED
            DISPLAY "AUDIT LOGGING DISABLED - ERROR: " WS-AUDIT-STATUS
    END-EVALUATE.

WRITE-AUDIT-ENTRY.
    IF WS-AUDIT-ENABLED = 'Y'
        PERFORM WRITE-AUDIT-RECORD
        ADD 1 TO WS-AUDIT-ENTRIES
    END-IF.

WRITE-AUDIT-STARTUP.
    ACCEPT WS-CURRENT-TIMESTAMP FROM TIMESTAMP.
    STRING "STARTUP " WS-CURRENT-TIMESTAMP 
           " APPLICATION INITIALIZED"
           DELIMITED BY SIZE
           INTO AUDIT-RECORD.
    
    WRITE AUDIT-RECORD.
    IF WS-AUDIT-STATUS = "00"
        ADD 1 TO WS-AUDIT-ENTRIES
        DISPLAY "STARTUP AUDIT ENTRY WRITTEN"
    ELSE
        DISPLAY "ERROR WRITING STARTUP AUDIT: " WS-AUDIT-STATUS
        MOVE 'N' TO WS-AUDIT-ENABLED
    END-IF.

WRITE-AUDIT-RECORD.
    *> Format audit record with timestamp and details
    ACCEPT WS-CURRENT-TIMESTAMP FROM TIMESTAMP.
    STRING WS-CURRENT-TIMESTAMP " " WS-AUDIT-MESSAGE
           DELIMITED BY SIZE
           INTO AUDIT-RECORD.
    
    WRITE AUDIT-RECORD.
    IF WS-AUDIT-STATUS NOT = "00"
        DISPLAY "AUDIT WRITE ERROR: " WS-AUDIT-STATUS
        *> Continue processing even if audit fails
    END-IF.

CLOSE-AUDIT-LOGGING.
    IF WS-AUDIT-ENABLED = 'Y'
        PERFORM WRITE-AUDIT-SHUTDOWN
        CLOSE AUDIT-LOG
        DISPLAY "AUDIT LOGGING CLOSED - ENTRIES WRITTEN: " WS-AUDIT-ENTRIES
    END-IF.

Optional audit logging that degrades gracefully.

Optional Reference Data

Validation with Optional Files

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT TRANSACTION-FILE ASSIGN TO "TRANS.DAT"
        ORGANIZATION IS SEQUENTIAL
        FILE STATUS IS WS-TRANS-STATUS.
        
    SELECT OPTIONAL VALIDATION-FILE ASSIGN TO "VALID.REF"
        ORGANIZATION IS INDEXED
        ACCESS MODE IS RANDOM
        RECORD KEY IS VALID-CODE
        FILE STATUS IS WS-VALID-STATUS.

DATA DIVISION.
FILE SECTION.
FD  TRANSACTION-FILE.
01  TRANSACTION-RECORD.
    05  TRANS-ID        PIC X(10).
    05  TRANS-CODE      PIC X(6).
    05  TRANS-AMOUNT    PIC 9(8)V99.

FD  VALIDATION-FILE.
01  VALIDATION-RECORD.
    05  VALID-CODE      PIC X(6).
    05  VALID-DESC      PIC X(30).
    05  VALID-LIMITS.
        10  MIN-AMOUNT  PIC 9(8)V99.
        10  MAX-AMOUNT  PIC 9(8)V99.

WORKING-STORAGE SECTION.
01  WS-VALIDATION-CONTROL.
    05  WS-VALIDATION-AVAILABLE PIC X VALUE 'N'.
    05  WS-STRICT-MODE          PIC X VALUE 'N'.

PROCEDURE DIVISION.
INITIALIZE-VALIDATION.
    OPEN INPUT VALIDATION-FILE.
    
    EVALUATE WS-VALID-STATUS
        WHEN "00"
            MOVE 'Y' TO WS-VALIDATION-AVAILABLE
            MOVE 'Y' TO WS-STRICT-MODE
            DISPLAY "VALIDATION FILE LOADED - STRICT MODE ENABLED"
            
        WHEN "05"
            MOVE 'N' TO WS-VALIDATION-AVAILABLE
            MOVE 'N' TO WS-STRICT-MODE
            DISPLAY "VALIDATION FILE NOT FOUND - LENIENT MODE"
            
        WHEN OTHER
            MOVE 'N' TO WS-VALIDATION-AVAILABLE
            MOVE 'N' TO WS-STRICT-MODE
            DISPLAY "VALIDATION FILE ERROR: " WS-VALID-STATUS
            DISPLAY "CONTINUING IN LENIENT MODE"
    END-EVALUATE.

VALIDATE-TRANSACTION.
    IF WS-VALIDATION-AVAILABLE = 'Y'
        PERFORM STRICT-VALIDATION
    ELSE
        PERFORM BASIC-VALIDATION
    END-IF.

STRICT-VALIDATION.
    MOVE TRANS-CODE TO VALID-CODE.
    
    READ VALIDATION-FILE
        INVALID KEY
            DISPLAY "INVALID TRANSACTION CODE: " TRANS-CODE
            MOVE 'N' TO WS-TRANSACTION-VALID
        NOT INVALID KEY
            IF TRANS-AMOUNT < MIN-AMOUNT OR
               TRANS-AMOUNT > MAX-AMOUNT
                DISPLAY "AMOUNT OUT OF RANGE FOR CODE: " TRANS-CODE
                DISPLAY "  AMOUNT: " TRANS-AMOUNT
                DISPLAY "  RANGE: " MIN-AMOUNT " TO " MAX-AMOUNT
                MOVE 'N' TO WS-TRANSACTION-VALID
            ELSE
                MOVE 'Y' TO WS-TRANSACTION-VALID
                DISPLAY "TRANSACTION VALIDATED: " TRANS-ID
            END-IF
    END-READ.

BASIC-VALIDATION.
    *> Basic validation without reference file
    IF TRANS-CODE = SPACES OR TRANS-AMOUNT <= 0
        DISPLAY "BASIC VALIDATION FAILED: " TRANS-ID
        MOVE 'N' TO WS-TRANSACTION-VALID
    ELSE
        MOVE 'Y' TO WS-TRANSACTION-VALID
        DISPLAY "BASIC VALIDATION PASSED: " TRANS-ID
    END-IF.

Validation logic that adapts based on optional reference files.

Optional Report Generation

Flexible Reporting System

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT DATA-FILE ASSIGN TO "DATA.DAT"
        ORGANIZATION IS SEQUENTIAL
        FILE STATUS IS WS-DATA-STATUS.
        
    SELECT OPTIONAL SUMMARY-REPORT ASSIGN TO "SUMMARY.RPT"
        ORGANIZATION IS SEQUENTIAL
        FILE STATUS IS WS-SUMMARY-STATUS.
        
    SELECT OPTIONAL DETAIL-REPORT ASSIGN TO "DETAIL.RPT"
        ORGANIZATION IS SEQUENTIAL
        FILE STATUS IS WS-DETAIL-STATUS.
        
    SELECT OPTIONAL ERROR-REPORT ASSIGN TO "ERRORS.RPT"
        ORGANIZATION IS SEQUENTIAL
        FILE STATUS IS WS-ERROR-STATUS.

WORKING-STORAGE SECTION.
01  WS-REPORT-CONTROL.
    05  WS-SUMMARY-ENABLED     PIC X VALUE 'N'.
    05  WS-DETAIL-ENABLED      PIC X VALUE 'N'.
    05  WS-ERROR-ENABLED       PIC X VALUE 'N'.
    05  WS-REPORTS-GENERATED   PIC 9(2) VALUE 0.

PROCEDURE DIVISION.
INITIALIZE-REPORTS.
    PERFORM SETUP-SUMMARY-REPORT.
    PERFORM SETUP-DETAIL-REPORT.
    PERFORM SETUP-ERROR-REPORT.
    
    DISPLAY "REPORT GENERATION SETUP COMPLETE".
    DISPLAY "  SUMMARY REPORT: " WS-SUMMARY-ENABLED.
    DISPLAY "  DETAIL REPORT: " WS-DETAIL-ENABLED.
    DISPLAY "  ERROR REPORT: " WS-ERROR-ENABLED.

SETUP-SUMMARY-REPORT.
    OPEN OUTPUT SUMMARY-REPORT.
    
    EVALUATE WS-SUMMARY-STATUS
        WHEN "00"
            MOVE 'Y' TO WS-SUMMARY-ENABLED
            ADD 1 TO WS-REPORTS-GENERATED
            PERFORM WRITE-SUMMARY-HEADER
            
        WHEN "05"
            MOVE 'N' TO WS-SUMMARY-ENABLED
            DISPLAY "SUMMARY REPORT DISABLED - FILE NOT CONFIGURED"
            
        WHEN OTHER
            MOVE 'N' TO WS-SUMMARY-ENABLED
            DISPLAY "SUMMARY REPORT DISABLED - ERROR: " WS-SUMMARY-STATUS
    END-EVALUATE.

PROCESS-DATA-WITH-REPORTS.
    OPEN INPUT DATA-FILE.
    
    PERFORM READ-DATA-RECORD.
    
    PERFORM UNTIL WS-DATA-STATUS = "10"
        PERFORM PROCESS-RECORD
        
        IF WS-RECORD-VALID = 'Y'
            IF WS-SUMMARY-ENABLED = 'Y'
                PERFORM UPDATE-SUMMARY-TOTALS
            END-IF
            
            IF WS-DETAIL-ENABLED = 'Y'
                PERFORM WRITE-DETAIL-LINE
            END-IF
        ELSE
            IF WS-ERROR-ENABLED = 'Y'
                PERFORM WRITE-ERROR-LINE
            END-IF
        END-IF
        
        PERFORM READ-DATA-RECORD
    END-PERFORM.
    
    PERFORM FINALIZE-REPORTS.

WRITE-SUMMARY-LINE.
    IF WS-SUMMARY-ENABLED = 'Y'
        MOVE WS-SUMMARY-LINE TO SUMMARY-RECORD
        WRITE SUMMARY-RECORD
        
        IF WS-SUMMARY-STATUS NOT = "00"
            DISPLAY "ERROR WRITING SUMMARY: " WS-SUMMARY-STATUS
            MOVE 'N' TO WS-SUMMARY-ENABLED
        END-IF
    END-IF.

FINALIZE-REPORTS.
    IF WS-SUMMARY-ENABLED = 'Y'
        PERFORM WRITE-SUMMARY-TOTALS
        CLOSE SUMMARY-REPORT
    END-IF.
    
    IF WS-DETAIL-ENABLED = 'Y'
        CLOSE DETAIL-REPORT
    END-IF.
    
    IF WS-ERROR-ENABLED = 'Y'
        CLOSE ERROR-REPORT
    END-IF.
    
    CLOSE DATA-FILE.
    
    DISPLAY "PROCESSING COMPLETE".
    DISPLAY "  REPORTS GENERATED: " WS-REPORTS-GENERATED.

Flexible report generation with optional output files.

Error Handling Patterns

Graceful Degradation

WORKING-STORAGE SECTION.
01  WS-OPTIONAL-FEATURES.
    05  WS-FEATURE-COUNT     PIC 9(2) VALUE 0.
    05  WS-FEATURES-TABLE.
        10  WS-FEATURE-ENTRY OCCURS 10 TIMES.
            15  WS-FEATURE-NAME    PIC X(20).
            15  WS-FEATURE-STATUS  PIC X.
                88  FEATURE-ENABLED  VALUE 'Y'.
                88  FEATURE-DISABLED VALUE 'N'.

PROCEDURE DIVISION.
CHECK-OPTIONAL-COMPONENTS.
    MOVE 0 TO WS-FEATURE-COUNT.
    
    *> Check configuration file
    PERFORM CHECK-CONFIG-FILE.
    
    *> Check audit logging
    PERFORM CHECK-AUDIT-LOG.
    
    *> Check validation reference
    PERFORM CHECK-VALIDATION-REF.
    
    *> Check backup facility
    PERFORM CHECK-BACKUP-FACILITY.
    
    PERFORM DISPLAY-FEATURE-STATUS.

CHECK-CONFIG-FILE.
    ADD 1 TO WS-FEATURE-COUNT.
    MOVE "CONFIGURATION" TO WS-FEATURE-NAME (WS-FEATURE-COUNT).
    
    OPEN INPUT CONFIG-FILE.
    IF WS-CONFIG-STATUS = "00" OR WS-CONFIG-STATUS = "05"
        SET FEATURE-ENABLED (WS-FEATURE-COUNT) TO TRUE
        IF WS-CONFIG-STATUS = "00"
            CLOSE CONFIG-FILE
        END-IF
    ELSE
        SET FEATURE-DISABLED (WS-FEATURE-COUNT) TO TRUE
        DISPLAY "WARNING: CONFIG FILE ERROR - " WS-CONFIG-STATUS
    END-IF.

DISPLAY-FEATURE-STATUS.
    DISPLAY "OPTIONAL FEATURE STATUS:".
    PERFORM VARYING WS-INDEX FROM 1 BY 1 
            UNTIL WS-INDEX > WS-FEATURE-COUNT
        
        DISPLAY "  " WS-FEATURE-NAME (WS-INDEX) ": "
        
        IF FEATURE-ENABLED (WS-INDEX)
            DISPLAY "ENABLED"
        ELSE
            DISPLAY "DISABLED"
        END-IF
    END-PERFORM.
    
    DISPLAY " ".
    DISPLAY "APPLICATION WILL CONTINUE WITH AVAILABLE FEATURES".

SAFE-OPTIONAL-OPERATION.
    *> Template for safe optional operations
    EVALUATE TRUE
        WHEN FEATURE-ENABLED (WS-CONFIG-FEATURE)
            PERFORM ENHANCED-PROCESSING
            
        WHEN FEATURE-DISABLED (WS-CONFIG-FEATURE)
            PERFORM STANDARD-PROCESSING
            
        WHEN OTHER
            PERFORM MINIMAL-PROCESSING
            DISPLAY "RUNNING IN MINIMAL MODE"
    END-EVALUATE.

Systematic checking and graceful degradation of optional features.

Best Practices

  • Always provide meaningful default behavior when optional files are missing
  • Check file status "05" specifically for optional files not present
  • Document which files are optional and what happens when they're missing
  • Log the status of optional features at program startup
  • Design programs to degrade gracefully when optional components are unavailable

File Status for Optional Files

StatusMeaningAction
00File opened successfullyProceed with file operations
05Optional file not presentUse default behavior
35File exists but cannot openHandle error or use defaults
37Wrong access modeCheck file permissions

Design Patterns

Configuration Pattern

Load settings from optional file with defaults

Logging Pattern

Enable logging only when log file is available

Validation Pattern

Enhanced validation with optional reference data

Feature Toggle

Enable features based on optional file presence

Related Concepts

File Status

Checking status code 05 for missing optional files

OPEN Statement

Opening files with proper error handling

SELECT Clause

File declaration in Environment Division

Error Handling

Graceful degradation and default behaviors