Sunteți pe pagina 1din 79

INFORMES

CON

VISUAL FOXPRO 9

Walter R. Ojeda Valiente


Asuncin Paraguay
Mayo de 2017
Walter R. Ojeda Valiente

INDICE
INTRODUCCIN---------------------------------------------- 3
TABLAS USADAS EN ESTE DOCUMENTO -------------------------- 4
LA INTERFAZ CON EL USUARIO ------------------------------- 10
PROTECCIN DEL INFORME ----------------------------------- 11
Proteccin de objetos --------------------------------- 11
Nombres de campos de texto en tiempo de diseo -------- 17
ToolTips en tiempo de diseo -------------------------- 21
DATOS AGRUPADOS ------------------------------------------ 24
INFORMES CON MLTIPLES BANDAS DE DETALLE ----------------- 28
CLCULO DE TOTALES PREVIOS ------------------------------- 37
EL OBJETO REPORT LISTENER -------------------------------- 40
NUEVA VENTANA DE VISTA PREVIA (PREVIEW) ------------------ 43
CREANDO UNA PGINA WEB ----------------------------------- 46
CREANDO UN ARCHIVO XML ----------------------------------- 48
ENVIANDO EL ARCHIVO A UN GRFICO ------------------------- 51
ESTABLECIENDO LA VENTANA DE VISTA PREVIA ----------------- 53
POSICIONAMIENTO ABSOLUTO --------------------------------- 55
RECORTE DE LOS CAMPOS DE TEXTO --------------------------- 56
BARRAS CON COLORES ALTERNADOS ---------------------------- 58
CHECKBOXS EN LOS INFORMES -------------------------------- 59
INFORMES CON CORTES DE CONTROL FLEXIBLES ----------------- 61
CAMBIAR EL TAMAO DEL PAPEL ------------------------------ 65
HACKEANDO UN INFORME ------------------------------------- 67
Tipos de objeto --------------------------------------- 69
Cdigos de objeto ------------------------------------- 70
CONTANDO LA CANTIDAD DE GRUPOS --------------------------- 72
TRUCOS Y CONSEJOS ---------------------------------------- 76
CONCLUSIN ----------------------------------------------- 79

2
Walter R. Ojeda Valiente

INTRODUCCIN

Aunque Visual FoxPro 9 introdujo muchas mejoras que pueden ser


usadas cuando se crea un informe, muchas de ellas an hoy en da siguen
siendo desconocidas para una gran cantidad de programadores. El objetivo
de este documento es mostrar lo que fue agregado y lo que fue mejorado en
esta versin.

Ahora tenemos a nuestra disposicin un ms completo arsenal de


herramientas que nos permitirn crear informes con mayor calidad y en
menor tiempo que con las versiones anteriores.

Los informes son cruciales para nuestras aplicaciones, sirven tanto para
analizar los terabytes de datos que generan los usuarios como para que se
recuerden del nmero de telfono de la secretaria.

Este documento no est dirigido a los principiantes en la creacin de


informes quienes an no saben lo que es una banda de ttulos o una banda
de detalles, por ejemplo, sino a quienes ya tienen bastante experiencia y han
creado decenas o centenas de informes y quieren saber como mejorarlos.

Para facilitar tu tarea, se han incluido en el archivo .ZIP que contiene a


este documento todas las tablas (con formato .DBF) y todos los informes (con
extensin .FRX) que he utilizado para elaborarlo, adems de un formulario
MAIN.SCX que permite llamar a algunos de los ejemplos, y tambin dos
programas .PRG que realizan algunas tareas interesantes.

Cuando termines de leer este documento, tus habilidades para crear


informes con Visual FoxPro 9 probablemente habrn aumentado.

Si tienes alguna duda, pregunta, o consulta, puedes contactarme en:

wrov@hotmail.com

3
Walter R. Ojeda Valiente

TABLAS USADAS EN ESTE DOCUMENTO

A travs de este documento se vern muchas capturas de pantalla que


mostrarn el resultado de la ejecucin de los informes, cada uno de esos
informes puede estar basado en una o ms tablas. Para entender mejor lo
que muestran es que a continuacin se detallan las estructuras y los registros
de esas tablas.

TABLA: PAISES
PAI_IDENTI N 2 && Identificador
PAI_NOMBRE C 20 && Nombre del pas
INDEX ON PAI_IDENTI TAG PAI01
INDEX ON PAI_NOMBRE TAG PAI02

TABLA: SUCURSALES
SUC_IDENTI N 2 && Identificador

SUC_NOMBRE C 25 && Nombre de la Sucursal

INDEX ON SUC_IDENTI TAG SUC01

INDEX ON SUC_NOMBRE TAG SUC02

TABLA: CLIENTES
CLI_IDENTI N 10 && Identificador

CLI_NOMBRE C 40 && Nombre del Cliente

CLI_IDEPAI N 2 && Identificador del pas

4
Walter R. Ojeda Valiente

CLI_IDESUC N 2 && Identificador sucursal

INDEX ON CLI_IDENTI TAG CLI01

INDEX ON CLI_NOMBRE TAG CLI02

INDEX ON CLI_IDEPAI TAG CLI03

INDEX ON CLI_IDESUC TAG CLI04

TABLA: PRODUCTOS
PRD_IDENTI N 10 && Identificador

PRD_NOMBRE C 60 && Nombre del Producto

PRD_PRECIO N 10 && Precio unitario de venta

PRD_PORIVA N 2 && Porcentaje I.V.A. que paga

INDEX ON PRD_IDENTI TAG PRD01

INDEX ON PRD_NOMBRE TAG PRD02

TABLA: VENTASCAB (ventas cabecera)


VTC_IDENTI N 10 && Identificador

VTC_FECHAX D 8 && Fecha de la venta

VTC_TIPDOC N 1 && 1=Contado, 2=Crdito

VTC_NRODOC C 15 && Nmero de la Factura

VTC_IDECLI N 10 && Identificador del Cliente

INDEX ON VTC_IDENTI TAG VTC01

INDEX ON DTOS(VTC_FECHAX) TAG VTC02

INDEX ON VTC_NRODOC TAG VTC03

INDEX ON VTC_IDECLI TAG VTC04

5
Walter R. Ojeda Valiente

TABLA: VENTASDET (ventas detalles)


VEN_IDENTI N 10 && Identificador

VEN_IDECAB N 10 && Identificador de la cabecera

VEN_IDEPRD N 10 && Identificador del Producto

VEN_CANTID N 5 && Cantidad vendida

VEN_PRECIO N 10 && Precio unitario de venta

INDEX ON VEN_IDENTI TAG VEN01

INDEX ON STR(VEN_IDECAB) + STR(VEN_IDENTI) TAG VEN02

TABLA: COBRANZAS
COB_IDENTI N 10 && Identificador

COB_IDECLI N 10 && Identificador del Cliente

COB_FECHAX D 8 Fecha de la cobranza

COB_NRODOC C 15 Nmero de la Factura cobrada

COB_RECIBO C 15 Nmero del Recibo entregado

COB_MONTOX N 10 Monto cobrado al Cliente

INDEX ON COB_IDENTI TAG COB01

INDEX ON COB_IDECLI TAG COB02

6
Walter R. Ojeda Valiente

Captura 1. Los registros de la tabla PAISES

Captura 2. Los registros de la tabla SUCURSALES

Captura 3. Los registros de la tabla CLIENTES

7
Walter R. Ojeda Valiente

Captura 4. Los registros de la tabla PRODUCTOS

Captura 5. Los registros de la tabla VENTASCAB

8
Walter R. Ojeda Valiente

Captura 6. Los registros de la tabla VENTASDET

Captura 7. Los registros de la tabla COBRANZAS

9
Walter R. Ojeda Valiente

LA INTERFAZ CON EL USUARIO

La interfaz ha cambiado, en versiones anteriores se tena una pantalla


de dilogo para cada tarea, en Visual FoxPro 9 se tiene una sola pantalla de
dilogo pero tabulada, para que todas las opciones disponibles puedan ser
accedidas desde un solo lugar. Eso facilita nuestro trabajo.

Captura 8. Las propiedades del informe

Como puedes ver, hay una pestaa para Page Layout, otra pestaa
para Optional Bands, otra pestaa para Data Grouping, etc. En un solo
cuadro de dilogo tienes todo lo que puedes necesitar.

10
Walter R. Ojeda Valiente

PROTECCIN DEL INFORME

Proteccin de objetos
Si les permites a los usuarios modificar tu informe, entonces puedes
necesitar que exista un nivel de proteccin para que no hagan un desastre.
Ya sabes, usuarios bobos nunca faltan. Es por eso que en Visual FoxPro 9
existe una nueva palabra clave: PROTECTED

Para permitir a los usuarios modificar un informe, puedes escribir:


MODIFY REPORT MiInforme

Para permitir a los usuarios modificar un informe, pero protegindolo:


MODIFY REPORT MiInforme PROTECTED

Veamos un ejemplo. Creamos un informe con el nombre LST01 y le


agregamos una etiqueta (CLIENTES), un campo de texto (CLI_NOMBRE), y una
lnea horizontal.

Recuerda que los usuarios podrn modificar este informe, tienen esa
posibilidad, nuestra aplicacin se los permite. Lo que haremos ahora ser
limitar la cantidad de errores que ellos puedan cometer.

11
Walter R. Ojeda Valiente

Captura 9. Protegiendo una etiqueta

En la Captura 9. vemos como proteger a una etiqueta. En este caso


queremos proteger a la etiqueta CLIENTES para que los usuarios no puedan
moverla ni eliminarla. Lo conseguimos haciendo doble clic sobre ella, luego
clic sobre la pestaa Protection y luego marcando Object cannot be moved
or resized (el objeto no puede ser movido ni se puede cambiar su tamao) y
Object cannot be deleted (el objeto no puede ser eliminado).

Cuando desde nuestra aplicacin se ejecute el comando:


MODIFY REPORT LST01 PROTECTED

Los usuarios vern lo siguiente:

Captura 10. La etiqueta CLIENTES est protegida

12
Walter R. Ojeda Valiente

Donde podrn cambiar algunas de las propiedades de la etiqueta


CLIENTES pero no podrn moverla, ni cambiarle el tamao, ni eliminarla, ya
que todas esas opciones les fueron deshabilitadas. Al hacer doble clic sobre
esa etiqueta, el cuadro de dilogo que se ver ser el siguiente:

Captura 11. Las propiedades no protegidas de la etiqueta CLIENTES

Si comparas la Captura 9. con la Captura 11. notars que la pestaa


Protection ha desaparecido. Eso es lgico, si los usuarios pudieran ver la
pestaa Protection entonces cuando quisieran podran quitar cualquier
proteccin que nosotros hubiramos establecido.

13
Walter R. Ojeda Valiente

De la misma manera que hicimos para proteger a una etiqueta tambin


podemos proteger a un campo de texto, a una lnea, a un rectngulo, a una
banda, o a cualquier otro objeto. Veamos ahora como proteger a un campo
de texto, aunque como es casi lo mismo que proteger a una etiqueta
seguramente ya sabes como realizar esa tarea.

Captura 12. Las protecciones al campo de texto CLI_NOMBRE

En este caso, no queremos que los usuarios puedan eliminar al campo


de texto CLI_NOMBRE, por lo tanto lo protegemos haciendo doble clic sobre
l y luego en la pestaa Protection marcamos la casilla Object cannot be
deleted (el objeto no puede ser eliminado). Los usuarios podrn cambiar
muchas propiedades del campo de texto CLI_NOMBRE, por ejemplo su color,
su tamao, si se mostrar normal o en negritas, etc., pero no podrn
eliminarlo porque esa opcin no les permitimos que tengan.

14
Walter R. Ojeda Valiente

Cuando en nuestra aplicacin se ejecute el comando:


MODIFY REPORT LST01 PROTECTED

Y los usuarios hagan doble clic sobre el campo de texto CLI_NOMBRE,


vern la siguiente pantalla:

Captura 13. Las propiedades no protegidas del campo texto CLI_NOMBRE

Donde como puedes ver, la pestaa Protection ha desaparecido. Si no


hubiera desaparecido, los usuarios podran quitar las protecciones que les
hubiramos puesto al campo de texto.

Ahora, los usuarios podrn cambiar muchas de las propiedades de


CLI_NOMBRE pero no podrn eliminarlo porque no tienen permiso para
eliminar ese campo de texto.

15
Walter R. Ojeda Valiente

Tambin las bandas pueden ser protegidas. Por ejemplo, si hacemos


doble clic sobre la banda Detail (detalles), veremos sus propiedades, y en la
pestaa Protection podremos determinar si el tamao de la banda puede ser
cambiado o no y si el cuadro de dilogo de las propiedades ser visible o no.

Captura 14. Protegiendo a la banda de Detalles

Desde luego que de la misma manera tambin podramos proteger a


las bandas Page Header, Page Footer, etc.

16
Walter R. Ojeda Valiente

Nombres de campos de texto en tiempo de diseo


Quizs notaste que en la pestaa Protection de los campos de texto te
preguntan por Design-time caption.

Captura 15. Design-time caption

Qu es eso de Design-time caption, para qu sirve?

Se trata del ttulo o nombre, que tendr un campo de texto en tiempo


de diseo, cuando el usuario lo est editando.

Normalmente, cuando se modifica un informe, en los campos de texto


se ve el nombre del campo correspondiente, algo como:

17
Walter R. Ojeda Valiente

Captura 16. En tiempo de diseo se muestra el nombre del campo

Sin embargo, si lo deseamos, podemos ocultar el nombre de nuestro


campo para que el usuario no pueda verlo. En su lugar vern el nombre o el
alias que se nos haya ocurrido poner, algo como:

Captura 17. Un nombre alternativo para el campo de texto

18
Walter R. Ojeda Valiente

Entonces, lo que ver el usuario cuando modifique al informe ser:

Captura 18. El usuario ve el nombre alternativo del campo de texto

Si comparas la Captura 16. con la Captura 18. notars que el campo de


texto tiene otro nombre. En la Captura 16. se llamaba CLI_NOMBRE (que es
el nombre verdadero del campo) y en la Captura 18. se llama Nombre del
Cliente (que es un nombre alternativo para ese campo).

Sin embargo, si el usuario hace doble clic sobre el campo Nombre del
Cliente ver la siguiente pantalla:

Captura 19. Al hacer doble clic sobre el campo de texto se ve el nombre real

19
Walter R. Ojeda Valiente

Y all est viendo el nombre verdadero del campo de texto. Para qu


entonces sirve tener un Design-time caption?

Pues para que al usuario le sea ms fcil entender el significado o la


utilidad de nuestro campo de texto. Nosotros como programadores nos
podemos sentir cmodos con un campo llamado SAL_ULTFVE pero para los
usuarios eso puede parecer chino, algo inentendible, y estarn ms felices si
en su lugar les mostramos Ultima fecha de venta.

Entonces, el texto que escribimos en Design-time Caption est dirigido


normalmente a los usuarios que modificarn nuestro informe. No ser de
mucha utilidad para nosotros, pero para ellos s.

20
Walter R. Ojeda Valiente

ToolTips en tiempo de diseo


Otra facilidad que podemos brindarles a los usuarios son los ToolTips, o
sea los textos de ayuda que se muestran cuando colocamos el cursor sobre
un objeto.

Captura 20. Poniendo un ToolTip para el campo de texto CLI_NOMBRE

Con doble click en (1) elegimos el campo de texto, en (2) editamos el


ToolTip de ese campo de texto, y en (3) escribimos el mensaje descriptivo.

21
Walter R. Ojeda Valiente

Captura 21. El ToolTip es visible solamente en tiempo de diseo

Para que se pueda agregar o cambiar un ToolTip, debemos escribir:


MODIFY REPORT MiInforme

Ya que si escribimos:
MODIFY REPORT MiInforme PROTECTED

No tendremos la opcin de editar el ToolTip. S podremos ver los que


ya se hayan establecido previamente, pero no podremos agregar nuevos ni
modificar ni eliminar a los ya existentes. Recuerda que los ToolTips sirven
para ayudar a los usuarios que modifican informes, para facilitarles el trabajo.

22
Walter R. Ojeda Valiente

Y por ese motivo no se les puede permitir editar los ToolTips o podran
escribir algo fuera de lugar. Si el usuario Luis edita al ToolTip y escribe una
estupidez, luego cuando el usuario Juan modifique al informe no ver al
ToolTip original sino la estupidez que escribi Luis. Evidentemente, eso no
estara bien, no es admisible.

Algo muy importante a recordar es que los ToolTips pueden ser


puestos a todos los objetos, no solamente a los campos de texto. Tambin las
etiquetas pueden tener ToolTips, las lneas, los rectngulos, etc.

23
Walter R. Ojeda Valiente

DATOS AGRUPADOS

AGRUPACIN SIMPLE
Listado 1.
CLOSE ALL
CLEAR ALL

SELECT 0
USE PAISES
SET ORDER TO TAG PAI01

SELECT 0
USE CLIENTES
SET ORDER TO TAG CLI03
SET RELATION TO CLI_IDEPAI INTO PAISES

REPORT FORM LST02 PREVIEW

Captura 22. Clientes agrupados por pases

24
Walter R. Ojeda Valiente

En el informe LST02, cuya ejecucin se muestra en la Captura 22.


vemos la forma tradicional de agrupar registros, con ttulos en la cabecera y
en el pie de cada grupo, y con cada registro ocupando una fila distinta.

Captura 23. Propiedades para agrupar a los Clientes en 2 columnas

El informe LST03 es similar al informe LST02 pero con algunos cambios,


en Columns Number (cantidad de columnas) ponemos 2, y en Column
print order (orden de impresin de las columnas) elegimos Left to right
(de izquierda a derecha). El resultado es el siguiente:

25
Walter R. Ojeda Valiente

Captura 24. Clientes agrupados por pases, en 2 columnas

Como puedes ver, los nombres de los clientes ahora aparecen en 2


columnas, ya no un cliente en cada fila como era el caso en la Captura 22.
Este tipo de informes puede ser muy til en algunas circunstancias, entonces
es importante saber que podemos crearlo con facilidad.

Si en Columns Number de la Captura 23. ponemos 3, entonces


veremos algo as:

Captura 25. Clientes agrupados por pases, en 3 columnas

26
Walter R. Ojeda Valiente

Desde luego que podemos colocar varias columnas de texto en la


banda Detalles de nuestro informe. Por ejemplo, si adems del Nombre del
Cliente queremos colocar el Nombre de la Sucursal, tendramos algo as:

Listado 2.
CLOSE ALL

SELECT 0
USE PAISES
SET ORDER TO TAG PAI01

SELECT 0
USE SUCURSALES
SET ORDER TO TAG SUC01

SELECT 0
USE CLIENTES
SET ORDER TO TAG CLI03
SET RELATION TO CLI_IDEPAI INTO PAISES, ;
CLI_IDESUC INTO SUCURSALES

REPORT FORM LST05 PREVIEW

Captura 26. Nombres de clientes y de sucursales, en 2 columnas

27
Walter R. Ojeda Valiente

INFORMES CON MLTIPLES BANDAS DE DETALLE

Todos los informes tienen al menos una banda de detalle, y lo bueno


con Visual FoxPro 9 es que si lo queremos o lo necesitamos ahora podemos
tener hasta 20 bandas de detalle en un solo informe.

Para agregar bandas de detalles adicionales, en el Men hacemos clic


sobre Report y luego sobre Properties:

Captura 27. Para agregar bandas de detalle al informe

28
Walter R. Ojeda Valiente

Captura 28. Debes hacer clic en Optional Bands y luego en Add

Haciendo clic en Optional Bands (bandas opcionales) y luego en


Add (agregar) puedes agregar bandas adicionales a tu informe. Un informe
puede tener hasta 20 bandas de detalle, lo cual es ms que suficiente para
todas tus necesidades.

Adems, las bandas pueden tener cabeceras (header) y pies de pgina


(footer). Estas son opcionales, solamente las colocas si quieres colocarlas. En
general resultan tiles para poner ttulos y mostrar totales o sub-totales.

Para que una banda de detalles tenga su propia cabecera (header) y su


propio pie (footer), debes hacer doble clic sobre esa banda y luego marcar la
casilla Associated header and footer bands, tal como se muestra en la
Captura 29.

29
Walter R. Ojeda Valiente

Captura 29. Agregando header y footer a una banda de detalles

Captura 30. Despus de agregar header y footer a una banda de detalles

30
Walter R. Ojeda Valiente

Y cmo sabe el Visual FoxPro cules tablas y cuales registros de esas


tablas queremos mostrar en el informe?

Eso se lo indicamos en el Target alias expression de la Captura 29.

Fjate que como muy bien lo indica su nombre, lo que escribimos all
debe ser una expresin. O sea que si queremos poner el nombre de una tabla
o de un cursor, debemos escribirlo entre comillas. Pero tambin podramos
escribir una variable o una funcin, y eso es muy bueno porque nos permite
crear informes muy interesantes.

En Target alias expression podemos:

1. Dejar en blanco, eso significa que la tabla o cursor actual ser utilizado.
Esa es nuestra tabla principal.
2. Escribir el nombre de una tabla hija, la cual debe estar relacionada con
la tabla principal a travs de SET RELATION o a travs del Data
Environment del informe
3. Escribir el nombre de la tabla principal. Esto solamente podemos hacer
en la primera banda de detalles. Sirve para pedirle que procese todos
los registros de la tabla principal antes de pasar a la siguiente banda.

Las bandas de detalle tienen otras opciones ms, tal como habrs
observado en la Captura 29.: permiten empezar en una nueva pgina o en
una nueva columna, empezar en 1 cada vez que son procesadas, imprimir la
cabecera de la banda en cada pgina, y escribir los detalles en una nueva
pgina cuando la cantidad de espacio que resta en una pgina es menor que
un valor establecido.

31
Walter R. Ojeda Valiente

Captura 31. El informe LST06 en el Report Designer

En la Captura 31. vemos a nuestro informe cuando terminamos de


disearlo. Aqu, hay tres puntos muy importantes a considerar:

1. Cada una de las tablas de detalles debe estar relacionada con la tabla
de cabecera, no funcionar si no es as. Esa relacin puedes hacerla
mediante el comando SET RELATION o mediante el Data Environement
del informe.
2. Los nombres de los campos de texto deben estar precedidos por los
nombres de sus correspondientes tablas. Eso significa que no debemos
escribir VTC_FECHAX sino VENTASCAB.VTC_FECHAX, anlogamente no

32
Walter R. Ojeda Valiente

debemos escribir COB_NRODOC sino COBRANZAS.COB_NRODOC, y as


sucesivamente.
3. Igualmente, cuando usamos variables, deben estar precedidas por el
nombre de su tabla correspondiente. O sea que no debemos escribir
VTC_TOTALX sino VENTASCAB.VTC_TOTALX

Captura 32. El nombre de la columna precedido por el nombre de la tabla

33
Walter R. Ojeda Valiente

Captura 33. El nombre de la variable precedido por el nombre de la tabla

Hay una excepcin a esta regla y es cuando usas el nombre de la tabla


principal, en ese caso no es obligatorio escribir el nombre de la tabla. Por
ejemplo, si tu tabla principal es CLIENTES entonces si quieres puedes escribir
CLI_NOMBRE, no es obligatorio escribir CLIENTES.CLI_NOMBRE

34
Walter R. Ojeda Valiente

Recuerdas que las tablas de detalle deben estar relacionadas con la


tabla cabecera? Por eso establecemos un SET RELATION a continuacin:

Listado 3
CLOSE ALL

SELECT 0
USE VENTASCAB
SET ORDER TO TAG VTC04 && Indexado por Identificador del Cliente

SELECT 0
USE COBRANZAS
SET ORDER TO TAG COB02 && Indexado por Identificador del Cliente

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDENTI INTO VENTASCAB, ;
CLI_IDENTI INTO COBRANZAS

REPORT FORM LST06 PREVIEW

Captura 34. El resultado de la vista previa del informe

35
Walter R. Ojeda Valiente

En la Captura 34. vemos, para cada cliente, todo lo que le hemos


vendido y todo lo que le hemos cobrado, con sus respectivos totales. Este
informe tiene ms pginas, aqu solamente se muestra la primera pgina,
porque las siguientes son similares.

Cmo funciona?

1. Debemos relacionar a nuestra tabla cabecera con cada una de nuestras


tablas de detalles
2. Se procesa un registro de la tabla cabecera. Luego se procesan todos
los registros de la primera tabla de detalles que estn relacionados con
la tabla cabecera. Luego se procesan todos los registros de la segunda
tabla de detalles que estn relacionados con la tabla de cabecera.
3. Se pasa al siguiente registro de la tabla cabecera.
4. Se regresa al paso 2. hasta que la tabla cabecera ya no tenga ms
registros.

36
Walter R. Ojeda Valiente

CLCULO DE TOTALES PREVIOS

Otro gran provecho que podemos obtener de las mltiples bandas de


detalles es que podemos realizar clculos previos. Esto nos resultar muy til
cuando queremos que los totales se muestren antes de que se muestren los
detalles o cuando queremos mostrar los porcentajes del monto total en cada
una de las filas. Eso nos obligar a conocer tanto el monto total como la
cantidad de filas procesadas, previamente a la impresin.

Cmo lo conseguimos?

Ejecutando a la banda de detalles dos veces. Una, ser la encargada de


realizar los clculos; la otra, ser la encargada de mostrar los resultados.

En la primera banda de detalles no se muestra algo visible, ya que la


usamos exclusivamente para actualizar contadores y acumuladores y otras
variables que podamos necesitar.

Captura 35. El informe LST07 en el Report Designer

37
Walter R. Ojeda Valiente

Captura 36. Las variables calculadas en la banda de detalles 1

Tal y como se puede ver en la Captura 36., la variable nCantidadVentas


reinicia su valor a 0 cuando finaliza la banda de detalles 1. Recuerda que el
Visual FoxPro primero procesa a un registro de la tabla principal, luego todos
los registros de la banda de detalles 1 relacionados, luego todos los registros
de la banda de detalles 2 relacionados. Por ese motivo, cuando finaliza el
procesamiento de la banda de detalles 1, en la variable nCantidadVentas se
tiene la cantidad de registros que hay en esa banda. Anlogamente, en la
variable nTotalVentas se tiene la suma del campo VTC_TOTALX.

Eso significa que, antes de que empiece el procesamiento de la banda


de detalles 2, ya se conoce el valor de las variables nCantidadVentas y
nTotalVentas. Y como conocemos esos valores, podemos usarlos en la banda
de detalles 2. Interesante, verdad?

38
Walter R. Ojeda Valiente

Listado 4.

CLOSE ALL

SELECT 0
USE VENTASCAB
SET ORDER TO TAG VTC04

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDENTI INTO VENTASCAB

REPORT FORM LST07 PREVIEW

Captura 37. Mostrando totales en la cabecera

Como puedes ver en la Captura 37., antes de mostrar los registros de


detalle hemos mostrado la cantidad de ellos y el monto total, en los detalles
hemos mostrado el porcentaje que esa venta corresponde al total vendido a
cada cliente. Muy til, muy interesante, y muy fcil de hacer.

39
Walter R. Ojeda Valiente

EL OBJETO REPORT LISTENER

Para ejecutar un informe de la forma antigua, tradicional, debemos


escribir:
REPORT FORM MiInforme

Esa forma sigue funcionando perfectamente con Visual FoxPro 9, pero


ahora tenemos otra forma, mucho mejor. Y es mediante el uso de un objeto
llamado Report Listener.

Para indicarle al Visual FoxPro que queremos usar la forma nueva, hay
dos maneras:

a) Escribir:
SET REPORTBEHAVIOR 90

b) Escribir:
loListener = CreateObject(MiReportListener)

REPORT FORM MiInforme OBJECT loListener

All, se instancia un objeto Report Listener manualmente, si prefieres


hacerlo automticamente debes especificar el tipo de objeto y escribir, por
ejemplo:
REPORT FORM MiInforme OBJECT TYPE 1

Los tipos de objeto (OBJECT TYPE) predefinidos son:

0 para enviar el informe a la impresora


1 para ver una vista previa del informe
4 para que se cree un archivo XML
5 para que se cree un archivo HTML

40
Walter R. Ojeda Valiente

Claro que t puedes pensar Pero en mi aplicacin tengo decenas de


informes, debo buscar y cambiar todos los comandos REPORT FORM que
encuentre para adecuarlo a la forma nueva?

Afortunadamente, no es necesario. En Visual FoxPro 9 existe una


forma ms sencilla de hacerlo, y es a travs de un SET.

Escribiendo:
SET REPORTBEHAVIOR 90

Le dices al Visual FoxPro que quieres usar la forma nueva, entonces


cuando l vea el comando:
REPORT FORM MiInforme TO PRINTER

Lo reemplazar automticamente por:


REPORT FORM MiInforme OBJECT TYPE 0

Y cuando vea al comando:


REPORT FORM MiInforme PREVIEW

Lo reemplazar automticamente por:


REPORT FORM MiInforme OBJECT TYPE 1

Lo aconsejable, y lo recomendable es que siempre uses la forma nueva,


por eso al principio de tu aplicacin deberas escribir:
SET REPORTBEHAVIOR 90

Y si alguna vez, por algn motivo, necesitas regresar a la forma antigua


entonces puedes escribir:
SET REPORTBEHAVIOR 80

Y claro, una vez que ya no necesites usar la forma antigua deberas


regresar a usar la forma nueva. Ya sabes como hacerlo (poniendo 90 en lugar
de 80).

41
Walter R. Ojeda Valiente

A veces (no siempre) cuando imprimes un informe antiguo usando la


forma nueva, encuentras algunas pequeas diferencias, los informes no se
ven exactamente iguales. Al imprimir ves que no son idnticos. Para corregir
esas pequeas diferencias tienes dos alternativas posibles: a) cambias el
informe antiguo para adecuarlo a la forma nueva, b) antes de ejecutarlo
escribes SET REPORTBEHAVIOR 80

Importante:

Para que en las aplicaciones que distribuyas a tus usuarios se pueda


usar la forma nueva, debes copiar el archivo REPORTOUTPUT.APP en la
carpeta donde se encuentra tu .EXE

Ese archivo lo encontrars en la carpeta donde instalaste al Visual


FoxPro 9, por ejemplo en:

C:\Program Files\Microsoft Visual FoxPro 9\

42
Walter R. Ojeda Valiente

NUEVA VENTANA DE VISTA PREVIA (PREVIEW)

Otra mejora que encontramos en Visual FoxPro 9 es la ventana de


vista previa, ahora tiene ms opciones.

Captura 38. La vista previa antigua

Captura 39. La vista previa nueva

Captura 40. Se pueden ver 1, 2, 4 pginas en la vista previa

43
Walter R. Ojeda Valiente

Tambin se ha mejorado la legibilidad del texto a altas escalas, por


ejemplo si en la forma antigua (REPORTBEHAVIOR 80) queremos ver con una
escala del 300%, esto es lo que veramos:

Captura 41. Vista previa antigua con escala del 300%

Captura 42. Vista previa moderna con escala del 300%

En la vista previa moderna es mucho ms ntido, en este documento la


diferencia casi no se aprecia pero si observas un informe en el monitor de tu
computadora all s que la diferencia ser apreciable.

44
Walter R. Ojeda Valiente

Adems, si haces clic con el botn derecho sobre tu informe, vers un


men contextual.

Captura 43. Men contextual al hacer clic con el botn derecho

El men contextual tiene las mismas opciones que la ToolBar de arriba,


pero adems si queremos podemos ocultar la ToolBar.

Otra mejora que tenemos en Visual FoxPro 9 es que las opciones que
elegimos quedan guardadas y la siguiente vez que ejecutemos el informe
sern seleccionadas por defecto. Por ejemplo, si elegimos un zoom de 300%
la siguiente vez que ejecutemos el informe ser con un zoom de 300%.

45
Walter R. Ojeda Valiente

CREANDO UNA PGINA WEB

Si queremos crear una pgina web, bien hecha, con el contenido de


nuestro informe, es muy fcil.

Listado 5.
Local loListener

loListener = .NULL.

DO (_ReportOutput) with 5, loListener

loListener.TargetFileName = "Ventas a clientes.html"


loListener.QuietMode = .F. && No muestra el mensaje

CLOSE ALL

SELECT 0
USE VENTASCAB
SET ORDER TO TAG VTC04 && Indexado por Identificador cliente

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDENTI INTO VENTASCAB

SET REPORTBEHAVIOR 90

REPORT FORM LST07 OBJECT loListener

Si queremos que aparezca un mensaje indicativo despus de haberse


creado el archivo .HTML (o sea, la pgina web) en QuietMode debemos
poner .T.

Al ejecutar el cdigo anterior, se crear un archivo .HTML, que se


puede usar en cualquier sitio web, tal y como podemos ver en la Captura 44.

46
Walter R. Ojeda Valiente

Captura 44. La pgina web creada automticamente

47
Walter R. Ojeda Valiente

CREANDO UN ARCHIVO XML

Si queremos crear un archivo .XML (se usa para intercambiar datos en


Internet) tambin lo tenemos muy fcil, como vemos a continuacin:

Listado 6.
Local loListener

loListener = .NULL.

DO (_ReportOutput) with 4, loListener

loListener.TargetFileName = "Ventas a clientes.xml"


loListener.QuietMode = .F. && No muestra el mensaje
loListener.XMLMode = 0

* Los valores de .XMLMode pueden ser:


* 0 = Solamente datos
* 1 = Solamente forma de salida
* 2 = Ambos

CLOSE ALL

SELECT 0
USE VENTASCAB
SET ORDER TO TAG VTC04

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDENTI INTO VENTASCAB

SET REPORTBEHAVIOR 90

REPORT FORM LST07 OBJECT loListener

Al ejecutar ese cdigo, se crear un archivo con formato XML (uno de


los estndares que se usan para intercambiar datos entre aplicaciones en
Internet).

48
Walter R. Ojeda Valiente

Captura 45. Primeras lneas del archivo .XML creado automaticamente

En la Captura 45. vemos las primeras lneas del archivo .XML que el
Visual FoxPro 9 cre. El formato es correcto y completamente funcional.

49
Walter R. Ojeda Valiente

Listado 7.
loListener.TargetFileName = "Ventas a clientes 2.xml"
loListener.QuietMode = .F. && No muestra el mensaje
loListener.XMLMode = 2

Para crear un archivo .XML completo solamente debemos poner el


nmero 2 en la propiedad .XMLMode del objeto Listener, tal y como vemos
en el Listado 7. (tambin se cambi el nombre del archivo .XML para que no
se confunda con el anteriormente creado)

Lo que obtendremos en ese caso ser algo similar a esto:

Captura 46. Primeras lneas de un archivo .XML completo

Aqu hay muchos ms detalles, por ejemplo vemos el nombre de la


impresora, la orientacin del papel, el ancho del papel, la cantidad de copias,
etc.

En general, se usa la primera forma para el intercambio de datos.

50
Walter R. Ojeda Valiente

ENVIANDO EL ARCHIVO A UN GRFICO

Tambin tenemos la opcin de enviar nuestro archivo a un grfico. Los


formatos soportados son: BMP, EMF, GIF, JPG, PNG, TIFF.

Por ejemplo, para crear un archivo .JPG podramos escribir:

Listado 8.
Local loListener

loListener = CreateObject("ReportListener")
loListener.ListenerType = 3 && Grfico

CLOSE ALL

SELECT 0
USE VENTASCAB
SET ORDER TO TAG VTC04

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDENTI INTO VENTASCAB

SET REPORTBEHAVIOR 90

REPORT FORM LST07 OBJECT loListener

loListener.OutputPage(1, "VentasClientes.jpg", 102)

Los cdigos de los formatos grficos son:

100 = imagen de tipo EMF


101 = imagen de tipo TIFF
102 = imagen de tipo JPEG
103 = imagen de tipo GIF
104 = imagen de tipo PNG
105 = imagen de tipo BMP

Como en la propiedad OutputPage escribimos 102, eso significa que


queremos un archivo JPEG.

51
Walter R. Ojeda Valiente

El resultado de ejecutar el Listado 8. es:

Captura 47. El informe enviado a un grfico con formato JPEG

A veces, un informe con un formato grfico no se ve tan bien como con


otro formato grfico. Por ejemplo, si en este caso elegimos el formato PNG el
informe se ve mejor, es ms ntido.

Captura 48. El informe enviado a un grfico con formato PNG

52
Walter R. Ojeda Valiente

ESTABLECIENDO LA VENTANA DE VISTA PREVIA

Como ahora tenemos un Report Listener, o sea un objeto dedicado a


imprimir informes, podemos hacer algunas cosas interesantes con l, como
por ejemplo definir la ventana en la cual se mostrar la vista previa.
Local loPreview, loListener

* Se define la ventana de vista previa

loPreview = .NULL.

DO (_ReportPreview) WITH loPreview

with loPreview
.CanvasCount = 2
.ToolBarIsVisible = .T.
.Width = 800
.ZoomLevel = 4
endwith

* Se crea el objeto Listener

loListener = CreateObject("ReportListener")

with loListener
.ListenerType = 1 && Vista previa
.PreviewContainer = loPreview
endwith

* Se abren las tablas que tienen los datos

CLOSE ALL

SELECT 0
USE VENTASCAB
SET ORDER TO TAG VTC04

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDENTI INTO VENTASCAB

* Se muestra el informe

SET REPORTBEHAVIOR 90

REPORT FORM LST07 OBJECT loListener

53
Walter R. Ojeda Valiente

En el objeto loPreview, la propiedad CanvasCount indica la cantidad de


paneles que estarn visibles, su valor puede ser 1, 2, 4; la propiedad
ZoomLevel indica el porcentaje del zoom y ese nmero es el orden en el cual
se muestran los porcentajes: 1=10%, 2=25%, 3=50%, 4=75%, 5=100%, etc.

La propiedad ZoomLevel puede ser muy til para mostrar informes a


los usuarios que no tienen una buena vista. Si en esa propiedad colocamos
un valor de 11 (Fit to Width) entonces el informe ocupar todo el ancho del
monitor y las letras y los nmeros se vern muy grandes. Muy til.

54
Walter R. Ojeda Valiente

POSICIONAMIENTO ABSOLUTO

Otra de las caractersticas de los informes de Visual FoxPro 9 que


puede ayudarnos a crear mejores informes es el posicionamiento absoluto.
Eso significa que podemos decirle donde exactamente queremos que se
muestre un objeto (etiqueta, campo de texto, lnea, rectngulo, etc.)

Captura 49. Ahora se puede posicionar exactamente un objeto

Tal y como puedes ver en la Captura 49., ahora cada objeto se puede
posicionar en un lugar exacto, ya no hace falta que estemos con el mouse
subiendo y bajando y yendo de izquierda a derecha para colocarlo en el lugar
deseado. El posicionamiento absoluto facilita nuestro trabajo.

55
Walter R. Ojeda Valiente

RECORTE DE LOS CAMPOS DE TEXTO

Captura 50. El modo de recorte de los campos de texto

Si haces doble clic sobre un campo del informe, aparecer la ventana


de dilogo llamada Field Properties. Si tu campo del informe contiene texto
alfanumrico entonces puedes elegir el modo de recorte que deseas utilizar
cuando el texto en ese campo sea muy largo y no entre todo en l. Por
ejemplo, si en tu campo del informe hay lugar para mostrar 20 caracteres y el
texto que contiene ocupa 28 caracteres.

Como puedes ver en la Captura 50., ahora hay 6 formas en las cuales
se puede recortar el texto (trim mode, en ingls).

56
Walter R. Ojeda Valiente

Default trimming. Se agregan tres puntos al final, lo cual significa que


hay ms caracteres pero que no pueden ser vistos.
Trim to nearest character. Se corta el texto en el ltimo carcter que
cabe en el campo, se completa con espacios en blanco.
Trim to nearest word. Se corta el texto en la ltima palabra que cabe
en el campo, se completa con espacios en blanco.
Trim to nearest character, append ellipsis. Se corta el texto en el
ltimo carcter que cabe en el campo, se completa con tres puntos.
Trim to nearest word, append ellipsis. Se corta el texto en la ltima
palabra que cabe en el campo, se completa con tres puntos.
Filespec: Show inner paths as ellipsis. Aparecen los caracteres del
principio y del final, y los del medio son reemplazados por tres puntos.

Captura 51. Todos los modos de recorte de los campos de texto

En la Captura 51. puedes ver el resultado de usar cada uno de los 6


tipos de recorte del texto.

En algunas aplicaciones podra ser mejor usar el primer tipo de recorte,


en otras sera mejor usar el segundo tipo de recorte, etc.

Lo bueno es que tenemos varias posibilidades, y elegir una u otra ya es


demasiado fcil.

57
Walter R. Ojeda Valiente

BARRAS CON COLORES ALTERNADOS

Desde las primeras computadoras se acostumbraba a imprimir los


informes en papel con colores alternados, gris y blanco, eso mejora la
visibilidad y hace ms fcil la lectura de los informes.

Para obtener ese efecto podemos hacer lo siguiente:

1. Agregamos un rectngulo con color de fondo transparente


2. En la pestaa Print When del cuadro de dilogo Rectangle
Properties escribimos: MOD(RECNO(), 2) = 0
3. Agregamos un rectngulo con color de fondo opaco, y con una
tonalidad de gris bastante clara, para no gastar mucha tinta de la
impresora. Un RGB(192, 192, 192) suele quedar muy bien, aunque
si la impresora est en modo de ahorro de tinta tendremos que usar
nmeros menores, por ejemplo 128, 128, 128.
4. En la pestaa Print When del cuadro de dilogo Rectangle
Properties escribimos: MOD(RECNO(), 2) = 1

Captura 52. Informe con lneas de colores alternados

58
Walter R. Ojeda Valiente

CHECKBOXS EN LOS INFORMES

Cuando en un informe debemos mostrar un valor que evala a


verdadero o a falso, podemos poner .T., y .F., o S, y No, o algo as. Sin
embargo, queda mucho ms presentable y mucho ms profesional si usamos
checkboxes en esos casos.

La forma ms sencilla de imprimir checkboxes es usando las fuentes de


tipo Wingdings que vienen nativamente con el Windows, o sea que siempre
las tenemos a nuestra disposicin. Si en tu computadora buscas el mapa de
caracteres del Windows, encontrars algo similar a esto:

Captura 53. La fuente Wingdings en el Mapa de caracteres del Windows

Como puedes ver, abajo y a la izquierda, tambin nos dice cual es el


cdigo ASCII (en hexadecimal) del carcter elegido. En este caso: 0xFE

59
Walter R. Ojeda Valiente

Entonces, en nuestro informe solamente debemos colocar un campo


de texto y en la pestaa Print When de las propiedades de ese campo de
texto escribir una condicin que evale a .T. cuando queremos mostrar el
carcter.

Captura 54. Checkboxes en nuestro informe

En las fuentes Wingdings hay muchos ms caracteres que podemos


usar, estn a nuestra disposicin, ya depende de nuestra creatividad usarlos.

Este tipo de informe es muy bueno para presentarlo al propietario o a


los altos directivos de una Empresa. Les gusta mucho ms que aquellos que
simplemente ponen S, .T., o algn otro texto.

60
Walter R. Ojeda Valiente

INFORMES CON CORTES DE CONTROL FLEXIBLES

Supongamos que el gerente nos pide dos informes sobre las ventas,
contendrn los mismos datos, pero uno de ellos debe estar agrupado por
fechas y el otro debe estar agrupado por clientes. En una situacin as la gran
mayora de los programadores crearan dos informes. Sin embargo la forma
profesional es crear un solo informe.

Por qu?

Primero, porque se trabaja menos. Segundo, si hay que hacer un


cambio al informe se lo hace en un solo lugar, si debemos hacerlo en dos
lugares entonces existe la posibilidad de que no sean idnticos, o que hicimos
uno, nos llamaron, y dejamos al otro sin terminar, etc. Y si en lugar de dos
informes son tres, cuatro, o ms, la cosa se complica en demasa.

Captura 55. Cortes de control flexibles

El truco est en agrupar, no por el nombre de un campo de nuestra


tabla o cursor, sino por un nombre genrico.

Es ese nombre genrico el que usaremos en todos los casos.

61
Walter R. Ojeda Valiente

Listado 9.
SELECT ;
VTC_FECHAX, ;
VTC_FECHAX AS MIGRUPO, ;
VTC_NRODOC, ;
VTC_TOTALX, ;
CLI_NOMBRE AS VTC_NOMCLI, ;
VTC_IDECLI ;
FROM ;
VENTASCAB ;
JOIN ;
CLIENTES ;
ON VTC_IDECLI = CLI_IDENTI ;
ORDER BY ;
MIGRUPO ;
INTO CURSOR ;
MICURSOR

REPORT FORM LST12 PREVIEW

SELECT ;
VTC_FECHAX, ;
VTC_NRODOC, ;
VTC_TOTALX, ;
CLI_NOMBRE AS VTC_NOMCLI, ;
CLI_NOMBRE AS MIGRUPO ;
FROM ;
VENTASCAB ;
JOIN ;
CLIENTES ;
ON VTC_IDECLI = CLI_IDENTI ;
ORDER BY ;
MIGRUPO ;
INTO CURSOR ;
MICURSOR

REPORT FORM LST12 PREVIEW

Aqu, el campo genrico se llama MIGRUPO, en ambos casos.

62
Walter R. Ojeda Valiente

La primera vez que ejecutamos el informe, vemos esto:

Captura 56. Las ventas estn agrupadas por fechas

Donde como puedes ver, las ventas estn agrupadas por fechas. En la
segunda ejecucin vemos esto:

63
Walter R. Ojeda Valiente

Captura 57. Las ventas estn agrupadas por nombres de los clientes

Donde, como puedes ver, las ventas estn agrupadas por los nombres
de los clientes. En sntesis, hicimos un solo informe pero nos sirvi para
mostrar los registros agrupados con diferentes criterios. Muy bien, as hemos
ahorrado trabajo.

64
Walter R. Ojeda Valiente

CAMBIAR EL TAMAO DEL PAPEL

A veces, podramos encontrarnos con esta situacin: nuestro informe


est diseado para que se vea bien en papel de tamao Carta, pero el
cliente tiene papel de tamao A4.

Evidentemente, no saldr bien. Entonces, cmo lo solucionamos? Una


alternativa es crear dos informes, uno optimizado para tamao Carta y el
otro optimizado para tamao A4. Funcionar, claro, pero nos har trabajar
de ms, sobre todo cuando no es un solo informe el que debemos cambiar
sino que son decenas o cientos los informes.

La segunda alternativa es hackear nuestro informe para que se


adecue a lo que necesitamos. Eso es lo que veremos aqu.

Listado 10 (CAMBIAR_TIPO_PAPEL.PRG)
LParameters tcNombreInforme, tcTipoPapel
Local lcAlias

#DEFINE MSG_ICONO_ERROR 16

if Parameters() <> 2
=MessageBox("Debes enviar como parmetros el Nombre del Informe que
deseas cambiar y el tipo de papel que deseas que tenga (Carta, A4,
Oficio, etc.)", MSG_ICONO_ERROR, "Hay un problema")
Return
endif

tcNombreInforme = tcNombreInforme + iif(Right(tcNombreInforme, 4) <>


".FRX", ".FRX", "")

lcAlias = Alias()

select 0

USE (tcNombreInforme) EXCLUSIVE

DO CASE
CASE tcTipoPapel == "A4"
REPLACE EXPR WITH SubStr(EXPR, 1, At("PAPERSIZE", EXPR) - 2) ;
+ "PAPERSIZE=9" ;
+ SubStr(EXPR, At("PAPERSIZE", EXPR) + 12)
REPLACE WIDTH WITH 77433.000

65
Walter R. Ojeda Valiente

CASE tcTipoPapel == "Carta"


CASE tcTipoPapel == "Oficio"
ENDCASE

USE

if !Empty(lcAlias)
SELECT (lcAlias)
endif

Return
*
*

En el Listado 10. vemos como podemos cambiar el tipo de papel del


informe.

Todos los informes, aunque sus archivos tienen la extensin .FRX son
en realidad tablas .DBF con otra extensin. Por lo tanto, podemos hacer un
USE de esas tablas/informes. No debemos olvidar colocar la extensin .FRX o
no se abrirn, ya que un USE supone que la extensin ser .DBF

El primer REPLACE lo que hace es grabar en el campo EXPR todo lo que


est antes de PAPERSIZE, luego graba el nuevo PAPERSIZE (con el valor 9, que
es el correspondiente al papel de tamao A4), y luego vuelve a grabar lo
que estaba despus del PAPERSIZE.

El segundo REPLACE graba el ancho que tienen todas las hojas de


tamao A4.

Y eso es todo, ahora, nuestro informe que estaba programado para


usar hojas de papel de tamao Carta ha sido cambiado para que utilice
hojas de papel de tamao A4. Fcil, rpido, y sencillo.

Cmo usar este programa?

Debemos ejecutarlo antes que nuestro informe, por ejemplo:


DO CAMBIAR_TIPO_PAPEL WITH LST13, A4

REPORT FORM LST13 PREVIEW

Y listo, ya aparecer correctamente en hojas de papel de tamao A4.

66
Walter R. Ojeda Valiente

HACKEANDO UN INFORME

Como sabes, aunque todos los informes tienen la extensin .FRX en


realidad se trata de tablas .DBF con otra extensin.

Esa es la forma que tiene el Visual FoxPro de diferenciar entre tus


tablas de datos y las tablas que contienen datos que usar en los informes.

Entonces, como en realidad se trata de tablas .DBF con la extensin


cambiada, podemos hacer un USE de esas tablas y realizar en ellas todas las
operaciones que podemos realizar en las tablas .DBF

Desde luego, que si hacemos algo mal podramos estropear el informe


y dejarlo inutilizable, por eso hasta que adquieras experiencia en este tema
lo recomendable es que hagas una copia de tus informes antes de siquiera
intentar hackearlos.

Si escribes estos comandos:


USE LST07.FRX

BROWSE

Vers algo similar a la Captura 58.

67
Walter R. Ojeda Valiente

Captura 58. Primeras filas y primeras columnas del archivo LST07.FRX

En la Captura 58. vemos las primeras filas y las primeras columnas de


la tabla LST07.FRX. El significado de muchas de las columnas es muy fcil de
deducir leyendo sus nombres. Por ejemplo Name es el Nombre, Expr es
la Expresin, VPos es la posicin vertical, HPos es la posicin horizontal,
etc.

Las principales columnas, las que nos resultarn de ms utilidad


cuando hackeemos el informe son las siguientes:

OBJTYPE, OBJCODE, NAME, EXPR, SUPEXPR

68
Walter R. Ojeda Valiente

Tipos de objeto:

En la columna OBJTYPE se guarda el Tipo del Objeto (o sea, si se trata


de una etiqueta, de un campo de texto, de una lnea, de un rectngulo, etc.).
Sus posibles valores son:

1 = Definicin del informe. Siempre es el primer registro de la tabla. Y


siempre hay uno y solamente uno. En l se guardan datos como: el
nombre de la impresora, la orientacin del papel (horizontal o vertical),
el tamao del papel, etc.
2 = Obsoleto. Se usaba en FoxPro 2.x
3 = Obsoleto. Se usaba en FoxPro 2.x
4 = Obsoleto. Se usaba en FoxPro 2.x
5 = Es una etiqueta. O sea, label en ingls. Un texto que permanece
esttico durante todo el informe.
6 = Lnea. Es una lnea horizontal o vertical. Cada lnea en el informe
tiene su propio registro en la tabla.
7 = Rectngulo. Es un rectngulo con esquinas perpendiculares o con
esquinas redondeadas.
8 = Campo de texto. Es un campo de datos, su contenido es variable.
9 = Banda. Es una de las bandas usadas en el informe (cabecera, pie,
sumario, etc.).
10 = Grupo de objetos. Objetos agrupados juntos al elegir la opcin
Group que se encuentra en la opcin Format del Report Designer.
No confundas esto con grupos de datos.
17 = Grfico / OLE bound. Es un grfico o un objeto OLE incrustado.
18 = Variable. Es una de las variables definidas por el usuario.
21 = Obsoleto. Se usaba en FoxPro 2.x
23 = Fuente. El tipo de letra usado por defecto en el informe.
25 = Data Environment. El Data Environment del informe.
26 = Cursor, Relation, o Cursor Adapter. Para saber cual de ellos, hay
que mirar el campo NAME.

69
Walter R. Ojeda Valiente

Cdigos de objeto:

En muchos casos el valor de la columna OBJTYPE no es suficiente para


identificar al registro. Para que se lo pueda identificar adecuadamente
tambin debemos mirar el valor que se encuentra en la columna OBJCODE.

OBJTYPE OBJCODE
1=Definicin del informe Siempre 53
2 = Obsoleto Ya no se usa
3 = Obsoleto Ya no se usa
4 = Obsoleto Ya no se usa
5 = Etiqueta Siempre 0
6 = Lnea Siempre 0
7 = Rectngulo Siempre 4
8 = Campo de texto Siempre 0
9 = Banda 0 = Ttulo (Title)
1 = Encabezado de pgina (Page Header)
2 = Encabezado de columna (Column Header)
3 = Encabezado de grupo (Group Header)
4 = Detalle (Detail)
5 = Pie de grupo (Group Footer)
6 = Pie de columna (Column Footer)
7 = Pie de pgina (Page Footer)
8 = Resumen (Summary)
9 = Encabezado de detalle (Detail Header)
10 = Pie de detalle (Detail Footer)
10 = Grupo de objetos Siempre 0
17 = Imagen grfica Siempre 0
18 = Variable Siempre 0
21 = Obsoleto Ya no se usa
23 = Fuente Siempre 0
25 = Data Environment Siempre 0
26 = Cursor, Relation Siempre 0
Tabla 1. El significado de los campos OBJTYPE y OBJCODE

70
Walter R. Ojeda Valiente

Ahora, puedes realizar cualquier cambio que quieras en los


registros de la tabla LST07.FRX y ese cambio se ver reflejado en el informe
LST07. Por supuesto que LST07.FRX es solamente un ejemplo, t debers
elegir el nombre de tu propio informe.

Esto puede ser muy til para cambiar la impresora, la orientacin del
papel, el tamao del papel, o cualquier otra caracterstica que te interese.

71
Walter R. Ojeda Valiente

CONTANDO LA CANTIDAD DE GRUPOS.

Si necesitas conocer la cantidad de grupos impresos, cmo lo haces?

Por ejemplo, si miramos la Captura 59., que corresponde al informe


LST14.FRX, veremos que hay 3 grupos. Cmo conocemos esa cantidad? No
podemos usar la funcin RecCount(PAISES) porque en nuestra tabla PAISES
pueden haber pases que no corresponden a ningn cliente. Y entonces?

Captura 59. Mostrando la cantidad de grupos

La solucin es escribir cdigo en las expresiones On Entry y On Exit


de las bandas de nuestro informe.

72
Walter R. Ojeda Valiente

Cada banda de nuestro informe nos permite ejecutar expresiones


cuando se entra a la banda y cuando se sale de la banda. Tambin existe una
funcin poco conocida del Visual FoxPro llamada _VFP.SETVAR() que nos
resultar til en este caso.

Entonces, en la expresin On Entry de la banda Page Header de


nuestro informe escribimos:
_VFP.SETVAR("nCantidadGrupos", 0)

Con lo cual estamos creando a la variable nCantidadGrupos e iniciando


su valor a 0.

Captura 60. Creando una variable en la expresin On entry de la banda


Page Header

73
Walter R. Ojeda Valiente

Lo que le estamos diciendo aqu al Visual FoxPro es: cuando entres a


la banda Page Header crea una variable llamada nCantidadGrupos e inicia su
valor a 0.

Ahora, lo que nos est faltando es incrementar el valor de esa variable.


Esa tarea se tambin se realizar en una expresin On entry pero en este
caso de la banda Group Header. En ella escribiremos:
_VFP.SETVAR("nCantidadGrupos", nCantidadGrupos + 1)

Como la variable nCantidadGrupos ya existe (porque la creamos en la


banda Page Header) entonces podemos utilizarla.

Captura 61. Creando una variable en la expresin On entry de la banda


Group Header

Y eso es todo, como la variable nCantidadGrupos existe y guarda en


ella la cantidad de grupos impresos, podemos utilizarla cuando sea necesario,
tal y como vimos en la Captura 59.

74
Walter R. Ojeda Valiente

Para ver el informe mostrado en la Captura 59. puedes escribir:

Listado 11.
SELECT 0
USE PAISES
SET ORDER TO TAG PAI01

SELECT 0
USE CLIENTES
SET RELATION TO CLI_IDEPAI INTO PAISES

REPORT FORM LST14 PREVIEW

As como hemos escrito una expresin en On entry tambin


podemos escribir una expresin en On exit.

Ya depender de tus necesidades y de tu creatividad saber como


quitarles provecho a las expresiones On entry y On exit de las bandas.
Pueden ser de mucha utilidad en algunos casos.

75
Walter R. Ojeda Valiente

TRUCOS Y CONSEJOS
1. Cmo puedo mostrar los nmeros de pgina en la forma Pgina X de
Y, dnde Y es la cantidad total de pginas?

En un campo de texto de tu informe escribe:


"Pgina " + TRANSFORM(_pageno) + " de " +
TRANSFORM(_pagetotal)

2. Cmo puedo hacer que la impresora elegida por el usuario sea la


impresora por defecto en esa sesin?
SET PRINTER TO NAME GETPRINTER()

3. Si el usuario elige una impresora como se ha mostrado en 2., eso


cambiar la impresora por defecto en las dems aplicaciones?

No, solamente afecta a la impresora por defecto del Visual FoxPro, no


afecta a la impresora por defecto del Windows.

4. Cmo puedo hacer que la impresora por defecto del Windows sea
tambin la impresora por defecto del Visual FoxPro?
SET PRINTER TO DEFAULT

5. Qu hace la funcin GETPRINTER()?

Le permite al usuario seleccionar una impresora, esa impresora puede


ser local o estar en la red.

6. Qu hace la funcin SYS(1037)?

Abre la ventana de dilogo Page Setup, donde el usuario puede


seleccionar el tamao del papel, la fuente del papel, y la orientacin.

7. Cmo puedo hacer para que se le pida al usuario que seleccione la


impresora cuando haga clic sobre el botn de Imprimir?
REPORT FORM MiInforme TO PRINTER PROMPT PREVIEW

76
Walter R. Ojeda Valiente

8. Cmo puedo saber si hay alguna impresora instalada?


lnCantidadImpresoras = APRINTERS(laImpresoras)

IF lnCantidadImpresoras > 0 && Hay impresoras

&& Tus comandos aqu

ENDIF

9. Cmo puedo conocer los nombres de todas las impresoras?


lnCantidadImpresoras = APRINTERS(laImpresoras)

FOR lnI = 1 to lnCantidadImpresoras

? laImpresoras[lnI]

ENDFOR

10. Quiero que los usuarios vean la vista previa pero que no puedan
imprimir el informe. Cmo lo hago?

Hay un programa llamado INFORMES_VFP9.PRG que est incluido en el


archivo .ZIP que contiene a este documento. Ese programa muestra
como subclasar a un objeto Report Listener, como establecer el nivel
de zoom, como poner el ancho de la ventana de vista previa, y como
deshabilitar el botn de la impresora. Para ejecutarlo, debes enviarle
como parmetro el nombre de tu informe, el nivel de zoom, el ancho
de la ventana, y si quieres que el botn de imprimir est habilitado,
algo como:
DO INFORMES_VFP9 WITH LST07, 5, 800, .F.

donde debes reemplazar a LST07 por el nombre de tu informe y a los


dems parmetros por los valores que consideres adecuados.

Entre parntesis, si estudias ese programa podras aprender algo ms


sobre clases.

77
Walter R. Ojeda Valiente

11.Quiero que algunos objetos (etiquetas, campos de texto, etc.) se vean


en la vista previa pero no en el informe impreso, es eso posible?

S, la forma antigua es la siguiente:

a) doble clic sobre el objeto


b) clic sobre la pestaa Print when
c) escribir en el campo Print only when expression is true: NOT
WEXIST(Printing) .AND. NOT WEXIST(Imprimiendo)
d) SET REPORTBEHAVIOR 80
e) REPORT FORM MiInforme PREVIEW

12 Cmo hago para ocultar el icono de la impresora?

Listado 12.
Local loPreview

DO (_ReportOutput) WITH 1

loPreview = .NULL.

DO (_ReportPreview) WITH loPreview

loPreview.AllowPrintFromPreview = .F.

_oReportOutput['1'].PreviewContainer = loPreview

REPORT FORM (tcNombreInforme) PREVIEW

Un valor .F. no permite imprimir desde la vista previa. Otras opciones


de la ventana de vista previa puedes encontrar en el archivo PRUEBA01.PRG

78
Walter R. Ojeda Valiente

CONCLUSIN

Hay mucho ms que se puede escribir sobre los informes, y quizs ms


adelante escriba otro documento que muestre las caractersticas avanzadas y
muchos trucos que tengo en la cabeza pero me han quedado en el tintero,
porque ya quera terminar de elaborar este documento, mi tiempo siempre
es escaso. De todas maneras, con el contenido de este documento creo que
ya has tenido suficiente para comprobar la potencia de los informes que se
pueden crear con el lenguaje Visual FoxPro.

Los informes son muy pero muy importantes, en nuestras aplicaciones


ya que marcan la diferencia entre una aplicacin profesional y una realizada
por principiantes.

Adems, no debes olvidar que quien firma tus cheques es en general el


propietario de una Empresa o un alto directivo, esas personas no cargan
datos y ni siquiera miran los monitores de sus empleados, lo que ellos ven
son los informes que se les presentan. Si tus informes no les gustan, es muy
poco probable que vuelvan a contratarte.

Entonces, saber como elaborar buenos informes puede marcarte la


diferencia entre recibir un gran cheque o recibir una despedida. T decides.

Si tienes alguna duda, consulta, o sugerencia, puedes contactarme en:

wrov@hotmail.com

Walter.

79

S-ar putea să vă placă și