28 de junio de 2017

Múltiples bandas de detalle en informes (2)

La necesidad de obtener informes con múltiples bandas de detalle en informes de Visual FoxPro, es tan antigua como la propia herramienta. Pero hasta ahora no contábamos con facilidades para lograr el resultado esperado por los usuarios sin que nos representara un dolor de cabeza.

Hace unos días, escribí sobre este tema. (Múltiples bandas de detalle en informes (1)). Luego de haber adquirido un poco más de experiencia, me decido a revisar un poco el tema, para complementar algunos de sus aspectos.

¿Qué ocurría antes de VFP 9.0?

Pues, lo podíamos lograr. Pero no era nativo y había que recurrir a procesos que si bien, eran posibles, también eran complejos. Se trataba, en pocas palabras, de crear un cursor con los campos necesarios a mostrar en cada banda y algún o algunos campos adicionales, que controlaban que los datos fueran agrupados correctamente en bandas.

Dentro del Diseñador de informes, la tarea consistía en crear dentro de la única banda de detalle existente, tantos grupos de campos a mostrar como bandas finales necesitamos. En este caso, al ver el diseñador, teníamos campos superpuestos y resultaba bien difícil, como ya dije, era complejo; pero era posible. Felizmente ahora este proceder es nativo.

Múltiples bandas de detalle

Contar con la posibilidad de crear múltiples bandas de detalle es una de las mejoras más importantes y más solicitadas. A partir de VFP 9.0 es posible procesar múltiples tablas hijas para cada registro de la tabla padre. Existen posibilidades ilimitadas de lo que se puede hacer con esta nueva característica. Veamos como se controla el procesamiento de registros.

Procesamiento de registros

El informe tiene un cursor conductor - este cursor se procesa una única vez. El procesamiento de sus registros se pausa por los cambios diseñados en los grupos. Entonces el motor de informes deja de moverse por el cursor conductor y realiza las acciones pertinentes, ejemplo escribe el pie de grupo para el grupo que termina y el encabezado de grupo para el siguiente grupo y luego continúa procesando el cursor. Se admiten encabezados y pies para bandas de detalle. Son similares a los encabezados y pies de grupos en alguna medida, tienen algunas diferencias.

Para cada registro padre que se procesa, ocurre lo siguiente:

  • Se procesa el encabezado de la banda 1.
  • Se procesa el detalle de la banda 1 una vez para cada registro hijo en el alias destino asociado.
  • Se procesa el pie de la banda 1.
  • Se procesa el encabezado de la banda n
  • Se procesa el detalle de la banda n una vez para cada registro hijo en el alias destino asociado.
  • Se procesa el pie de la banda n.

Donde,

Expresión del Alias destino - es el término utilizado para describir qué tabla es la tabla conductora para una banda de detalle en particular.

Definir multibandas - De forma predeterminada los informes se crean con una sola banda de detalle. Se pueden adicionar bandas desde el diálogo Bandas Opcionales incrementando el valor dentro del control Spinner (hasta 20). Luego, hay que definir el alias para cada banda, este aspecto lo veremos con detenimiento. Al aumentar un número aparece una nueva banda de detalle y al disminuir uno se elimina la banda con mayor número (la última en haber sido creada)

El trabajo multibandas nos ofrece nuevas posibilidades; pero nos exige ser mucho más cuidadosos, porque ahora en cada banda no estará la tabla padre sino una de las hijas, y hay que definir el nombre del alias en el cuadro de texto Expresión del Alias destino (Target alias expresion,) del Cuadro de diálogo Propiedades de la banda de detalle (Detail band propierties). En caso de estar trabajando con una sola banda, pues no pasa nada si la dejamos en blanco, toma la tabla padre que será justo lo que deseamos.

El cuadro de diálogo Detalles contiene las propiedades de la banda de Detalles.

Alias destino (Target alias) - Es el alias que se recorre en la banda donde se encuentra. Es una expresión. Debe ir entre comillas, para que evalúe la expresión y obtenga los valores existentes en el Alias indicado. Si no se ponen las comillas, se entiende que es una expresión, por ejemplo Clientes, pudiendo ser una variable, o un campo que contiene el nombre del alias que se obtiene en tiempo de ejecución. Este nombre va a aparecer en la barra gris que define la banda. Se recomienda definir los campos incluyendo el nombre del alias para evitar confusiones. El tipo de alias dependerá del contenido que se quiera mostrar.

Nueva función para cláusula SUMMARY - Elimina toda la información de las bandas, incluyendo su detalle, encabezado y pie de banda. Si existen expresiones a evaluar en al entrar y al salir de alguna banda no se van a ejecutar con la cláusula SUMMARY. Por otra parte no elimina los encabezados y pies de grupos que se hayan definido y sus expresiones a evaluar para en al entrar y al salir del grupo sí se van a evaluar.

Las variables y expresiones calculadas en el informe adquieren una nueva dimensión, Reset based on, en la ficha Variables de la ventana Propiedades indica que se deben procesar los registros de la tabla hija y no se limpia hasta que no termine el informe, lo que permite realizar cálculos y combinaciones entre las bandas utilizando valores calculados de unas en otras. Al seleccionar un número de banda específica, VFP procesa el cálculo solamente durante el proceso de esa banda. Si se escoge más de un sitio, pues se procesa mientras duren las bandas seleccionadas.

Diferencias entre las Bandas de Detalles y las Agrupaciones de Datos (Data Grouping)

Sirven para mostrar diferentes tipos de relaciones entre los datos. Las múltiples bandas de detalle sirven para mostrar diferentes datos de tablas hijas de una tabla principal que no estén relacionadas entre sí. Mientras, las agrupaciones de datos, permiten, agrupar datos por diferentes criterios a partir de tablas relacionadas entre sí con índices creados y activos en ese momento.

Bandas de Detalles Agrupaciones de Datos
No se anidan, son consecutivas Se pueden anidar
No se crean subgrupos dentro de ellas Se crean subgrupos
No dependen del alias (target alias). Se pueden mostrar independientemente de si existan o no registros que cumplan las condiciones en esa banda, por tanto pueden existir sin que haya banda de detalle asociado. Dependen del alias (target alias) que se le indique. No se muestran si no existe al menos un registro en la banda detalle de ese grupo
Su límite máximo es de 20 bandas Su límite máximo es de 74 bandas
Su límite mínimo es una banda Su límite mínimo es cero bandas
Cuando termina una banda, si existe otra banda de detalle el puntero se mueve nuevamente al inicio del alias actual Cuando acaba un grupo, el puntero se mueve al siguiente registro
La expresión para el alcance de una banda de detalle (target alias) se limita a una expresión que de nombre a una tabla abierta en la sesión de datos actual No existe límite para la creación de una expresión que defina el alcance de un grupo

Diferencias entre los encabezados y pies de Bandas de Detalle y los encabezados y pies de Bandas de Grupos

Encabezados y pies de Bandas de Detalle Encabezados y pies de Bandas de Grupos
Se pueden mostrar los encabezados y pie de banda (son opcionales). Si existen, se muestran incluso cuando no hay datos, por ejemplo que no haya coincidencia entre la tabla padre y la hija. Si no se desea imprimir el encabezado de la banda de detalle en este caso, debe utilizar una expresión del tipo NOT EOF(<target alias>) en Imprimir cuando (Print When) Si no hay elemento de agrupación en la selección, no se puede mostrar encabezado y/o pie para él, debido a que no existe tampoco el grupo como tal. Tiene que existir algún elemento, incluso si no se desea imprimir el detalle y se emplea la cláusula SUMMARY en el comando REPORT FORM, que se encarga de eliminarla.
La cláusula SUMMARY en el comando REPORT FORM, elimina todas las bandas de detalle, así como sus correspondientes encabezados y pies. La cláusula SUMMARY en el comando REPORT FORM, NO elimina los encabezados y pies de las bandas de grupo.
Si se incluye la cláusula SUMMARY, NO se ejecutan los eventos OnEntry / OnExit. Aunque se incluya la cláusula SUMMARY, los eventos OnEntry / OnExit SIEMPRE se ejecutan.

Los encabezados y pies de ambos tipos de bandas tienen características similares, por ejemplo la evaluación de su contenido y el código colocado en sus eventos OnEntry y OnExit ocurren en el mismo momento.

Variables y Cálculos del informe

Con la introducción de las múltiples bandas de detalle, las variables y cálculos del informe tienen algunas peculiaridades. Es necesario entender completamente como se procesan para utilizarlas con eficiencia. De otro modo, puede obtener resultados inesperados.

El cuadro desplegable Reiniciar basado en (Reset value based on) que vemos en el cuadro de diálogo Variables del informe determina que la variable se reinicia basada en los cambios del valor de la opción seleccionada. Si se define en el informe más de una banda, cada banda de detalle se agrega al cuadro desplegable.

Al seleccionar una Banda de detalle en particular se procesa este cálculo sólo para los registros del target alias de esta banda de detalle. La variable de informe no se altera mientras se procesan los registros en otros alias. Esto permite asociar una variable de informe para una banda de detalle en particular. El valor de la variable no se limpia hasta que el encabezado de esa misma banda de detalle se procesa para el siguiente registro de la tabla padre.

Si selecciona otro valor en Reiniciar en base a diferente a una banda de detalle, el cálculo se procesa en varios lugares. Primero, se aplica el cálculo para cada registro padre. Segundo, se aplica para cada registro en el alias destino de la primera banda de detalle. Luego, se aplica el cálculo para cada registro en el alias destino de la segunda banda de detalle, etc.

Informes sencillos

Un informe sencillo con múltiples bandas de detalle consiste en una tabla padre que conduce el informe y dos o más tablas hijas que están relacionadas con la tabla padre.

Un ejemplo de este caso, lo podemos ver en el panel Solutions, al que accedemos desde Menú - Herramientas - Administrador del panel de Tareas. A los ejemplos Solutions también se puede acceder desde la ventana de comandos

DO (HOME(2)+"Solution\Solution") 

Entonces, buscamos en el panel Solutions Samples, abrimos el árbol - New in Visual FoxPro 9.0 y buscamos "The typical multiple detail band report"

El aspecto del informe visto desde el Diseñador es el que se muestra en la siguiente figura. En ella se aprecian dos bandas de detalle asociadas a dos alias diferentes, agrupadas a su vez a nivel de la tabla principal, padre o conductora del informe. El resultado en este caso es un informe donde para cada Employee.EmployeeID se van a mostrar los datos que están almacenados en los alias employeeterritories y orders.

Cálculos (sum / count)

Un informe con múltiples bandas de detalle no necesariamente necesita tener múltiples tablas hijas. La misma tabla hija puede ser utilizada en más de una banda de detalle.

Por ejemplo para obtener Totales de grupos, antes de VFP 90, era muy difícil imprimir subtotales en la banda encabezado de grupo. El dato tenía que ser procesado previamente para calcular los totales antes de ejecutar el informe. Con VFP90, no se requiere procesamiento previo. Para ello la idea es crear bandas múltiples de detalle.

En la banda de detalle 1, TargetAlias = tabla hija. Una variante puede ser, marcar bandas de encabezado y pie y no colocar nada en la banda de detalle. En la banda pie para la banda de detalle 1, podemos agregar etiquetas y campos que serán calculados. Para ellos, en la ficha Cálculos de la ventana Propiedades, estableceremos: Iniciar basado en (Reset based on) Banda de detalle 1.

En la banda de detalle 2 TargetAlias = tabla hija, se marcan bandas de encabezado y pie y se agrega cualquier otro dato necesario a la banda de detalle 2.

La definición de informe descrita anteriormente, dice al Generador de informes de VFP 9.0, que procese dos veces la tabla hija para cada registro en la tabla Padre. La primera vez, realiza los cálculos que se hayan pedido (count y/o sum) y lo imprime. El segundo pase de la tabla hija imprime el detalle. Este proceso se repite para cada registro de la tabla Padre.

Otra opción puede ser no mostrar nada en la Banda 1, es decir, emplearla solamente para el cálculo. La banda 2 se encargaría entonces de mostrar los datos calculados por la Banda1.

Es muy importante comprender que el resultado de los cálculos a los que se asigne “Iniciar basado en (Reset based on) una Banda de detalle determinada, van a mantener su valor hasta el final de ejecución de todas las bandas y sólo cambiará en el momento que se vuelva a ejecutar la banda para la que se ha establecido su alcance.

Cálculos (porcentajes)

Otro concepto en los informes es mostrar el porcentaje del total de cada línea de detalle, en la medida en que se imprimen las líneas. Esto puede ser realizado también con múltiples bandas de detalle. Para ello, la idea es crear múltiples bandas de detalle. En la primera banda, TargetAlias = tabla hija, se marcan bandas de encabezado y pie y no se coloca nada en la banda de detalle.

Luego, crear algunas variables de informe, por ejemplo: una variable para el total donde Valor a almacenar igual a Tablahija.CampoATotalizar establezca Tipo de cálculo igual a Suma y Reiniciar basado en Detail 1. Y luego, crear una variable llamada pare el Porciento, donde Valor a almacenar igual a ROUND(100 * TablaHija.CampoATotalizar / nTotal, 2), Tipo de cálculo = Ninguno

Los datos van a estar en la banda de detalle 2, junto a un control que devuelve el resultado de la expresión nPorciento. En el pie de banda 2 se agrega el objeto Total, con expresión igual a Tablahija.CampoATotalizar, a Tipo de cálculo = Suma y Reiniciar basado en = Detail 2. Igual para Total Porciento, con expresión = nPorciento.

La definición de informe descrita anteriormente, dice al Generador de informes de VFP 9.0, que procese dos veces la tabla Hija para cada registro en la tabla Padre. La primera vez totaliza los valores para que puedan ser utilizados en el segundo pase. El segundo pase de la tabla Hija imprime el dato para el usuario, utilizando la variable de informe que fue calculada en la primera banda de detalle. Este proceso se repite para cada registro en la tabla Padre.

Volvemos a los ejemplos Solutions y encontramos para este caso "A multiple detail band report used for calculations"

En la siguiente figura se observan claramente cómo las dos bandas de detalle tienen el mismo alias. Lo que se hace en este caso es, que no se muestra nada en la Banda 1, la que es empleada solamente para el cálculo. La banda 2 se encarga de mostrar los datos calculados por la Banda1.

Sin dudas, es un paso muy grande de avance, con respecto a lo que existía antes de la versión VFP 9.0.

Por una parte, no es necesario ningún proceso previo para la creación de cursores y además, todos los campos son visibles en la ventana del Diseñador, lo que influye directa y favorablemente en la productividad y los tiempos dedicados al mantenimiento de los informes.

No obstante, hacerse con el control de las múltiples bandas de detalle puede tomar un tiempo. Hay que entender cómo trabajan todas las tablas juntas, establecer correctamente las alias para cada banda y es esencial e imprescindible establecer correctamente la relación entre las tablas. Debe tener también el control sobre cómo se afectan las variables y los cálculos por las múltiples bandas de detalle.

Espero que haya resultado de utilidad.

Saludos,

Ana María Bisbé York
www.amby.net


4 comentarios :

  1. Sra Ana María, es posible que pueda realizar un ejemplo sobre graficos de barras en un informe frx, utilizando etiiquetas como lo mostró en una publicación de hace algun tiempo.

    ResponderBorrar
  2. Anita, excelente trabajo.
    Consulta:
    Para sumar subtotales de varias bandas, ¿Cómo recomiendas plantearlo?
    Gracias de antemano.

    ResponderBorrar
  3. Anita, en el caso que no existan registros en una banda pero tiene cabecera (Detail Header), ¿Cómo ocultas dicha cabecera?. Gracias de antemano.

    ResponderBorrar
  4. Hola. Tengo un soberano enredo, tengo una factura con 3 cursores, el primero datos del cliente, etc, el segundo productos y sus precios cantidad etc y el tercero diferentes tipos de pago credito efectivo debito cheque(los clientes pagan hasta con 5 o mas tipos), pero solo obtengo el primer detalle pero me intercala el segundo, otra en el primer detalle recorre todo el cursor pero en el segundo se queda siemore en el primer registro, por favor un ejemplo, gracias. Uso vfp con mysql

    ResponderBorrar

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.