Continuando con la serie de entradas relacionadas con el tema de la estrategia de desarrollo en ILE presento una plantilla de programa de selección de un registro.
Se define:
Definición de las estructuras de datos
/COPY *LIBL/QRPGLESRC,BAN00VAR
/COPY *LIBL/QRPGLESRC,BAN01M1CP
La rutina /Copy (BAN00VAR) contiene definición de variables comunes a todos los programas de pantalla. Se detallará en un apartado.
La rutina /Copy (BAN01M1CP) contiene la definición de los componentes de acceso a base de datos. (Ver entrada de componente de acceso a base de datos)
Procedimientos internos
Parámetros de entrada.
Se define los parámetros de entrada a este programa. Tendrá siempre un estructura de datos (P_Parametros) y un campo de resultado de la operación (P_Resultado).
La estructura de datos (Ds_Parametros) contiene las variables de entrada/salida al programa. En este caso son dos valores de salida que contiene el id de país y su nombre (IdPais y DsPais) del registro de la lista seleccionado por el usuario
Si se quiere modificar el flujo de proceso, basta con cambiar el contenido de esta variable al finalizar su grupo de acciones.
Si se desea incluir nuevas acciones, se crearía una nueva situación incluyendo las instrucciones que fuera y al finalizar estas acciones debería cambiar el contenido de la variables de situación para pasar a otro estado. Lógicamente, habría también que cambiar que alguien llamará a este nuevo grupo cambiado la variable de situación.
Las situaciones por las que esta pasando el programa son constantes definidas en el /Copy común y son las siguientes:
Primero carga las variables de cabecera (D_DsPais=P_DatosBus.DsPais) de la pantalla que son los campos de búsqueda. Lo carga con el contenido que tenga en la estructura; inicialmente serán blancos/ceros pero posteriormente tendrá lo escrito por el usuario.
Después inicializa el subfichero.
Y por último cargará el subfichero. Para ello leerá el componente de acceso a base de datos (Obt_LstPais) (que se encuentra en el programa de servicio con todos los componentes de acceso a BD) con los parámetros para que devuelva el máximo de registros y utilice la selección del campo de búsqueda indicado por el usuario (W_Sel.S_DsPais=P_DatosBus.DsPais). Leerá la tabla de registros devuelta y por cada uno de ellos, generará un registro en la lista.
Presenta la pantalla al usuario y recoge el mandato pulsado por el usuario
Se valida el subfichero y se recoge la selección realizada por el usuario.
Objetivo
Realizar un programa que presenta una ventana de selección (típica consulta de F4 en formato window) donde se podrá un registro para devolver al programa que le ha llamado.
En este ejemplo, se realizará una ventana de selección de países.
En este ejemplo, se realizará una ventana de selección de países.
Configuración
Este programa utilizará un componente de acceso a base de datos de lista de países similar al que se definió en la entrada de acceso a BD a través del uso del programa de servicio que lo contiene .- El nombre del módulo donde esta el ventana de lista de selección BAN40P1
- La definición de la pantalla estará definida como BAN40S1
- Utiliza el programa de servicio BAN01SRV que contiene los componentes de acceso a BD.
- El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
Este ejemplo sirve de plantilla para otro proceso similar.
Fuente de la pantalla. BAN40S1
Se define la pantalla para presentar la lista de registro y para seleccionar un registro.
A DSPSIZ(24 80 *DS3)
A PRINT
A R BAN40S01 SFL
A SFLNXTCHG
A S_OPCION 1A B 8 4VALUES(' ' '1')
A S_DSPAIS 35A O 8 12
A S_IDPAIS 3A O 8 8
A R BAN40C01 SFLCTL(BAN40S01)
A CF03(03 'Salir')
A RTNCSRLOC(*RECNAME ®CUR &CAMCUR)
A OVERLAY
A SFLCSRRRN(&CURS01)
A 40N41 SFLDSP
A N41 SFLDSPCTL
A 41 SFLCLR
A 40N41 SFLEND(*MORE)
A SFLSIZ(0010)
A SFLPAG(0009)
A 61 SFLMSG('Solo se puede seleccionar u-
A n registro' 61)
A WINDOW(BAN40P01)
A CURS01 5S 0H
A NRR 4S 0H SFLRCDNBR(CURSOR)
A CAMCUR 10A H
A REGCUR 10A H
A WKSTNS 10A O 1 30DSPATR(HI)
A 2 3DATE
A EDTCDE(Y)
A DSPATR(HI)
A 2 40USER
A DSPATR(HI)
A D_DSPAIS 25A B 4 10DSPATR(HI)
A 4 4'Pais'
A 7 3'Opc'
A DSPATR(HI)
A DSPATR(UL)
A 7 8'Pais'
A DSPATR(HI)
A DSPATR(UL)
A 5 4'1-Seleccionar'
A 1 18'Lista de paises'
A DSPATR(HI)
A 1 3'BAN40P1'
A DSPATR(HI)
A R BAN40P01
A WINDOW(2 15 20 50)
A WDWBORDER((*DSPATR RI) (*CHAR ' -
A '))
A 18 5'F3-Salir'
A R BAN40R00
A KEEP
A ASSUME
A 5 3' '
Se define:
- El subfichero (BAN4001) con un campo que recogerá la opción (S_OPCION) y donde se presentan los campos de identificación y descripción de país (S_IDPAIS y S_DSPAIS)
- El registro de control (BAN40C01). Tendrá un campo para buscar y para restringir los datos que aparecen en la lista y buscará por descripción de país (D_DSPAIS)
Fuente del proceso. BAN40P1
Se presenta el fuente del modulo que controla la lista de selección (F4). Utilizará el componente de acceso de base de datos similar al que se presento en entradas previas en este blog.
Nota: pondré en color azul lo que debería cambiar en esta plantilla del fuente RPG para hacer un nuevo programa de selección de otra entidad.
Nota: pondré en color azul lo que debería cambiar en esta plantilla del fuente RPG para hacer un nuevo programa de selección de otra entidad.
Definición ficheros y variables
Se define la pantalla de lista para selección y las estructuras de datos que se utilizarán en el programa. Como en todos los fuentes anteriores, se utilizan estructuras de datos para no cambiar las llamadas entre funciones cuando hagamos otro proceso similar; sólo bastaría con cambiar las variables contenidas en las estructura.
*==============================================================
* Plantilla Pantalla de lista seleccion F4 - V1.0 *==============================================================
H DEBUG DECEDIT('0,') DATEDIT(*DMY.)
FBan40S1 CF E WORKSTN USROPN
F INFDS(CURSOR)
F SFILE(Ban40S01:NRR)
D NRR S 4 0
D G_UltReg S 4 0
// Ds de DEFINICION de los campos de busqueda de cabecera
DDs_DatosBus DS QUALIFIED
D TipoOrden 2
D DsPais 25
// Ds de DEFINICION de los campos de seleccion del subfichero
DDs_ClaveSel DS QUALIFIED
D IdPais 3
D DsPais 50
// Ds con la clave seleccionada
D W_ClaveSel Ds LikeDs(Ds_ClaveSel)
// Ds con los datos de busqueda
D W_DatosBus Ds LikeDs(Ds_DatosBus)
Definición de las estructuras de datos
- (Ds_DatosBus). Campos de cabecera de la ventana que sirven para buscar y restringir los datos que aparecen en la lista. Hay un campo fijo siempre que es el tipo de orden (TipoOrden) que servirá para definir la ordenación de la sentencia SQL de lectura y que utilizará para llamar al componente de acceso a base de datos.
En este ejemplo será el nombre de país (DsPais). - Tiene asociada la variable de trabajo (W_DatosBus) que se utilizará en el programa
- (Ds_ClaveSel). Contiene los campos asociados al registro de la lista que ha seleccionado el usuario y que en este caso, se devolverán al programa que le llamó. En este ejemplo el id de país y su nombre (IdPais y DsPais)
- Tiene asociada la variable de trabajo (W_ClaveSel) que se utilizará en el programa
Recursos y definición de prototipos internos.
En esta parte se define recursos comunes y los componentes internos del programa./COPY *LIBL/QRPGLESRC,BAN00VAR
DDsp_CargaDsp PR
D P_DatosBus LikeDs(Ds_DatosBus) Const
DDsp_DatosDspLst PR
D P_Accion Like(WAccActual)
D P_AccionCons 10
DDsp_ObtCab PR
D P_DatosBus LikeDs(Ds_DatosBus)
DDsp_ValidarLst PR
D P_Error n
* Seleccionado
D P_HaySeleccion n
D P_OpcionSel 1
D P_ClaveSel LikeDs(Ds_ClaveSel)
/COPY *LIBL/QRPGLESRC,BAN01M1CP
// Ds de DEFINCICION de los parametros de entrada
DDs_Parametros DS Qualified
D IdPais 3
D DsPais 50
DBan40P1 PR
D P_Parametros LikeDs(Ds_Parametros)
D P_Resultado 3
DBan40P1 PI
D P_Parametros LikeDs(Ds_Parametros)
D P_Resultado 3
La rutina /Copy (BAN00VAR) contiene definición de variables comunes a todos los programas de pantalla. Se detallará en un apartado.
La rutina /Copy (BAN01M1CP) contiene la definición de los componentes de acceso a base de datos. (Ver entrada de componente de acceso a base de datos)
Procedimientos internos
- (Dsp_CargaDsp) Se utilizará para cargar los campos y datos de la ventana
- (Dsp_DatosDspLst) Se utilizará para procesar la lista y obtener la acción realizada por el usuario
- (Dsp_ObtCab) Se utilizará para obtener los campos de cabecera de pantalla (busqueda) rellenados por el usuario
- (Dsp_ValidarLst) Se utilizará para validar las opciones de la lista y recuperar el registro seleccionado por el usuario
Parámetros de entrada.
Se define los parámetros de entrada a este programa. Tendrá siempre un estructura de datos (P_Parametros) y un campo de resultado de la operación (P_Resultado).
La estructura de datos (Ds_Parametros) contiene las variables de entrada/salida al programa. En este caso son dos valores de salida que contiene el id de país y su nombre (IdPais y DsPais) del registro de la lista seleccionado por el usuario
Flujo principal
Se presenta el flujo principal del programa. Es necesario mencionar que es no está escrito linealmente sino que está incluido en un bucle y utiliza una variable (WSitActual) para ir cambiando de estado y para cada estado realiza un grupo de acciones determinado; A la finalización de las acciones de un grupo, la variable cambiará de estado y en el siguiente ciclo realizará otras acciones. Cuando alcance un estado de finalización (CSitFinalizar) terminará el proceso.Si se quiere modificar el flujo de proceso, basta con cambiar el contenido de esta variable al finalizar su grupo de acciones.
Si se desea incluir nuevas acciones, se crearía una nueva situación incluyendo las instrucciones que fuera y al finalizar estas acciones debería cambiar el contenido de la variables de situación para pasar a otro estado. Lógicamente, habría también que cambiar que alguien llamará a este nuevo grupo cambiado la variable de situación.
/FREE
Open Ban40S1;;
WSitActual= CSitCargarDsp;
Clear W_DatosBus;
W_DatosBus.TipoOrden ='2A';
Dow WSitActual<>CSitFinalizar;
Select;
/////////////////////////////////////////////////////
// VISTA: Cargar la pantalla ///////////////////////
/////////////////////////////////////////////////////
When WSitActual = CSitCargarDsp;
Dsp_CargaDsp(W_DatosBus);
WSitActual= CSitShowDatos;
////////////////////////////////////////////////////
// VISTA: Presenta datos de pantalla ///////////////
////////////////////////////////////////////////////
When WSitActual = CSitShowDatos;
Dsp_DatosDspLst (W_Accion : W_AccionCons);
Select;
When W_Accion=CAccSalir;
P_Resultado = CRtnSalir;
WSitActual= CSitFinalizar;
When W_Accion=CAccEnter;
WSitActual = CSitValidar;
EndSl;
////////////////////////////////////////////////////
// VISTA: Valida los datos de pantalla ////////////
/////////////////////////////////////////////////////
When WSitActual = CSitValidar;
Dsp_ValidarLst (W_Error : W_HaySeleccion : W_OpcionSel :
W_ClaveSel);
If Not W_Error;
If W_HaySeleccion;
Select;
When W_OpcionSel='1';
P_Parametros.IdPais = W_ClaveSel.IdPais;
P_Parametros.DsPais = W_ClaveSel.DsPais;
P_Resultado = CRtnConfirmado;
WSitActual = CSitFinalizar;
Other;
WSitActual= CSitShowDatos;
EndSl;
Else;
// Recarga la lista segun la selección
Dsp_ObtCab(W_DatosBus);
WSitActual = CSitCargarDsp;
EndIf;
Else;
WSitActual = CSitShowDatos;
EndIf;
EndSl;
EndDo;
Close Ban40S1;
Eval *InLr=*On;
/END-FREE
Las situaciones por las que esta pasando el programa son constantes definidas en el /Copy común y son las siguientes:
- (CSitCargarDsp). Es la inicial. Realizará la carga de los campos de cabecera de pantalla (búsqueda) y la lista del registros del subfichero.
- (CSitShowDatos). Presenta la pantalla y esperará a que el usuario realice una acción y recogerá el mandato pulsado por el usuario.
Si ha pulsado el mandato de salida (W_Accion=CAccSalir) devolverá al programa que le llamó que no ha hecho nada () y finalizará (P_Resultado = CRtnSalir). En caso contrario, validará la pantalla. - (CSitValidar). Valida el subfichero y si es correcto y el usuario ha seleccionado algo, recoge la selección de registro elegido por el usuario y finaliza devolviéndosela (P_Parametros.IdPais y P_Parametros.DsPais al programa que le llamó e indicándole que ha confirmado (P_Resultado = CRtnConfirmado).
- (CSitFinalizar). Finaliza el proceso.
Componente interno de Carga de pantalla
Realiza la carga de la cabecera de la pantalla y del subfichero,
*=======================================================
* Cargar los datos de la lista
*=======================================================
PDsp_CargaDsp B
DDsp_CargaDsp PI
D P_DatosBus LikeDs(Ds_DatosBus) Const
D W_MaxReg S 10I 0
D W_DatosLst Ds Dim(999) LikeDs(Ds_BasPais)
D W_Sel DS LikeDs(Ds_SelPais)
D W_NumReg S 2 0
D W_TotReg S 10 0
// Paginacion
D W_Pag S 10I 0
D W_NumRegCar S 10I 0
/FREE
// Carga los campos de cabecera de la pantalla
D_DsPais = P_DatosBus.DsPais;
// Inicializa el subfichero
G_UltReg=*Zeros;
Nrr=*Zeros;
*In40=*Off;
*in41=*On;
Write Ban40c01;
*in41=*Off;
W_MaxReg=99;
W_Pag = *Zeros;
W_NumRegCar = *Zeros;
W_Sel.S_DsPais = P_DatosBus.DsPais;
Obt_LstPais(w_DatosLst : W_NumReg : W_TotReg :
W_Pag : W_NumRegCar : P_DatosBus.TipoOrden :
W_Sel);
// Carga la lista del subfichero
DoW G_UltReg<W_NumReg and G_UltReg<=W_Maxreg;
G_UltReg=G_UltReg+1;
S_Opcion = *Blanks;
S_IdPais = W_DatosLst(G_UltReg).IdPais;
S_DsPais = W_DatosLst(G_UltReg).DsPais;
Nrr = G_UltReg;
Write Ban40S01;
EndDo;
// Verificar si ha cargado algun registro para presentarlo
If G_UltReg>=1;
*In40=*On;
Nrr=1;
EndIf;
/END-FREE
P E
Primero carga las variables de cabecera (D_DsPais=P_DatosBus.DsPais) de la pantalla que son los campos de búsqueda. Lo carga con el contenido que tenga en la estructura; inicialmente serán blancos/ceros pero posteriormente tendrá lo escrito por el usuario.
Después inicializa el subfichero.
Y por último cargará el subfichero. Para ello leerá el componente de acceso a base de datos (Obt_LstPais) (que se encuentra en el programa de servicio con todos los componentes de acceso a BD) con los parámetros para que devuelva el máximo de registros y utilice la selección del campo de búsqueda indicado por el usuario (W_Sel.S_DsPais=P_DatosBus.DsPais). Leerá la tabla de registros devuelta y por cada uno de ellos, generará un registro en la lista.
Componente interno de Obtener campos de cabecera
PDsp_ObtCab B
DDsp_ObtCab PI
D P_DatosBus LikeDs(Ds_DatosBus)
/FREE
P_DatosBus.DsPais = D_DsPais;
/END-FREE
P E
Recupera los datos de cabecera seleccionados por el usuario (D_DsPais) y los carga sobre la estructura de datos para búsqueda (P_DatosBus)
Componente interno de Presentar pantalla
Presenta la pantalla al usuario y recoge el mandato pulsado por el usuario
PDsp_DatosDspLst B
DDsp_DatosDspLst PI
D P_Accion Like(WAccActual)
D P_AccionCons 10
/FREE
// Pie de la ventana
Write Ban40P01;
Exfmt Ban40C01;
Select;
When *In03=*On;
P_Accion=CAccSalir;
Other;
P_Accion=CAccEnter;
EndSl;
/END-FREE
P E
Componente interno de Validar pantalla
Se valida el subfichero y se recoge la selección realizada por el usuario.
PDsp_ValidarLst B
DDsp_ValidarLst PI
D P_Error n
* Seleccionado
D P_HaySeleccion n
D P_OpcionSel 1
D P_ClaveSel LikeDs(Ds_ClaveSel)
D WNrr S 4 0
D WNrrSel S 4 0
/FREE
P_HaySeleccion=*Off;
P_Error=*off;
P_ClaveSel=*Zeros;
*In61=*Off;
If Nrr>*Zeros;
// Verifica que no hay errores en la seleccion
WNrr=1;
Chain WNrr Ban40S01;
Dow %Found and Not P_Error;
If S_Opcion<>*Blanks;
If Not P_HaySeleccion;
P_HaySeleccion=*On;
Else;
P_Error=*on;
*In61=*On;
Nrr=WNrr;
Iter;
EndIf;
EndIf;
Update Ban40S01;
WNrr=WNrr+1;
Chain WNrr Ban40S01;
EndDo;
// Comprueba la opcion seleccionada (si la hay)
If Not P_Error and P_HaySeleccion;
WNrr=1;
Chain WNrr Ban40S01;
Dow %Found and Not P_Error;
If S_Opcion<>*blanks;
P_ClaveSel.IdPais = S_IdPais;
P_ClaveSel.DsPais = S_DsPais;
P_OpcionSel = S_Opcion;
S_Opcion = *Blanks;
WNrrSel=WNrr;
Update Ban40S01;
EndIf;
WNrr = WNrr+1;
Chain WNrr Ban40S01;
EndDo;
Nrr = WNrrSel;
EndIf;
EndIf;
/END-FREE
P E
En el proceso se valida que solo se haya seleccionado un registro. Si no hay error, recupera los datos del registro seleccionado (S_IdPais y S_DsPais) y serán los valores que se devolverán al programa que le ha llamado.
// Estructuras y campos de control de pantalla
D Sistema SDS
D Usuario 254 263
D WKSTNS 244 253
D CURSOR DS
D PXCUR 370 371B 0
D PXNRC 378 379B 0
// Constantes de acciones dentro del programa
DWAccActual S 15
D CAccSalir C 'Salir '
D CAccAlta C 'Alta '
D CAccEnter C 'Enter '
D CAccCons C 'ConsultaF4 '
D CAccAnterior C 'Anterior '
D CAccConfirmar C 'Confirmar '
D CPagSig C 'PaginaSig '
// Constantes de posibles situaciones del programa
D W_Accion S Like(WAccActual)
D W_AccionCons S 10
D WSitActual S 15
D CSitCargarDsp C 'Cargar_Dsp '
D CSitFinalizar C 'Finalizar '
D CSitShowDatos C 'ShowDatos '
D CSitValidar C 'Validar '
D CSitAlta C 'Alta '
D CSitRecuperar C 'Recuperar '
D CSitCargarDat C 'Cargar_Datos '
D CSitActualizar C 'Actualizar '
D CSitEnter C 'Enter '
// Constantes de tipos de ejecucion programa
D CEjeAlt C 'Add'
D CEjeMod C 'Upd'
D CEjeBor C 'Dlt'
D CEjeCon C 'Dsp'
* Validacion
D W_Error S n
* Datos seleccionados de la lista
D W_HaySeleccion S n
D W_OpcionSel S 1
** Variables de trabajo
D w_Resultado S 3
D CRtnConfirmado C 'OK'
D CRtnSalir C 'Sal'
Anexo. /Copy BAN00VAR declaraciones generales y comunes
Presenta la pantalla al usuario y recoge el mandato pulsado por el usuario
D Sistema SDS
D Usuario 254 263
D WKSTNS 244 253
D CURSOR DS
D PXCUR 370 371B 0
D PXNRC 378 379B 0
// Constantes de acciones dentro del programa
DWAccActual S 15
D CAccSalir C 'Salir '
D CAccAlta C 'Alta '
D CAccEnter C 'Enter '
D CAccCons C 'ConsultaF4 '
D CAccAnterior C 'Anterior '
D CAccConfirmar C 'Confirmar '
D CPagSig C 'PaginaSig '
// Constantes de posibles situaciones del programa
D W_Accion S Like(WAccActual)
D W_AccionCons S 10
D WSitActual S 15
D CSitCargarDsp C 'Cargar_Dsp '
D CSitFinalizar C 'Finalizar '
D CSitShowDatos C 'ShowDatos '
D CSitValidar C 'Validar '
D CSitAlta C 'Alta '
D CSitRecuperar C 'Recuperar '
D CSitCargarDat C 'Cargar_Datos '
D CSitActualizar C 'Actualizar '
D CSitEnter C 'Enter '
// Constantes de tipos de ejecucion programa
D CEjeAlt C 'Add'
D CEjeMod C 'Upd'
D CEjeBor C 'Dlt'
D CEjeCon C 'Dsp'
* Validacion
D W_Error S n
* Datos seleccionados de la lista
D W_HaySeleccion S n
D W_OpcionSel S 1
** Variables de trabajo
D w_Resultado S 3
D CRtnConfirmado C 'OK'
D CRtnSalir C 'Sal'
Se define para reutilizar en todos los programas de pantalla las siguientes variables que estarán en las diferentes plantillas:
- Estructuras y variables para pantalla
- Constantes de acciones realizadas por el usuario (CAccAlta, CAccSalir etc.)
- Variables y constantes por las que pasa el programa (WSitActual, CSitValidar etc.)
- Constantes de tipo de ejecución para programa mantenimiento (CEjeAlt , CEjeBor etc)
- Constantes de retorno al programa que le llamó (CRtnConfirmado, CRtnSalir etc)
Muy buena explicación y excelentes plantillas de ejemplo para trabajar.
ResponderEliminarMuchas gracias Javier
EliminarExcelente hermano de verdad es mi forma preferida de programar...Gracias
ResponderEliminarMuchas gracias Juan
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminar