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.

miércoles, 25 de febrero de 2009

Ahora si es en serio: Error de Dispositivo.










El mensaje de Error de Dispositivo puede generarse por varias razones.

Vamos a enumerar algunas de ellas.

1.-En el programa realizas un Exfmt del registro de control de un subfile y los indicadores que permiten mostrar el registro de control y/o el subfile están apagados.

2.-En el programa realizas un Exfmt del registro de control de un subfile y los indicadores para mostrar el registro de control y el subfile están encendidos pero el subfile no contiene ningún registro grabado.



Este problema suele suceder cuando leemos un archivo en el programa y a medida que leemos el archivo vamos grabando un registro respectivo en el subfile con la información que nos interesa.
Finalmente al salir del lazo de lectura del archivo, encendemos los indicadores y hacemos un Exfmt del registro de control del subfile. Si el archivo de lectura no tenía data, nunca llenamos el subfile y por ende, a la hora de mostrarlo no hay nada que mostrar. Por esta razón el programa Rpg nos muestra un Error de Dispositivo. Podemos controlar con un indicador o con una pregunta si el archivo de lectura tenía o no registros para leer. Dependiendo si el archivo estaba vacío o no, apagamos o encendemos los indicadores para desplegar el subfile o impedir que sea mostrado.

Un subfile lo podemos definir a través de su registro de control (en el SDA) de dos maneras:

1.-Inicializado en forma automática: SFLINZ

Si elegimos que sea inicializado en forma automática no nos ocurre el problema que acabamos de describir. Sin embargo esta practica no es muy utilizada porque el tamaño del archivo de lectura pudiera ser menor que el numero de líneas definidos para el subfile. Para evitar que esas cantidad de lineas en blanco sean mostradas en la pantalla los programadores deben activar en el SDA un indicador de nondisplay ND a todos los campos del subfile y luego hacer update a los registros que quedaron en blanco (los campos con valores en cero o blanco) con el indicador asociado al ND = *ON.

Pseudo-Código para el caso SFLINZ
Fuente Del SDA

A R SFLR SFL
A nombre 15 A 2 10
A direccion 30 A 2 34
A*
A*
A*
A R SFLCTLR SFLCTL(SFLR)
A SFLPAG(17)
A SFLSIZ(17)
A 01 SFLDSP
A SFLDSPCTL
A 02 SFLINZ
A 2 10'NAME'
A 2 34'ADDRESS'
A

Este tipo de subfile resiste perfectamente este tipo de programación:

C* Inicializa Subfile generando 17 registros con valores 0 o blanco en sus campos.
C seton 02
C write SFLCTLR
C setoff 02
C*
C Línea = Línea +1 (contador de linea del subfile declarado en hoja F)
C Read archivo 99
C Dow not *in99
C UPDATE SFLR
C Linea = Línea + 1
C Read archivo
C Enddo

Si el archivo esta vacío y realizamos esta operación:
C seton 01
C EXFMT SFLCTLR

No se produce un error de dispositivo pero nos muestra 17 líneas en blanco en la
Pantalla. Para eliminar las líneas en blanco, tendríamos que recorrernos el subfile desde el principio prendiendo el indicador de ND (no display) y haciendo update a cada registro del subfile.

2.-Inicializado el subfile con un clear: SFLCLR.

Pseudo-Código para el caso SFLCLR
Fuente Del SDA

A R SFLR SFL
A nombre 15 A 2 10
A direccion 30 A 2 34
A*
A*
A*
A R SFLCTLR SFLCTL(SFLR)
A SFLPAG(17)
A SFLSIZ(17)
A 01 SFLDSP
A SFLDSPCTL
A 02 SFLCLR
A 2 10'NAME'
A 2 34'ADDRESS'
A

Este tipo de subfile resiste perfectamente este tipo de programación:

C* Inicializa Subfile generando un subfile vacío.
C seton 02
C write SFLCTLR
C setoff 02
C*
C Línea = Línea +1 (contador de linea del subfile declarado en hoja F)
C Read archivo 99
C Dow not *in99
C WRITE SFLR
C Linea = Línea + 1
C Read archivo
C Enddo

Si el archivo esta vacío y realizamos esta operación:
C seton 01
C EXFMT SFLCTLR

Se produce un error de dispositivo
A menos que luego del Enddo del lazo de lectura coloquemos el siguiente código:
C* seton 01
C If Linea = 1
C Setoff 01
C Endif
C EXFMT SFLCTLR


De esta manera nos evitamos el error de dispositivo.

3.-Otra causa de error es el tratar de grabar una línea del subfile dos veces. Me refiero al segundo caso (SFLCLR) Por ejemplo: si en el lazo de lectura nos olvidamos de incrementar el contador de línea, cuando hagamos el segundo write SFLR estamos tratando de sobreescribir un registro del subfile que ya estaba escrito previamente. (En realidad nos da un intento de grabar registro duplicado, aunque me ha pasado que el mensaje de primer nivel me dice error de dispositivo; luego en el detalle del mensaje me especifica registro duplicado)


4.-También el uso de palabras claves que requieren el uso de variables “escondidas” en el SDA puede originar error de dispositivo.

Un ejemplo de este caso es el uso de la palabra clave CSRLOC en el SDA. Esta palabra clave utilizada para posicionar en la pantalla el cursor en una fila y columna especifica, requiere de dos variables
CSRLOC(FILA COLUMNA) para este ejemplo, llamamos a las variables FILA Y COLUMNA.
Si las variables FILA y COLUMNA están en cero al momento de mostrar la pantalla: EXFMT también da error de dispositivo a menos que coloquemos un indicador en el SDA que condicione la activación del CSRLOC.

Encendemos el indicador solamente cuando queremos que el cursor se mueva a las posiciones contenidas en las variables FILA y COLUMNA si el indicador está apagado, el cursor se mueve por omisión tal y como lo maneja el SDA para los campos de entrada, salida e I/O.

Revisa las palabras claves de tu pantalla y verifica que al momento de hacer un EXFMT las variables asociadas a los keywords contienen valores válidos.




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, 23 de febrero de 2009

Mejorando los Tiempos de Respuesta













Supongamos que tienes un archivo muy grande que es el lazo principal del programa y que dentro de este lazo haces chain a una tabla constantemente de la cual extraes información de un código que a su vez lo usas para actualizar el archivo grande.

El siguiente pseudo-código fuente como ejemplo para ilustrar de lo que se trata:

FArchivoGrande U K Disk
FTabla I K Disk

C Read Archivo Grande 99
C Dow not *in99
C Clave Chain Tabla 98
c*
c Eval Campog = campot
c update ArchivoGrander (la r al final: nombre de registro)
c*
c Read Archivo Grande 99
c Enddo
c Seton LR
c*


Si el "ArchivoGrande" tiene un total de 5.000.0000 de registros, esto
significa que en la ejecucion del programa se realizan un total de accesos
al disco relacionado como sigue:

Total lecturas:

Sobre el Archivo grande: 5.000.000
Sobre la tabla: 5.000.000
----------
10.000.000

Hay que añadir a esta cifra los accesos al disco que se hacen por cada update al archivo grande que son 5.000.000 puesto que se realiza un update por cada registro leído en el archivogrande.

En un ejercicio de imaginación supongamos que cada acceso a disco "cuesta" un milisegundo. Un milisegundo es 0,001 segundos. 15.000.000 accesos x 0,001 segundos
representa 15.000 segundos que traducidos a minutos son 250. Llevados a horas son 4,16 horas. (aproximandamente 4 horas, 9 minutos, 36 segundos)

Son 15.000.000 de acceso al disco lo cual representan 15.000.000 de operaciones de I/O.
La operaciones de I/O son las mas lentas que procesa cualquier sistema operativo.


Si queremos reducir el tiempo de respuesta es necesario reducir la cantidad de lecturas y grabaciones al disco.


Vamos a generar un código fuente mas efectivo en cuanto a tiempo de respuesta.

FArchivoGrande U K Disk
FTabla I K Disk

D*
DTclave 5 S dim(1000) *Arreglo que guarda clave de la tabla*
DTdata 10 A dim(1000) *Arreglo guarda la data de la tabla*
Dindice 4 S 0 *Indice de acceso al arreglo*
D*

c* Lectura de la tabla y se guarda en un arreglo.
C*
C Eval Indice = 1
C Read Tabla 01
c Dow not *in01
C eval Tclave(indice) = Clave
c eval Tdata(indice) = Campot
c Eval Indice = Indice + 1
c Read Tabla 01
c Enddo


C*
C Read Archivo Grande 99
C Dow not *in99
c Eval Indice = 1
C Clave Lookup,Indice Tclave 98
c*
c Eval Campog = Tdata(indice)
c update ArchivoGrander (la r al final: nombre de registro)
c*
c Read Archivo Grande 99
c Enddo
c Seton LR
c*

El uso de arreglos ( o matrices) reduce los tiempos de respuesta porque los accesos a un arreglo NO SON accesos al disco.
vamos a contabilizar el número de I/O que tenemos en esta versión:

Lecturas:
Sobre el ArchivoGrande: 5.000.000
Sobre la tabla : 1.000
---------
5.001.000
Updates:

Sobre el ArchivoGrande: 5.000.000

Un total de 10.001.000 accesos a disco. Esto representa: 10.001.000 x 0,001 segundos = 10001 segundos consumidos en acceso a disco que traducidos a minutos son: 166,683 y llevados a horas son: 2,77805 horas. (esto es aproximadamante 2 horas, 46 minutos, 41 segundos), reduciendose en un 33% el tiempo de respuesta. ¿Impresionante no?



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

domingo, 22 de febrero de 2009

Mejores Practicas en RPG: Uso de Constantes e Indicadores



Uso de constantes en un programa RPG:


Por ejemplo:

Si status = 1 es Activo y Status = 2 es Inactivo,
es recomendable declarar dos contantes:

D ACTIVO const(1)
D INACTIVO const(2).


Al preguntar en el programa por el status no es lo mismo decir:

C If Status = 1

que decir

C If Status = Activo,

De esta manera se autodocumenta el programa y se hace mas legible para un nuevo programador que deba darle mantenimiento.

----------------------------------

sábado, 21 de febrero de 2009

Cómo hacer debug a un programa en Batch


Usa tu pantalla interactiva para hacer debug a un trabajo sometido en batch (por lotes)

Podrás colocar el trabajo batch en modo debug y establecer los puntos de break sin tener que correr el programa en modo interactivo.

Sigue los siguientes pasos:
1.-Somete el job con la opción HOLD(*YES) en el parámetro del comando SBMJOB hold(*YES) o también puedes colocar en HOLD la cola de trabajo por donde será sometido el job antes de someter el job usando el comando HLDJOBQ
2.-Determina el nombre del job, usuario y numero de job sometido usando el Comando WRKSBMJOB
3.-Tipea el siguiente comando en tu pantalla: STRSRVJOB JOB(job name/user/number)
4. Tipea el commando de Star Debug en tu pantalla: STRDBG
5. Libera el job de la cola de trabajos, para ello Tipea el comando WRKSBMJOB y coloca un 6 al lado del job que quieres liberar o, si la cola de trabajos esta en HOLD libera la cola de trabajos con el comando RLSJOBQ
6. Un mensaje aparecerá en pantalla cuando el job este listo para arrancar. El mensaje te dirá que puedes comenzar a hacer el debug. Presiona F10 para que te muestre la línea de Comandos en pantalla.
7. Ahora puedes comenzar el debug tipeando el comando de Break point en pantalla: ADDBKP

------------------------------------------------------------------------------------


¿Sabías que puedes usar el debug interactivo para hacer debug a un programa
Sometido?
Sigue los siguientes pasos:
1.-Modifique el programa CL desde donde el programa RPG es llamado para incorporar
Un mensaje de espera antes de que el RPG sea llamado. Esto puede realizarse
Añadiendo el comando SNDUSRMSG en el CLP antes de la llamada al RPG

2.-Una vez que el programa CL ha corrido y está en starus MSGW, coloque el comando
STRISDB en pantalla: STRISDB program UPDPRD(*YES) INVPGM(*NO) SRVJOB(*SELECT)
El parámetro SRVJOB(*SELECT) debería habilitarte la selección del job que está en
MSGW. Selecciona este job de la lista de Jobs que están desplegados en pantalla.
Responde el mensaje para que el job continúe ( coloca cualquier respuesta)
3.-La sesión de Debug debería comenzar ahora, y tendrás frente a ti el fuente del programa. Ahora añade los puntos de break dentro del programa


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

Respuestas inteligentes a preguntas ¿tontas.?


Este es un personaje llamado: "El vacilador". Aparece cada cierto tiempo y se encarga de dar respuestas inteligentes a preguntas tontas...


1.-¿Cómo hago para que el cursor se posicione en la primera línea de subfile cuando doy Enter?

- toma el Mouse y colocas el cursor en la primera línea

2.-¿Cómo hago para que las dos ventanas aparezcan al mismo tiempo en la pantalla?

-Colocas una al lado de la otra, si la pones encima, ni modo…

3.-Cuando un archivo me dice que ha alcanzado el máximo número de registros
¿Que debo hacer?,

-Borra los que te sobren.

4.-¿Por donde puedo ver la data de un archivo?

-Por la pantalla o en papel.


5.-¿Cómo puedo hacer para ver las variable de un programa sin tener que hacer debug?

-colocas STRNODBG

6.-La compilación me dice que el programa no sabe como terminar.

-Claro, lo tienes que terminar tú, o ¿acaso pensaste que se iba a terminar solo?

7.-Para compilar un RPG no ILE ¿cual es el comando?
-Colocas CRTNOILERPG

8.- Por que me dice que variable es demasiado pequeña para contener el valor?

-Seguro que el nombre que pusiste a la variable es de una o dos letras…

9.-Me da índice fuera de rango pero no entiendo, ¿por qué?

-Estas tocando la pantalla con el índice

10.-Le doy F5 y no me refresca la pantalla.

-Pana, venden unos ventiladores de escritorio bien buenos, prueba con eso
A ver si te funciona


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

Los peores errores que pueden sucederle a un programador en RPG


Los peores errores que pueden sucederle a un programador en RPG

1.-Error de dispositivo.

1.1-Este es un clásico error “tapa amarilla”, es decir, puede significar, cualquier cosa.
Puedes pasar horas en eso y por ensayo y error, quitas, pones, vuelves a poner y a quitar keywords y hasta que la pegaste…por fin!

Anécdota.

En una empresa donde trabajó un amigo, un aprendiz de RPG le consulto a su líder de proyecto sobre el error de Dispositivo que estaba dando su programa.
La respuesta del líder: Es que tienes que cambiarte de pantalla, si quieres usa mi maquina.


1.3 Pasados tres meses del programa EDD (que daba Error De Dispositivo) ¿se acuerdan?

Hay que cambiar el programa EDD ¿ a quien se lo damos?.

Respuestas:

-yo estoy ocupado en otra cosa.
-Tengo que entregar mañana esto que estoy haciendo.
-Debo levantar información para el proyecto.
-Dáselo a fulano que fue el último que lo cambió
-Yo no quiero ese muerto
-Esto saliendo para una reunión
-ay! No….
-¿No estará por entrar alguien nuevo?


2.-Data decimal Error.

2.1- Este es un mensaje de error clasificado como “exasperante”, se busca,
el archivo, la variable del programa, se hace debug y nadaaaaaaaaaaaaaa…
Llamada telefónica de consulta a un pana:
-chamo! Tengo un programa acá con data decimal error y no consigo que pasa
-¿Ya le hiciste debug?
-si, ya se cual es la variable pero esta bien, está en cero, pero cuando pasa a la siguiente instrucción da error.
-¿que hace la siguiente instrucción?
-Un move a un campo alfabético
-¿estas seguro que es alfabético?
-si, es alfabético.
-no sé chamo, tengo que ver el programa.

Solución:

2.2- Se darán cuenta que las siglas de este error Data Decimal Error DDE son similares a la de Error De Dispositivo EDD.

Solución: no llame ningún archivo, programa, módulo, ni pantalla, con esta combinación de letras DDE EDD DED

Es pavosisisisisisimoooooooooooooo

PD: En Venezuela es llama pavoso a algo que da mala suerte.



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