jueves, 7 de julio de 2011

Cobol: redefines

El redefines en cobol es muy útil cuando a un tipo de dato le queremos dar un determinado formato o cambiarlo a otro tipo de dato. También se usa para crearnos "arrays" de elementos.

Ejemplo 1: es muy corriente que un dato que sea un PIC X lo queramos pasar a un PIC 9 -> esto se consigue mediante la cláusula redefines tal y como se indica a continuación:

             01  WS-CADENA          PIC X(3).
             01  WS-CADENA-R REDEFINES WS-CADENA PIC 9(3).

Ejemplo 2: a veces queremos pasar un dato definido como PIC X a una estructura con varios campos -> esto se consigue mediante la cláusula redefines tal y como se indica a continuación:

             01  WS-FEC             PIC X(10).
             01  WS-FECHA  REDEFINES WS-FEC.
                  05  WS-FEC-A      PIC X(4).
                  05  WS-FILLER     PIC X(1) VALUE '-'.
                  05  WS-FEC-M      PIC X(2).
                  05  WS-FILLER     PIC X(1) VALUE '-'.
                  05  WS-FEC-D      PIC X(2).


Ejemplo 3: para crearnos tablas de elementos -> esto se consigue mediante la cláusula redefines tal y como se indica a continuación:

             01  TABLA-D.
                  05 FILLER     PIC X(9) VALUE "LUNES    ".
                  05 FILLER     PIC X(9) VALUE "MARTES   ".
                  05 FILLER     PIC X(9) VALUE "MIERCOLES".
                  05 FILLER     PIC X(9) VALUE "JUEVES   ".
                  05 FILLER     PIC X(9) VALUE "VIERNES  ".
                  05 FILLER     PIC X(9) VALUE "SABADO   ".
                  05 FILLER     PIC X(9) VALUE "DOMINIGO ".
             01  TABLA-DIAS  REDEFINES TABLA-D.
                  05  DIA        PIC X(9) OCCURS 7 TIMES.


Cuando queramos hacer referencia a alguno de los días de la semana tenemos que hacer lo siguiente: DIA(X) siendo X un valor entre 1 y 7. Hay que tener mucho cuidado de no poner cosas como por ejemplo DIA(0) o poner cualquier otro valor mayor a 7 pues estaríamos haciendo referencia a posiciones de la tabla que no existen y el programa daría error de ejecución. Has leído bien, error de ejecución. No da error de compilación porque el compilador es incapaz de detectar que se está accediendo a una posición errónea.

Hay que tener en cuenta dos cosas:
1) La tabla de este ejemplo es una tabla 'cerrada', es decir, no se va a aumentar con más elementos pero nos podemos enfrentar en alguna ocasión a tablas que tengan que ser modificadas para incluir nuevos elementos. ¿Cómo se actuaría en este caso? Imagínate que tenemos la siguiente tabla con sólo 3 elementos:

             01  TABLA-T.
                  05 FILLER     PIC X(10) VALUE "VISA ORO  ".
                  05 FILLER     PIC X(10) VALUE "VISA GOLD ".
                  05 FILLER     PIC X(10) VALUE "MASTERCARD".
             01  TABLA-TARJETAS  REDEFINES TABLA-T.
                  05 TARJETA   PIC X(10) OCCURS 3 TIMES.


Y queremos incluir una nueva tarjeta. El hecho de incluir una nueva tarjeta supone que se deben incluir los cambios que se han marcado en rojo:

             01  TABLA-T.
                  05 FILLER     PIC X(10) VALUE "VISA ORO  ".
                  05 FILLER     PIC X(10) VALUE "VISA GOLD ".
                  05 FILLER     PIC X(10) VALUE "MASTERCARD".
                  05 FILLER     PIC X(10) VALUE "PLATINUM  ".            
            01  TABLA-TARJETAS  REDEFINES TABLA-T.
                  05 TARJETA   PIC X(10) OCCURS 4 TIMES.


2) Hay que tener en cuenta el tema de índices. En este caso, para hacer referencia a un elemento de la tabla hay que hacer lo siguiente:

             TARJETA(X)

             siendo X -> un valor entre 1 y 3 (antes  de añadir el elemento)
                              un valor entre 1 y 4 (tras añadir el nuevo elemento)

Es decir, la tabla se ha incrementado en una posición por lo que el índice que se emplea para acceder a la tabla puede acceder a una (y sólo a UNA!!!) posición más. Mucho ojo con acceder a la posición 0 o a posiciones superiores al máximo número de elementos existentes en la tabla pues vamos a provocar un error de ejecución en cuanto se ejecutase el programa.

6 comentarios:

  1. Desde lo conceptual, el artículo está muy bueno.

    ResponderEliminar
  2. yo diria que este articulo esta excelente, y quien lo escribio tiene una larga trayectoria programando. Te doy las gracias humildemente.

    ResponderEliminar
  3. Desde Programación e Informática Fácil nos alegra que este post os parezca bueno y excelente. Para eso estamos, para explicar las cosas relacionadas con el mundo Host y pueda servir de utilidad a quien esté trabajando en dicho entorno o estudiando Cobol.

    ResponderEliminar
  4. Hola buenas noches, espero me puedan guiar lo que pasa que yo necesito pasar una variable pic 9(15)v99 comp-3. a una variable pic x(15), es igual de posible con el redefines?

    ResponderEliminar
  5. con variable de tipo caracter es mas facial, creo yo el problema es de numerica a x(??)

    ResponderEliminar
  6. Quizás de un numérico a un alfanumérico COMP no es tan sencillo, al menos usando un redefines.

    Échale un ojo al siguiente ejemplo:

    01 Tarifa.
    02 cpo-1 pic 999.
    02 cpo-2 pic x
    02 cpo-3 pic 99.
    01 valor1 pic 9(5).
    01 valor2 pic 999v99.
    move cpo-1 to valor1(01:03)
    move cpo-3 to valor1(04:02)
    move valor1 to valor2

    El "juego" que hace con los MOVEs para pasar de un alfanumérico a un numérico de 3 enteros y 2 decimales. Por aquí pueden ir los tiros pero haciéndolo a la inversa (del numérico al alfanumérico).

    ResponderEliminar