Кобол Вопрос - Юникод - PullRequest
4 голосов
/ 11 мая 2011

В настоящее время мы пытаемся преобразовать наш старый код COBOL из ANSII в UNICODE, однако мы столкнулись с проблемой, когда простое изменение полей PIC X на PIC N и установка NSYMBOL (NATIONAL) вызовут проблемы, когда структуры данных содержат REDEFINES или Оператор RENAME с элементарными элементами DATA с использованием полей PIC 9.

01 WS-RECORD PIC N(26).
01 WS-RECORD-1 REDEFINES WS-RECORD.
02 WS-NUM PIC 9(6).
02 WS-DATA PIC N(20).

MOVE N"123456ABCDEFGHIJKLM" TO WS-RECORD.

В приведенном выше примере перемещаемая строка будет в формате UTF-16, поэтому поле WS-NUM будет повреждено, поскольку оно будет содержать X «310032003300», что является недопустимым числом, WS-DATA будет содержать X «3400350036004100. .etc

Вопрос в том, как при использовании типов данных NATIONAL (UTF-16) можно обрабатывать числовые значения, чтобы получить правильные данные после их переопределения.

Я могу заставить это работать следующим образом, но получу недопустимые данные в другом WS-RECORD.

MOVE 123456 TO WS-NUM.
MOVE N"ABCDEFGHIJKLM" TO WS_DATA.

Вышеприведенное будет правильным, однако, если я изучу WS-RECORD, я увижу ??? ABCDEFGHIJKLM где ??? является X "313233343536" в шестнадцатеричном формате.

Наша проблема в том, что у нас есть несколько записей данных в зависимости от идентификатора типа записи, мы также используем переопределения во многих наших элементах ССЫЛКИ.

Кто-нибудь имел опыт перехода от устаревшего ASCII к UNICODE?

Ответы [ 4 ]

3 голосов
/ 17 мая 2011

Решение, предложенное MicroFocus, приведено ниже: -

Размеры WS-NCHAR-1 и WS-NCHAR-FIELD имеют разные размеры, потому что размер «pic 9 (6)» равен половине размера.«pic n (6)».

Таким образом, быстрое, но неопрятное решение состоит в том, чтобы поместить заполнитель, а затем повторно исправить поле с помощью «FUNCTION DISPLAY-OF», хотя это работает, клиент действительно долженСледует понимать, что размер «pic n» отличается от «pic 9», поэтому необходимо соблюдать осторожность при использовании переопределений и во время преобразования.

Измененный пример, который должен показать вам, что я имею в виду в коде ...

01 ONE-PICN           PIC N.
01 ONE-PIC9           PIC 9.

01 WS-NCHAR-FIELD     PIC N(20).   
01 WS-NCHAR-1 REDEFINES WS-NCHAR-FIELD.
   02  WS-NUM            PIC 9(6).
   02  FILLER            PIC X(6).
   02  WS-REST           PIC N(14).

DISPLAY "PIC N SIZE     : " length of ONE-PICN    
DISPLAY "PIC 9 SIZE     : " length of ONE-PIC9

DISPLAY "WS-NCHAR-FIELD : " length of WS-NCHAR-FIELD   
DISPLAY "WS-NCHAR-1     : " length of WS-NCHAR-1

DISPLAY "WS-REST        : " length of WS-REST    
DISPLAY "WS-NUM         : " length of WS-NUM

MOVE N"123456ABCDEFGHIJKLM"  TO WS-NCHAR-FIELD.

MOVE FUNCTION DISPLAY-OF(WS-NCHAR-FIELD(1:6),1252) TO WS-NUM


DISPLAY "WS-NUM     : " WS-NUM    DISPLAY "WS-REST    : " WS-REST

Вышеописанное не работает для S9 (n) COMP или S9 (n) V9 (n) ELEMENTRY ITEMS, с VISUAL COBOL. Я обнаружил, что могу просто переместить числовые значения непосредственно в PIC N (n) ELEMENTSи затем используйте FUNCTION NUMVAL (), чтобы получить фактическое числовое значение. Я пока не пробовал использовать поля со знаком / COMP и десятичные поля.

Спасибо всем за помощь.

3 голосов
/ 11 мая 2011
02 WS-NUM PIC 9(6) USAGE NATIONAL.

Должно работать (по крайней мере, на компиляторах IBM).

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

Вы можете использовать ФУНКЦИЮ ОТОБРАЖЕНИЯ и референсную модификацию и добавить заполнитель, чтобы гарантировать сбалансированный размер, добавьте 78, чтобы уменьшить использование магического числа!

Во всяком случае, как я уже сказал, это немного грязно, но работает ..

например:

  MOVE FUNCTION DISPLAY-OF(WS-RECORD-1(
                 1:LENGTH OF WS-RECORD(1:6)),1252)

С обновленной программой:

     78 NUM-SIZE  VALUE 6.

     01 WS-RECORD   PIC N(26).
     01 WS-RECORD-1 REDEFINES WS-RECORD.
       02 WS-NUM      PIC 9(NUM-SIZE).
       02 FILLER      PIC X(NUM-SIZE).
       02 WS-DATA     PIC N(20).


     MOVE N"123456ABCDEFGHIJKLM" TO WS-RECORD.

     DISPLAY "WS-NUM     : " WS-NUM
     DISPLAY "WS-DATA    : " WS-DATA

       MOVE FUNCTION DISPLAY-OF(WS-RECORD-1(
                 1:LENGTH OF WS-RECORD(1:NUM-SIZE)),1252)
              TO WS-NUM

     DISPLAY "WS-NUM     : " WS-NUM
     DISPLAY "WS-DATA    : " WS-DATA

(обновлено с лучшим решением)

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

Если я вас правильно понимаю, вы хотите преобразовать X'3000 'в X'30', X'3100 'в X'31 и т. Д. Через X'3900' в X'39 '.

Я просмотрел документацию по MicroFocus и не смог найти встроенную функцию, которая бы делала это.

Вы можете определить свою собственную процедуру для этого.

Рабочая память для процедуры будет выглядеть так:

01  WS-NUMERIC-CONVERSION.
    05  WS-LOOP-COUNT                     PIC S9(04) COMP.
    05  WS-NATIONAL-POSITION              PIC S9(04) COMP.
    05  WS-NUMBER-OF-CHARACTERS           PIC S9(04) COMP.
    05  WS-NATIONAL-INPUT.
        10  WS-NATIONAL-INPUT-BYTE        PIC X
                                          OCCURS 40 TIMES.
    05  WS-ASCII-OUTPUT.
        10  WS-ASCII-OUTPUT-BYTE          PIC X
                                          OCCURS 20 TIMES.

Процедура будет выглядеть следующим образом:

NATIONAL-TO-ASCII.
    PERFORM VARYING WS-LOOP-COUNT FROM 1 BY 1
        UNTIL WS-LOOP-COUNT > WS-NUMBER-OF-CHARACTERS

        COMPUTE WS-NATIONAL-POSITION = WS-LOOP-COUNT + WS-LOOP-COUNT - 1
        MOVE WS-NATIONAL-INPUT-BYTE(WS-NATIONAL-POSITION)
            TO WS-ASCII-OUTPUT-BYTE(WS-LOOP-COUNT)
    END-PERFORM.

Вызов процедуры будет выглядеть так:

05  WS-NATIONAL-NUMBER-X.
    10  WS-NATIONAL-NUMBER                 PIC N(06).
05  WS-ASCII-NUMBER-X.
    10  WS-ASCII-NUMBER                    PIC 9(06).


MOVE something TO WS-NATIONAL-NUMBER
MOVE WS-NATIONAL-NUMBER-X TO WS-NATIONAL-INPUT
MOVE +6 TO WS-NUMBER-OF-CHARACTERS
PERFORM NATIONAL-TO-ASCII
MOVE WS-ASCII-OUTPUT TO WS-ASCII-NUMBER-X
MOVE WS-ASCII-NUMBER TO something else

Определенная мною рабочая память процедуры обрабатывает число длиной до 20 символов. Если этого недостаточно, увеличьте поля WS-NATIONAL-INPUT и WS-ASCII-OUTPUT.

...