Imprimir Vectores en REXX

Todo lo relacionado con REXX en este ambiente.
Responder
friendspark
Usuario
Usuario
Mensajes: 15
Registrado: 17 Ene 2012, 12:47
País: Inglaterra
Ciudad: Milton Keynes
Ocupación: Implementador

Imprimir Vectores en REXX

Mensaje por friendspark » 30 Sep 2014, 07:51

Hola a todos,

Estoy tratando de hacer un REXX que lea un fichero linea a linea y por cada una, que identifique un delimitador y le otorge un espacio estandar de 50 caracteres a cada campo para asi formatear un fichero que tiene el mismo numero de campos en cada fila pero que cada campo es de longitud variable(ninguno de ellos sobrepasa los 50 caracterres).

Ejemplo:

"123","hola","casablanca", "Romero","",...
"2","adios adios","rabat", "Felipe","1562584",...


El resultado que busco es el siguiente pero dando un tamanyo maximo de 20:

"123" ,"hola" ,"casablanca" , "Romero" ,"" ,...
"2" ,"adios adios" ,"rabat" , "Felipe" ,"1562584" ,...



Mi idea inicial era recorrer la fila y cuando detectase el delimitador, que grabase el nuevo campo en el fichero o en el buffer para ir conformando la nueva fila formateada....pero no se como poder ir grabando en el fichero de sallida sin saltar de linea...

Mi segunda idea era generar un vector con x componentes y al final volcar todos los campos en la fila...pero solo me imprime el primero.

tambien me gustaria saber como puedo usar mas filas cuando uso la sentencia PUSH dado que cuando intento hacer...


PUSH ARRAY.7 ARRAY.10 ARRAY.9 ARRAY.11 ARRAY.12 ARRAY.13 ARRAY.14 ARRAY.15

y quiero seguir en la siguiente linea tal como muestro a continuacion...esta segunda linea me da error.

PUSH ARRAY.7 ARRAY.10 ARRAY.9 ARRAY.11 ARRAY.12 ARRAY.13 ARRAY.14 ARRAY.15
ARRAY.17 ARRAY.20 ARRAY.9 ARRAY.31 ARRAY.42 ARRAY.53 ARRAY.64 ARRAY.75



Incluyo el codigo que hice:

TRACE R

MSGSTATUS = MSG(ON)

SAY 'START THE PROCESS'

"EXECIO 1 DISKR INFILA (STEM INFA."
IF RC > 0 THEN DO
SAY 'ERROR OPENING INFILA.'
EXIT 0
END

FIN = '".'
COMMA = ','

DO WHILE RC = 0
NUM = 1
CURRENT_POS= SUBSTR(INFA.1,NUM,1)
NEXT_TWO_POS= SUBSTR(INFA.1,NUM,2)
INI_FIELD = 1
TOT_FIELD = 0
FIELDS = 1

DO WHILE NEXT_TWO_POS <> FIN

IF CURRENT_POS = COMMA THEN DO
NEW_FIELD= SUBSTR(INFA.1,INI_FIELD,TOT_FIELD)
NEW_FIELD_50 = LEFT(NEW_FIELD,55)
ARRAY.FIELDS = NEW_FIELD_50
INI_FIELD = NUM + 1
TOT_FIELD = 0
FIELDS = FIELDS+1
END
ELSE DO
TOT_FIELD = TOT_FIELD + 1
END

NUM = NUM + 1
CURRENT_POS= SUBSTR(INFA.1,NUM,1)
NEXT_TWO_POS= SUBSTR(INFA.1,NUM,2)

END /* DE 2ND DO */

RC = 0
"DROPBUF"
PUSH ARRAY.7 ARRAY.10 ARRAY.9 ARRAY.11
"EXECIO * DISKW OTFIL"

"EXECIO 1 DISKR INFILA (STEM INFA."
END /* DE 1ST DO */

Avatar de Usuario
Vicente
Colaborador avanzado
Colaborador avanzado
Mensajes: 543
Registrado: 21 Jul 2011, 04:52
País: España
Ciudad: Malaga
Ocupación: Técnico en Sistemas

Re: Imprimir Vectores en REXX

Mensaje por Vicente » 30 Sep 2014, 09:43

Hola friendspark,
Si me lo permites aquí te dejo algunos consejos.

El primero y más importante, que supongo habrás hecho, es darle una lectura completa a la parte del manual de TSO:
REXX reference, en los capítulos donde explic las funciones y el capítulo "TSO/REXX Commmands".

Si el fichero de entrada no es muy grande, poner un * en tu EXECIO en lugar de un 1, hará que se lea todo el fichero de una vez y lo guarde en tu vector. La variable INFA.0 contendrá el número de registros leidos.

Puede saber en que lugar se encunetra una ocurrencia de uno o más caracteres en un string utilizando la función POS( búscala en el manual). Esto simplificará mucho tu código.

Tambien la instrucción PARSE VAR te permite cortar, con una sola instrucción, una cadena en muchos trozos; por ejemplo

Código: Seleccionar todo

PARSE VAR INFA.1 campo1 ',' campo2 ',' campo3 ',' .....',' resto
PARSE VAR INFA.1 '"' campo1 '","' campo2 '","' campo3 .... '",' resto
Pero esto será viable dependiendo de si conoces bien como te vienen los datos y cuando terminan.

En cuanto a tu problema con PUSH, es que la segunda linea no contiene una instrucción REXX válida. Tienes dos opciones:
1) Continuar la linea PUSH en otra, haciendola terinar en coma (Ver el capítulo de "Conceptos generales"). pero no te aconsejo esto.
2) Escribir mas de una sentencia PUSH, teniendo en cuenta que es una cola LIFO (la última que escribas será la primera que se grabe) y utilizar la sencia EXECIO n DISkW donde n es el número de líneas PUSH.

Creo que es mejor que lo deje aquí y cuando tengas escrito un código más simple usando EXECIO * DISKR o POS( o PARSE, etc... volvemos a comentarlo.

Siento no tener tiempo ahora de dedicarme a tu otro Post. Luego lo veré.

Pd.: Si utilizas el botón "Code" puedes incluir tu código entre

Código: Seleccionar todo

 y 
, esto lo hará más fácil de leer, como he hecho yo con el ejemplo de PARSE VAR

Un saludo
Varios días probando, equivocandote y volviendo a probar
pueden ahorrarte quince minutos de lectura de un manual.

elpantanero
Colaborador
Colaborador
Mensajes: 78
Registrado: 25 Oct 2007, 06:31
País: España
Ciudad: Madrid
Ocupación: Técnico en Sistemas

Re: Imprimir Vectores en REXX

Mensaje por elpantanero » 06 Oct 2014, 05:18

eso también lo puedes hacer con un sort, con ICEMAN
algunos ejemplos:
//* COPIA LA ENTRADA(INDD) A LA SALIDA O SALIDAS(MAX10)
//*
//* LINEAS DE CONTINUACION CON - NO IMPORTA ELORDEN
//* COMENTARIOS CON * EN LA COL 1
//* SYNTAX COPY FROM (INDD) TO (OUTDD,...) USING(XXXX) VSAMTYPE(X)
//* LOCALE PASA DE LOS DEFECTOS DE LA INSTALACION
//* LOCALE(NAME)
//*
//* EJEMPLOS:
//* COPYOMIT:COPIA SIN ALGUNOS REGISTROS
//* COPYOUTF: COPIA SIN REGISTROS Y FORMATENADOLA SALIDA
//* COPYVARF: COPIA A VARIOS DE SALIDA
//*
//ICETOOL1 EXEC PGM=ICETOOL,REGION=0M
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//OUTDD1 DD DISP=SHR,DSN=
//TOOLIN DD *
//ABCDCNTL DD *
./ ADD NAME=COPYOMIT
//* COPYOMIT:COPIA SIN ALGUNOS REGISTROS
//*
//*
//*
//ICETOOL1 EXEC PGM=ICETOOL,REGION=0M 0317002
//TOOLMSG DD SYSOUT=* 0318002
//DFSMSG DD SYSOUT=* 0318002
//INDD DD DISP=SHR,DSN=UTE9901.MERGE.A
//OUTDD1 DD DISP=SHR,DSN=UTE9901.MERGE.SAL 0318002
//TOOLIN DD * 0319002
COPY FROM(INDD) TO(OUTDD1) USING(ABCD)
//ABCDCNTL DD *
OMIT COND=(20,2,CH,EQ,C'Al')
/*
./ ADD NAME=COPYOUTF
//* COPIA SIN ALGUNOS REGISTROS
//* y formateando la salida
//* COLOCA PRIMERO * Y LUEGO SOLO DELA 1 A LA 10
//* CON OUTFILE NO ES NECESARIO EL TO
//*
//ICETOOL1 EXEC PGM=ICETOOL,REGION=0M 0317002
//TOOLMSG DD SYSOUT=* 0318002
//DFSMSG DD SYSOUT=* 0318002
//INDD DD DISP=SHR,DSN=A
//OUTDD1 DD DSN=.MERGE.SAL1, 0318002
// UNIT=SYSDA,DISP=(NEW,CATLG),SPACE=(TRK,(1,1)), 00020000
// DCB=(DSORG=PS,RECFM=FB,BLKSIZE=0,LRECL=16) 00030000
//TOOLIN DD * 0319002
COPY FROM(INDD) USING(ABCD)
//ABCDCNTL DD *
OMIT COND=(20,2,CH,EQ,C'Al')
OUTFIL FNAMES=OUTDD1,OUTREC=(C'******',1,10)
/*
./ ADD NAME=COPYOUTF
//* COPIA SIN ALGUNOS REGISTROS
//* y formateando la salida
//* COLOCA PRIMERO * Y LUEGO SOLO DELA 1 A LA 10
//* CON OUTFILE NO ES NECESARIO EL TO
//*
//ICETOOL1 EXEC PGM=ICETOOL,REGION=0M 0317002
//TOOLMSG DD SYSOUT=* 0318002
//DFSMSG DD SYSOUT=* 0318002
//INDD DD DISP=SHR,DSN=UTE9901.MERGE.A
//OUTDD1 DD DSN=UTE9901.MERGE.SAL1, 0318002
// UNIT=SYSDA,DISP=(NEW,CATLG),SPACE=(TRK,(1,1)), 00020000
// DCB=(DSORG=PS,RECFM=FB,BLKSIZE=0,LRECL=16) 00030000
//TOOLIN DD * 0319002
COPY FROM(INDD) USING(ABCD)
//ABCDCNTL DD *
OMIT COND=(20,2,CH,EQ,C'Al')
OUTFIL FNAMES=OUTDD1,OUTREC=(C'******',1,10)
/*
./ ADD NAME=COPYSEPA
//* DE LA ENTRADA SEPARA A OTROS DEPENDIENDO DE
//* LO QUE TENGA EN UN CAMPO
//* el resto lo mete en OUTFIL SAVE,FNAMES=OUTDD3
//*
//ICETOOL1 EXEC PGM=ICETOOL,REGION=0M 0317002
//TOOLMSG DD SYSOUT=* 0318002
//DFSMSG DD SYSOUT=* 0318002
//INDD DD DISP=SHR,DSN=UTE9901.MERGE.A
//OUTDD1 DD SYSOUT=* 0318002
//OUTDD2 DD SYSOUT=* 0318002
//OUTDD3 DD SYSOUT=* 0318002
//TOOLIN DD * 0319002
COPY FROM(INDD) USING(ABCD)
//ABCDCNTL DD *
OUTFIL INCLUDE=(1,6,CH,EQ,C'Javier'),FNAMES=OUTDD1
OUTFIL INCLUDE=(1,6,CH,EQ,C'JEMNS '),FNAMES=OUTDD2
OUTFIL SAVE,FNAMES=OUTDD3
/*
./ ADD NAME=COPYVARF
//* COPYVARF: COPIA A VARIOS DE SALIDA
//ICETOOL1 EXEC PGM=ICETOOL,REGION=0M 0317002
//TOOLMSG DD SYSOUT=* 0318002
//DFSMSG DD SYSOUT=* 0318002
//INDD DD DISP=SHR,DSN=UTE9901.MERGE.A
//OUTDD1 DD DSN=UTE9901.MERGE.SAL1, 0318002
// UNIT=SYSDA,DISP=(NEW,CATLG),SPACE=(TRK,(1,1)), 00020000
// DCB=(DSORG=PS,RECFM=FB,BLKSIZE=0,LRECL=80) 00030000
//OUTDD2 DD DSN=UTE9901.MERGE.SAL2, 0318002
// UNIT=SYSDA,DISP=(NEW,CATLG),SPACE=(TRK,(1,1)), 00020000
// DCB=(DSORG=PS,RECFM=FB,BLKSIZE=0,LRECL=80) 00030000
//TOOLIN DD * 0319002
COPY FROM(INDD) USING(ABCD)
//ABCDCNTL DD *
OUTFIL FNAMES=(OUTDD1,OUTDD2)
/*
El Pantanero (el mas viejo de los dinosaurios del pantano)

Responder