Вот несколько советов ...
Используйте иерархическую структуру записей для просмотра данных различными способами.Например:
01 ITEM-REC.
05 ITEM-CODE.
10 ITEM-NUM-CODE PIC 9(3).
10 ITEM-CHAR-CODE PIC A(3).
88 ITEM-TYPE-A VALUE 'AAA' THRU 'AZZ'.
88 ITEM-TYPE-B VALUE 'BAA' THRU 'BZZ'.
05 QUANTITY PIC 9(4).
ITEM-CODE
- это поле группы из 6 символов, первая часть которого числовая (ITEM-NUM-CODE), а последняя часть буквенная (ITEM-CHAR-CODE).Вы можете ссылаться на любую из этих трех переменных в вашей программе.Когда вы ссылаетесь на ITEM-CODE
или любой другой элемент группы, COBOL обрабатывает переменную так, как если бы она была объявлена как PIC X
.Это означает, что вы можете MOVE
почти все, что угодно, не вызывая ошибки.Например:
MOVE 'ABCdef' TO ITEM-CODE
или
MOVE 'ABCdef0005' TO ITEM-REC
Ни один из них не вызовет ошибку, даже если элементарный элемент данных ITEM-NUM-CODE
определенно не является числом.Чтобы проверить достоверность ваших данных после перемещения группы, вы должны проверять каждый элементарный элемент данных отдельно (если вы точно не знаете, что ошибки типов данных не могли возникнуть).Есть множество способов сделать это.Например, если элемент данных должен быть числовым, будет работать следующее:
IF ITEM-NUM-CODE IS NUMERIC
CONTINUE
ELSE
DISPLAY 'ITEM-NUM-CODE IS NOT NUMERIC'
PERFORM BIG-BAD-ERROR
END-IF
COBOL предоставляет тесты различных классов, которые можно применять к элементу данных.Например: обычно используются NUMERIC, ALPHABETIC и ALPHANUMERIC.
Другой распространенный способ проверки диапазонов значений - это определение различных 88 уровней, но соблюдайте осторожность.В приведенном выше примере ITEM-TYPE-A
- это уровень 88, который определяет диапазон данных от «AAA» до «AZZ» на основе последовательности упорядочения, действующей в настоящее время.Чтобы убедиться, что ITEM-CHAR-CODE
содержит только буквенные символы, а первая буква - это «A» или «B», вы можете сделать что-то вроде:
IF ITEM-CHAR-CODE ALPHABETIC
DISPLAY 'ITEM-CHAR-CODE is alphabetic.'
EVALUATE TRUE
WHEN ITEM-TYPE-A
DISPLAY 'ITEM-CHAR-CODE is in range AAA through AZZ'
WHEN ITEM-TYPE-B
DISPLAY 'ITEM-CHAR-CODE is in range BAA through BZZ'
WHEN OTHER
DISPLAY 'ITEM-CHAR-CODE is in some other range'
END-EVALUATE
ELSE
DISPLAY 'ITEM-CHAR-CODE is not alphabetic'
END-IF
Обратите внимание на отдельный тест для ALPHABETIC
выше.Зачем это делать, когда тесты 88 уровня могли бы сделать эту работу?На самом деле 88-х не достаточно, потому что они охватывают весь диапазон от AAA
до AZZ
в зависимости от последовательности сортировки, действующей в настоящее время.В среде на основе EBCDIC (очень большое количество магазинов COBOL использует EBCDIC) это фиксирует значения, такие как A}\
.символы закрывающей скобки и обратной косой черты не являются альфа-символами, но попадают в середину диапазона от «A» до «Z» (что такое * * @! это все?).Также обратите внимание, что такое значение, как «aaa», не удовлетворяет условию ITEM-TYPE-A
, поскольку строчные буквы выходят за пределы указанного диапазона.Возможно, пришло время проверить таблицу символов EBCDIC.
Наконец, вы можете подсчитать количество вхождений символа или строки символов в переменную с глаголом INSPECT
следующим образом:
INSPECT ITEM-CODE TALLING DASH-COUNT FOR ALL '-'
DASH-COUNT
должен быть числовым элементом и содержать количество символов тире в ITEM-CODE
.Глагол INSPECT
не очень полезен, если вы хотите посчитать количество цифр.Для этого вам понадобится одно утверждение для каждой цифры.
Возможно, будет проще просто написать код, например:
PERFORM VARYING I FROM 1 BY 1
UNTIL I > LENGTH OF ITEM-CODE
EVALUATE ITEM-CODE(I:1)
WHEN '-'
COMPUTE DASH-COUNT = DASH-COUNT + 1
WHEN '0' THRU '9'
COMPUTE DIGIT-COUNT = DIGIT-COUNT + 1
WHEN OTHER
COMPUTE OTHER-COUNT = OTHER-COUNT + 1
END-EVALUATE
END-PERFORM
Теперь спросите себя, почему мне удобно использовать ноль через 9проверка дальности?Подсказка: посмотрите на последовательность сортировки.
Надеюсь, это поможет.