Menu

COBOL - Unstring Statement


A instrução UNSTRING faz com que os dados contíguos em um campo de envio sejam separados e colocados em vários campos de recebimento.

A instrução UNSTRING é usada para analisar itens individuais de uma única string. Qualquer número de itens pode ser analisado. Strings inteiras ou parciais podem ser analisadas. Todos os itens fornecidos como operandos INTO serão analisados.

Sintaxe:

UNSTRING identifier-1 DELIMITED BY ALL identifier-2 or literal-1
                             [OR] [ALL identifier-3 or literal-2]
    INTO  identifier-4
    [DELIMITER IN identifier-5]
    [COUNT IN identifier-6]
    [WITH POINTER identifier-7]
    [TALLYING IN identifier-8]
    [ON OVERFLOW imperative-statement-1]
    [NOT ON OVERFLOW imperative-statement-2]
END-UNSTRING

identificador-1
Representa o campo de envio. Os dados são transferidos deste campo para os campos de recebimento de dados (identificador-4).

identificador-1 deve fazer referência a um item de dados de categoria alfabética, alfanumérica, editada alfanumérica, DBCS, nacional ou editada nacionalmente.

identificador-2, literal-1, identificador-3, literal-2
Especifica um ou mais delimitadores.

identificador-2 e identificador-3 devem fazer referência a itens de dados da categoria alfabética, alfanumérica, editada alfanumérica, DBCS, nacional ou editada nacionalmente.

literal-1 ou literal-2 deve ser da categoria alfanumérica, DBCS ou nacional e não deve ser uma constante figurativa que comece com a palavra ALL.

identificador-4
Especifica um ou mais campos de recebimento.

identificador-4 deve fazer referência a um item de dados de categoria alfabética, alfanumérica, numérica, DBCS ou nacional. Se o item de dados referenciado for de categoria numérica, sua cadeia de caracteres de imagem não deve conter o símbolo de imagem P, e seu uso deve ser DISPLAY ou NATIONAL.

identificador-5
Especifica um campo para receber o delimitador associado ao identificador-4.

O Identificador-5 deve fazer referência a um item de dados de categoria alfabética, alfanumérica, DBCS ou nacional.

identificador-6
Especifica um campo para conter a contagem de caracteres que são transferidos para o identificador-4.

identificador-6 deve ser um item de dados inteiro definido sem o símbolo P em sua cadeia de caracteres PICTURE.

identificador-7
Especifica um campo para manter uma posição de caractere relativa durante o processamento UNSTRING.

identificador-7 deve ser um item de dados inteiro definido sem o símbolo P na string PICTURE.

identificador-7 deve ser descrito como um item de dados de tamanho suficiente para conter um valor igual a 1 mais o número de posições de caracteres no item de dados referenciado pelo identificador-1.

identificador-8
Especifica um campo que é incrementado pelo número de campos delimitados processados.

identificador-8 deve ser um item de dados inteiro definido sem o símbolo P em sua cadeia de caracteres PICTURE.

DELIMITADO POR
Essa frase especifica delimitadores nos dados que controlam a transferência de dados.

Cada identificador-2, identificador-3, literal-1 ou literal-2 representa um delimitador.

Se a frase DELIMITED BY não for especificada, as frases DELIMITER IN e COUNT IN não devem ser especificadas.

TUDO
Várias ocorrências contíguas de qualquer delimitador são tratadas como se houvesse apenas uma ocorrência; esta ocorrência é movida para o campo de recebimento do delimitador (identificador-5), se especificado.

Os caracteres delimitadores no campo de envio são tratados como um item elementar do mesmo uso e categoria do identificador-1 e são movidos para o campo de recebimento do delimitador atual de acordo com as regras da instrução MOVE.

Quando DELIMITED BY ALL não for especificado e forem encontradas duas ou mais ocorrências contíguas de qualquer delimitador, o campo de recebimento de dados atual (identificador-4) é preenchido com espaços ou zeros, conforme a descrição do campo de recebimento de dados.

Delimitador com dois ou mais caracteres
Um delimitador que contém dois ou mais caracteres é reconhecido como delimitador somente se os caracteres delimitadores forem ambos os seguintes:
  • Contíguo
  • Na sequência especificada no campo de envio
Dois ou mais delimitadores Quando dois ou mais delimitadores são especificados, existe uma condição OR e cada ocorrência não sobreposta de qualquer um dos delimitadores é reconhecida no campo de envio na sequência especificada.


Por exemplo:

DELIMITED BY "AB" or "BC"

Uma ocorrência de AB ou BC no campo de envio é considerada um delimitador. Uma ocorrência de ABC é considerada uma ocorrência de AB.

EM
Esta frase especifica os campos onde os dados devem ser movidos.

identificador-4 representa os campos de recebimento de dados.

DELIMITADOR EM
Esta frase especifica os campos onde os delimitadores devem ser movidos.

identificador-5 representa os campos de recebimento do delimitador.

A frase DELIMITER IN não deve ser especificada se a frase DELIMITED BY não for especificada.

EU CONTO COM
Esta frase especifica o campo onde é mantida a contagem das posições dos caracteres examinados.

identificador-6 é o campo de contagem de dados para cada transferência de dados. Cada campo contém a contagem das posições dos caracteres examinados no campo de envio, encerrados pelos delimitadores ou no final do campo de envio, para a movimentação para este campo de recebimento. Os delimitadores não estão incluídos nesta contagem.

A frase COUNT IN não deve ser especificada se a frase DELIMITED BY não for especificada.

PONTEIRO
Quando a frase POINTER é especificada, o valor do campo de ponteiro, identificador-7, se comporta como se fosse aumentado em 1 para cada posição de caractere examinado no campo de envio.

Quando a execução da instrução UNSTRING é concluída, o campo ponteiro contém um valor igual ao seu valor inicial mais o número de posições de caracteres examinadas no campo de envio.

Quando esta frase é especificada, o usuário deve inicializar o campo de ponteiro antes de iniciar a execução da instrução UNSTRING.

CONTAR EM
Quando a frase TALLYING é especificada, o campo de contagem de área, identificador-8, contém (no final da execução da instrução UNSTRING) um valor igual ao valor inicial mais o número de áreas receptoras de dados atuadas.

Quando esta frase é especificada, o usuário deve inicializar o campo de contagem de área antes de iniciar a execução da instrução UNSTRING.

EM TRANSBORDO
Uma condição de estouro existe quando:
  • O valor do ponteiro (explícito ou implícito) é menor que 1.

  • O valor do ponteiro (explícito ou implícito) excede um valor igual ao comprimento do campo de envio.

  • Todos os campos de recebimento de dados foram acionados e o campo de envio ainda contém posições de caracteres não examinadas.

Quando ocorre uma condição de estouro
Uma condição de estouro resulta nas seguintes ações:
  • Não são transferidos mais dados.

  • A operação UNSTRING é encerrada.

  • A frase NOT ON OVERFLOW, se especificada, é ignorada.

  • O controle é transferido para o final da instrução UNSTRING ou, se a frase ON OVERFLOW for especificada, para a instrução imperativa-1.

declaração-imperativa-1
Declaração ou declarações para lidar com uma condição de estouro.

Se o controle for transferido para o comando imperativo-1, a execução continua de acordo com as regras para cada comando especificado no comando imperativo-1.

Se uma ramificação de procedimento ou instrução condicional que causa a transferência explícita de controle for executada, o controle será transferido de acordo com as regras dessa instrução.

Caso contrário, após a conclusão da execução da instrução imperativa-1, o controle é transferido para o final da instrução UNSTRING.

Quando uma condição de estouro não ocorre
Quando, durante a execução de uma instrução UNSTRING, as condições que causariam uma condição de estouro não forem encontradas, então:
  • A transferência de dados está concluída.

  • A frase ON OVERFLOW, se especificada, é ignorada.

  • O controle é transferido para o final da instrução UNSTRING ou, se a frase NOT ON OVERFLOW for especificada, para a instrução imperativa-2.
declaração-imperativa-2
Instrução ou instruções para lidar com uma condição de estouro que não ocorre.

Se o controle for transferido para o comando imperativo-2, a execução continua de acordo com as regras para cada comando especificado no comando imperativo-2. Se uma ramificação de procedimento ou instrução condicional que causa a transferência explícita de controle for executada, o controle será transferido de acordo com as regras dessa instrução. Caso contrário, após a conclusão da execução da instrução imperativa-2, o controle é transferido para o final da instrução UNSTRING.

END-UNSTRING
Esse terminador de escopo explícito serve para delimitar o escopo da instrução UNSTRING. END-UNSTRING permite que uma instrução condicional UNSTRING seja aninhada em outra instrução condicional. END-UNSTRING também pode ser usado com uma instrução UNSTRING imperativa.
Pontas:
  • Os operandos devem ser não numéricos.

  • Os operandos POINTER e COUNT, se houver, devem ser inteiros positivos que são suas figuras devem conter apenas 9's.

  • INICIALIZE os itens recebidos antes do UNSTRING, para remover caracteres indesejados que possam ter sobrado de uma operação anterior.

  • Use a cláusula OVERFLOW para detectar estouro de campo no(s) campo(s) receptor(es).

Exemplo 1:

UNSTRING ID-SEND DELIMITED BY DEL-ID OR ALL "*"
    INTO ID-R1 DELIMITED IN ID-D1 COUNT IN ID-C1
         ID-R2 DELIMITED IN ID-D2
         ID-R3 DELIMITED IN ID-D3 COUNT IN ID-C3
         ID-R4 COUNT IN ID-C1
    WITH POINTER ID-P
    TALLYING IN ID-T
    ON OVERFLOW GO TO OFLOW-EXIT

Nota: Todos os campos de recebimento de dados são definidos como alfanuméricos

Vamos ver a execução da instrução UNSTRING,

image missing

Onde,

ID-P(pointer) = 21
ID-T(tallying field) = 05

Nota: após a execução - ambos inicializados em 01 antes da execução.

Ordem de Execução abaixo:
  1. 3 caracteres são colocados em ID-R1.

  2. Como ALL * é especificado, todos os asteriscos consecutivos são processados, mas um asterisco é colocado em ID-01.

  3. 5 caracteres são colocados em ID-R2.

  4. A ? é colocado em ID-R2. O campo de recebimento atual agora é ID-R3.

  5. A ? é colocado i ID-D3; ID-R3 é preenchido com espaços. nenhum caractere é transferido, então 0 é colocado n ID-C3.

  6. Nenhum delimitador é encontrado antes de 5 caracteres preencherem o ID-R4; 8 é colocado no ID-C4, representando o número de caracteres examinados desde o último delimitador.

  7. ID-P é atualizado para 21, o comprimento total do campo de envio +1. ID-T é atualizado para 5, o número de campos atuados em +1, uma vez que não há caracteres não examinados no ID-send, o OVERFLOW EXIT não é obtido.

Exemplo 2:

........
FILE SECTION.
*  Record to be acted on by the UNSTRING statement:
 01  INV-RCD.
     05  CONTROL-CHARS               PIC XX.
     05  ITEM-INDENT                 PIC X(20).
     05  FILLER                      PIC X.
     05  INV-CODE                    PIC X(10).
     05  FILLER                      PIC X.
     05  NO-UNITS                    PIC 9(6).
     05  FILLER                      PIC X.
     05  PRICE-PER-M                 PIC 99999.
     05  FILLER                      PIC X.
     05  RTL-AMT                     PIC 9(6).99.
*
*  UNSTRING receiving field for printed output:
 01  DISPLAY-REC.
     05  INV-NO                      PIC X(6).
     05  FILLER                      PIC X VALUE SPACE.
     05  ITEM-NAME                   PIC X(20).
     05  FILLER                      PIC X VALUE SPACE.
     05  DISPLAY-DOLS                PIC 9(6).
*
*  UNSTRING receiving field for further processing:
 01  WORK-REC.
     05  M-UNITS                     PIC 9(6).
     05  FIELD-A                     PIC 9(6).
     05  WK-PRICE REDEFINES FIELD-A  PIC 9999V99.
     05  INV-CLASS                   PIC X(3).
*
*  UNSTRING statement control fields:
 77  DBY-1                           PIC X.
 77  CTR-1                           PIC S9(3).
 77  CTR-2                           PIC S9(3).
 77  CTR-3                           PIC S9(3).
 77  CTR-4                           PIC S9(3).
 77  DLTR-1                          PIC X.
 77  DLTR-2                          PIC X.
 77  CHAR-CT                         PIC S9(3).
 77  FLDS-FILLED                     PIC S9(3).
-----

No PROCEDURE DIVISION, essas configurações ocorrem antes da instrução UNSTRING

Um ponto (.) é colocado em DBY-1 para uso como delimitador.

CHAR-CT (o campo POINTER) é definido como 3.

O valor zero (0) é colocado em FLDS-FILLED (o campo TALLYING).

Os dados são lidos no registro INV-RCD, cujo formato é o mostrado abaixo.

column 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
DATA   ZYFOUR-PENNY-NAILS     707890/BBA 475120 00122 000379.50

Declaração UNSTRING:

* Move subfields of INV-RCD to the subfields of DISPLAY-REC
* and WORK-REC:
     UNSTRING INV-RCD
       DELIMITED BY ALL SPACES  OR "/"  OR DBY-1
       INTO ITEM-NAME    COUNT IN CTR-1
            INV-NO       DELIMITER IN DLTR-1  COUNT IN CTR-2
            INV-CLASS
            M-UNITS      COUNT IN CTR-3
            FIELD-A
            DISPLAY-DOLS DELIMITER IN DLTR-2  COUNT IN CTR-4
       WITH POINTER CHAR-CT
       TALLYING IN  FLDS-FILLED
       ON OVERFLOW  GO TO UNSTRING-COMPLETE.

Como o campo POINTER CHAR-CT tem valor 3 antes que a instrução UNSTRING seja executada, as duas posições de caracteres do campo CONTROL-CHARS em INV-RCD são ignoradas.

Após a execução da instrução UNSTRING, os campos contêm os valores mostrados abaixo.

FieldValue
DISPLAY-REC
707890 FOUR-PENNY-NAILS            000379
WORK-REC475120000122BBA
CHAR-CT (the POINTER field)55
FLDS-FILLED (the TALLYING field)6

Explicação da execução:
  1. As posições 3 a 18 (FOUR-PENNY-NAILS) de INV-RCD são colocadas em ITEM-NAME, justificadas à esquerda na área, e as quatro posições de caracteres não utilizadas são preenchidas com espaços. O valor 16 é colocado em CTR-1.

  2. Como TODOS OS ESPAÇOS são codificados como um delimitador, os cinco caracteres de espaço contíguos nas posições 19 a 23 são considerados uma ocorrência do delimitador.

  3. As posições 24 a 29 (707890) são colocadas em INV-NO. A barra do caractere delimitador (/) é colocada em DLTR-1 e o valor 6 é colocado em CTR-2.

  4. As posições 31 a 33 (BBA) são colocadas em INV-CLASS. O delimitador é SPACE, mas como nenhum campo foi definido como área de recepção para delimitadores, o espaço na posição 34 é ignorado.

  5. As posições 35 a 40 (475120) são colocadas em M-UNITS. O valor 6 é colocado em CTR-3. O delimitador é SPACE, mas como nenhum campo foi definido como área de recepção para delimitadores, o espaço na posição 41 é ignorado.

  6. As posições 42 a 46 (00122) são colocadas no CAMPO-A e justificadas à direita na área. A posição do dígito de ordem superior é preenchida com um zero (0). O delimitador é SPACE, mas como nenhum campo foi definido como área de recepção para delimitadores, o espaço na posição 47 é ignorado.

  7. As posições 48 a 53 (000379) são colocadas em DISPLAY-DOLS. O delimitador de ponto (.) em DBY-1 é colocado em DLTR-2 e o valor 6 é colocado em CTR-4.

  8. Como todos os campos de recebimento foram acionados e dois caracteres em INV-RCD não foram examinados, a instrução ON OVERFLOW é executada. A execução da instrução UNSTRING foi concluída.