133838291 Rapido 4GL Sistemas

45
Rápido 4GL sistemas, inc. Documentación Técnica Corporativo Normas de codificación manual Progreso documentación técnica Corporativo Normas de codificación manual Progreso Υν προχεσο rápido 4GL Systems, Inc. http://www.fast4gl.com/ 220 White Horse Pike • Audubon, NJ 08106 Teléfono +1 877 327-8445 • Fax +1 609 547-7876 Por: Christopher Schreiber Tabla de contenidos Documento Descripción * Este manual se destina a * Este manual no tiene por objeto * Consideraciones sobre el diseño de base de datos * Definición * Tablas (o archivos) * Los campos (o columnas) * Los índices * Integridad Referencial * Convenciones de nomenclatura * General Convenciones de nomenclatura * Procedimientos * Variables * Reproductores *

Transcript of 133838291 Rapido 4GL Sistemas

Page 1: 133838291 Rapido 4GL Sistemas

Rápido 4GL sistemas, inc.

Documentación Técnica Corporativo

Normas de codificación manual Progreso

documentación técnica Corporativo

Normas de codificación manual Progreso

Υν προχεσο rápido 4GL Systems, Inc.

http://www.fast4gl.com/

220 White Horse Pike • Audubon, NJ 08106

Teléfono +1 877 327-8445 • Fax +1 609 547-7876

Por: Christopher Schreiber

Tabla de contenidos

Documento Descripción *

Este manual se destina a *

Este manual no tiene por objeto *

Consideraciones sobre el diseño de base de datos *

Definición *

Tablas (o archivos) *

Los campos (o columnas) *

Los índices *

Integridad Referencial *

Convenciones de nomenclatura *

General Convenciones de nomenclatura *

Procedimientos *

Variables *

Reproductores *

Page 2: 133838291 Rapido 4GL Sistemas

Marcos *

Buffers *

Arroyos *

Bloques *

Ficheros de trabajo y tablas temporales *

Referencias externas *

Estructura Procedimiento *

Esquema general *

Programa de cabecera *

Variables *

Define Otros *

Formas *

Las rutinas de inicio *

Procedimiento de estilo *

Sangría *

Las declaraciones por línea *

Capitalización *

Las etiquetas de bloque *

Puntuacion *

Comentarios *

Diccionario formatos y etiquetas *

Archivos de inclusión *

Si / Entonces / ventas *

Declaración del caso *

Sale del programa *

Page 3: 133838291 Rapido 4GL Sistemas

Listado de Nombres de campo *

Frase de venta de opciones de formato *

Listado de frases Opciones de marco *

Palabras clave no usar *

Palabras claves que se deben evitar *

Abreviaturas *

Varios *

Marcos *

Transacciones *

Control de errores *

Registro de lectura *

Registro de cierre *

Portabilidad *

Terminales *

Nombres *

Ficheros de trabajo *

Sistemas Operativos *

Color *

Del sistema operativo *

Rendimiento *

Técnicas de codificación *

Multi-Base de datos *

Uso de múltiples bases de datos *

Transacciones Entendimiento *

Descripción de la Operación Alcance *

Page 4: 133838291 Rapido 4GL Sistemas

Ámbito de aplicación por defecto del bloque *

Control de Operaciones *

Sub-transacciones *

Registro de Seguros y ámbito de aplicación *

Registro Esclusas *

Registro Alcance *

Usando XREF y Listados *

Listados *

XREF *

Documento general

Estas son las razones por las cuales el Progreso de codificación manual de normas se ha creado.

Para facilitar la legibilidad del programa Progress y el mantenimiento futuro, es importante identificar y alentar un estilo coherente de codificación. Este documento no pretende abordar todos los temas posibles porque nuestra experiencia nos ha demostrado que cuanto más tiempo la norma es el cumplimiento menos que hay. No esperamos que todos estén de acuerdo con las normas contenidas aquí. Sin embargo, estas son las normas y directrices que provienen de años de la experiencia y no debería perderse de vista, salvo en situaciones de especial.

Ningún documento de esta naturaleza siempre se debe escribir en el vacío. Le alentamos infórmenos de las omisiones y los puntos débiles que podemos hacer los cambios necesarios y ayudar a otros a tener un buen comienzo en sus aplicaciones de Progress.

Este manual se destina a

• Escenografía y programación de las normas para los programadores de Progreso • Proporcionar directrices para el equipo y los líderes de proyecto durante las

revisiones de código

Debe ser una cuestión sencilla de aplicar las normas establecidas aquí para todos los nuevos programas. El objetivo es introducir un estilo de codificación eficientes que permitan mejorar la legibilidad, mantenimiento y rendimiento.

Este manual no pretende

• Enseñe a nadie cómo programar en el Progreso.

Page 5: 133838291 Rapido 4GL Sistemas

Este documento no sugiere ningún tipo o estilo de SmartObjects y programación de interfaz gráfica de usuario en general. El informe abarca el desarrollo de 4GL código y diccionario de datos solamente.

Consideraciones sobre el diseño de base de datos

Adecuada base de datos de diseño y convenciones de nomenclatura son probablemente la parte más importante del proceso de desarrollo de aplicaciones.

Para que el código Progreso para ser fácilmente legible y mantenible, amplia previsión debe ir en el diseño y las convenciones de nomenclatura para la propia base de datos.

Definición

• Exteriores campos clave tiene el mismo nombre de campo como lo hacen en su mesa original.

• Duplicar los nombres de campo no debe utilizarse a menos que una clave externa se define.

• Con el terreno y los nombres de tablas, subraya ("_") guiones ("-") no se debe utilizar para evitar posibles problemas con las implementaciones tercera parte de SQL.

• ayudar a nivel de campo debe ser ingresado.

• Mesa y descripciones de los campos debe ser introducido.

• formatos por defecto de campo se introducen.

• Siempre debe haber un índice único primaria por tabla.

• El campo que se repite la mayoría debería ser el primer componente seguido por la mayoría de repetir siguiente campo. Esto hace la búsqueda mucho más eficaz y ayuda con compresión de índice (nota: el campo más la repetición es aquella cuyo valor cambia por lo menos los más de varios registros!).

• No añadir o eliminar campos / tablas / índices sin llevar a cabo análisis de impacto para anticipar todos los efectos del cambio.

Mesas (o archivos)

• Si se desea la compatibilidad DOS, los nombres de archivo deben ser limitados a 8 caracteres, aunque permite el Progreso 32. Esta restricción se levantó en Construcción versión 6 con la adición de un carácter de 8 "vertedero" de nombre para el diccionario.

• Otra razón para mantener los nombres de archivo corto es que almacena los progresos de estos nombres, literalmente, en el R-compilado el código. Por lo tanto, los nombres largos tienen un impacto directo sobre el tamaño de los códigos R. Esto se aplica también al campo, variable, y los nombres de workfile.

Page 6: 133838291 Rapido 4GL Sistemas

• Utilice archivos de inclusión para la validación supresión diccionario. Esto permite a los criterios de supresión al ser cambiado, aunque una base de datos puede estar siendo utilizado por otros usuarios. Basta con editar el archivo de inclusión y volver a compilar los procedimientos afectados.

Los campos (o columnas)

• Se recomienda que los nombres de campo se limita a 12 caracteres, a pesar de los progresos permite 32.

• Sea consciente de las limitaciones de utilizar el tipo de datos recid. Durante un volcado de datos utilizando EXPORTACIÓN, Progreso convierte el recid al valor desconocido (?). Usando almacenados recid s normalmente requiere que el desarrollador escriba volcado de la costumbre y los procedimientos de carga.

• Para los campos decimales, el número de decimales almacenados debe estar igual o superior al número de decimales muestra en el formato.

• El uso de la SIDE-ETIQUETAS causará campos decimales, mediante el formato de carácter ">" a perder la alineación decimal dependiendo del tamaño del número que se muestra (incluso si el formato es el mismo tamaño). Por lo tanto, el uso de la "z" el formato de caracteres se recomienda.

• Los formatos para tipos de datos lógicos siempre debe tener el formato positivos a la izquierda y el negativo a la derecha. Un formato de "No / Sí" puede provocar problemas graves lógica.

• Para los formatos campo de caracteres, no utilice el "!" y "9" caracteres de formato a menos que un personaje debe ser entrado porque el progreso no permite que un personaje en blanco o no alfabéticos utilizando este formato.

• La longitud de una etiqueta debe limitarse a 14 a fin de que la etiqueta no se truncará cuando se muestran CON COLUMNA 1 o con 2 columnas. Si 3 o 4 columnas se utilizan con frecuencia, la etiqueta no deberá ser superior a 12 caracteres.

• Columna-Las etiquetas deben ser del mismo ancho o menor que el formato del campo para que actúe como una etiqueta de "corto" para los informes apretado y pantallas. Si el espacio en pantalla es limitado no pila de etiquetas de las columnas más de 2 niveles de profundidad.

• Evite usar el valor desconocido (?) Como valor inicial, salvo para las fechas. En los campos numéricos, los cálculos que el valor desconocido suele dar lugar a un resultado desconocido.

Ejemplo

Page 7: 133838291 Rapido 4GL Sistemas

Precio Cantidad UPDATE. / * El usuario entra 5 y? * / ASIGNAR total = Cantidad Precio *. / Total * ahora es igual? * /

• El valor inicial de un campo lógico siempre debe ser sí o no. Considere lo siguiente:

Ejemplo

Formato: N / G Sello: neto o bruto Inicial: N

La "N" en la inicial podría conducir a los no iniciados en la creencia de que el defecto se va por el "Net" cuando en realidad se pondrá por defecto a una lógica n o "G" por "bruto".

• Obligatorio en general debe estar a YES en los campos donde el valor desconocido podría causar un problema. Esto es para prevenir la corrupción lógica de los datos descritos en el ejemplo anterior.

• El progreso no comprueba la sintaxis de una expresión de validación hasta que un procedimiento es compilado que utiliza esa expresión. Cada vez que un valexp inscrito o modificada, a la salida de la prueba diccionario de la validación mediante el uso de:

Ejemplo

INSERTAR cliente.

Esto comprobará la sintaxis de todas las expresiones de validación en el archivo. Asimismo, recuerda que la validación diccionario sólo se aplica a las declaraciones de entrada de datos (UPDATE SET y INMEDIATA-FOR).

Índices

• El índice principal debe ser el índice que se utiliza con mayor frecuencia para recorrer un archivo con una para cada uno, no el índice utilizado principalmente para acceso aleatorio. Esto hará que los datos que sean objeto de dumping en ese orden. Cuando los datos posteriormente se vuelve a cargar en una base de datos nueva, el s recid se asignan secuencialmente a los registros durante la carga. Cuando el índice principal se construye, que se construirá con las referencias a estos recids secuencial. Todos los otros índices para que se construirá con la recids en orden no secuencial.

• componentes de caracteres índice debe ser definido como Abreviar en 'sí' (a menos que el componente no es el último componente del índice). Esto permitirá el uso de un INMEDIATA PARA ENCONTRAR usando la combinación / sin utilizar el COMIENZA función.

Page 8: 133838291 Rapido 4GL Sistemas

• No crear índices que comparten los mismos componentes.

Ejemplo

Índice Índice-A-B Campo, campo-A Campo B-Campo-B Campo-C

Índice-A se considera redundante en este ejemplo, a menos que si Índice-A fue único e índice B-no lo era.

• Se recomienda que los nombres de índice se limita a 12 caracteres.

Integridad Referencial

La integridad referencial significa asegurar que todos los campos claves externas pueden ser resueltos a una entrada válida en un tabla asociada.

Esto implica que cuando estos campos de clave externa se rellenan un cheque debe ser hecho para asegurar la entrada válida existe. Si una entrada se borra, un cheque se deben hacer las inscripciones en cualquier tabla que puede utilizar sus campos como claves externas. Si tales relaciones existen, entonces la supresión debería ser rechazada.

Normalmente las comprobaciones de integridad referencial se debe poner en su lugar cuando:

• es un valor de entrada a un campo de clave externa durante la interacción del usuario

• se escribe una entrada a la base de datos

• una entrada se ha eliminado

La integridad referencial puede realizarse en tres lugares, el diccionario de datos, base de datos activa (crear, buscar, ceder, escritura y borrado) y el código de la aplicación en sí.

Utilice el gatillo SUPR para imponer la integridad y la supresión de auditoría y el gatillo WRITE para la auditoría.

Convenciones de nomenclatura

A raíz de Convenciones de nomenclatura básica aumentará en gran medida la legibilidad del código.

Para facilitar la legibilidad progresos del programa y de mantenimiento futuro, es importante identificar y promover un estilo coherente de codificación. Este documento no pretende abordar todos los temas posibles porque nuestra experiencia nos ha demostrado que cuanto más tiempo la norma es el cumplimiento menos que hay.

Page 9: 133838291 Rapido 4GL Sistemas

No esperamos que todos estén de acuerdo con las normas contenidas aquí. Sin embargo, estas son las normas y directrices que vienen de años de experiencia, no debe ser desviado de, salvo en situaciones especiales.

General Convenciones de nomenclatura

• Todo progreso palabras reservadas deben ser totalmente en mayúsculas. Otras entidades de programación, tales como nombres de variables, se de casos de uso ya sea menor o una mezcla de mayúsculas y minúsculas, como se describe a continuación para distintos casos concretos. Para los casos no se discute más adelante, todo en minúsculas es la opción preferida.

• Los nombres de tablas de campo y comenzará con una letra mayúscula, y se usan minúsculas para el resto de los nombres sola palabra. Para los nombres de palabras múltiples, cada una de las palabras serán separados por el carácter de subrayado ('_') y cada palabra se iniciará con una letra mayúscula.

Procedimientos

• Si compatibilidad con las convenciones Progreso se desea, las extensiones de archivo que sigue al nombre se debe utilizar:

Extensiones de archivo Nombre

. P Procedimiento . I Incluir Archivo . W Ventana

Variables

• Para distinguir las variables de los campos de base de datos, se recomienda que un prefijo o sufijo se utilizará para establecer el nombre real fuera. Esto hace que sea mucho más fácil para el programador de mantenimiento para realizar un seguimiento variables a través de una cadena de procedimientos. Si la variable se define como un campo, el nombre del campo debe estar contenida en el nombre de variable.

Variable de nomenclatura

vDate DEFINE VARIABLE COMO FECHA NO-DESHACER. DEFINE VARIABLE vItem_no Item.Item_no COMO NO-UNDO. DEFINE entrada de parámetros ipUpdate tan lógica NO-UNDO. DEFINE VARIABLE sGLCode COMPARTIDA COMO PERSONAJE NO-UNDO. DEFINE VARIABLE GLOBAL COMPARTIDA gsCompany COMO ENTERO NO-UNDO.

• Debido a que la versión 6 permite la construcción db.file.field, se recomienda que los nombres de base de datos y archivo / amortiguadores ser distintos nombres para evitar confusión sobre database.file y file.field.

Page 10: 133838291 Rapido 4GL Sistemas

Reproductores

• Un número de otros widgets están disponibles en V7 y V8. Las convenciones de nomenclatura de estas deben ser las mismas que para el campo y nombres de archivo pero con un prefijo que indica qué tipo de objeto se refiere. Estos son los siguientes:

Widget de nomenclatura

br Examinar qu consulta cb cuadros combinados ed Caja Editor Activar Caja tg Radio Set rs sl Lista de selección

Ejemplos Widget

CONSULTA PARA DEFINIR quOffice_Header Office_Header.

DEFINE brOffice_Header BUSCAR BÚSQUEDA quOffice_Header PANTALLA Office_Header.Office_Number Office_Header.Office_Type Con el título "Seleccione una Oficina" 8 ABAJO.

cbHist_Date DEFINE variable como formato de fecha "99/99/9999" VER-AS-BOX COMBO LISTA DE TEMAS-04/07/1066, 20/01/1966/27/10/1991.

Marcos

• Al igual que con las variables, nombres de los marcos también debe tener un prefijo o sufijo a prenderlos. Además, el marco debe ser identificado por tipo (locales o compartidos). En conversaciones con varias pantallas, el marco también puede necesitar estar contados.

Marco de nomenclatura

DEFINE MARCO fMain.

Buffers

• Almacenadores intermediarios también deben tener un sufijo / prefijo que se identifique como compartidos o locales. El nombre del archivo base de datos que representa el búfer debe estar contenido en el nombre.

Buffer de nomenclatura

DEFINE BUFFER bCustomer para el cliente.

Page 11: 133838291 Rapido 4GL Sistemas

Arroyos

• Corrientes debería tener un sufijo o prefijo.

Corriente de nomenclatura

DEFINE sReport STREAM.

Bloques

• etiquetas de bloque son para estar en una línea separada por encima del bloque de instrucciones.

Bloque etiquetas

MAIN-LOOP: REPEAT: PANTALLA Customer.Name. END. / * MAIN-LOOP: * /

• etiquetas de bloque debe tener un sufijo o prefijo y dar algunas indicaciones sobre el nivel de anidamiento de la manzana se está etiquetando.

Los nombres de etiqueta de bloque

MAIN-LOOP: REPEAT: / * La interacción del usuario / TRANS-LOOP: / * * Actualización de transacciones / END. / * TRANS-LOOP: * / END. / * MAIN-LOOP: * /

•• bloques con etiqueta debe tener la etiqueta de bloque como un comentario al

lado de la instrucción END para el bloque, incluir los dos puntos en la etiqueta de bloque para una rápida / fácil acceso a la inicial y final del bloque.

Bloque Comentarios Label

MAIN-LOOP: HACER: / * Bloque de código aquí * / END. / * MAIN-LOOP: * /

• El progreso permite etiquetas duplicadas bloque en el mismo acto, sin embargo, esta práctica no se recomienda debido a la posibilidad de confusión.

Ficheros de trabajo y Temp Tablas

Page 12: 133838291 Rapido 4GL Sistemas

• Para distinguir ficheros de trabajo de los campos de base de datos, un prefijo se debe utilizar. Si el workfile representa un archivo de diccionario, el nombre workfile debe contener el nombre del archivo diccionario. Esto hará que sea más fácil localizar al realizar búsquedas de texto.

Workfile y la tabla de nombres Temp

DEFINE ttCustomer TEMP-CUADRO clientes, como el. DEFINE COMO wfCustomer WORKFILE cliente.

• Cuando un índice se compone de un solo campo, el nombre del índice debe ser el mismo que el campo.

• Cuando un índice tiene más de un componente, el índice debería tratar de parafrasear a los campos utilizados en el índice.

Nombramiento de Indices

Nombre del índice: cliente-ord

Índice Cust con-num y Ord campos no.

Referencias externas

• Cuando la producción se dirige a Progreso un archivo ASCII, las convenciones de nomenclatura se aplicarán las siguientes.

• Por razones de portabilidad, el nombre del archivo no debe superar los 8 caracteres con un sufijo de 3 caracteres.

• Para evitar colisiones con otros usuarios que también puede ser la escritura de archivos ASCII en el disco, una de las siguientes convenciones se puede utilizar:

• Escribe al directorio home del usuario o especialmente designados directorio temporal.

• Realiza el nombre del archivo único. Por lo general, la eTime función con un desempate como identificador de usuario es suficiente para evitar conflictos de nombres.

• Utilice un archivo. D sufijo para los ficheros que contienen datos EXPORTACIÓN ed.

Procedimiento Estructura

Siguiendo estas pautas de procedimiento Estructura permitirá ser capaz de rastrear el flujo del programa con mayor facilidad.

Esquema general

El esquema general o el flujo de un programa debe ser el siguiente:

Esquema general

Page 13: 133838291 Rapido 4GL Sistemas

1. Encabezamiento 2. Variables

3. Otras definiciones

4. Formularios

5. Consejo de Procedimiento

6. Punto de salida

Programa de cabecera

El encabezamiento de cada programa se organiza de la siguiente:

Programa de cabecera

1. Nombre del programa 2. Nombre de la aplicación / módulo

3. Ubicación del Programa / Directorio

4. Aviso de Copyright

5. Historia Modificación / Revisiones / Iniciales / Fecha

6. Razones para cada cambio

7. Incluir lista de archivos

8. Archivos de leer (entrada)

9. Archivos por escrito (de salida)

10. Objetivo y descripción general del programa

Variables

Variables deben ser dispuestos en el orden siguiente:

Variables

Todo el sistema incluyen las variables de archivos. Aplicaciones específicas incluyen variables de archivo. nuevas global compartida nuevas para compartir compartido local

Las variables se presentan en orden alfabético para hacer más fácil localizarlos.

Page 14: 133838291 Rapido 4GL Sistemas

• Todas las variables, ficheros de trabajo, y definir los parámetros deben ser definidos como no-deshacer. Todas las excepciones deben ser comentados para evitar cambios futuros que vayan a causar problemas.

• Las variables siempre se define como file.field nombre-siempre que sea apropiado para la auto-documentación y facilidad de mantenimiento. Una posible desventaja es que, al igual que una sesión requiere estar conectado a la base apropiada.

• Las variables no tienen el mismo nombre como un campo de base de datos oa una base de datos (versión 6) para mayor claridad.

• Todos compartían NUEVO / variables compartidas deben ser almacenados en los archivos de inclusión que pasa NUEVO como parámetro en el procedimiento de los que inicialmente definido. Esto facilita el mantenimiento y evitar problemas con los conflictos de tipo de datos, NO-UNDO, ALCANCE, etc

• Cuando las variables que definen todas las opciones de definición debe ajustarse para mejorar la legibilidad.

Variable de alineación

DEFINE VARIABLE vNombre AS carácter de formato "x (10)" LABEL "Nombre" NO UNDO. DEFINE VARIABLE vKey AS INTEGER FORMATO "zz9" NO-UNDO.

• N variables deben ser definidas en una declaración que no sea una declaración DEFINE. El progreso permite la definición de variables en la pantalla, UPDATE, la forma y los datos de otras declaraciones de la manipulación, pero son difíciles de encontrar y mantener cuando DEFINE d de esta manera.

Define Otros

Otras definiciones se describen en el siguiente orden:

Define Otros

1. nueva corriente global compartida 2. corriente compartida nueva

3. corriente compartida

4. corriente

5. búfer compartida nueva

6. compartida de amortiguamiento

Page 15: 133838291 Rapido 4GL Sistemas

7. buffer

8. workfile compartida nueva

9. compartida workfile

10. workfile

11. nuevo marco compartido

12. estructura compartida

13. parámetro de entrada

14. parámetro de salida

15. parámetro de entrada-salida

Formularios

Los formularios serán las definiciones que figuran en el orden siguiente:

Formularios

1. Nuevo marco para compartir archivos incluyen las formas 2. marco compartidas incluyen formas de archivo

3. Incluir archivo de formularios

4. formas locales

• Todas las opciones Frase MARCO asociados con un marco debe aparecer sólo en la declaración FORMA para facilitar el mantenimiento.

• Todas las formas descritas en un programa se debe dar nombres explícitos marco. Esto es particularmente importante cuando se forman s se colocan al inicio de un procedimiento, alcance a la cuadra procedimiento.

Las rutinas de inicio

• Cualquier archivo de inclusión rutinas de inicio, como las partidas de pantalla y los controles de seguridad debe aparecer juntos.

• Variable de inicialización también debería hacerse en esta sección. Punto de salida:

• Todos los procedimientos deben tener un punto de salida común. Normalmente es una instrucción RETURN en la última línea del procedimiento. Un RETORNO cualquier otra parte del procedimiento es similar a una declaración GOTO en otro idioma. La única diferencia es que el regreso sólo puede volver al procedimiento de llamada.

Page 16: 133838291 Rapido 4GL Sistemas

• Este punto de salida también debe ser utilizado para ocultar cualquier marco que no es necesario que sea visible en la de volver al procedimiento de llamada e inicializar las variables compartidas que deben ser.

Procedimiento Estilo

Procedimiento Estilo es única para cada programador. Sin embargo, a raíz de estas sugerencias permitirá a los programas que se escribe para ser más fácil de mantener.

Sangría

• indentación recomendada es de 3 espacios. • Cuando el nivel de bloque de anidamiento llega al punto donde las líneas se

están "rotos" antes de tiempo, 2 sangría espacio está permitido, aunque esto puede ser un síntoma de diseño del programa pobres.

• Todas las declaraciones contenidas dentro de un bloque debe tener una sangría:

Ejemplo sangría

MAIN-BLOCK: Para cada cliente: PANTALLA cliente. ORDEN-BLOCK: Para cada orden WHERE Order.Cust_Num = Customer.Cust_Num NO BLOQUEAR: Orden de presentación. END. / * ORDEN-BLOCK: * / END. / * MAIN-BLOCK: * /

• FIN declaraciones siempre se alineará con la declaración de bloques que están terminando.

Las declaraciones por línea

• Sólo una declaración por línea es permitido para mejorar la legibilidad. • Una declaración no podrá ser prorrogado por el uso de la tilde (~).

Capitalización

• Todo el código será en minúsculas, con excepción de las etiquetas de bloque y el texto dentro de un comentario.

Bloque etiquetas

• Grandes bloques PARA REPETIR y cada uno debe ir precedida de una etiqueta de bloque que se describe la función del bloque.

Page 17: 133838291 Rapido 4GL Sistemas

• La etiqueta debe estar en una línea por sí mismo por encima del encabezado de bloque (véase el ejemplo anterior).

• bloques NO sólo requieren etiquetas cuando se usan para otros fines que no sean declaraciones que agrupa como la definición de un marco nuevo o cambiar el alcance de transacción, o cuando son más de 10-12 líneas.

• Cualquier bloque que está sujeta a una siguiente, deje, o declaración UNDO debe tener una etiqueta de bloque. El siguiente, deje, o una declaración explícita referencia UNDO esa etiqueta.

Puntuacion

• Todas las declaraciones proceso terminará con períodos salvo la etiqueta de bloque y bloque de cabeceras (REPEAT / DE / DO), que se terminan con dos puntos.

Comentarios

• Todas las cabeceras de bloque (PARA CADA / REPEAT) debe ir precedido de un comentario que describe el propósito del bloque, especialmente si ese bloque es un bloque de transacción.

• Todas las declaraciones END para los bloques se deben seguir con un comentario de que "coincide con" el fin de la declaración de encabezado de bloque. Las únicas excepciones serían los bloques que contienen algunas declaraciones muy

Ejemplo Comentarios

/ * Actualización de Documentos del cliente * / CUST-UPDATE-BLOCK: REPEAT: INMEDIATA PARA Customer.Cust_Num. ENCONTRAR cliente USO Customer.Cust_Num. UPDATE cliente CON COLUMNA 1. END. / * CLIENTE-UPDATE-BLOCK: * /

• comentarios de varias líneas deben estar en la forma:

Multi-Line Ejemplo Comentarios

/ * Esta línea es la primera línea de comentarios ** Y esta es la segunda línea * /

• comentarios de una sola línea debe estar en la forma:

Ejemplo de línea única Comentarios

Page 18: 133838291 Rapido 4GL Sistemas

/ * Esta es una línea de un comentario * /

• No hay necesidad de comentar la declaración END:

No hay necesidad de enviar algún comentario de la END

De ser cierto-condición THEN HACER: MENSAJE "True". END.

Diccionario formatos y etiquetas

• Etiquetas, formatos, validación y la ayuda del diccionario se debe utilizar en lugar de reemplazar en el procedimiento.

• Cuando imperiosa etiquetas diccionario, hacerlo en el formulario o declaración MARCO definir si una se utiliza para definir el marco.

• Para las variables especificar ETIQUETA y formato en el FORMULARIO DE DEFINIR o declaración en lugar de en el manejo de datos tales como declaraciones mostrar y actualizar.

• Use LABEL when defining side-labels and COLUMN-LABEL when defining column labels. Keep the width of the COLUMN-LABEL the same as the FORMAT .

Column-Label Example

Pasado Date Last Date Invoiced Last Date Invoiced Invoiced -------- ------------------ --------- 12/31/99 12/31/99 12/31/99

In this example, Last!Date!Invoiced may be the best for the convservation of horizontial space at the cost of one line of vertical space.

Archivos de inclusión

• When overriding dictionary labels, do so on the FORM or DEFINE FRAME statement if one is being used to define the frame.

• Use system include files whenever possible.

• System include files used across multiple applications are located in the "include" directory.

• Application specific include files are located in that application's subdirectory (eg ar/).

Page 19: 133838291 Rapido 4GL Sistemas

• Named parameters rather than positional parameters will be used whenever parameters need to be passed to an include file.

• It is recommended that include files not be nested more than 3 levels deep as debugging can be difficult. Also the "explosion" of the include files seen when using the COMPILE / LISTING option makes the code difficult to read.

• Include file coding style, simple includes:

Simple Include Files

{std-var.i}

• Include file coding style, simple parameters:

Simple Parameter Include Files

{std-var.i &var-type = "NEW"}

• Include file coding style, multiple parameters:

Parámetro de múltiples archivos de inclusión

(Lookup.i Y de nombre de archivo = Cliente Y el chasís-atr = "NO-BOX 2 columnas" Customer.Cust_Num & key = )

• Incluir archivos no deben terminar un bloque empezó fuera del archivo de inclusión. Por el contrario, un archivo de inclusión no debe comenzar un bloque que termina fuera del archivo de inclusión.

• No codificar un nombre de ruta en el archivo de incluir una referencia. PROPATH se puede utilizar (y ajusta dinámicamente según sea necesario) para cambiar los directorios en tiempo de compilación.

• No ponga observaciones en el plazo de llaves incluyen una llamada de archivo, como el compilador tiende a confundirse.

No use los comentarios dentro de un archivo de incluir una referencia

(Lookup.i / * Esto puede volar! * / & Param = "valor" )

Si / Entonces / ventas

Page 20: 133838291 Rapido 4GL Sistemas

• El uso de NO debe ser evitado. Buena prueba de estilo dicta una condición positiva siempre que sea posible. De acuerdo a utilizarse al analizar las funciones lógicas y variables.

• Mezcla de AND y OR condiciones se debe evitar, pero si se utiliza el orden de evaluación deben ser explícitamente indicado a través del uso de paréntesis. Ponga cada condición en una línea separada la alineación y / o s verticalmente.

Mezclados y / o Ejemplo Condiciones

Si es verdad-Y cond1 -Y cierto cond2 (True-O cond3 verdadero-cond4) ENTONCES

• Para un grupo de condiciones relacionadas con AND, la condición más probable (s) debe ser probada por primera vez.

• Para un grupo de condiciones conectadas por OR, la condición más probable (s) debe ser probada por primera vez.

• Every branch of an IF / THEN / ELSE will use a DO block to enclose the code even if there is only one statement. The cost is a slight increase in R-code size. This will prevent errors if other statements are added to the branch later on.

Example of when to use DO: END. with an IF Statement

IF true-condition THEN {include.i}.

If this include file originally had only one statement and more were added later, the new statement would not be conditionally executed. Instead you should use:

IF true-condition THEN HACER: {include.i} END.

• The only exception would be a nested IF / THEN / ELSE when there was only one possible statement.

Example of when not to use DO: END. with an IF Statement

Si la selección = "A" luego en Ejecutar add.p. ELSE Si la selección = "C" ENTONCES change.p RUN. ELSE Si la selección = "D" luego en Ejecutar delete.p.

Page 21: 133838291 Rapido 4GL Sistemas

•• else debe aparecer en líneas independientes, en consonancia

con las declaraciones de IF para que se apliquen.

• Para los ensayos en recintos, alinee el s OR y AND s.

Compuesto Y / O Ejemplo

SI condición AND vBegDate> Y Order.Order_Date vEndDate <Order.Order_Date ENTONCES HACER: / Declaraciones * * / END.

• Al probar los campos lógicos o variables, no utilice TRUE, FALSE, sí, y no para realizar comparaciones debido a la reducción del rendimiento y de mayor código R.

• Use the Progress CASE statement (V7) when ever possible. If it is necessary to use nested IF statements, use the following constructs:

Multiple IF / THEN / ELSE Example

IF condition AND vBegDate > Order.Order_Date AND vEndDate < Order.Order_Date THEN HACER: /* Statements */ END. ELSE IF NOT (condition) THEN HACER: /* Statements */ END.

• The use of "null" THEN s and ELSE s is not allowed.

Null THEN / ELSE Example

IF condition THEN . ELSE.

This code does compile and illustrates what a "null" THEN or ELSE is.

Case Statement

• In Version 7 Progress use the CASE statement, instead of nested IF / THEN / ELSE statements.

Example of the CASE statement

Page 22: 133838291 Rapido 4GL Sistemas

CASE selection WHEN "A" THEN RUN add.p. WHEN "C" THEN RUN change.p. WHEN "D" THEN RUN delete.p. OTHERWISE MESSAGE "Incorrect Selection.". FIN DEL CASO.

Program Exits

• All procedures should have a single exit point. The last statement of every program should be a RETURN and this should be the only RETURN used in a program. To "goto" a RETURN from within the program, use the LEAVE statement.

Example of Program Exits

PRINCIPALES: REPEAT: PROMPT-FOR Customer.Cust_Num. FIND Customer USING Customer.Cust_Num NO-ERROR. IF NOT(AVAILABLE(Customer)) THEN LEAVE MAIN. UPDATE Customer WITH 2 COLUMNS. END. /* MAIN */ RETURN.

Listing Field Names

• All field names should be "qualified" and typed in as filename.field-name. • If common file names are used between multiple databases, the convention

dbname.filename.fieldname should be used.

• Lists of field names in a DISPLAY, UPDATE, FORM, etc. should be shown as follows:

• All names can fit all on one line:

Example of Fields on one line

DISPLAY Customer.Cust_Num Customer.Name.

• Multi-line listing: One field per line indented 3 spaces. Also if the FRAME Phrase is used, it will be aligned with the fields/variables.

Example of Fields on multiple lines

UPDATE Customer.Cust_Num Customer.Name Cliente.Direccion

Page 23: 133838291 Rapido 4GL Sistemas

Customer.Phone CON MARCO fCustFrame.

• Cuando se muestra un subconjunto de una matriz, utilice la siguiente notación:

Ejemplo de uso de una matriz

PANTALLA array [1 DE 5].

Este método es más fácil de leer y mantener que enumerar a cada elemento del arreglo individual.

Frase de venta de opciones de formato

• Cuando el formato de las opciones de frases se utilizan, deben estar alineados verticalmente u horizontalmente.

Ejemplo de las opciones de Formato Frase

UPDATE Customer.Name AYUDA "Introducir el nombre de los clientes ' VALIDAR (NE Customer.Name "," Nombre de cliente debe introducir ") Customer.Contact A 20 AYUDA "Enter Contacto del cliente".

UPDATE vStartDate AL 10 DE AYUDA "Enter Fecha de inicio" vEndDate AT 50 AYUDA "Enter Fecha de finalización"

UPDATE Customer.Name AYUDA "Introducir el nombre de los clientes ' VALIDAR (NE Customer.Name "," Error ") A 20 Customer.Contact AYUDA "Enter Contacto del cliente".

Listado de frases Opciones de marco de

• Organizar opciones de marco de expresión de manera que se evite la colocación de dos números enteros juntos por las diferentes opciones.

Ejemplo de las opciones que se deben evitar frases marco

UPDATE Customer.Name Customer.Phone CON RETENER 1 8 2 2 ABAJO ROW COLUMNAS.

Page 24: 133838291 Rapido 4GL Sistemas

Ejemplo de las opciones de frases marco preferente

UPDATE Customer.Name Customer.Phone Con 2 columnas 8 ABAJO ROW 2 RETENER 1.

Palabras clave no usar

• instrucción STOP: Útil solo para probar. • USE-INDEX option: Essentially hard-codes an index name into a

procedure. Don't use unless knowledge of data distribution shows that Progress' automatic index selection will be incorrect. Should never be used in Version 7 Progress.

Keywords to Avoid

• OF : OF makes code easier to read, but hides the name of the field(s) being used to relate the files together. Ok to use when there are no further qualifications necessary for record selection. Do not use OF and WHERE together.

• ENTERED function: The ENTERED flag is easily cleared by an UNDO , RETRY and could lead to incorrect results.

• RELEASE statement: Use of this statement within a TRANSACTION might indicate a lack of understanding record and/or transaction scope. RELEASE cannot release SHARE-LOCK or EXCLUSIVE-LOCKs within a transaction.

• OR operator: Use in a WHERE clause can negate the efficient use of an index.

Las abreviaturas

• The abbreviation of variables, file and field names is not allowed. • The following keywords should not be abbreviated, because the minimum

allowed abbreviation is too short:

Keywords to NOT Abbreviate

ACCUMULATE DISPONIBLE AVERAGE ALL COLORS (BLACK, BLUE, CYAN, ETC.) BLINK FECHA LUZ NO-VALIDATE PROMPT-FOR RECID

Page 25: 133838291 Rapido 4GL Sistemas

SUB-AVERAGE TRANSACCIÓN DESTACAN

• The following keywords may be abbreviated, but not as much as Progress allows:

Las palabras clave que pueden ser abreviadas

Palabras ANIMALES CARÁCTER CHAR DECIMAL diciembre DESCENDING DESCIENDA ENTERO INT De registro lógico

• Todo progreso compatible con otros abreviaturas se admiten.

Misceláneo

• Duro de codificación de los valores en cualquier programa no se recomienda con las siguientes excepciones: los parámetros pasados a un archivo de inclusión y constantes que no cambia (por ejemplo, 12 meses en un año).

• No hardcode keylabels en un procedimiento.

Ejemplo de codificación Keylabels

MENSAJE "Introducir datos y Pulse" + KBLABEL ("GO").

• S largo mensaje que no caben en una línea debe ser codificada:

Ejemplo de mensajes largos

MENSAJE "Este es un mensaje muy largo que no cabe en una" "Línea en el código.".

• Nota en el ejemplo anterior que la cadena de mensaje se delimita con un espacio en blanco en cada extremo. Esta sugerencia también se refiere al TÍTULO s.

Ejemplo de los títulos

FORMA Customer.Cust_Num Customer.Name Con el título "La información de los clientes 'centrado.

•• Algebraico lógico operadores estilo se prefieren sobre el estilo FORTRAN. De

cualquier estilo es aceptable.

Page 26: 133838291 Rapido 4GL Sistemas

Ejemplo de Operadores

En lugar preferente de a> <b bis NE a <= b bis LE a> b = GE bis un GT bis b> ba una LT <b a = b bis EQ

• Cuando utilice DO MIENTRAS / REPEAT los bucles while, siempre de ensayo de un "menor que" o "mayor que" enfermedad en lugar de "igual a". Esto evita que un bucle infinito si la igualdad "a la" condición nunca se cumple.

Ejemplo de un control aceptable

TEST-BLOCK: NO bien esto es cierto: / * Declaraciones * / SI <= 0 THEN vCounter PRUEBA DE LICENCIA-Block. END. / * TEST-BLOCK * /

Ejemplo de un control Inaceptable

TEST-BLOCK: NO bien esto es cierto: / * Declaraciones * / SI vCounter = 0 THEN PRUEBA DE LICENCIA-Block. END. / * TEST-BLOCK * /

•• carácter de campo TRIM sensibles a espacios a la izquierda (es

decir, ordenar campos).

• Los campos en un comunicado FORMA debe aparecer verticalmente uno por línea para facilitar su mantenimiento.

Ejemplo de un Formulario de Declaración

FORMA Customer.Cust_Num Customer.Name Customer.Phone CENTRADO CON LÍNEA 2.

Ejemplo de una forma inaceptable Declaración

Page 27: 133838291 Rapido 4GL Sistemas

Customer.Cust_Num FORMA Customer.Name Customer.Phone CON CENTRADO.

Marcos

• Los marcos deben ser normalizados mediante el cuadro de defecto o sin caja. Marcos usado para la salida impresa debe usar NO-BOX para recuperar la línea en blanco (y columnas) que asigna el Progreso de la "invisible" cuadro de gráficos en la parte superior del marco.

• Para anchos de marco normalizado de los informes, el uso anchos estándar que contienen los caracteres por pulgada utiliza normalmente en la impresora:

Marco Anchos

10 IPC: 75/125 12 IPC: 90/140 etcétera

• Evite anchos que superan 132 columnas sobre todo porque lo que compromete la capacidad para que un usuario envíe un informe amplio a sus terminales (mediante la instrucción TERMINAL) sin envoltorio. Además, significa que no hay necesidad de apoyar condensada / impresión comprimido para una variedad potencialmente de impresoras.

• Para aprovechar al máximo el papel, pero todavía dejan un margen adecuado, PÁGINA uso talla 60.

Transacciones

• Bloque de cabeceras que definen una transacción explícitamente debe utilizar la palabra clave de transacción para auto-documentación. Esto permitirá que el compilador de captura de transacciones posibles errores.

Control de errores

• A Progress error (eg entering a duplicate key into a unique index) should not send the user back to the beginning of the block which is the Progress default ( UNDO , RETRY ). Instead, more localized DO ON ERROR blocks along with NEXT-PROMPT should be used to keep the cursor on the field where the error occurred.

• The UNDO statement should never be used without a RETRY , NEXT , LEAVE or RETURN even though Progress allows it. Always follow the UNDO with the appropriate action ( NEXT , LEAVE , RETRY , RETURN ) and a label if appropriate. Although Progress allows the use of RETURN , as stated earlier this is to be avoided.

Page 28: 133838291 Rapido 4GL Sistemas

Record Reading

• Always use WHERE instead of OF so that whoever is looking at the code always knows which fields are being used to join files, unless there are no further conditions necessary for record selection. Do not use OF and WHERE together.

Example of Acceptable Record Reading

ORDER-BLOCK: FOR EACH Order WHERE Order.Cust_Num = "1000" NO-LOCK: PANTALLA Order.Cust_Num Order.Ord_Num.

ITEM-BLOCK: FOR EACH Order_Line OF Order NO-LOCK: PANTALLA Order_Line.Order_Line_Num Order_Line.Item_Num. END. /* ITEM-BLOCK: */ END. /* ORDER-BLOCK: */

Example of Unacceptable Record Reading

ORDEN-BLOCK: Para cada orden WHERE Order.Cust_Num = "1000" NO BLOQUEAR: PANTALLA Order.Cust_Num Order.Ord_Num.

ITEM-BLOCK: PARA CADA Order_Line De orden donde Order_Line.Order_Qty> 0 NO BLOQUEAR: PANTALLA Order_Line.Order_Line_Num Order_Line.Item_Num. END. / * PUNTO-BLOCK: * / END. / * ORDEN-BLOCK: * /

Page 29: 133838291 Rapido 4GL Sistemas

• USO se puede utilizar en vez de cuando, debido USO se especifica la clave utilizada.

• Para un buen estilo el lado izquierdo de la comparación en una cláusula WHERE siempre será el campo utilizado para recuperar el registro.

Ejemplo de una cláusula where

ENCONTRAR DONDE Customer.Cust_Num cliente = 10.

En lugar de:

ENCONTRAR DONDE cliente = 10 Customer.Cust_Num.

• Si el nivel de transacción y estructura de soporte que, todos los registros relacionados se deben encontrar en una sola instrucción FOR EACH.

Ejemplo de un compuesto para cada declaración

PARA CADA cliente NO-LOCK, Cada Orden de NO-LOCK WHERE Order.Cust_Num = Customer.Cust_Num, CADA Order_Line NO-LOCK WHERE Order_Line.Order_Num = Order.Ord_Num: END.

•• Cuando hay varias condiciones en la cláusula WHERE, utiliza el

siguiente formulario (tenga en cuenta la sangría):

Ejemplo de múltiples Condición WHERE cláusula

Ejemplo 1:

PARA CADA cliente WHERE Customer.Cust_Num> 10 y Customer.Cust_Num <100 y Customer.State = "MA" NO BLOQUEAR: END.

Ejemplo 2:

NO PARA CADA cliente-LOCK WHERE Customer.Cust_Num> 10 y Customer.Cust_Num <100 y Customer.State = "MA", Cada Orden de NO-LOCK WHERE Y = Order.Cust_Num Customer.Cust_Num

Page 30: 133838291 Rapido 4GL Sistemas

Order.Order_Num> 100 BREAK POR Order.Order_Date POR Customer.Name: END.

• Cuando se recupera uno a uno los registros relación en una instrucción FOR, la CADA se debe utilizar en caso de que el registro no se encuentra. Si hay una posibilidad de que un registro puede faltar, debe ser atrapado usando FIND / NO-ERROR y la función DISPONIBLE.

• Cuando un INMEDIATA PARA va seguido de un buscar, usar NO-ERROR en la instrucción FIND a menos que desee utilizar la opción predeterminada Progreso control de errores (un mensaje de error seguido de UNDO, RETRY del UNDO bloque más cercano). FIND / NO-ERROR siempre será seguida de una prueba con la función DISPONIBLE.

• FIND / NO-WAIT siempre será seguida de una prueba con la función BLOQUEADO.

• El orden de las comparaciones en una cláusula WHERE debe seguir esta jerarquía:

Orden de comparaciones en una cláusula WHERE

1. Los campos del índice utilizado por el FIND / FOR EACH. Las comparaciones deben ser en el mismo orden que los campos se producen en el índice.

2. Los campos de los índices no se utilizan por la FIND / PARA CADA.

3. No reajustables campos.

4. Variables.

5. Expresiones.

• Do not use a FIND statement on a non-unique index or when all of the components of a unique index are not supplied. FIND is designed to retrieve a single record based upon unique index information. Use FIND FIRST / NEXT / PREY / LAST for all other situations.

• Do not use a FOR block when retrieving a single record based upon a one-to-one relationship.

Do Not Use a Join for a one-to-one Relationship

FOR EACH Order_Line: DISPLAY Order_Line.

Page 31: 133838291 Rapido 4GL Sistemas

FOR EACH Item OF Order_Line: DISPLAY Item. END. END.

The use of FOR EACH when retrieving the item misleads one into thinking that the order-line: item relationship is one-to-many rather than one-to-one.

• When testing logical fields or variables in a WHERE clause, explicitly test against the implicit true or false value of the field for R-code and performance reasons.

Registro de bloqueo

• Use NO-LOCK siempre que el estado de la información no es importante (por ejemplo, la mayoría de las investigaciones e informes) para reducir la contención y mejorar el rendimiento.

• Cuando ello sea razonablemente seguro de que un usuario se actualiza un registro existente y que el registro no causará bloqueo contención, leer el acta EXCLUSIVA-LOCK. Esto reducirá las posibilidades de abrazo mortal, así como ofrecer una pequeña ganancia de rendimiento.

• SHARE-LOCK nunca debe ser usado. Con SHARE-LOCK siempre existe la posibilidad de que mortales abrazos, o callejón sin salida, podrían ocurrir.

• Siempre explícitamente el estado de bloqueo. El uso de la opción de inicio-NL es prohibido.

Portabilidad

Dado que los programas El progreso puede ser desplegado en muchas plataformas diferentes, es importante mantener algunos de estos problemas la portabilidad en mente cuando se está programando.

Terminales

• Debido a que existe la posibilidad de que el progreso puede ser ejecutado utilizando los terminales con un número variable de líneas disponibles (25 para DOS, 24 para la mayoría de terminales ASCII), utilice las siguientes funciones para el cálculo de las líneas disponibles y aprovechar al máximo el espacio disponible en pantalla.

Gran fiabilidad y Verificación

LÍNEAS DE PANTALLA- MARCO-DOWN MARCO y el resto del MARCO-LINE

Page 32: 133838291 Rapido 4GL Sistemas

En el marco de la frase:

expresión ABAJO ROW expresión

• La misma situación existe con el espacio y no tener el espacio de toma de terminales. Para aprovechar al máximo el espacio disponible en la pantalla y seguir manteniendo la portabilidad, se recomienda lo siguiente:

• Todos los marcos con la entrada de datos o el uso de atributos de color se utilizará ATTR-espacio en el marco de frases de ese marco.

• Todos los procedimientos serán compilados con la opción-ATTR-ESPACIO opción NO.

Nombres

• If DOS compatibility is needed, the following items will be limited to 8 characters in length.

DOS Limitations

Nombres de archivo Procedure Names Include File Names

• Name suffixes are limited to 3 characters. • The period "." may not be used in the body of the name, but only to separate the

procedure or include name from the suffix.

• All procedure and include file names should be in lower case.

Workfiles

• On 640K DOS machines, there is very little memory available to allocate to local buffer space (the -l parameter). The 64K barrier on local buffer size on DOS machines affects portability when large numbers of workfile records might be created. Because of this, the use of workfiles is discouraged unless both of the following conditions are met:

• The number of workfile records created will remain static or not exceed a predetermined "high water mark".

• The workfile records will not be increased in size during execution of the procedure.

Sistema Operativo

• Use the OPSYS function to shield operating system calls.

Checking for the Operating System Example

Page 33: 133838291 Rapido 4GL Sistemas

CASE OPSYS WHEN "unix" THEN UNIX. WHEN "msdos" THEN DOS. WHEN "vms" THEN VMS. WHEN "btos" THEN BTOS. WHEN "os2" THEN OS2. WHEN "os400" THEN OS400. WHEN "nt" THEN NT. EN OTRO LUGAR MESSAGE "Unknown Operating System:" OPSYS. FIN DEL CASO.

Color

• Utilice el valor de color (color variable) en todas las frases marco. An installation that starts with monochrome monitors and then migrates to color can easily take advantage of the color if the coding is done in this style.

Operating System Specific

• OUTPUT THRU is very useful and powerful, but is not supported on all Progress platforms.

• AUTO-RETURN should never be used.

• When a transaction completes, the user should be informed with a message that the transaction has successfully finished and been committed to the database.

• Warning messages should be preceded with "WARNING:"

• Error messages should be preceded with "ERROR:". This includes the valmsg in the dictionary as well as the second argument of the VALIDATE format phrase option.

• All error messages should be accompanied by an audible BELL .

• Help messages should be preceded with "Enter".

• Because the END-ERROR key has two possible actions that might be taken, the ambiguous nature of the key can confuse users.

Rendimiento

Although Performance is often not the first priority when programming, it is important to keep some of these basic concepts in mind.

Coding Techniques

• CAN-FIND is more efficient than FIND because CAN-FIND only looks at the index (usually 1 I/O operation) where FIND retrieves the entire record (minimum of 2 I/Os).

Page 34: 133838291 Rapido 4GL Sistemas

• For the display of constant data, the construct:

Example of Displaying Constant Data

FORMA "This is a constant string" WITH FRAME fTest. VIEW FRAME fTest.

/* This is more efficient then: */

DISPLAY "This is a constant string".

•• When there are more than 1 assignments next to each other, use the ASSIGN

statement.

Example of the Assign Statement

ASIGNAR vVar1 = vVar2 vVar3 = vVar4.

/* This is more efficient, and produces smaller R-code then ** the following: */

vVar1 = vVar2. vVar3 = vVar4.

• Minimize RUN statements (use include files if possible) and use a fully qualified path name with a RUN statement. Only qualify the path from the top directory of the application to allow flexibility in a development/production environment.

• Minimize calls to the operating system.

• When sharing a record between programs, use SHARED BUFFER s instead of passing a RECID with a shared variable. Exception: when reading the record NO-LOCK in the calling procedure (no transaction active) and re-reading the record EXCLUSIVE-LOCK in the sub-procedure to limit the transaction to the sub-procedure.

• When a variable is changed in a transaction or sub-transaction that variable and all other variables in that procedure are written to the local before image (.lbi) file. To reduce the overhead of this journaling, define variables as NO-UNDO when:

When is use NO-UNDO Variables

1. The variable represents a constant that will never change.

Page 35: 133838291 Rapido 4GL Sistemas

2. The variable is always initialized before it is used.

3. UNDO processing serves no useful purpose.

4. The variable is changed in a loop that an error may not occur in.

• Reading a record NO-LOCK eliminates the need for Progress to check the locking table for a slight performance gain.

• Read records EXCLUSIVE-LOCK instead of the default which is a SHARE-LOCK upgraded to an EXCLUSIVE-LOCK when the record is updated.

• For multiple string comparisons, use CAN-DO , LOOKUP or INDEX versus multiple comparisons OR ed together.

Examples of CAN-DO and LOOKUP

CAN-DO("PA,NJ,DE",vState) /* This is the most effiecent */

LOOKUP(vState,"PA,NJ,DE") <> 0

vState = "PA" OR vState = "NJ" OR vState = "DE" /* Do Not Use */

• Reduce start/stop of transactions in a tight loop (eg batch creation of a large number of records).

Example of Reducing Transactions

INPUT FROM datafile. REPEAT TRANSACTION: REPEAT vCounter = 1 TO 100: CREATE Customer. IMPORT Customer. END. END.

/* Is more efficient then: */

INPUT FROM datafile. REPEAT: CREATE Customer. IMPORT Customer. END.

•• When loading data into a database, use the NO-ECHO option on the INPUT

FROM statement.

Page 36: 133838291 Rapido 4GL Sistemas

• When loading data into the database, use IMPORT (Version 6 and later) rather than SET or UPDATE .

• Only use WORKFILE s for a fixed number of static records Creating WORKFILE records in an unrestricted way can crash the user by running out of local buffer (-l) memory. Also re-sizing existing WORKFILE records is a potential performance inhibitor.

Multi-Database

Working in a Multiple Database environment can bring up some more issues to be concerned about.

Using Multiple Databases

• Do not use the Progress Auto-Connect feature. It can cause unexpected pauses in a procedure as the connection is initiated.

• For modularity, put ail CONNECT logic at the start of the user's session.

• Use NO-ERROR on the CONNECT and test to see if the connection was established using the CONNECTED function.

• Use one CONNECT statement per database. If a multi-database CONNECT fails, all subsequent connections will not be established.

Understanding Transactions

Transactions, and how Progress handles them, are often difficult but yet an important concept for programmers to grasp.

The manner in which Progress handles transactions is one of the unique and powerful features of the 4GL. It is also an area that we tend to struggle with usually because we imagine that the subject is more complex than it is in reality.

This is an important subject, however, as with a little bad planning and careless programming it is possible to adversely and dangerous affect the behavior of your application from both a user interface point of view and a performance and "physical" database point of view.

Transaction Scope Overview

A transaction scope is logical grouping of changes being carried out to data that Progress guarantees will either be committed as a whole or UNDO ne as a whole. Reasons for undoing a transaction will range from a user deciding to abort the current set of changes (pressing F4 for example), to applications errors, to hardware failure.

Page 37: 133838291 Rapido 4GL Sistemas

Each completed transaction is guaranteed to have been written permanently to the database whilst any incomplete transactions will not be written to the database of they are interrupted.

If you are unsure whether a transaction is currently active in your program use the TRANSACTION function which will return true if a transaction is currently active.

Default Block Scop e

Progress code is structured in blocks. These take the form of procedures, triggers, DO blocks (including IF / THEN DO ), FOR EACH and REPEAT . Of these the procedures, triggers, FOR EACH , DO ON ERROR and REPEAT will start a transation if there is a find with an EXCLUSIVE-LOCK in their block.

This meanes that should a change be made to the data or a record found with an exclusive lock within these blocks, a transaction will be scoped to the bounds of those blocks.

DO blocks have weak transaction scoping. If a change to data is made to a DO block then the transaction is scoped to the next outer transaction block.

Ejemplo # 1

REPEAT: /* transaction starts here */ /* some code ....... * / FIND FIRST Order EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Order. /* some code ....... * / END. /*transaction ends here */

Example #2

REPEAT: /* transaction DOES NOT start here */ /* some code ....... * / REPEAT: /* transaction starts here */ FIND FIRST Order EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Order. END. /* transaction ends here */ /* some code ....... * / END. /* repeat */

Ejemplo # 3

REPEAT: /* transaction starts here */ /* some code */ DO WHILE TRUE:

Page 38: 133838291 Rapido 4GL Sistemas

FIND FIRST Order EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Order. END. /* DO WHILE */ /* some code ....... * / END. /*transaction ends here */

Example #4

/* start of a procedure transaction starts here */ FIND FIRST Customer EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Customer. /* Some code */

REPEAT: /* some code.... * / FIND NEXT Order OF Customer EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Order. /* some code.... * / END.

/*end of the procedure transaction ends here */

Controlling Transactions

It is possible to force any block to start a transaction by using the TRANSACTION keyword (note this differs from the TRANSACTION function mentioned above).

This method can be used to both increase and decrease the size of a transaction. Take Example 4 from above:

Example #4

/* start of a procedure transaction starts here */ DO TRANSACTION: /* Transaction starts here */ FIND FIRST Customer EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Customer. /* Some code */ END. /* Transaction ends here */

/* some code */

REPEAT: /* some code.... * / DO TRANSACTION: /* Another Transaction starts here */

Page 39: 133838291 Rapido 4GL Sistemas

FIND NEXT Order OF Customer EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Check locked status ....... * / UPDATE Order. /* some code.... * / END. /* Second Transaction ends here */ END.

/*end of the procedure */

The transactions in this example have now been scoped in a much more granular fashion.

You may want to increase the scope of a transaction boundary:

Example #5

DO TRANSACTION: /* Transaction starts here */ FOR EACH Order EXCLUSIVE-LOCK: DELETE Order. END. END. /* Transaction End */

If a system crash occurs here none of the Order records will be deleted. Of course this scenario also holds locks on all the records until the end of the transaction.

Sub-transactions

With Progress it is only possible to have one active transaction at a time. If a transaction block becomes part of an existing transaction it will form a sub-transaction.

Sub-transactions can be used to UNDO parts of a transaction, however, the changes made in a sub-transaction do not get committed until the end of the main transaction.

One of the most common ways of starting a sub-transaction is by calling another procedure whilst a transaction is active.

Example #6

DO TRANSACTION ON ERROR UNDO, RETRY: /* transaction starts here */ IF RETRY THEN MESSAGE "You've undone your customer changes as well." IF NOT CAN-FIND Customer OF WHERE Customer-Name = "Test") THEN RUN newcust.p. FIND FIRST Order EXCLUSIVE-LOCK. UPDATE Order WITH 2 COLUMN. END.

Page 40: 133838291 Rapido 4GL Sistemas

/**** newcust.p ***** /* Program to add a new customer */

/* some code */

DO TRANSACTION ON-ERROR UNDO, LEAVE: /* start a sub transaction */ FIND FIRST Customer EXCLUSIVE-LOCK. UPDATE Customer WITH 2 COLUMNS. END. /* end a sub transaction */

The program newcust.p may not be expecting to be called within another transaction. Any update made in newcust.p can be rolled back in the calling routine if the user presses F4.

Another side effect of this scenario is that a lock will be maintained on the Customer record until the end of the main transaction in the calling procedure.

Record Locks and Scope

Understanding Record Locking and Record Scope are essential in order to produce an effective program design.

Record Locks

Progress has row-level locking. This means it locks individual records at a time (as opposed to pages or tables).

Two types of lock are supported, they are the SHARE-LOCK and the EXCLUSIVE-LOCK . In addition, Progress can read records with NO-LOCK .

A SHARE-LOCK allows a record to be read by more than one user so long as that record is not being modified. A SHARE-LOCK gets upgraded to an EXCLUSIVE-LOCK if the modification on that record begins.

An EXCLUSIVE-LOCK prevents any other user modifying or placing a SHARE-LOCK on a record.

NO-LOCK allows the record to be read no matter what state another user has it in. It cannot however be modified. NO-LOCK allows dirty reads. In other words, the data that is being read may not have been committed to the database.

The Progress default for a record is SHARE-LOCK as this provides the user with the most protection. However, this option is not recommended unless absolutely required. In general, the developer should know what is going to happen to the record and read it with a NO-LOCK or an EXCLUSIVE-LOCK .

Page 41: 133838291 Rapido 4GL Sistemas

Record Scope

This subject relates to how long information in a Progress record buffer remains active and by association how long Progress keeps a lock on the record.

Record locks are held for the longest of the transaction scope or record buffer scope. It is possible for a record buffer to have a wider scope that the transaction scope.

Locks are held on a record not a buffer (remember it is possible to have multiple buffers pointing to one record).

Example #7

FIND FIRST Customer. /* Some code */

DO TRANSACTION: /* transaction start */ UPDATE Customer WITH 2 COLUMNS. END. /* transaction end */

/* Some code */ PAUSE.

The record buffer spans the whole of this procedure, including the PAUSE statement. The first FIND will instigate a SHARE-LOCK on the customer record.

When the DO TRANSACTION is encountered the SHARE-LOCK gets upgraded to an EXCLUSIVE-LOCK . At the end of the transaction the changes to the record are committed and the lock on the record is down graded to a SHARED-LOCK .

Example #8

FIND FIRST Customer NO-LOCK. /* Some code */

DO TRANSACTION: /* transaction starts */ FIND FIRST Customer EXCLUSIVE-LOCK. UPDATE Customer WITH 2 COLUMNS. END. /*SHARE-LOCK on Customer record is active */

Note that in the above example the lock status after the end of the transaction is still SHARE-LOCK . In other words, the record can only be read not modified by another user in this state.

Note that finding another record in the same table will release the SHARE-LOCK .

The RELEASE statement can also be used to clear out a record buffer and release the locks on that record at the end of the transaction.

Page 42: 133838291 Rapido 4GL Sistemas

Example #9

FIND FIRST Customer NO-LOCK. /* Some code */

DO TRANSACTION: /* transaction start */ FIND FIRST Customer EXCLUSIVE-LOCK. UPDATE Customer WITH 2 COLUMNS. RELEASE Customer. END. /* transaction end, No more locks held */

/* Some code */ PAUSE.

In this example the lock is released at the end of the transaction but the Customer buffer is no longer available.

RELEASE is a bit of a cop-out indicating a failure to properly control your record and transaction scopes. In addition it behaves differently if it is used in a sub-procedure that has been called within an existing record scope. In this case the lock is not released but downgraded to a SHARE-LOCK at the end of the procedure.

Finally, it is possible to narrow (or increase) the scope of your record by using the DO FOR tablename construct. This strongly scopes the record to the block. No references to the buffer can be made outside the block without a subsequent FIND .

Example #10

DO TRANSACTION: /* transaction start */ FIND FAST Customer EXCLUSIVE-LOCK. UPDATE Customer WITH 2 COLUMNS. RELEASE Customer. END. /* transaction end, No more locks held */

IF AVAILABLE Customer THEN MESSAGE "Customer record is available"

The free reference to Customer outside the transaction boundary effectively increase the scope of that record (but not the transaction).

The following example ensures that the record is not available outside the bounds of the transaction. In fact, it should not compile .

Example #11

DO FOR Customer TRANSACTION: /* transaction start *? FIND FIRST Customer EXCLUSIVE-LOCK. UPDATE Customer WITH 2 COLUMNS.

Page 43: 133838291 Rapido 4GL Sistemas

RELEASE Customer. END. /* transaction end, No more locks held */

IF AVAILABLE Customer THEN MESSAGE "Customer record is available".

Using XREF and Listings

Using the Progress XREF and Listings compiler options can give invaluable insight into a program and are often useful in debugging.

When a program has been completed, it should be compiled to produce two extra files. These are the LISTING file and the XREF (cross-reference) file. These files contain vital information, which will help ensure that your programs behave as expected. Use these files to help with unit testing and code reviews.

Listados

The listing file expands include files and numbers the program lines by block. At the end of the listing is a summary of each block within the procedure, the procedure itself being the main block.

The record buffers and transaction that are scoped to the block are shown, as are the frame scopes.

Use the COMPILE filename.p LISTING filename.lst option form the PROGRESS editor of the Compile option in the Application Compiler to produce the output file.

Example Listing

1 showlist.p 2 3 {} Line Blk 4 -- ---- --- 5 1 1 DO FOR Account: 6 2 2 DO TRANSACTION: /* start of a transaction */ 7 3 2 FIND FIRST account EXCLUSIVE-LOCK 8 4 2 MESSAGE TRANSACTION. /* "yes" or "no" */ 9 5 2 PAUSE. 10 6 1 END. 11 7 1 12 8 2 REPEAT: /* start of a transaction */ 13 9 2 FIND FIRST policy_header EXCLUSIVE-LOCK. 14 10 2 LEAVE. 15 11 1 END. 16 12 1 17 13 1 /* shows the transaction is complete */ 18 14 1 MESSAGE TRANSACTION.

Page 44: 133838291 Rapido 4GL Sistemas

19 15 1 PAUSE 20 16 END. /* DO FOR Account */ 21 23 File Name Line Blk Type Tran Blk. Etiqueta 24 ---------- ---- ------------ ---- ------------------- 25 showlist.p 0 Procedure No 26 showlist.p 1 Do No 27 Buffers: policypl.Account 28 29 showlist.p 2 Do Yes 30 showlist.p 8 Repeat Yes 31 Buffers:policypl.Office_Header 32

Each block start has been highlighted along with the lines of interest at the bottom of the report.

The above listing shows that the record buffer for Account is scoped to the outer DO FOR Account: block. That there is no transaction scoped to this block. The inner DO TRANSACTION block has a transaction scoped to it.

The REPEAT block has both a record buffer (Office_Header) and a transaction scoped to it.

XREF

The cross reference compile option writes cross reference information between procedures and PROGRESS objects, including procedures, include files, tables, fields indices, variables frames and character strings.

Developers must use this facility to check the efficiency of their queries. Whenever a query is used, a SEARCH entry will be made in the XREF file. This is followed by the table name and the name of the index used to resolve the query. If the query is unbracketed (ie there are no criteria given to narrow down the search) or PROGRESS is unable to use an index to resolve the query then the phrase WHOLE-INDEX appears after the index name.

In the latter instance, the index name is the primary index, which only gives the order in which the records are returned. The rest of the query will be resolved by searching through the whole table. This scenario should be avoided.

Example Xref Program

FIND FIRST Account NO-LOCK. /* unbracketed search - no conditions */

/* this next one is bracketed by a non-indexed field */ FIND FIRST Office_Header. WHERE Office_Header.Effective_Date = TODAY NO-LOCK

Page 45: 133838291 Rapido 4GL Sistemas

/* this one is bracketed by a field indexed using a 2nd index */ FIND FIRST Office_Header. WHERE Office_Header.Account_No = Account.Account_No NO-LOCK.

This produces a number of lines, for index usage look for lines with SEARCH in them. As these XREF lines show:

Example Xref Output

Showref.p showxref.p 1 COMPILE showxref.p Showref.p showxref.p 1 SEARCH Account main_key WHOLE-INDEX Showref.p showxref.p 3 SEARCH Office_Header main_key WHOLE-INDEX Showref.p showxref.p 6 SEARCH Office_Header account

The second line relates to the unbracketed FIND statement, this is a valid scenario.

The third line shows a bracketed search (using Effective_Date) that cannot be resolved using an index. The primary index name (main_key) indicates the order in which the records will be returned and the WHOLE-INDEX phrases indicates that the whole table will have to be searched to resolve this query. This should be considered a bug as it will cause severe performance problems.

The final highlighted line shows a bracketed query that has been resolved using an index (account). This index was inspected and looks suitable as Account_no (the bracketing field) is also the first component in that index.