Volviendo a mis primeros días con las plataformas de gama media de IBM, el RPG era conocido por ser principalmente un programa generador de informes (aunque la parte de "generador" era demasiado optimista!). Así era cuando la escritura de programas interactivos con RPG era algo funesto a lo que dar forma (el ciclo RPG) aquello era algo que evidentemente no encajaba.

Con bastante esfuerzo, a veces titánico, un poco de tiempo y un par de libros de Shelly Cashman, era posible volver al día que se escribían programas RPG interactivos reparables. Ese código nunca hubiera ganado un concurso del “Código más agradable”, pero sí iba a ser eficiente y efectivo. Una vez amplié mi visión y aprendí otros idiomas de programación, me di cuenta del valor del código expresivo, y obvio - código escrito tanto para un programador de carne y hueso como para un compilador. Por desgracia, incluso con la llegada de ILE RPG a mediados de los 90, RPG persistió como un lenguaje de compilación no muy fácil de usar ni de comprender rápidamente a simple vista. Continuaré diciendo que nuestro viejo amigo “código RPG” es impermeable a ser expresivo y evidente.

Ya sé que voy con retraso, pero hace unos días empecé a trastear el 7.1 Technical Refresh 7.1 de ILE RPG, ese que permite formato libre para las capacidades del RPG. Ha sido una grata sorpresa descubrir bastantes aspectos sintácticos nuevos del lenguaje, pero, por primera vez, estoy escribiendo código RPG que es expresivo y comprensible. Si se escribe RPG para cosas serias, te ves en la obligación de adentrarte en el 7.1 Technical Refresh RPG, lo que cambiará para siempre la manera de escribir RPG, cuando el Refresh no añade ningún gran cambio funcional digno de mención.

En este artículo se presenta un ejemplo de programa RPG que escribí con la sintaxis de formato libre TR 7,1 RPG. Más bien me considero un programador de RPG al que le queda mucho que aprender, así que si ves algo incoherente (¡para lo que tengo un don!), Por favor, hágamelo saber. Eliminé algunas funcionalidades para mantener el código corto, creo que en 191 líneas probablemente estoy jugando con mi suerte. Pero estamos en el año 2015 y, por desgracia, ya no se pueden encontrar muchos artículos como este, así pues, ruego tengan paciencia conmigo. No voy a cubrir cada línea del RPG en detalle en este artículo, pero todo el proyecto, incluyendo el juego de rol, está disponible aquí para su descargadonde podrá seguir viendo el conjunto del proyecto (no es necesario un cliente Git para descargar el código- busque el botón "Descargar ZIP").

Haciéndolo móvil

Pensé en escribir una nueva sintaxis en ILE RPG para la aplicación RPG de ASNA Móvil (MR). Las aplicaciones en HTML5 pensadas principalmente para los Smartphone y las tabletas, también funcionan en los navegadores de escritorio y además son totalmente compatibles con la conectividad de IBM i. La aplicación que se presenta aquí es una pequeña y sencilla aplicación de cliente CRUD, con un poco más de chispa, vamos…un mapa de la dirección del cliente.

La intención de este artículo es doble:

  1. Mostrar TR 7.1 ILE RPG en funcionamiento. El programa completo de RPG muestra más contexto y capacidades que unos pocos fragmentos de RPG aquí o allá.
  2. Mostrar un modelo de RPG que dispone de (use su imaginación aquí) una IU parecida a un panel para una aplicación móvil. Los idiomas móviles son bastante diferentes de los que usábamos en el pasado con las pantallas verdes, pero tal y como verán, MR abstrae de una manera única y permite a los programadores de RPG crear aplicaciones móviles IMB i con nada más que el código RPG.

La pantalla de archivo RPG móvil de ASNA

Antes de meternos a trastear el ILE RPG para éstas aplicaciones móviles, hagamos un pequeño tour por el fichero de MR móvil. Este artículo no pretende ser un ensayo sobre ASNA Mobile RPG (MR) tanto como lo es de ILE RPG (escribí un artículo hace un tiempo que explicaba con más detalles Mobile RPG el cual puede leerse aquí). Mientras se tienen que entender un par de conceptos más sobre Mobile RPG, gracias al IBM Open Access API, hay mucho menos en lo que pensar. Mobile RPG proporciona una IU basada en el diseño de Windows, deja al usuario crear pantallas con formatos de ficheros pregrabados, tal y como se hacía con ficheros de la “vieja escuela”. MR cumple con el tradicional indicador “contract” entre medio del RPG y su fichero de pantalla.

Los tres pasos para crear una aplicación perfectamente capaz de funcionar de ASNA Mobile, se muestran en la figura que sigue a continuación:

Figura 1: Crear una aplicación que funciones de MR, requiere de 3 pasos.

Figure 1 Arriba se sintetizan los 3 pasos para crear una aplicación que funcione con MR Mobile.

Un pequeño detalle para cada paso, como sigue:

  1. Crear la IU mobile. MR ofrece un diseño basado en Windows para la creación de la IU móvil. Incluye todos los elementos de la interfaz de usuario que se esperan encontrar en una interfaz de usuario móvil (incluyendo cuadros de texto, botones, barras de navegación, mapas, tablas de datos, lista de datos, captura de firmas, imágenes y un largo etc.). Una vez creado el archivo de pantalla móvil, se exporta a través de la RM como un objeto tradicional (archivo de pantalla en el IBM i) éste nunca se verá realmente, sino que sólo existe para compilar un programa RPG asociado. Durante esta etapa de exportación, que opcionalmente puede guardar la fuente de archivo de visualización exportada, es útil para fines de aprendizaje ver como los elementos de IU se mapean para los idiomas de RPG.

  2. Escribir un programa de RPG. Este programa proporciona la lógica y el archivo IO para su aplicación móvil. Se compila contra el objeto archivo de pantalla creado por el proceso de exportación en el Paso 1.

  3. Poner en funcionamiento la aplicación. La aplicación móvil MR es una aplicación de base web HTML5 Que funciona en el móvil y en navegadores de escritorio. En tiempo real se interceptan la API Open Access de datos de IBM y los guía hasta la IU de MR. La pantalla tradicional se transforma en el archivo de pantalla móvil, que es transparente, y, en tiempo real, al programa RPG.

Echemos un vistazo más de cerca a los tres paneles de visualización del ejemplo de aplicación (que en realidad surgieron como formatos de registro de archivos de visualización).

La lista del panel móvil

La pantalla inicial para este ejemplo se muestra en la Figura 2A.

 

Figura 2A: la lista mobile en la pantalla, tiene este aspecto.

La pantalla inicial de nombre de formato del panel de lista es CUSTLIST. Ésta es desplazable, y el usuario puede seleccionar una fila de dos maneras: tocando en el nombre del cliente o mediante un toque en la flecha en el extremo derecho de la fila. Esta lista muestra eficazmente lo bien que se adapta a estos simuladores de dispositivos móviles.

Debido a que este es un ejemplo de una aplicación IBM i, se supone que podría estar utilizando un archivo de entrada con una gran cantidad de registros, por lo que el botón "Siguiente" se utiliza para conseguir la siguiente página de filas. Para este ejemplo, seis filas se muestran y la pantalla no es desplazable. Sin embargo, el número de filas que se muestran controladas por una constante en el programa RPG subyacente. A diferencia de una pantalla verde, las aplicaciones necesitan saber para qué van a emplearse, antes de ser concebidas. No es necesario compilar al final de cada secuencia (pero también podría ser razonable para cargar más de lo que estoy cargando aquí).

El diseño móvil RPG se utiliza para asignar teclas de función para el botón y otros elementos de la interfaz de usuario. En este panel, la tecla F3 se asigna a la tecla "Fin" y la tecla F5 se asigna al botón "Siguiente". El nombre de formato de registro para este panel de lista es CUSTINFO.

La lista del cliente en ILE RPG se lleva mucho como una forma muy simple de subarchivo. El subarchivo tiene los siguientes parámetros de configuración:

Descripción Valor
Nombre del subfichero CSTSBF
Nombre del controlador del subfichero CSTCTRL
Clear subfile indicator 99
Nombre del campo del texto principal CSTXT
Largura del texto principal 70
Nombre del campo del texto secundario CSTDTL
Largura del campo del texto secundario 50
Nombre del campo selección CSTSEL
Campo valor CSTVAL
Largura campo valor 30

 

El campo CSTSEL es un campo de un solo carácter que se rellena implícitamente por MR con un '1' cuando se toca la fila. Entonces se utiliza la operación READC RPG para identificar la fila seleccionada. El campo CSTVAL es un campo "oculto" que se utiliza para guardar datos ocultos para una fila. En este caso, el número de cliente se almacena en este campo (de modo que cuando se selecciona una fila, a través de READC, el número de cliente está disponible).

El panel actualizado

El cuadro de actualización móvil, se muestra en la Figura 2B.

 

Figura 2B: El panel de actualización Mobile muestra la información del cliente

El panel de actualización, que es el formato CUSTINFO, se muestra con un toque en el nombre de cliente desde el panel de lista. El usuario puede cambiar cualquiera de los campos presentados y pulsar aceptar o cancelar. Al tocar cualquier botón devuelve al usuario a la pantalla de inicio.

En este panel, la tecla F2 se asigna al botón "Atrás" y el botón "Cancelar", la tecla F8 se asigna al botón "Aceptar".

El panel de mapeo.

El mapa que se visualiza bajo estas líneas provee una funcionalidad de geo-localización.

Figura 2C: El mapa de la pantalla muestra una localización del cliente.

El mapeo del panel, que se muestra con el formato CUSTMAP, se muestra para un cliente cuando se activa el comando en la lista de panel. Un programa ILE RPG proporciona esta lógica aplicaciones móviles, Mobile RPG necesita de un idioma único para proporcionar una dirección del mapa, En este caso, sólo se muestra una dirección, pero Mobile RPG puede mostrar más direcciones.

El control del mapa se nutre de direcciones a través de un subarchivo muy simple de RPG. Este subfichero tiene las siguientes tareas de configuración:

Descripción Valor
Nombre del subfichero MAPSBF
Nombre del sufichero control        MAPCTRL
Clear subfile indicator 99
Address field name Location
Main text field length 60

 

Dando se hace clic en atrás, el usuario vuelve a la lista. Después de exportar los archivos de display, estos tres formatos de grabación se comprimen y el DDS residual del archivo fuente se visualiza (figura 3 abajo). Eche un vistazo y cerciórese que sus campos y subficheros resuelven lo explicado con anterioridad.

0001  A                                      DSPSIZ(27 132 *DS4)
0002  A                                      INDARA
0003   *--------------------------------------------------------
0004  A          R CUSTLIST
0005  A                                      OVERLAY
0006  A            MOREROWS      10A  O  1  2
0007   *--------------------------------------------------------
0008  A          R CUSTINFO
0009  A                                      OVERLAY
0010  A            CUSTKEY       50A  O  1  2
0011  A            CMNAME        40A  B  2  1
0012  A            CMADDR1       35A  B  2 43
0013  A            CMCITY        30A  B  3  1
0014  A            CMSTATE        2A  B  3 33
0015  A            CMPOSTCODE    10A  B  3 37
0016   *--------------------------------------------------------
0017  A          R CUSTMAP
0018  A                                      OVERLAY
0019  A            CMNAME        40A  O  1  2
0020  A            CSZ           60A  O  2  1
0021   *--------------------------------------------------------
0022  A          R CSTSBF                    SFL
0023  A            CSTSEL         1A  H
0024  A            CSTTXT        70A  O  1  5
0025  A            CSTVAL        30A  H
0026  A            CSTDTL        50A  O  3  1
0027   *--------------------------------------------------------
0028  A          R CSTCTRL                   SFLCTL(CSTSBF)
0029  A                                      SFLSIZ(2)
0030  A                                      SFLPAG(1)
0031  A N99                                  SFLDSP
0032  A N99                                  SFLDSPCTL
0033  A  99                                  SFLCLR
0034  A                                      OVERLAY
0035   *--------------------------------------------------------
0036  A          R MAPSBF                    SFL
0037  A            LOCATION      60A  O  1  2
0038   *--------------------------------------------------------
0039  A          R MAPCTRL                   SFLCTL(MAPSBF) 
0040  A                                      SFLSIZ(2)
0041  A                                      SFLPAG(1)
0042  A N99                                  SFLDSP
0043  A N99                                  SFLDSPCTL
0044  A  99                                  SFLCLR
0045  A                                      OVERLAY

Figura 3: Éste DDS fichero de pantalla se genera cuando la IU móvil de MR se exporta como un objeto de fichero de pantalla.

Piense en los objetos de los archivos display como un proxy de IU Mobile, pero al estar en funcionamiento a través del Open Access, se utiliza el archivo de MR Mobile. Repetimos que el proxy de IBM i se compila a nivel de procesamiento interno.

Una vez creado el archivo display de MR y su proxy, pongamos atención a algunas de las partes interesantes de la fuente del ILE RPG. Porque MR hace parecer que no se está creando una aplicación Mobile. El RPG se escribe (puede ser examinado) sin pensar que se esté creando una aplicación móvil. Piense, tan solo, que nos da la fuerza que por medio de 3 sencillos pasos, ir a un formato de display tradicional, (que, por cierto, es exactamente lo que hace)

La Fuente de ILE RPG

La Fuente entera de RPG, que puede verse abajo en la figura 4A y una sola copia en la Figura 4B. Una pequeña explicación del código se puede ver a continuación en las 2 listas:

0001  Ctl-Opt Option(*srcstmt) Dftactgrp(*No) ActGrp('rpmobile');
0002 
0003  Dcl-F smplst WORKSTN Infds(infds)
0004                       Handler('MOBILERPG')
0005                       SFile(CSTSBF:CSTRRN)
0006                       SFile(MAPSBF:CSTRRN);
0007 
0008  Dcl-F CustomerL2 Disk(*ext) Usage(*Input) Keyed
0009                   Rename(RCMMASTER:RCUSTL2);
0010 
0011  Dcl-F CustomerL1 Disk(*ext) Usage(*Update) Keyed
0012                   Rename(RCMMASTER:RCUSTL1);
0013 
0014  Dcl-DS CustL2Key LikeRec(RCUSTL2:*Key);
0015  Dcl-DS TopRow    LikeRec(RCUSTL2:*Key);
0016 
0017  Dcl-S CstRRN   Zoned(4:0);
0018  Dcl-C MAXROWS  Const(6);
0019 
0020  /copy RPMRDATA/QRPGLESRC,KEYMAPF
0021 
0022  Dcl-DS Action Qualified;
0023      Exit           Char(1) Inz(F03);
0024      Cancel         Char(1) Inz(F02);
0025      Back           Char(1) Inz(F02);
0026      ItemTapped     Char(1) Inz(F01);
0027      ChevronTapped  Char(1) Inz(F04);
0028      More           Char(1) Inz(F05);
0029      Backward       Char(1) Inz(F06);
0030      Find           Char(1) Inz(F07);
0031      OK             Char(1) Inz(F08);
0032      Display        Char(1) Inz(F09);
0033      Remove         Char(1) Inz(F10);
0034  End-DS;
0035 
0036  SetLL *LoVal CustomerL2;
0037  LoadCstLst();
0038  ExFmt CUSTLIST;
0039 
0040  Dow ActionRequest <> Action.Exit;
0041      Select;
0042          When CurrentFormat = 'CUSTLIST';
0043               Select;
0044                   When ActionRequest = Action.ItemTapped;
0045                       ReadC CSTSBF;
0046                       If ReadCustById(%INT(CSTVAL));
0047                          // Customer not found.
0048                       EndIf;
0049                       ExFmt CUSTINFO;
0050 
0051                   When ActionRequest = Action.ChevronTapped;
0052                       ReadC CSTSBF;
0053                       If ReadCustById(%INT(CSTVAL));
0054                          // Customer not found.
0055                       EndIf;
0056                       CSZ = %TRIM(CMADDR1) + ', ' +
0057                             %TRIM(CMCITY) + ', ' +
0058                             CMState;
0059                       ShowMap(CSZ);
0060                       ExFmt CUSTMAP;
0061 
0062                    When ActionRequest = Action.More;
0063                       LoadCstLst();
0064                       ExFmt CUSTLIST;
0065 
0066                    Other;
0067                       ExFmt CUSTLIST;
0068               EndSl;
0069 
0070         When CurrentFormat = 'CUSTINFO';
0071              Select;
0072                  When ActionRequest = Action.OK;
0073                      UpdateCust();
0074                      RefreshCustList(CMName:
0075                                      CMCustNo);
0076                      ExFmt CUSTLIST;
0077 
0078                  When ActionRequest = Action.Cancel;
0079                      RefreshCustList(TopRow.CMName:
0080                                      TopRow.CMCustNo);
0081                      ExFmt CUSTLIST;
0082 
0083                  When ActionRequest = Action.Back;
0084                      SetLL *LoVal CustomerL2;
0085                      LoadCstLst();
0086                      ExFmt CUSTLIST;
0087 
0088                  Other;
0089                      SetLL *LoVal CustomerL2;
0090                      LoadCstLst();
0091                      ExFmt CUSTLIST;
0092              EndSl;
0093 
0094         When CurrentFormat = 'CUSTMAP';
0095              Select;
0096                  When ActionRequest = Action.OK OR
0097                       ActionRequest = Action.Back;
0098                      RefreshCustList(CMName:
0099                                      CMCustNo);
0100                      ExFmt CUSTLIST;
0101              EndSl;
0102 
0103      EndSl;
0104  EndDo;
0105 
0106  *InLR = *On;
0107  Return;
0108 
0109  Dcl-Proc UpdateCust;
0110      Update RCustL1;
0111  End-Proc;
0112 
0113  Dcl-Proc LoadCstLst;
0114      Dcl-S RowCount Packed(12:0);
0115 
0116      *IN99 = *On;
0117      Write CSTCTRL;
0118      CstRRN = 0;
0119      RowCount = 0;
0120 
0121      DoW (RowCount < MAXROWS);
0122          Read CustomerL2;
0123          If NOT %EOF;
0124              If RowCount = 0;
0125                  TopRow.CMName = CMName;
0126                  TopRow.CMCustNo = CMCustNo;
0127              EndIf;
0128              RowCount = RowCount + 1;
0129              CstRRN = CstRRN + 1;
0130              CSTSEL = '0';
0131              CSTTXT = CMName;
0132              CSTDTL = %Trim(CMCITY) + ', ' + CMSTATE;
0133              CSTVAL = %CHAR(CMCustNO);
0134              Write CSTSBF;
0135          Else;
0136              Leave;
0137          EndIf;
0138      EndDo;
0139 
0140      *In99 = *Off;
0141      Write CSTCTRL;
0142      PeekForEOF();
0143  End-Proc;
0144 
0145  Dcl-Proc PeekForEOF;
0146      Read CustomerL2;
0147      If NOT %EOF;
0148         Eval MOREROWS = 'More...';
0149         ReadP CustomerL2;
0150      Else;
0151         Eval MOREROWS = 'No More';
0152         SETLL *LOVAL CustomerL2;
0153      EndIf;
0154  End-Proc;
0155 
0156  Dcl-Proc ReadCustById;
0157      Dcl-Pi *N Ind;
0158          CustNo Packed(9:0) CONST;
0159      End-Pi;
0160 
0161      Chain CustNo CustomerL1;
0162      Return %EOF();
0163  End-Proc;
0164 
0165  Dcl-Proc RefreshCustList;
0166      Dcl-Pi *N;
0167          Name Like(CMName);
0168          CustNo Like(CMCustNo);
0169      End-Pi;
0170 
0171      CustL2Key.CMName = Name;
0172      CustL2Key.CMCustNo = CustNo;
0173      SetLL %KDS(CustL2Key) CustomerL2;
0174      LoadCstLst();
0175  End-Proc;
0176 
0177  Dcl-Proc ShowMap;
0178      Dcl-Pi *N;
0179          Address Char(60);
0180      End-Pi;
0181 
0182      *IN99 = *On;
0183      Write MAPCTRL;
0184 
0185      CstRRN = 1;
0186      Location = Address;
0187      Write MAPSBF;
0188 
0189      *In99 = *Off;
0190      Write MAPCTRL;
0191  End-Proc;

Figura 4A. Lista completa de la Fuente ILE RPG.

Narrativa de varios trozos de RPG

Línea 1

Define las opciones del tiempo de compilación para el programa.

Líneas 2 – 12

Declarar el archivo de estación de trabajo y dos archivos de disco (L2 Cliente se teclea el nombre del cliente y número, y L1 Cliente se teclea solamente por el número de cliente). La continuación del archivo de estación de trabajo en la línea 4 registros de este programa RPG con la API de acceso abierto. Se trata de los programas RPG donde se utiliza un archivo de pantalla tradicional.

Líneas 14 – 15

Una característica genial, estas líneas proponen una llave perfectamente capaz de definir unas estructuras de datos para los dos archivos de disco. Estos atajos de una-línea sirve como listas maestras alternativas (facilita el uso al usuario).

Líneas 17 – 18

Estas son 2 variables globales para el programa (usando variables locales en procedimientos que reducen sustancialmente las dependencias globales de variabilidad.)

Línea 20

Incluir los INFDS de copia (de la Figura 4B mostrada abajo) y sus constantes. Esto permite el truco muy de la vieja escuela de interrogar el valor hexadecimal de la posición de la India 369 para determinar qué función (o la clave especial) se presionó. Las posiciones 260-270 también definen e interrogan a la última escritura en formato de archivo de visualización como "Formato de moneda". Este campo es un instrumento para guiar la lógica de este programa. (Dicho sea de paso, me sorprendió al darme cuenta de que, con el RPG móvil y API Open Access de IBM, esta característica estructura INFDS de datos funciona bien! Los datos INFDS fluyen naturalmente en el nuevo en el programa RPG través de Open Access.)

Líneas 22 – 34

Declarar una estructura de datos completo llamado "Acción" que asigna las constantes de teclas de función (vistas en la copia de la figura 4B) a acciones semánticas. Esto permite que el programador no pensar en pulsaciones de teclas de función, pero las acciones sobre el usuario seleccionado (por ejemplo, de una lista chevron haber sido aprovechado). Mi plan a largo plazo para esta estructura de datos es mapear "acciones" reutilizables y genéricas a las teclas de función y luego pasar esa definición al miembro copia Figura 4B. Téngase en cuenta que un par de estas acciones se definen varias veces. Esto es para aquellos momentos en una acción de "Volver" es diferente también semánticamente de una acción "Cancelar" (por ejemplo) pero ambos se implementan con una pulsación de tecla F2. Me sorprendí al encontrar lo que parecía ser conflictos de tipo de palabras clave con algunos nombres de campo en las estructuras de datos de RPG. Por ejemplo, el ILE RPG no tolera en absoluto una acción que se denomina "Siguiente", para mi gran decepción. Es por esto que hay una acción de "Más"; Seguro que sería más fácil si se pudiese leer "Siguiente".

Líneas 36 – 38

Aquí está el código de la línea principal para arrancar el programa. Estas tres líneas pueblan la lista inicial de los clientes. No hay subrutinas en este programa; lo cual se sustituye con los procedimientos. Gracias al formato libre de declaración de procedimientos TR 7.1 ya no es necesario hacer un gran esfuerzo para detectar los fallos en los procedimientos.

Lineas 40 – 104

Este es el bucle principal de este programa. Este bucle es demasiado largo para ser considerado un buen código en el libro de nadie. Aquí se ha sacrificado la calidad del código para obtener la lista fuente un poco más corta y menos complicada de entender de lo meramente necesario.

Líneas 42 – 49

Este es el punto de la narración donde las estructuras completos de datos, cartografía teclas de función a acciones semánticas y el seguimiento automático del formato de registro más reciente, realmente adquiere valor. Si bien es sólo un tramo, el código RPG casi se presenta como tres controladores para tres rutas (los tres formatos de registro), teniendo cada uno al menos una acción. Se puede ver fácilmente que, para el formato CUSTLIST, el programa permite tres acciones: Item Tapped, Chevron roscados, y más. Estas tres acciones (y la acción de salida) son las acciones disponibles en el panel CUSTLIST.

Líneas 46 – 46

Esta línea llama a un procedimiento que acepta un sólo argumento entero y devuelve un valor sin importancia que indica si se ha leído un registro. He dejado el control de errores como un ejercicio para el lector (Eso es por lo general lo que los escritores dicen que no saben cómo hacer algo) En este caso, lo prometo, es minimizar el ejemplo de código).

Lineas 74 – 75

Cuando se muestra el panel CUSTINFO (Figura 4B) y se pulsa el botón “Aceptar”, el programa necesita volver a la lista de clientes (Figura 4), pero también cambiar su posición para la cual el cliente acaba de actualizar. Actualizar CustList es un procedimiento que hace precisamente eso. Se pasa el nombre del cliente y número para poder posicionarse en la lista.

Líneas 113 – 143

Las cargas de procedimiento de prueba hasta el valor constante FILAS MAX de filas en el subarchivo se muestra en la Figura 4A. Tenga en cuenta la RowCount variable se declara a nivel local (por lo tanto, no está disponible para el resto del programa) y no se olvide que los archivos de disco también pueden ser declarados localmente en los procedimientos. De lo contrario no hay mucho RPG aquí de interés, aunque estaría a bien tener en cuenta que este RPG está en realidad completando la lista que se muestra en un teléfono inteligente.

Líneas 156 – 163

El ReadCustById lee un registro de cliente del archivo L1 cliente por número de clientes. Línea 157 declara la interfaz del procedimiento (donde * N es un atajo muy necesario para el nombre del procedimiento). Si un tipo de datos RPG se declara después de la * N, que es el tipo que el procede el retorno, tiene que haber un código de operación de retorno con una variable de ese tipo en el procedimiento para devolver el valor de la persona que llama. Cualquier declaración de variables entre la DCL-Pi y el Fin-Pi define argumentos que deben ser pasados al procedimiento que se requiere. Para los procedimientos simples (los que toman efectivamente el lugar de subrutinas) las declaraciones Dcl-Pi / End-Pi se pueden omitir. Lo visto hasta ahora del código RPG sólo es la punta del iceberg, pero todo sigue los patrones y las explicaciones dadas en la explicación del código.

 

0001  Dcl-Ds Infds;
0002      ActionRequest Char(1)  Pos(369);
0003      CurrentFormat Char(10) Pos(261);
0004  End-Ds;
0005
0006  Dcl-C F01 const(x'31');
0007  Dcl-C F02 const(x'32');
0008  Dcl-C F03 const(x'33');
...
0028  Dcl-C F23 const(x'bb');
0029  Dcl-C F24 const(x'bc');
0030
0031  // Other attention keys
0032  Dcl-C Clear_Key       const(x'bd');
0033  Dcl-C Enter           const(x'f1');
0034  Dcl-C Help            const(x'f3');
0035  Dcl-C PageUp          const(x'f4');
0036  Dcl-C PageDown        const(x'f5');
0037  Dcl-C Print_Key       const(x'f6');
0038  Dcl-C Auto_Enter      const(x'50');

Figura 4B. Miembro externo de la fuente para definir la estructura de datos INFDS y sus constantes.

¡Dele una oportunidad al formato 100% libre!

Este artículo pretende mostrar TR 7,1 de formato libre y el ILE RPG en acción y también que, con ASNA móvil RPG, usted puede usar ILE RPG para trabajar la construcción de un nuevo tipo de aplicación muy poco convencional pero a la vez muy potente para su IBM i. Leer el código desde siempre ha sido mucho más complicado que escribirlo, pero con la última actualización RPG de IBM se eleva sustancialmente la capacidad de escribir RPG de manera legible. Me quito el sombrero ante IBM ya que nos brinda la posibilidad de tener en nuestras manos tan poderosa herramienta. No deje pasar la oportunidad de trastear esta nueva sintaxis. Vale la pena salirse de la zona de confort de la vieja escuela del RPG para adoptar esta nueva sintaxis.

 

 

Recursos para el aprendizaje TR7.1 ILE RPG

Four Reasons RPG Geezers Should Care About The New Free-Form RPG, Jon Paris en la jungla IT (o el resto de cosas que Jon Paris o Susan Ganter hayan escrito acerca de RPG— le animo a que busque en google!)

El blog de Simón Hutchinson RPGPGM.COM