Mostrando entradas con la etiqueta redefines cobol. Mostrar todas las entradas
Mostrando entradas con la etiqueta redefines cobol. Mostrar todas las entradas

miércoles, 24 de julio de 2013

Cobol: conversiones entre tipos de datos (2)

Supongamos que tenemos un fichero de entrada en el que uno de los campos, por ejemplo REG-E-IMPORTE, es un PIC X(15) y representa un importe de 13 posiciones enteras y 2 posiciones decimales. ¿Qué tendríamos que hacer para convertir dicho campo a un PIC S9(13)V9(2) USAGE COMP-3?

Es muy sencillo y muy fácil. En un programa que he realizado recientemente (y que está probado) he declarado en working las siguientes variables:

          01 WS-IMP1                                 PIC X(15).             
          01 WS-IMP1-N REDEFINES WS-IMP1      PIC 9(15).             
          01 WS-IMP1-AUX                        PIC 9(15) VALUE ZEROES.
          01 WS-IMP-AMORT-PRINC       PIC S9(13)V9(02).      

En el programa, en donde corresponda, tendríamos que codificar lo siguiente:

          MOVE REG-E-IMPORTE               TO WS-IMP1                 

          MOVE WS-IMP1-N                        TO WS-IMP1-AUX             

          MOVE WS-IMP1-AUX(1:13)        TO WS-IMP-AMORT-PRINC(1:13)

          MOVE WS-IMP1-AUX(14:2)        TO WS-IMP-AMORT-PRINC(14:2)



Pues esto es todo lo que hay que hacer. A lo mejor te preguntarás: pero, ¿qué sucede si el campo REG-E-IMPORTE es un PIC X(13) y tenemos que convertirlo a un PIC S9(13)V9(2) USAGE COMP-3? Pues muy sencillo. Tanto la longitud de WS-IMP1 como la de WS-IMP1-N sería 13 mientras la definición de WS-IMP1-AUX y WS-IMPO-AMORT-PRINC sería exactamente a la indicada anteriormente. En cuanto al código, sería exactamente el mismo que el indicado anteriormente.

miércoles, 2 de enero de 2013

Cobol: conversiones entre tipos de datos (1)

En una entrada anterior, cuyo título era Cobol: redefines (pinchar aquí para ver dicha entrada),  vimos cómo utilizar la cláusula redefines. En uno de los ejemplos indicados se utilizaba esta cláusula para convertir un alfanumérico en un numérico. Ésto es muy útil cuando tenemos datos alfanuméricos del tipo '00005', '00045', '00345' y '02345' porque al redefinirlos en un dato numérico del tipo PIC 9(05) tenemos que obtendríamos los siguientes datos numéricos: 00005 (o lo que es lo mismo 5), '00045' (o lo que es lo mismo 45), '00345' (o lo que es lo mismo 345) y '02345' (o lo que es lo mismo 2345).

Pero, ¿qué sucede si nos llega un alfanumérico como '1     '? Como se puede observar en ese alfanumérico, lo que nos estaría llegando es un 1 y cuatro espacios en blanco detrás de ese 1. Si redefinimos dicho alfanumérico en un numérico como el indicado anteriormente, PIC 9(05), tendríamos el valor 1 con valores inadecuados en las cuatro posiciones siguientes y esto podría resultar indeseable al realizar un tratamiento de dicho dato numérico. Pues bien, en esta entrada vamos a ver cómo solventar este caso.

Veamos el siguiente ejemplo: queremos transformar la cadena '10        ' en una variable numérica 00010 (o 10) de tipo PIC S9(5). Para ello haremos el tratamiento que se explica a continuación.

Tenemos las siguientes variables:

  W100-NUM-DIAS -> PIC X(10)
  variable alfanumérica que podrá venir informado como '10        ' o '360       '

  W100-NUM-DIAS-N -> PIC S9(5)
  variable numérica en la que guardaremos el valor anterior transformado

  W400-INDICE   -> PIC 9(02)
  W400-CONT-NUM -> PIC 9(01)
  W400-IND-NUM  -> PIC 9(01)
  W400-IND-MAX  -> PIC 9(01)

Y la siguiente constante:

  W300-M-1 PIC S9(1) VALUE -1.

El código a ejecutar para realizar dicha transformación sería el siguiente:

     MOVE 1                         TO W400-CONT-NUM

     PERFORM UNTIL W100-NUM-DIAS(W400-CONT-NUM:1) IS NOT NUMERIC
                          OR W400-CONT-NUM > 5
           ADD 1                       TO W400-CONT-NUM
     END-PERFORM

     MOVE W400-CONT-NUM             TO W400-IND-NUM
     ADD W300-M-1                         TO W400-IND-NUM
     MOVE 5                                   TO W400-IND-MAX
     MOVE ZEROES                          TO W100-NUM-DIAS-N

     PERFORM UNTIL W400-IND-NUM = ZEROES OR W400-IND-MAX = ZEROES
          MOVE W100-NUM-DIAS(W400-IND-NUM:1) TO
                   W100-NUM-DIAS-N(W400-IND-MAX:1)  
          ADD W300-M-1                TO W400-IND-NUM
          ADD W300-M-1                TO W400-IND-MAX
     END-PERFORM.

Este fragmento podría incluirse en un párrafo cuyo nombre podría ser, por ejemplo, TRANSFORMAR-ALFANUM-NUM.


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.