Ir al contenido


Foto

QRComposite de QRComposites


  • Por favor identifícate para responder
21 respuestas en este tema

#1 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 02 junio 2013 - 09:59

Buenas, tengo un dilema.

Tengo una lista de animales, digamos: a1, a2, a3, ... an
Cada uno de esos animales tiene una serie de informes particulares, tienen un informe de pesajes, otro de vacunas, otro de enfermedades. Todos ellos en QReport's diferentes.

En un momento dado tengo que mostrar una lista con "el informe completo" (historia clínica completa) que consiste en la unión de los informes particulares. Hasta aquí la cosa va bien. El informe combinado lo hago con un QRComposite. Muestro la vista previa e imprimo sin problemas.

Resulta que ahora necesito que me salga (aquí quiero hacer una vista previa también) una unión de los informes completos de una sola vez, esto es: a1 (pesajes, vacunas, enfermedades), a continuación a2 (pesajes, vacunas, enfermedades), a continuación a3 (pesajes, vacunas, enfermedades), ... . En la vista previa debo ver un solo informe con estos informes uno abajo del otro y que tengan la numeración de hojas de manera continua.

Esto es particularmente importante puesto que la cantidad de animales es muy elevada y no es operativo imprimir la "historia clínica completa" de a una por vez.

Lo primero que se me ocurre es hacer una composición de composiciones o como se lo llame, pero no he dado con la forma correcta. ¿Cómo puede resolverse este tema?

Espero que se haya entendido, gracias.

Santiago.
  • 0

#2 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 02 junio 2013 - 01:58

Si no es posible hacerlo con una composición de QRComposite's. ¿Alguna otra opción?
  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 02 junio 2013 - 03:27

Ummm... no sabría decir si es posible hacer una composición de una composición. No lo he probado; de hecho hasta el momento no he utilizado QRComposite.
¿Podrías dar un ejemplo o la descripción de como es cada informe compuesto? ¿Cómo está "estructurado" el informe?
Esto también dependerá de como está diseñada la tabla.

Si resulta ser que la consultas para generar el informe desde a1 a an son similares, o es más... es la misma, y únicamente lo que las hace diferente es lo da unicidad, el ID de la tabla maestra de la cual se desprenden yo me imagino que tal vez... , y sólo tal vez... no podría asegurarlo sin demasiadas pruebas, se pueda diseñar un único informe que se alimente con una única consulta con un order-by y configurar la banda que da inicio a cada informe (que se corresponde a un id en particular) a que se inicie en una nueva hoja.

Es decir que si en realidad la consulta, en términos abstractos, consiste en un:

select <tus-campos|subconsulta-de-historia-clinica>
from <tus-tablas>
group by TablaMaestra.IDAnimal
order by TablaMaestra.IDAnimal


Siendo subconsulta la consulta que genera cada informe en particular.
Entonces el motor debiera de devolver TODOS los informes de las historias clínicas agrupados y ordenados por el ID.

Luego es el QR quien se encarga de mostrar la información de forma adecuada y dar inicio a cada informe en una nueva hoja.
Es una idea que se me ocurrió, ahora de que sea viable no se. Para tener algo más preciso me temo que habría que saber como está diseñada tu tabla y tus informes.

Ahora, si resulta ser que cada informe tiene sus particularidades... se me rompe los esquemas.

Admito que tengo el cerebro en OFF hoy  8o| y no estoy con todas las luces prendidas  :D

Saludos,
  • 0

#4 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 02 junio 2013 - 04:42

La cosa viene así:

Los animales son los bovinos: terneros, terneras, vacas, toros.
Los informes son varios y muy distintos, así tenemos informes de: pesajes, vacunaciones, enfermedades, evolución de terneros (datos del crecimiento del ternerito), evolución de los toros (datos del crecimiento cuando ya es toro adulto), evolución de vacas (datos cuando ya es vaca adulta), preñeces (de las vacas claro)

Cada uno de estos informes tiene relación (en líneas generales) con una tabla, mas otra que es en la que están los datos generales del animalito.

Ahora bien, cuando el dueño del ganado quiere vender a sus animales necesita saber, y el cliente, que condición tienen sus "bichos". De ahí que estos informes están por separado, al momento de la verdad es bueno tener un informe donde se vean todos los datos (algo así como una carpeta con la vida del animal, a esto le llamamos "historia clínica")

Las sql's para cada informe son todas distintas, lo único en lo que coinciden son en los datos de identificación del animal (caravana, marca, tatuaje, cabaña, fecha nacimiiento, sexo, edad actual...)

Si quiero saber un aspecto particular del animal, puedo hacerlo, por ejemplo: "deme el historial de vacunación del animal con caravana tal...", dice el comprador (a esto lo puedo ver en vista previa e imprimirlo)
Si quiero saber toda la historia clínica del animal, puedo hacerlo, por ejemplo: "deme la historia clínica del animal con caravana tal... que es el que quiero comprar", dice el comprador (a esto lo puedo ver en vista previa e imprimirlo) --> Aquí tengo la composición de todos los informes particulares y va muy bien.

Resulta que cuando el propietario se decide a vender, quiere vender la mayor cantidad posible de animales por supuesto y lo mas sensato es tener una "carpeta" con la historia clínica (en papel)  de cada animal en venta y esto es lo que no puedo hacer. Selecciono, por ejemplo, 250 animales que van a la venta y quiero los datos de todos ellos; sería bueno que el sistema me muestre la vista previa y me imprima los 250 informes (uno a continuación del otro), pero dando click una sola vez y no hacer 250 click's, uno por cada animal.  Aquí es donde yo "invento" eso de la composición de QrComposite's.

Bueno, espero haber aclarado mas la cosa.

Santiago.
  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 02 junio 2013 - 06:06

Ahora veo,
Así si se complica la cosa.

No recuerdo si es posible con QR guardar un reporte. Porque la posibilidad que estuve considerando es que se tenga guardado cada reporte en disco. Luego cuando se selecciona el listado a imprimir, bastaría con leer el "tipo" de informe a imprimir, cargarlo en el componente, y mandar a imprimir.

De forma burda, algo como:



delphi
  1. ListadoSeleccion.First;
  2. for i := 0 to ListadoSeleccion.RecordCount - 1 do
  3. begin
  4.   // suponiendo que existiera un campo por el que se pudiera diferenciar un tipo de reporte...
  5.   tipo := ListadoSeleccion.FieldByName('Tipo').AsInteger;
  6.   id := ListadoSeleccion.FieldByName('IDAnimal').AsInteger;
  7.   case tipo of
  8.   1: reporte := 'NombreReporteTipo1.qrp'; //nombre del archivo
  9.   2: reporte := 'NombreReporteTipo2.qrp';
  10.   ...
  11.   end;
  12.   QRForm.QRRep.LoadReport(reporte); // O quizá algo como QRForm.QRRep.QRPrinter.Load();
  13.   QRForm.QRRep.DataSet.SQL.add('WHERE IDAnimal = :ParamID');
  14.   QRForm.QRRep.DataSet.SQL.ParamByName('ParamID').AsInteger := id;
  15.   QRForm.Print;
  16. end;



Siendo ListadoSeleccion un DataSet con el listado ya filtrado de los animales para el informe, QRForm el Form donde estará el TQuickRep/TQRCompositeReport al que llamo QRRep.

Es decir, estar abriendo el reporte para cada tipo. Luego a éste report le indicamos que a su dataset asociado lo filtramos con el where según el ID del animal para que efectivamente se muestre el dato del animal en cuestión y por último mandarlos a imprimir.
Esto suponiendo que tal apertura del reporte lleve consigo la SQL que su dataset necesite y sólo haga falta añadir algún filtro. Sino habrá que tener tales SQLs almacenada previamente en algún lado.

Lo escribí al vuelo, no tengo a Delphi a mano en estos momentos.

Es una posibilidad, aunque tengo mis reservas de si es posible algo como esto.

Tengo un vago recuerdo de que si es posible tener un reporte almacenado en Disco. Lo que no recuerdo es si QR tiene un Load/Save... como método, o si había que utilizar a TQRPrinter como intermediario.

Algo como:



delphi
  1. QRForm.QRRep.QRPrinter.Load()



Quizá la principal desventaja, si es que es posible hacerlo de esta forma, será la lentitud para procesar e imprimir todo. Porque el QR deberá generar el reporte en tiempo de ejecución y luego filtrar los datos para su dataset. Se formará una cola de impresión con tantos archivos como animales tenga y podría ser posible que esto lleve a problemas.

Por ahora es a lo que llego. Seguramente hay otras alternativas de como enfocarlo. Habrá que ver que dicen el resto de los compañeros.

Saludos,
  • 0

#6 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 02 junio 2013 - 06:14

Suena interesante, voy a ver... de igual manera, espero que los otros colegas tengan otras ideas para probar.
Cualquier avance, o retroceso, en el tema lo cuento aquí.
Gracias compañero.

Santiago.
  • 0

#7 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 03 junio 2013 - 04:51

Gracias a la idea de Delphius he avanzado bastante, lo cuento:
Pude mandar cada "historia clínica" seleccionada a un archivo .qrp, eso lo he logrado de la siguiente manera:



delphi
  1.   for i:=0 to (nros_caravana.Count - 1) do
  2.   begin
  3. //.... código que no viene al caso
  4.  
  5.     QRCompositeReport1.Prepare; //Esto ejecuta el OnAdd que levanta los informes particulares, anda bien.
  6.     TQuickRep(QRCompositeReport1.Reports.Items[0]).Printer.Save('reportes\Reporte' +  IntToStr(i) + '.QRP');
  7.   end;
  8.   qrcmpstrprtJuegosCompletos.Preview;



Con esto puedo guardar masivamente todas las "historias", lo que no he podido hacer ha sido levantarlas y mostrarlas en el preview, que es la última línea del código.

En el OnAdd de qrcmpstrprtJuegosCompletos:



delphi
  1. procedure TFrmBuscarPesajes.qrcmpstrprtJuegosCompletosAddReports(
  2.   Sender: TObject);
  3. var
  4.   i:Integer;
  5.   r:TQuickRep;
  6. begin
  7.   r:=TQuickRep.Create(nil);
  8.   r.QRPrinter:=TQRPrinter.Create(r);
  9.   with qrcmpstrprtJuegosCompletos.Reports do
  10.   begin
  11.   //Tenemos que recuperar los archivos .qrp que guardamos por ahí
  12.     for i:=0 to (nros_caravana.Count - 1) do
  13.     begin
  14.       r.QRPrinter.Load('reportes\Reporte' + IntToStr(i) + '.QRP');
  15.       Add(r);
  16.     end;
  17.   end;
  18. end;



El código anterior no me da error pero al aparecer la ventana de vista previa no se ve nada, aparece vacía. Para colmo si lo intento nuevamente me dice que el "último .qrp está siendo usado por otro procedimiento y no se puede tocar"

Los avances han sido buenos pero me falta la frutilla del postre que sería poder levantar los .qrp y armar el informe completo.

¿Alguien tiene sugerencias?

Gracias.
  • 0

#8 Héctor Randolph

Héctor Randolph

    501st Legion

  • Moderadores
  • PipPipPip
  • 664 mensajes
  • LocationMéxico

Escrito 03 junio 2013 - 09:41

En el código anterior solamente estás creando un reporte y en el ciclo for agregas el mismo muchas veces.

En realidad lo que debes hacer es crear varios reportes y agregarlos.

Debes llamar al constructor en cada ciclo.

Algo como esto:



delphi
  1. procedure TFrmBuscarPesajes.qrcmpstrprtJuegosCompletosAddReports(
  2.   Sender: TObject);
  3. var
  4.   i:Integer;
  5.   r:TQuickRep;
  6. begin
  7.  
  8.   with qrcmpstrprtJuegosCompletos.Reports do
  9.   begin
  10.  
  11.   //Tenemos que recuperar los archivos .qrp que guardamos por ahí
  12.     for i:=0 to (nros_caravana.Count - 1) do
  13.     begin
  14.       r:=TQuickRep.Create(nil);
  15.       r.QRPrinter:=TQRPrinter.Create(r);
  16.       r.QRPrinter.Load('reportes\Reporte' + IntToStr(i) + '.QRP');
  17.       Add(r);
  18.     end;
  19.   end;
  20. end;



Saludos
  • 0

#9 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 04 junio 2013 - 12:48

En el código anterior solamente estás creando un reporte y en el ciclo for agregas el mismo muchas veces.

En realidad lo que debes hacer es crear varios reportes y agregarlos.

Debes llamar al constructor en cada ciclo.


He hecho lo que sugieres y nada, igual que antes. El preview me sale vacío.

Santiago.
  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 04 junio 2013 - 01:14


He hecho lo que sugieres y nada, igual que antes. El preview me sale vacío.

Santiago.

Eso se debe a que el componente de QR no tiene asociado un DataSet del cual extraer los datos para confeccionar el informe.
De mi pseudo ejemplo notarás que lo que hago es añadir un filtro. Eso lo hice pensando en la posibilidad de que el QR en su Save() almacenara internamente la consulta SQL y creara el DataSet en cuestión.
Bueno, la cosa aparentemente no es tan así... deberás asociarle un DataSet que ejecute la consulta SQL especialmente diseñada para el informe.
En caso de que al crear el QR éste crea su propio DataSet, entonces bastará con asignarle a éste la consulta SQL apropiada para el informe y configurarlo si es necesario.
Sino no lo crea, pues ya será responsabilidad nuestra el hacerlo.

Entonces, de algún modo debes de asociar a cada reporte, con su SQL. Puedes tener a las consultas guardadas en disco, y hacer por ejemplo:



delphi
  1. r.QRPrinter.Load('reportes\Reporte' + IntToStr(i) + '.QRP');
  2. r.DataSet.SQL.LoadFromFile('SQLReporte' + IntToStr(i) + '.SQL'); // el DataSet debe estar creado



Fíjate que en mi código de ejemplo expuse un WHERE ID = algo. Es fundamental para garantizar de que el informe sólo presente la consulta con los datos específicos a dicho animal.

Esto debiera de bastar para que el componente ahora si pueda ejecutar la vista previa sin problemas.

Saludos,
  • 0

#11 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 04 junio 2013 - 01:36

Esto sí que es extraño, yo me he cansado de hacer informes en QReport sin asociar consultas SQL's y nunca han dado un problema.

Sin duda es algo que estoy haciendo mal...
Se supone que un .qrp es un archivo que se guarda en un formato distinto a como fue originado el informe.

Bueno, seguiré probando y les digo.
¿No será que esta versión de QReport tiene algún drama? Uso la 5.02
Gracias.
  • 0

#12 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 04 junio 2013 - 02:32

Sigo pensando que falta algo o que mi QR no va bien, hice lo siguiente:

1) Guardé un .qrp con la ventana preview -- reporte0.qrp (lo he comprobado y tiene datos, lo abrí en preview)
2)


delphi
  1. qckrpJuegos.Prepare;
  2. qckrpJuegos.Printer.Load('reportes\Reporte0.QRP');
  3. qckrpJuegos.Preview;



qckrpJuegos es un componente QReport que puse en el formulario.
Resultado: Ventana vacía.

¿Alguna idea sobre esto?

Gracias.
  • 0

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 04 junio 2013 - 07:06

Hola,
Mañana por la tarde podré darle un tiempo a probar esto.
Intentaré recrear las cosas que se han venido comentando. Lástima que en D6, QuickReport no viene con los fuentes como para estudiar en profundidad el caso.

Sino estudiaré que otras posibilidades hay.

Saludos,


  • 0

#14 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 04 junio 2013 - 07:23

Algo que sí hice funcionar fue esto: (solamente puedo ver de a uno por vez, pero ya es algo, cuando intento ponerlo en el Add del Composite, otra vez los problemas...)



delphi
  1. procedure TFrmBuscarPesajes.componer_informe_completo(una_pagina_por_animal:Boolean);
  2. var
  3.   h:TQRPHandler;
  4. begin
  5. //.....
  6.  
  7. //Esto sí funciona, pero individualmente
  8.   h:=TQRPHandler.Create;
  9.   h.Filename:='reportes\Reporte0.QRP';
  10.   h.Preview;
  11.   h.Filename:='reportes\Reporte1.QRP';
  12.   h.Preview;
  13. end;



Puedo ver los dos preview's, uno a la vez, con el reporte cargado.
Espero que esto sirva de ayuda a la causa.

Santiago.

  • 0

#15 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 04 junio 2013 - 07:24

Uhhh, metí la pata, lo mandé tres veces.
El correcto es el último de la lista.
Gracias.

Santiago.
  • 0

#16 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 05 junio 2013 - 07:40

Uhhh, metí la pata, lo mandé tres veces.
El correcto es el último de la lista.
Gracias.

Santiago.


Listo, también lo edité para eliminar las citas.

Saludos
  • 0

#17 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 06 junio 2013 - 07:18

Hola,
Santiago14 no he podido darme el tiempo necesario para hechar luz, disculpas.
En estos próximas días si estaré investigando un poco más; lo más probable es que sea el fin de semana.
Tomaré en cuenta las últimas novedades que comentaste. Quizá por allí vayan los tiros... quien sabe.
Lo que hace un poco más difícil llegar a entenderle las cosas es que al menos en D6 QR no viene con las fuentes y la documentación no es del todo aclaratoria. Es todo a ensayo y error.
Voy a estar consultando en inglés a ver si de casualidad llego a algo más.

Saludos,
  • 0

#18 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 06 junio 2013 - 07:37

Ok, igual te digo que creo que dí en la tecla. Luego de probar bien lo que encontré lo subo y comento como es la cosa.

Santiago.
  • 0

#19 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 06 junio 2013 - 05:27

Después de tanto luchar, ¡llegamos a buen puerto!
Encontré la manera de hacerlo, lo cuento:

1) Generamos los .qrp, uno por cada informe independiente que tengo
2) Los guardamos en disco, cada uno con nombre. reporte0.qrp, reporte1.qrp, ... reporteN.qrp
3) Los levantamos y juntamos en un solo .qrp
4) Lo mostramos usando TQRPHandler de la unit QRExtra

¿Cómo hacemos el paso 3?
Resulta que hace algún tiempo la gente de qusoft armó una pequeña unidad llamada "QRQRP", que no es mas que un .pas común y lo puso en un archivo llamado QR3RNGD4.ZIP, lo podemos encontrar en: http://www.quickrepo...x?WebInfoID=620
Este .zip tiene, entre otras cosas, un .pas (qrqrp.pas) donde encontramos un procedimiento llamado "combineQRP" que hace el trabajo. De igual manera, analizando un poco el procedimiento no lo hace de la manera convencional, usa TStream y otras cositas... pero eso es tema de debate posterior.

En definitiva, el código quedaría así:



delphi
  1. procedure TFrmBuscarPesajes.componer_informe_completo(una_pagina_por_animal:Boolean);
  2. var
  3.   i:Integer;
  4.   caravana_particular:TStringList;
  5.   reportes_previosQRP:TStringList;
  6.   //directorio_actual:string;
  7.   h:TQRPHandler;
  8. begin
  9.   with Application, DataModule1 do
  10.   begin
  11. //Código que no viene al caso, son las llamadas a sql's y voy armando los informes particulares
  12.  
  13.   end;
  14. //Caravanas particulares para los informes particulares de los animales
  15.   caravana_particular:=TStringList.Create;
  16.   caravana_particular.Add('');
  17. //Creamos el espacio para guardar las direcciones donde se guardan los .qrp
  18.   reportes_previosQRP:=TStringList.Create;
  19. //Creamos la estructura del directorio para guardar los archivos
  20.   Crear_directorio('reportes');
  21.   for i:=0 to (nros_caravana.Count - 1) do
  22.   begin
  23.   //Más sql's 
  24.  
  25.   //Me manda el reporte combinado a un archivo .qrp
  26.     QRCompositeReport1.Prepare;
  27.     TQuickRep(QRCompositeReport1.Reports.Items[0]).Printer.Save('reportes\Reporte' + IntToStr(i) + '.QRP');
  28.  
  29.     reportes_previosQRP.Add('reportes\Reporte' + IntToStr(i) + '.QRP');
  30.   end;
  31. //¡¡Aquí el gran truco!!
  32. //El primer parámetro es donde se guarda el .qrp consolidado
  33.   CombineQRP('reportes\Historia_clinica.qrp', reportes_previosQRP);
  34. //Lo vemos en el preview
  35.   h:=TQRPHandler.Create;
  36.   with h do
  37.   begin
  38.     FQuickrep.PreviewHeight:=700;
  39.     FQuickrep.PreviewWidth:=1050;
  40.     FQuickrep.PrevInitialZoom:=qrZoom100;
  41.     Filename:='reportes\Historia_clinica.qrp';
  42.     Preview;
  43.     Free;
  44.   end;
  45. end;



Con esto resolví el dilema, mi cliente contento y las vaquitas preocupadas porque las probabilidades de ir al asador aumentan.

Saludos.
  • 0

#20 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 06 junio 2013 - 05:57

Para facilitar la cosa, subo a este post el .zip que menciono antes: QR3RNGD4.ZIP
  • 0




IP.Board spam blocked by CleanTalk.