Bienvenidos a Iseries Venezuela

Las mejores prácticas, recursos, tips, enlaces, videos y artículos para informáticos relacionados con el Iseries y el As/400 lenguajes de programación RPG, ILE RPG y SQL.

The best practices, resources, tips, links, videoes and articles for computer related to the Iseries and the As/400 languages of programming RPG, ILE RPG and SQL.

domingo, 29 de noviembre de 2009

Preguntas y Respuestas Frecuentes












1.- ¿Cómo Chequear que se va a grabar clave duplicada?
C Monitor

C WRITE(E) FILENAME

C On-Error 01021

C EXSR $ERRROR

C EndMon


2.- ¿Es posible utilizar más de un subfile en pantalla?

Si es posible. La manera es de hacerlo es precisar el rango de columnas y filas en la pantalla asociado a cada subfile. En el programa, preguntas por la posición del cursor y vas a la rutina de avance o retroceso de un subfile o del otro dependiendo de la ubicación del cursor.

miércoles, 25 de noviembre de 2009

Aplicaciones Multi-idioma






Algunas veces queremos diseñar sistemas multi-idiomas, para realizar presentaciones del proyecto, mostrando la pantalla en español y en ingles. En la imagen que acompaña a este articulo podemos ver dos pantallas: una en ingles y la otra en español.

Haciendo Click en las imágenes las puedes ver ampliadas


Para realizar un sistema multi-idiomas, es necesario que los títulos en las pantallas no sean literales sino campos de salida. En el ejemplo tenemos los literales: usuario, producto, reclamo y monto, entre otros.

Lo primero que debemos hacer es crear dos archivos de mensajes con igual nombre pero en distintas bibliotecas. CRTMSGF. Supongamos que creamos el archivo de mensajes llamado TITULOS en la biblioteca: ESPANOL y otro archivo de mensajes llamado TITULOS en la biblioteca: INGLES. Un párrafo mas adelante explicaré su utilización.

El truco consiste en sustituir estos literales de pantalla por campos alfabéticos de salida.

jueves, 19 de noviembre de 2009

Botones en RPG


















Los Botones para seleccionar opciones son utilizados en diversas plataformas.

En RPG existe un mecanismo de emular los botones de selección como puede verse en la imagen adjunta a este artículo.

Haz click en la imagen para verla ampliada.

Es necesario declarar una variable numérica que sea de entrada y salida (bivalente)
2,0 bivalente, con atributo de desplazamiento de teclado: Y

Con F4 y luego 1 para seleccionar las propiedades del campo seleccionamos la ultima opción que vemos en pantalla titulada: Palabras claves de opción, colocando Y
(esta opción está antes del titulo que nos permite colocar palabras claves de texto).

Si no declaras el campo como está especificado esta opción de palabra claves de opción, no aparecerá en pantalla.

En la pantalla siguiente, especificamos que hay múltiples opciones con la palabra clave MLTCHCFLD = Multiple Choice field, luego elegimos seleccionar parámetros = Y; elegimos también definir las palabras claves de opción con Y
__________________________________________________________

Teclee opciones, pulse Intro.

Tipo de selección de opción . . . . . . . . 2 1=SNGCHCFLD 2=MLTCHCFLD

Seleccionar parámetros . . . . . . . . . Y                                                    
Opción de campo de selección . . . . . . . . CHOICE
Definir palabras clave de opción . . . . . Y _______________________________________________________________

Aparece la siguiente pantalla:

Donde dice número de opción colocamos el número de opción 1, 2, 3 definiendo el titulo de cada opción de botón en pantalla. Nuestro ejemplo es un botón con dos opciones. En este ejemplo se especifica para la segunda opción, pero debe especificarse para todas.

El campo de control es la variable que recogerá el valor 1 cuando el usuario elija esta opción con el Mouse. El Texto que titula la opción es ANUAL

__________________________________________________________________
Número de opción . . . . . . . . 2 Número, +/-, F4 para lista


Teclee opciones, pulse Intro.

Palabra clave Más

Opción de campo de selección . CHOICE Y Y=Sí

Indicadores . . . . . . . . . Nnn, +

Campo de texto . . . . . . . Nombre

Texto . . . . . . . . . . . . ANUAL

Espacio en blanco previo . . Y Y=Sí

Control de opción . . . . . . . CHCCTL Y

Campo de control . . . . . . CAMPO1
___________________________________________________________


En este link pueden descargar el código del fuente que fue desarrollado a manera de ejemplo:

Fuentes Botones en RPG

Autor: Ing. Liliana Suárez.


Si te pareció interesante, reenvialo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.

martes, 17 de noviembre de 2009

Subfiles: aprovechando su funcionalidad












Otra funcionalidad muy útil puede ser aplicada para el uso de subfiles y consiste en guardar los resultados de las validaciones de los datos incluidos por el usuario.

En general es común presentar una pantalla y luego mediante una serie de validaciones encender tal o cual indicador y se asocia un mensaje de error que posiciona el cursor en el dato inválido y/o lo resalta en pantalla. Este proceso es secuencial, es decir se valida el primer dato y se da el mensaje de error aunque otros campos pueden tener errores en ese mismo momento. Las siguientes validaciones deben esperar por el siguiente ENTER del usuario. En un ejemplo extremo suponiendo veinte campos en pantalla y todos errados, el usuario debe presionar ENTER 20 veces para corregir el error en cada dato.

Una mejora que puede hacerse al procedimiento anteriormente descrito es dar el mensaje de error de uno de los campos y resaltar los demás datos errados para que el usuario se alerte de los errores detectados sin saber necesariamente de qué se tratan.

Sustituyendo el uso del registro de pantalla simple por un subfile, el proceso se hace mucho mas eficiente para la corrección de errores de carga.

Debe definirse el subfile de manera que solo muestre un registro por pantalla (aunque el subfile tenga 1000 registros por definición) el usuario verá una pantalla para cargar data que sería el registro de control. Los mensajes de error serán almacenados en las líneas del subfile. El usuario verá una sola línea del subfile en la pantalla con el primer mensaje de error detectado en el programa, pero haciendo rollup puede ver todos los mensajes de error que se generaron al presionar un solo ENTER. Los datos erróneos pueden ser resaltados todos y además el usuario puede ver de una vez de qué se tratan todos los errores que el sistema está reportando.

Optimizando los tiempos de procesamiento tanto en los procesos de carga asi como en procesos interactivos y en batch, se van reduciendo los tiempos de respuesta y aumentando la satisfacción de los usuarios del sistema.

Si te pareció interesante, reenvialo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.

Autor: Ing. Liliana Suárez

sábado, 14 de noviembre de 2009

Adefesios en RPG





San Pablo escribía a los Efesios cartas aconsejándoles sobre dejar ciertos hábitos o conductas extravagantes y escandalosas. Con el devenir del tiempo, se utiliza la frase ADEFESIO en recuerdo a las cartas de San Pablo a esa comunidad. De San Pablo a los Efesios se tomó: Ad-Efesios (A los efesios).

Un Adefesio según la real academia de la lengua es algo que se ve feo, extravagante o ridículo.

A continuación, una pequeña muestra de algunos adefesios en la programación en RPG.


ADEFESIO 1


C_________ENDIF
C_________ENDDO
C_________ ENDSR
0401.00 *---* *- - - - - - - - - - - - - - - - - - - - - - - - - -
0402.00 ** MENSAJES DE ERROR **
0403.00 POLIZA NO REGISTRADA, VERIFIQUE
0404.00 POLIZA NO EXISTE EN DTOGEN, VERIFIQUE
0405.00 CON F1 ACTUALIZA PLAN DEL CERTIFICADO
0406.00 PARA EMITIR POLIZA, DEBE SELECCIONAR ''G'' Y PULSAR CF08

Colocar mensajes de validación en una tabla al final del programa es feo.

Es recomendable un archivo contentivo de los mensajes de error del sistema o módulo porque unifica criterios y estandariza la programación.


ADEFESIO 2
____________________L E
CAÑOFIN COMP UYEAR 1122
CN11 22 MESFIN COMP UMONTH 2233
CN11N22 33DIAFIN COMP UDAY 3333
C11
COR 22
COR 33 DO
C ADD SUMASI BSFIN
C SETON 12
C END

Programar una comparación entre dos fecha de esta manera es feo y extravagante.

Es recomendable, crear dos DS en el programa para realizar la pregunta de la siguiente manera:

IF FECHAFINAL (AAAAMMDD) <= FECHAACTUAL(AAAAmmDD) ADD SUMASU BSFIN ENDIF


 ADEFESIO 3

C *IN60 IFEQ *ON
C *IN61 OREQ *ON
C *IN03 OREQ *ON
C *IN04 OREQ *ON
C *IN05 OREQ *ON
C *IN06 OREQ *ON
C *IN62 OREQ *ON
C *IN63 OREQ *ON
C *IN64 OREQ *ON
C *IN65 OREQ *ON
C *IN66 OREQ *ON
C *IN67 OREQ *ON
C *IN68 OREQ *ON
C *IN69 OREQ *ON
C *IN70 OREQ *ON
C *IN71 OREQ *ON
C *IN72 OREQ *ON
C *IN73 OREQ *ON
C *IN74 OREQ *ON
C *IN75 OREQ *ON
C *IN76 OREQ *ON
C *IN77 OREQ *ON
C *IN78 OREQ *ON
C *IN79 OREQ *ON
C *IN80 OREQ *ON
C *IN81 OREQ *ON
C *IN82 OREQ *ON
C *IN83 OREQ *ON
C *IN84 OREQ *ON
C *IN85 OREQ *ON
C *IN86 OREQ *ON
C *IN87 OREQ *ON
C SETON 11
C ENDIF

Feo, extravagante y ridículo.

La imagen de este articulo es: Medusa obra maestra de MiguelAngel

Si te pareció interesante, reenvialo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.

Autor: Ing. Liliana Suárez

lunes, 9 de noviembre de 2009

Occur para actualizar archivos

      

En el siguiente código de programación vemos el uso del Occur para actualizar un archivo. Puede apreciarse que ya no es necesario el uso de variables de trabajo utilizadas como campos en la pantalla para guardar los valores modificados por el usuario. 


     f*************************************************************
     f*************************************************************
     fArchivo   uf   e           k Disk
     FArchidsp  cf   e             WORKSTN
     d*************************************************************
     d* Variables, Estructuras, Arreglos                          *
     d*************************************************************
     dDSARCHIVO      E DS                  EXTNAME(ARCHIVO)
     d                                                        Occurs(2)
     dINDICE           s              1s 0
     c*************************************************************
     c* Rutina Principal                                          *
     c*************************************************************
     c
     c*
     c                   Eval      Indice  = 1
     C     Indice        occur     DSARCHIVO
     c     Clave      chain(n)  archivo
     c                   Exfmt     FMT1
     c*                  Exsr      validar
     c*
     c*                  if        okey
     c                   Eval      Indice = 2
     C     Indice        occur     DSARCHIVO
     c     Clave     chain     archivo
     c*
     c                   if        %found
     c                   Eval      Indice = 1
     C     Indice        occur     DSARCHIVO
     c                   update    rarchi
     c*                  endif
     c*
     c                   endif
     c
     c                   Seton                                        Lr



Si declaramos dos ocurrencias sobre una DS que está asociada a la descripción externa del archivo que queremos actualizar, se hace innecesario declarar tantas variables auxiliares como campos tiene el archivo.
Cuando nos posicionamos en el indice = 1, inicialamente cargamos, en esta ocurrencia, los valores del archivo. Luego  el usuario altera los campos de pantalla con los valores que desea modificar. Con este procedimiento podemos declarar los campos en pantalla con los mismos nombres que tienen los campos en el archivo.Como seguimos posicionados en el Indice = 1, los cambios son realizados sobre esta ocurrencia de la DS del archivo.  Antes de  hacer un segundo chain sobre el archivo, nos posicionamos en la segunda ocurrencia con Indice = 2, para que los valores  leídos del archivo se carguen sobre esta ocurrencia de la DS y no altere los cambios que el usuario realizó en pantalla. Finalmente antes de realizar el UPDATE, nos volvemos a posicionar en el Occur con indice = 1 a fin de  rescatar los valores que queremos grabar y  realizar los cambios que el usuario está solicitando.


Si te pareció interesante, reenvialo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.

Autor: Ing. Liliana Suárez

jueves, 5 de noviembre de 2009

Sql para eliminar registros duplicados
















Eliminar registros con clave duplicada de un archivo utilizando SQL.



DELETE FROM LIBRERIA1/ARCHIVO1 where RRN(F1) > (Select MIN(RRN(F2)) From LIBRERIA1/ARCHIVO1 F2 WHERE F2.CLAVE = F1.CLAVE)



Debe leerse el comando de derecha a izquierda como las escrituras árabes. En este caso comenzando con el Select.

Este comando trabaja con el Record Number (Número de registro físico) con el que trabaja el Iseries al grabar los registros en un archivo. La palabra clave es: RRN.

El comando selecciona el menor record Number entre registros del mismo archivo con claves coincidentes. F1 y F2 son artificios usados por Sql para identificar rapidamente un archivo de otro archivo. El resultado de un select es una tabla interna subconjunto del archivo original,  cuyos registros coinciden con F1 (que tambien es el archivo original)  pero seleccionando el  registro con menor Record Number. Seguidamente, el comando procede a eliminar (DELETE) del archivo original el registro duplicado con mayor Record Number.




Si te pareció interesante, reenvialo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.

Autor: Ing. Liliana Suárez

miércoles, 4 de noviembre de 2009

SQLRPG para Eliminar Registros de un Archivo















 Con el fin de optimizar nuestros programas y el tiempo de respuesta de nuestros procesos, vamos a publicar una series de tips y articulos relacionados con el SQL en sus distintas presentaciones, hoy comenzamos con algo sencillo enmarcado en el RPG como lenguaje anfitrion de SQL. Borramos los registros de un archivo que cumplen con una condición. En este ejemplo queremos eliminar los registros cuya fecha de proceso sea menor a una fecha enviada por parámetro al programa SQLRPG



Código SQLRPG

C *Entry PList
C Parm varfec 80 (variable numérica de 8 posiciones y cero decimales)
C*
C/Exec Sql
C+ DELETE FROM ARCHIVO
C+ WHERE FECPRO <= :VARFEC
C/end-Exec


Para archivos de más de 4000.000 de registros esta instrucción puede tardar hasta 10 minutos. Con un RPG que utiliza un Read y un IF dentro del lazo de lectura, el proceso tarda hasta 1 hora y 20 minutos. Para compilar este programa, debe colocarse *NONE en el parámetro que corresponde al control de compromiso COMMIT, si no hemos creado un Journal sobre el archivo. Crear un Journal sobre el archivo le da al sistema operativo la posibilidad de revertir en forma automática el borrado de los archivos en caso de que así se requiera. Si el programa no compila revisa si colocaste correctamente este parámetro.

Crear o no un Journal a los archivos queda a criterio a las normativas de la Gerencia de Sistemas.

A continuación el parámetro de compilación.

 Crear objeto RPG ILE SQL (CRTSQLRPGI)

Teclee elecciones, pulse Intro.
 Objeto . . . . . . . . . . . . . . . . . . . . PROGRAMA
 Nombre Biblioteca . . . . . . . . . . . .LIBRERIA Nombre, *CURLIB
 Archivo fuente . . . . . . . . . . . . . . QRPGLESRC Nombre, QRPGLESRC

 Biblioteca . . . . . . . . . . . . . . . .  . .LIBFTES Nombre, *LIBL, *CURLIB
 Miembro fuente . . . . . . . . . . . . . .PROGRAMA Nombre, *OBJ
 Control de compromiso . . . . . . . .*NONE *CHG, *ALL, *CS, *NONE...
 Base de datos relacional . . . .  . . . *LOCAL
 Tipo de compilación . . . . . .  . . . .*PGM *PGM, *SRVPGM, *MODULE
 Salida del listado . . . . . . . . . . . . . *NONE *NONE, *PRINT
Texto descriptivo . . . . . . . . . . . . *SRCMBRTXT

En el próximo articulos continuaremos optimizando los tiempos de respuesta de de programación con SQL.

Si te pareció interesante, reenvialo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez