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.

Sunday, March 30, 2014

Algo más sobre Uso de Indicadores.

 







En un artículo anterior, al comenzar la edición de este blog, hice mención a varias recomendaciones a como usar los indicadores.


En esta oportunidad vamos a mencionar formas arcaicas o en desuso de los indicadores porque me lo han pedido en los últimos comentarios del blog.
Vamos a enfocarnos en:


Como NO utilizar los indicadores.

Hemos visto a programadores de RPG II y RPG III utilizar indicadores de esta forma:

N31N45N78       Move 1  VARIABLE

Algunas variaciones más monstruosas sobre el mismo tema.

N31N45N78    
Or
N78 78N90        Move 1  VARIABLE
     

Lo peor es que cuando incursionan en la programación con RPG IV conservan la misma forma arcaica de programar.

Luego de un tiempo el mismo programador no recuerda que diablos significa N31 N45  N78 y debe comenzar a realizar un análisis “forense” hasta dar con el concepto que involucra cada indicador.

Con RPG IV o con RPG FREE podemos declarar variables tipo Booleana en la hoja ‘D’ .Se declara tipo ‘n’ y listo!.

Por ejemplo si el indicador 31 indica que se aprobó el préstamo del cliente.
¿Por qué no declarar una variable tipo booleana? Una variable llamada: Prestamo_Aprobado.

Podemos hacer: Prestamo_Aprobado = *On  
o Podemos hacer: Prestamo_Aprobado = *Off

Y luego preguntar:  If Prestamo_Aprobado 

¿Es más sencillo y claro de entender verdad?

Otro uso arcaico de los indicadores es en las preguntas IF.

If *in03 = ‘1’  no es necesario preguntar si vale ‘1’ con colocar:

If  *in03       Es suficiente.

Lo mismo sucede con el indicador con negación delante:

If  *in03 = ‘0’ se reemplaza por: If Not *in03

Sin embargo la mayoría de los programadores se mantienen con su forma de programar en:
If  *in03 = ‘1’   If  *in03 = ‘0’ formas que denotan falta de claridad del programador en el manejo de las sentencias lógicas.

Es  lo mismo preguntar por *OFF que por ‘0’ al igual que preguntar por *ON que por ‘1’.

Hay instrucciones como el CHAIN el COMP que originalmente utilizan indicadores. Con la nueva programación en RPG-FREE se pueden utilizar operaciones como por ejemplo:

    Chain (Key1:Key2) Archivo    03    (El indicador 03 es opcional)

If %Found(archivo)  equivale a preguntar If  not*in03

La operación COMP que ya NO se usa es reemplazada por una condición estándar de
Comparación:   IF A > B

Otra costumbre en la vieja programación es esta:

45                         A IFGT B
                                 …..
                  ENDIF
Esto significa que si el indicador 45 esta encendido (*ON) ejecutar el IF y todo lo que hay adentro.
Esta es otra práctica que dista de estar entre las mejores prácticas de programación en RPG. Utilice todas las condiciones que necesite en la sentencia IF para despejar cualquier duda de su ejecución.

En Rpg_Free ya no es necesario el uso de indicadores para buscar un elemento en un arreglo (Array)

Posicion= %Lookup(‘hola’: Array: 1:200)

En Posicion  se devuelve la posición del arreglo donde se encontró la palabra ‘HOLA’ si POSICION es cero entonces no está en el arreglo.
Un indicador menos que utilizar y podemos usar una variable mas mnemotécnica (Posicion)


Si puedes utilizar variables estándar o variables booleanas en lugar de indicadores, tendrás suficientes indicadores a tu disposición cuando requieras verdaderamente el uso de indicadores como es el caso del manejo de pantallas. Para ese caso, no hay manera de reemplazar indicadores de pantalla con variables booleanas. El SDA no da espacio para variables booleanas o nombres largos que permitan el manejo de campos y condiciones en Keywords de pantallas para el despliegue y actualización interactiva de datos.

El utilizar RPG-Free nos brinda muchas facilidades que nos permiten ser más claros, sencillos y directos en la programación.

Si quieres “migrar” a RPG-Free revalúa tus técnicas de programación para que no repitas los mismos vicios que aprendiste en códigos de programación mas atrasados.

 Para mayor información sobre este tema puedes consultar este enlace de otro artículo publicado por mí en este mismo blog, hace algún tiempo:



Si te pareció interesante, reenvíalo 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

Sunday, February 16, 2014

Precedencia En Operaciones. Parece Sencillo Pero Puede Ser Engañoso.


















En esta oportunidad vamos a repasar un tema que pareciera sencillo pero que puede dar a muchas complicaciones en los resultados finales de nuestros programas en RPG/RPGLE

Veamos el siguiente ejemplo en RPG III:


C   M02SRC     IFEQ   *BLANK
C   M02SRC     OREQ   'A'
C   $PGMDT     ANDGT  $RIFPG
C   $CMD       ANDEQ  'DREXTR'

¿Como interpretar esta operación?

Si no tenemos clara la prioridad que el sistema le asigna a cada operador
podemos suponer cualquiera de las siguientes interpretaciones como válida:

1.-(M02SRC = *Blanks) or ((M02SRC  = 'A') and $PGMDT > $RIFPG)
     and $CMD = 'DREXTR'

2.-(M02SRC = *Blanks or (M02SRC  = 'A')) and $PGMDT > $RIFPG))
     and $CMD = 'DREXTR'




La siguiente lista indica la prioridad en la evaluación de los operadores de una operación en RPG comenzando con el del mayor prioridad hasta el de menor prioridad.

  1. ()
  2. Built-in functions, user-defined functions
  3. unary +, unary -, NOT
  4. **
  5. *, /
  6. binary +, binary -
  7. =, <>, >, >=, <, <=
  8. AND
  9. OR
¿que significa esto?. 

Aplicándolo al ejemplo anterior:


C   M02SRC     IFEQ   *BLANK
C   M02SRC     OREQ   'A'
C   $PGMDT     ANDGT  $RIFPG
C   $CMD       ANDEQ  'DREXTR'


Supongamos que las variables tienen los siguientes valores:

M02SRC = 'H'
$PGMDT = 100
$RIFPG = 85
$CMD = 'DRINTR'

Primero se evalúan los operadores >,= (Mayor que e igual a)
 (En RPG III es equivalente a  GT, EQ, para el caso que nos concierne)

Estos dos operadores ocupan la posición 7 de la lista lo que significa que tienen mayor prioridad que los operadores AND y OR que ocupan la posición 8 y 9 respectivamente:

Evaluamos los = y el >

M02SRC = *Blanks     --> FALSO
M02SRC =  'A'             --> FALSO
$PGMDT > $RIFPG    --> VERDADERO
$CMD = 'DRINTR'     --> FALSO



Luego se evalúan los AND y posteriormente los OR, puesto que el AND está en un puesto 8 de mayor prioridad que el OR que ocupa el puesto 9 de la lista que presentamos anteriormente.

Entonces en un primer paso el sistema operativo evalúa las condiciones que he colocado entre paréntesis a la que les da prioridad por tener un operador lógico AND.

 (M02SRC  = 'A' and $PGMDT > $RIFPG) and ($CMD = 'DREXTR')
     
 (FALSO               and VERDADERO)           and (FALSO)

El resultado de los operadores AND es FALSO


el resultado de las operaciones AND =Falso se procede a evaluar contra el OR que es el operador restante:

M02SRC = *Blanks OR (FALSO)

(FALSO                     OR   FALSO) 

La condición es FALSA por lo que no procede la ejecución de los comandos que continúan dentro del IF

Esto equivale a transcribir la operación de la siguiente manera:

(M02SRC = *Blanks) or ((M02SRC  = 'A') and ($PGMDT > $RIFPG)
     and ($CMD = 'DREXTR'))


Se entiende que la evaluación de lo que está entre paréntesis tiene mayor prioridad por ocupar en puesto 1 de la lista, lo que equivale a evaluar las condiciones =, > en primer lugar y se continúa con el proceso anteriormente descrito.

La siguiente expresión es equivalente:

M02SRC = *Blanks or (M02SRC  = 'A' and $PGMDT > $RIFPG
     and $CMD = 'DREXTR')

Para conservar la lógica del programa original decimos al sistema operativo que queremos evaluar primero todo lo que está entre paréntesis que serían los AND y sus operadores de = y > asociados y el resultado de esto se evalúa contra el OR.

Es importante tener esto claro sobretodo cuando queremos transcribir programas en RPG III a programas RPG IV o A RPG-FREE de una manera mas legible para el programador.



Enlace de referencia:

Si te pareció interesante, reenvíalo 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


Monday, January 13, 2014

Mejorando los Tiempos de Respuesta: Miembros en Archivos Físicos



Hay varias opciones para agilizar los tiempos de respuesta en el proceso de accesar la data de un archivo. Esta vez vamos a ver el uso de miembros en un archivo físico.

Los archivos físicos pueden ser “particionados” en varios miembros.  Esto de lo Miembros es  parecido a las particiones que se hacen a un disco con la diferencia de que se trata de particiones virtuales. Es decir particiones lógicas.

 Con el comando ADDPFM se pueden agregar miembros

 El comando es:
 ADDPFM FILE(LIBRERIA/ARCHIVO) MBR(NOMBRE-del-Miembro)

  El tope es hasta 32.767 miembros.
 Podemos poner un nombre mnemónico a cada miembro que nos permita a simple vista entender que tipo de data se almacena en ese miembro.

Supongamos que queremos tener en disco la data de cierre del año fiscal desde hace 14 años hasta el año actual. (Año actual =2014)
Cada miembro puede contener data de distintos años. Podemos crear tres miembros. Por ejemplo, el primer miembro contiene la data de los primeros cinco años, el segundo de los otros cinco y el tercero de los últimos cinco años.

Cuando vamos a grabar en un archivo debemos detectar la fecha de la data y hacer ovrdbf sobre el archivo con el miembro destino de la información. Las consultas, listadores y procesos deben grabar sobre el miembro que contiene la data correspondiente a la fecha dentro del rango definido.
Lo archivos lógicos además deben ser creados apuntando a cada miembro. De esta manera cada miembro tiene sus propios archivos lógicos e índices asociados. Cada aplicativo que utiliza el archivo hace una cantidad de accesos a la data mucho menor cuando se limita el alcance a un miembro específico que tiene un total de registros mucho menor que la sumatoria de todos los miembros.

Hagamos un ejercicio:

Al primer miembro lo podemos llamar AF00AL05 para indicar que contiene la data del año fiscal  (AF) desde el año 2000 (00) al año 2005 (05).

Creamos el miembro:
ADDPFM FILE(LIBRERIA/ARCHIVO) MBR(AF00AL05)

En caso de utilizar directamente el archivo físico en el programa, el OVRDBF correspondiente que tendría que hacer el aplicativo antes de actualizar o leer es:
OVRDBF FILE(ARCHIVO) TOFILE(LIBRERIA/ARCHIVO) MBR(AF00AL05)

Si decidimos crear un archivo lógico para utilizarlo en nuestras aplicaciones lo creamos de
Esta manera:
CRTLF FILE(LIBRERIA/LOGICO1) DTAMBRS((LIBRERIA/ARCHIVO(AF00AL05)))

Al segundo miembro lo podemos llamar AF06AL10 para indicar que contiene la data del año fiscal  (AF) 2006 (06) al 2010 (10)

Creamos el miembro:
ADDPFM FILE(LIBRERIA/ARCHIVO) MBR(AF06AL10)

En caso de utilizar directamente el archivo físico en el programa, el OVRDBF correspondiente que tendría que hacer el aplicativo antes de actualizar o leer es:
OVRDBF FILE(ARCHIVO) TOFILE(LIBRERIA/ARCHIVO) MBR(AF06AL10)

Si decidimos crear un archivo lógico para utilizarlo en nuestras aplicaciones lo creamos de
Esta manera:
CRTLF FILE(LIBRERIA/LOGICO2) DTAMBRS((LIBRERIA/ARCHIVO(AF06AL10)))
Al tercer miembro lo podemos llamar AF11AL15 Para indicar que contiene la data del año fiscal  (AF) 2011 (11) al 2015 (15)

Creamos el miembro:
ADDPFM FILE(LIBRERIA/ARCHIVO) MBR(AF11AL15)
En caso de utilizar directamente el archivo físico en el programa, el OVRDBF correspondiente que tendría que hacer el aplicativo antes de actualizar o leer es:
OVRDBF FILE(ARCHIVO) TOFILE(LIBRERIA/ARCHIVO) MBR(AF11AL15)
Si decidimos crear un archivo lógico para utilizarlo en nuestras aplicaciones lo creamos de
Esta manera:
CRTLF FILE(LIBRERIA/LOGICO3) DTAMBRS((LIBRERIA/ARCHIVO(AF11AL15)))

Gráficamemente podemos representar el archivo de la siguiente manera.




Algunas organizaciones al cierre de año, crean a tiempo de ejecución un miembro nuevo cuando detectan que es un año fiscal que no tiene miembro asignado. Es decir en los programas CLP crean un nuevo miembro siguiendo una nomenclatura estándar y grabando en un archivo aparte el nombre del nuevo miembro con el rango de fechas que le ha sido asignado.
Por ejemplo, podemos tener  un archivo de control de miembros definido de esta manera



Con la siguiente data cargada manual o automáticamente.









Si te pareció interesante, reenvíalo 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