jueves, 11 de octubre de 2007

Usando List & Label 12

Recientemente en el foro de FiveWin se viene hablando del generador de informes List & Label. Y aunque se comenta que es muy bueno, que funciona muy bioen, etc, la verdad es que no hay hasta la fecha ningún ejemplo funcional para ser usado con FiveWin. Bueno realmente si hay una primera aproximación de Jairo Centeno (gracias), que expone un ejemplo de como usar el generador de informes.

En esta entrada intentare poner un ejemplo de como usar el diseñador, y otro de lanzar un informe.

El primer punto a destacar es la filosofía de uso de este generador de informes. Mientras que la mayoria de generadores se basan en la conexion a un origen de datos, LL recibe los datos al momento, y su origen puede ser cualquiera, dejando en manos del programador el envio de datos al reporte.

La función DefineData, es la encargada de pasar los datos al reporte, tanto para diseño como para impresión. El primer paso es convertir los datos xBase a formato LL, y el segundo definir el campo o la variable dependiendo del valor recibido como parametro en lAsField. El segundo parametro oLl, es un objeto valido LL ya creado.

Para lanzar el diseñador de informes, llamamos a la funcion Disenya los pasos a seguir son muy simples.
1.- Creamos un nuevo objeto LL oLl = TActiveX():New( oWnd, "L12.List-Label12_Ctrl_32.1" )
2.- Ajustamos varias propiedades del objeto LL
3.- Llamamos a la función DefineData, que le enviara los campos al diseñador de informes.
alias->( DefineData(.t., oLl) )
4.-Invocamos el diseñador
oLl:Do("LlDefineLayout",oWnd:hWnd,"Designer",LL_PROJECT_LIST, "informe.lst")
Facil y sencillo, ahora manipulamos y diseñamos nuestro informe, y lo guardamos. Ya tenemos listo un informe para ser llamado desde nuestra aplicación.

Ya tenemos un informe creado, ahora vamos a llamar el informe desde nuestro programa, podeis revisar el código de la función Imprime que teneis más abjo, el funcionamiento es el siguiente:
1.- Creamos un nuevo objeto LL oLl = TActiveX():New( oWnd, "L12.List-Label12_Ctrl_32.1" )
2.- Ajustamos varias propiedades del objeto LL (inicio de variables, de campos, immpresora por defecto, ...)
3.- Llamamos a la función DefineData, que le enviara los campos al diseñador de informes.

Hasta aqui igual que para el diseñador.

4.- Empezamos la impresión

oLl:Do("LlPrintStart",LL_PROJECT_LIST,"Informe.lst",LL_PRINT_PREVIEW)
oLl:DO("llPrint")

5.- Montamos un bucle que recorra los registros que queremos imprimir, y para cada registro llamamos la Funcion DefineData (convierte y envia los datos aLL) y oLl:DO("llPrintFields") que imprime los campos.

5.- Una vez que hemos terminado los registros que queriamos imprimir, solo nos queda indicarle a LL que ya esta finalizado el listado.
oll:DO("llPrintEnd",0)
oLl:DO("LlPreviewDisplay", "informe.lst", , oWnd:hWnd)



Esto es un ejemplo muy sencillo, pero espero os aclare un poco el modo de funcionar, para ver con más profundidad todas las funciones y parametros, revisad la ayuda del producto.
En el código fuente incluido, se utiliza una tabla cuyo alias es tmp, y se presupone abierta, y una ventana oWnd tambien se presupone definida, y con scope en las funciones.
En la transformacion de tipos de datos, el formato fecha lo convierto a texto, aunque podria convertirse tambien a formato juliano si quisieramos hacer algún tipo de operación con la fecha dentro del informe.
Nada más, esta es mi primera entrada en el blog, así que espero os guste y os sea de utilidad. En la medida del tiempo disponible ire añadiendo nuevas entradas.











Código:


#include "cmbtll12.ch"

FUNCTION Disenya()

   LOCAL oLL,oWnd,hJob,cName:='qsl'

   oLl = TActiveX():New( oWnd, "L12.List-Label12_Ctrl_32.1" )

   oLl:Do( "LlSetOption", LL_OPTION_MULTIPLETABLELINES, 1)    //Permite multiples tablas

   oLl:Do( "LlDefineFieldStart" ) //Limpia buffer de campos

   oLl:DO( "LlDefineVariableStart")//Limpia buffer de variablesx

   Tmp->( DefineData(.t., oLl) )



   oLl:Do("LlSetPrinterDefaultsDir",hJob,"C:\Windows\Temp") //Arranca diseñador

   oLl:Do("LlDefineLayout",oWnd:hWnd,"Designer",LL_PROJECT_LIST, "log.lst")



RETURN NIL

//------------------------------------

FUNCTION Imprime()

   LOCAL oLL,oWnd,hJob,cName:='log.lst',cDir:=oAppl:cDirLocal

   oLl = TActiveX():New( oAppl:oWnd, "L12.List-Label12_Ctrl_32.1" )

   oLl:Do( "LlSetOption", LL_OPTION_MULTIPLETABLELINES, 1)

   oLl:Do( "LlDefineFieldStart" )

   oLl:DO( "LlDefineVariableStart")

   Tmp->( DefineData(.t., oLl) )

   oLl:Do("LlSetPrinterDefaultsDir",cDir)

   oLl:Do("LlPrintStart",LL_PROJECT_LIST,cName,LL_PRINT_PREVIEW)

   oll:DO("llPrintOptionsDialog",oAppl:oWnd:hWnd)

   oLl:DO("llPrint")

   Tmp->(DBGoTop())

   DO WHILE !Tmp->(Eof())

      Tmp->(DefineData(.T.,oLl))

      oLl:DO("llPrintFields")

      Tmp->(DBSkip())

   ENDDO

   oll:DO("llPrintEnd",0)

   oLl:DO("LlPreviewDisplay", cName, , oAppl:oWnd:hWnd)

   oLl:DO("llPreviewDeleteFiles",cName,cDir)

RETURN NIL

//----------------------------------------------

FUNCTION DefineData(lAsField,oLl)

   LOCAL FldType, FldContent, lExpr,i,DateBuffer:=Replicate(Chr(0),255)

   //Convierte formato xBase a List & Label

   FOR i:=1 TO FCount()

      DO CASE

      CASE FieldType(i)=='N'

         FldType:=LL_NUMERIC

         FldContent:=Str(FieldGet(i))

      CASE FieldType(i)=='C'

         FldType:=LL_TEXT

         FldContent:=Trim(FieldGet(i))

      CASE fieldType(i)=='M'

         FldType:=LL_TEXT

         FldContent:=FieldGet(i)

      CASE FieldType(i)=='L'

         FldType:=LL_BOOLEAN

         FldContent:=IF(FieldGet(i),'TRUE','FALSE')

      CASE FieldType(i)=='D'

         FldType:=LL_TEXT

         FldContent:=DToC(FieldGet(i))

      ENDCASE

      IF lAsField

         oLl:Do("LlDefineFieldExt",FieldName(i), FldContent, FldType )

      ELSE

         oLl:Do("LlDefineVariableExt", FieldName(i), FldContent, FldType )

      ENDIF

   NEXT

RETURN NIL

4 comentarios:

Unknown dijo...

Muchas gracias por tu aporte!!.

Un saludo,

Moisés

Mauricio Arevalo dijo...

Biel:

Gracias por la ayuda desinteresada que brindas a todos los usuarios de FWH, con colegas así la comunidad crece en conocimientos y vislumbra un futuro alagador para FHW.

Sere un asiduo visitante de tu blog.

Anónimo dijo...

Muy buen post, estoy casi 100% de acuerdo contigo :)

Anónimo dijo...

Muchos saludos, muy interesante el post, espero que sigas actualizandolo!