Проверка данных в COBOL - PullRequest
5 голосов
/ 21 мая 2011

Я на последнем курсе, который у меня будет для COBOL в колледже, и я должен написать интерактивные программы, которые должны отслеживать инвентарь для бизнеса.Я достиг нескольких частей, с которыми у меня проблемы.Во-первых, проверяется, что дата находится между 2011 и 2012 годами, а во-вторых, числа месяца и дня находятся в диапазоне от 1 до 12 и от 1 до 31, соответственно.Когда я запускаю свою программу, в сообщении об ошибке всегда говорится, что год неправильный, даже если я поставил его правильно.Вот мой код для этой части:

   WORKING-STORAGE SECTION.
       05  POLI-DATE-REQUESTED-S.
           10 POLI-DATE-REQUESTED-S-1  PIC XX.
           10 POLI-DATE-REQUESTED-S-2  PIC XX.
           10 POLI-DATE-REQUESTED-S-3  PIC XX.
           10 POLI-DATE-REQUESTED-S-4  PIC XX.

   SCREEN SECTION.
   01  SCREEN-IMAGE.
       05  BLANK SCREEN
           BACKGROUND-COLOR 0.
       05  LINE 02  COLUMN 02          PIC X(8)
               FROM TIME-HHMMSSXX-COLONS
               FOREGROUND-COLOR 15.
       05  LINE 02  COLUMN 25
               VALUE 'Purchase Order Line Item Maintenance'
               FOREGROUND-COLOR 14.
       05  LINE 02  COLUMN 70          PIC X(8)
               FROM DATE-MMDDYY-SLASHES
               FOREGROUND-COLOR 15.
       05  LINE 04  COLUMN 02  VALUE 'FUNCTION CODE:'
               FOREGROUND-COLOR 10.
       05  LINE 04  COLUMN 18          PIC X(3)
               USING FUNCTION-CODE-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 04  COLUMN 23  VALUE '(ADD, CHG, DEL, INQ, END)'
               FOREGROUND-COLOR 11.
       05  LINE 07  COLUMN 23  VALUE 'NUMBER:'
               FOREGROUND-COLOR 10.
       05  LINE 07  COLUMN 50          PIC X(4)
               USING POLI-VEND-NUMBER-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 08  COLUMN 23  VALUE 'ORDER ID:'
               FOREGROUND-COLOR 10.
       05  LINE 08  COLUMN 50          PIC X(8)
               USING POLI-ORDER-ID-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 09  COLUMN 23  VALUE 'LINE ITEM:'
               FOREGROUND-COLOR 10.
       05  LINE 09  COLUMN 50          PIC X(4)
               USING POLI-LINE-ITEM-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 10  COLUMN 23  VALUE 'ITEM ID:'
               FOREGROUND-COLOR 10.
       05  LINE 10  COLUMN 50          PIC X(10)
               USING POLI-ITEM-ID-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 11  COLUMN 23  VALUE 'QUANTITY:'
               FOREGROUND-COLOR 10.
       05  LINE 11  COLUMN 50          PIC X(5)
               USING POLI-QUANTITY-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 12  COLUMN 23  VALUE 'DATE REQUESTED (YYYYMMDD):'
               FOREGROUND-COLOR 10.
       05  LINE 12  COLUMN 50          PIC X(8)
               USING POLI-DATE-REQUESTED-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 13  COLUMN 23  VALUE 'QUOTED COST:'
               FOREGROUND-COLOR 10.
       05  LINE 13  COLUMN 50          PIC X(7)
               USING POLI-QUOTED-COST-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 17  COLUMN 23  VALUE 'DATE ADDED:'
               FOREGROUND-COLOR 10.
       05  LINE 17  COLUMN 40  PIC X(10)
               USING POLI-DATE-ADDED-S
               FOREGROUND-COLOR 15.
       05  LINE 18  COLUMN 23  VALUE 'DATE-CHANGED:'
               FOREGROUND-COLOR 10.
       05  LINE 18  COLUMN 40  PIC X(10)
               USING POLI-DATE-CHANGED-S
               FOREGROUND-COLOR 15.
       05  LINE 23  COLUMN 23  PIC X(55)
               FROM ERROR-MESSAGE-S
               FOREGROUND-COLOR 12.

   PROCEDURE DIVISION.
   900-VALIDATE-THE-FIELDS.
       IF POLI-DATE-REQUESTED-S-1 IS NOT = 20
           MOVE 'Year must be 2011 OR 2012' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF
       IF POLI-DATE-REQUESTED-S-2 IS NOT = 11 OR 12
           MOVE 'Year Must Be 2011 Or 2012' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF
       IF POLI-DATE-REQUESTED-S-3 IS < 1 OR > 12
           MOVE 'Month Must Be 1 Through 12' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF
       IF POLI-DATE-REQUESTED-S-4 IS < 1 OR > 31
           MOVE 'Day Must Be 1 Through 31' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF.

Кроме того, я должен убедиться, что запись в поле с именем POLI-ITEM-ID уже существует в другом проиндексированном файле с именем ITEM-MASTER.Я не совсем уверен, как это сделать, но я предполагаю, что это предполагает временное открытие файла и его поиск.Если бы кто-нибудь мог показать мне, как это сделать, я был бы благодарен, поскольку эти две вещи, кажется, единственные вещи, которые удерживают меня сегодня.Заранее благодарю всех за помощь.

Редактировать: Входные данные записаны на изображении на экране, которое является частью программы.Таким образом, я знаю, что то, что я вставил правильно в момент входа.Если это помогает, я включил ВЫБОР ЭКРАНА в код, но я не думаю, что это имеет какое-либо отношение к тому, почему моя запись даты считается ошибкой (то есть я ввел «2011», и он говорит мне на экране «Год долженбыть 2011 или 2012 ").

Ответы [ 4 ]

4 голосов
/ 22 мая 2011
   05  POLI-DATE-REQUESTED-S.
       10 POLI-DATE-REQUESTED-S-1  PIC 9999.
          88 Year-Valid            value 2011 thru 2012.
       10 POLI-DATE-REQUESTED-S-2  PIC 99.
          88 Month-Valid           value 01 thru 12.
       10 POLI-DATE-REQUESTED-S-4  PIC 99.              
          88 Day-Valid             value 01 thru 31.

Попробуйте переопределить ваши поля следующим образом. Затем вы можете выполнить простой тест полей с помощью:

  IF not Year-Valid
       MOVE 'Year must be 2011 OR 2012' TO ERROR-MESSAGE-S
  Else
       IF not Month-Valid
          MOVE 'Month Must Be 1 Through 12' TO ERROR-MESSAGE-S
       Else
          IF not Day-Valid
              MOVE 'Day Must Be 1 Through 31' TO ERROR-MESSAGE-S
          END-IF
       END-IF
  END-IF

Чтобы разобраться с поиском, выполните прямое чтение файла ITEM-MASTER. Это будет включать что-то вроде этого:

   SELECT ITEM-MASTER ASSIGN TO "fname.txt"
      ORGANIZATION IS INDEXED
      ACCESS MODE IS DYNAMIC
      RECORD KEY IS ITEM-MASTER-KEY.

и затем сделайте прямое чтение:

  READ ITEM-MASTER
     KEY IS POLI-ITEM-ID
     INVALID KEY  DISPLAY "error or something"
  END-READ
2 голосов
/ 26 мая 2011

Будьте осторожны - принятое решение не гарантирует числовые значения.Следующая программа иллюстрирует эту точку:

   PROGRAM-ID. EXAMPLE.                       
   DATA DIVISION.                             
   WORKING-STORAGE SECTION.                   
   01  TXT-VALUE        PIC X(4).             
   01  NUM-VALUE        PIC 9(4).             
       88 WS-VALID-NUM  VALUE  2000 THRU 2999.
   PROCEDURE DIVISION.                        
       MOVE '21b1' TO TXT-VALUE               
       MOVE TXT-VALUE TO NUM-VALUE            
       DISPLAY 'NUM-VALUE: ' NUM-VALUE        
       IF WS-VALID-NUM                        
          DISPLAY 'passed the range test.'    
       END-IF                                 
       IF NUM-VALUE IS NUMERIC                
          DISPLAY 'passed numeric test.'      
       ELSE                                   
          DISPLAY 'failed numeric test.'      
       END-IF                                 

, что приводит к следующему выводу:

NUM-VALUE: 21b1       
passed the range test.
failed numeric test.  

Урок: Всегда проверяйте числовые поля с помощью теста IS NUMERIC, а затем теста диапазона.

Кроме того, если исходные данные не были предварительно отредактированы для проверки правильности, не рекомендуется читать внешние данные непосредственно в числовые типы данных.Считывание '1b' из входного файла непосредственно в элемент данных PIC 9(2) дает значение 12 (в среде, основанной на ebcdic).Теперь он пройдет тест IS NUMERIC, а также тесты диапазона, даже если фактические входные данные не были числовыми.Причины «автоматического» преобразования немного выходят за рамки этого обсуждения - скажем так, правила перемещения данных в COBOL намного сложнее, чем большинство людей понимают.

1 голос
/ 24 мая 2011

Пост Джо Цицельбергера - это рекомендуемый и «чистый» способ сделать это.

Я бы только отметил, что ошибка в вашем исходном коде заключалась в том, что мы смешивали XX и числовые типы.Вы должны были использовать символьные литералы в своих тестах:

IF POLI-DATE-REQUESTED-S-1 IS NOT = '20'

или, что лучше, определить значения данных в виде чисел:

 10 POLI-DATE-REQUESTED-S-1  PIC 99.
0 голосов
/ 20 февраля 2013
01  FILLER. 
05  POLI-DATE-REQUESTED-S. 
    10  POLI-DATE-REQUESTED-S-1  PIC XXXX. 
        88  YEAR-VALID            VALUE "2011" THRU "2012". 
    10  POLI-DATE-REQUESTED-S-2  PIC XX. 
        88  MONTH-VALID           VALUE "01" THRU "12". 
        88  MONTH-IS-FEB          VALUE "02". 
        88  MONTH-IS-30-DAYS      VALUE "04" "06" "09" "11".
    10  POLI-DATE-REQUESTED-S-4  PIC XX. 
        88  DAY-MAY-BE-VALID      VALUE "01" THRU "31". 
        88  VALID-FEB-DAYS        VALUE "01" THRU "28". 
        88  VALID-30-DAYS         VALUE "01" THRU "30". 

Затем «первое сокращение» со студентом, которому не нужно беспокоиться о фактическом количестве дней в месяце, имеет:

MOVE SPACE                   TO ERROR-MESSAGE-S
EVALUATE TRUE 
  WHEN NOT POLI-DATE-REQUESTED-S NUMERIC 
      MOVE 'DATE MUST ONLY BE NUMBERS' 
                             TO ERROR-MESSAGE-S
  WHEN NOT YEAR-VALID 
    MOVE 'YEAR MUST BE 2011 OR 2012' 
                             TO ERROR-MESSAGE-S
  WHEN NOT MONTH-VALID 
    MOVE 'MONTH MUST BE 01 THROUGH 12' 
                             TO ERROR-MESSAGE-S
  WHEN NOT DAY-MAY-BE-VALID 
    MOVE "DAY IS ZERO OR MORE THAN 31" 
                             TO ERROR-MESSAGE-S
END-EVALUATE 

, а затем исправлено позднее для фактического числадней.

MOVE SPACE                   TO ERROR-MESSAGE-S
EVALUATE TRUE 
  WHEN NOT POLI-DATE-REQUESTED-S NUMERIC 
      MOVE 'DATE MUST ONLY BE NUMBERS' 
                             TO ERROR-MESSAGE-S
  WHEN NOT YEAR-VALID 
    MOVE 'YEAR MUST BE 2011 OR 2012' 
                             TO ERROR-MESSAGE-S
  WHEN NOT MONTH-VALID 
    MOVE 'MONTH MUST BE 01 THROUGH 12' 
                             TO ERROR-MESSAGE-S
  WHEN NOT DAY-MAY-BE-VALID 
    MOVE "DAY IS ZERO OR MORE THAN 31" 
                             TO ERROR-MESSAGE-S
  WHEN ( MONTH-IS-FEB 
       AND NOT VALID-FEB-DAYS ) 
   MOVE 'TOO MANY DAYS FOR FEBRUARY' 
                             TO ERROR-MESSAGE-S
  WHEN ( MONTH-IS-30-DAYS 
       AND NOT VALID-30-DAYS ) 
   MOVE 'NO 31ST THIS MONTH' 
                             TO ERROR-MESSAGE-S
END-EVALUATE 
...