Page 1 of 1

Usar un único objeto TFastReport y Clear()

Posted: Mon Dec 09, 2019 3:42 pm
by Israel Solis
Hola compañeros

Hace días se me presentó un problema de GPF con FastReport, mi error se debía a que cargaba y descargaba en cada ocasión la libreria TFastReoort, por consejo de Ignacio Ortiz ahora uso un único objeto TFastReport borrando su contenido con el método Clear() PERO ALGO HAGO MAL que no funciona correctamente...

Code: Select all

* * * * * * * * AQUI CREO EL UNICO OBJECTO TFASTREPORT... * * * * * * *
METHOD FormInitialize( oSender ) CLASS tFrmMain
       WITH OBJECT ::oFastReport := TFastReport():New(Self)
         :SetTitle( Application:cTitle + " - Reporte" )
         :cLanguage := "Spanish"
         :Create()
      END WITH
RETURN NIL


* * * * *  ESTE METODO ES LLAMADO EN VARIAS OCASIONES Y ARMA UN NUEVO REPORTE CON REGISTROS DIFERENTES... * * * * *
METHOD PrintCFDI(cFileFR3, cFileOutput, oDSdetalle, oDSsubDetalle) CLASS tFrmMain
   LOCAL oDetalle, oSubDetalle

   WITH OBJECT ::oFastReport
      oDSdetalle:GoTop()
      oDSsubDetalle:GoTop()

     // * * * * * * * *
     // EN UN SEGUNDO REPORTE YA NO MUESTRA REGISTROS DE LOS DATASET's,....
     
      oDetalle   := :AddDataSet( "Conceptos",     oDSdetalle )
      oSubDetalle:= :AddDataSet( cNameSubDetalle, oDSsubDetalle )
      oSubDetalle:SetMaster( oDetalle, { "IDCONCEPTO=IDCONCEPTO" } )

      :LoadFromFile( cFileFR3 )
      :AddFunction( "Function ValorBanco(cValor: String, nDato: Integer):String", "Sanroms", "bla, bla,..." )
      :AddFunction( "Function ValorTipoJornada(cValor: String, nDato: Integer):String", "Sanroms", "bla, bla,..." )
      :AddFunction( "Function ValorTipoNomina( cValor: String, nDato: Integer):String", "Sanroms", "bla, bla,..." )
      :AddFunction( "Function ValorPeriodoPago(cValor: String, nDato: Integer):String", "Sanroms", "bla, bla,..." )

      :DeleteCategory( "EMISOR" )
      :AddCategory( "EMISOR" )
      :AddVariable( "Emisor_Logotipo",  cLogotipo )
      :AddVariable( "Emisor_Domicilio", cDomicilio)


            :PrepareReport()
            :SetProperty( "PDFExport", "ShowDialog",    .F. )
            :SetProperty( "PDFExport", "FileName",      cFileOutput + ".pdf" )
            :SetProperty( "PDFExport", "Compressed",    .t. )
            :SetProperty( "PDFExport", "EmbeddedFonts", .t. )
            :SetProperty( "PDFExport", "PrintOptimized",.t. )
            :SetProperty( "PDFExport", "Author",        "Sanroms Software de México" )
            :SetProperty( "PDFExport", "Subject",       "Comprobante Fiscal Digital" )
            :DoExport( "PDFExport" )

      :Clear()  // SOLO CLEAR() y LISTO PARA EL SIGUIENTE REPORTE?
   END WITH

RETURN .T.



Mi problema es que solo en el PRIMER reporte generado muestralos registros de manera correcta, a partir de la SEGUNDA ocasión que se genera un nuevo reporte NO MUESTRA REGISTROS, como si los DataSet estuvieran vacios

Re: Usar un único objeto TFastReport y Clear()

Posted: Mon Dec 09, 2019 4:08 pm
by hgarciaj
Israel,
yo lo que hago es primero cargar el reporte y luego agregar los datasets, pero antes hago un create() del objeto fastreport y al final no un clear sino un end(), no se si esto te funcione pero yo no tengo problemas con los datos (te anexo el código)
WITH OBJECT AppData:oFr
:Create()
:loadfromstring(cReporte)
:cTitle:="CFDI "+::oDbfBrow:SERIE+"-"+::oDbfBrow:FOLIODIG
:AddDataSet("Datosgen",::oDatos)
:AddDataSet("FacturaE",::oDbfFacE)
oFactD:=:AddDataSet("Facturad",::oConcep)
oPedim:=:AddDataSet("Pedimento",::oPedim)
oImpto:=:AddDataSet("Impuestos",::oImptos)
:AddDataSet("Retencion",::oReten)
:AddDataSet("Relacion",::oRela)
:AddDataSet("Pagos",::oPagos)
:AddDataSet("Tienda",::oTienda)
:AddDataSet("OtraTienda",::oTienda2)
oPedim:SetMaster(oFactD,{"Codigo"})
IF AppData:VerCfdi='3.3'
oImpto:setMaster(oFactD,{"Codigo","Partida"})
oPedim:setMaster(oFactD,{"Codigo","Partida"})
ENDIF
:onafterload:={|o|o:oPrintoptions:cPrinter:=AppData:TicketImpre,o:oPrintOptions:lShowdialog:=pfalse}
:prepareReport()
:print()
:End()
:Create()
END

Re: Usar un único objeto TFastReport y Clear()

Posted: Mon Dec 09, 2019 5:33 pm
by Israel Solis
Hector,

Gracias por responder. Aparentemente el problema ese el :Create() (que instancia un nuevo objecto y carga la DLL ) y :End() (que destruye la instancia) en CADA OCASIÓN y eso, en teoría, podria provocar el problema, es por eso la recomendación de Ignacio que INTENTO HACER pero no me sale jejeje

Re: Usar un único objeto TFastReport y Clear()

Posted: Mon Dec 09, 2019 6:38 pm
by hgarciaj
Israel, revisé el código del método :Create y no instacia nuevamente si usas el método end destruyes el objeto y liberas la memoria por loque aparentemente no tendrías problemas, el problema es que por alguna razón se quedan colgados los datasets del reporte por loque solo podrás ver información en el primero ya que para la siguiente llamada los datasets se quedan en eof() y aunque uno crea que al volver a poner los datasets empiezan de cero la realidad es que se agregan como un nuevo alias y no hay forma de que se agreguen correctamente sino es volviendo a crear la instancia. Sugiero pruebes con cleardb() además de clear()

Re: Usar un único objeto TFastReport y Clear()

Posted: Mon Dec 09, 2019 10:06 pm
by Ariel
Israel,

en el fr de Sergey, yo uso :

oFr:ClearDataSets()

si estas usando el FR de Xailer no se si existe ese metodo, tambien podes hacer :
1) en un app declarar el oFr publico, AppData:oFr, AppData:oFr:= frReportManager():New(,.t.)
2) luego en cada report en vez de New(), AppData:oFr:AddReport()
3) AppData:oFr:ClearDataSets()

4) Al salir de tu app : AppData:oFr:DestroyFR()
asi lo uso no se si funcionará con el FR d Xailer, pero es cuestión de probar :)
Espero te sirva.
Saludos.

Re: Usar un único objeto TFastReport y Clear()

Posted: Tue Dec 10, 2019 3:22 pm
by Israel Solis
Héctor,

Gracias por tus consejos, pero No me funcionó agregando :ClearDB() ya que me marcó errores.

Ariel,

Precisamente ASI lo hacia yo con FR de Sergey y funcionaba sin problema, pero en FR de Xailer no existe esos métodos y la equivalencia seria usar el CLEAR() pero es lo que no logro.

MIL GRACIAS A AMBOS POR CONTESTAR !!

Re: Usar un único objeto TFastReport y Clear()

Posted: Tue Dec 10, 2019 9:23 pm
by ignacio
Buenos días,

Te ruego pruebes con la siguiente DLL:

https://www.xailer.com/files/temp/frx.dll

Saludos

Nota: Comprueba que los datos del dataset efectivamente cambian

Re: Usar un único objeto TFastReport y Clear()

Posted: Wed Dec 11, 2019 4:36 pm
by Israel Solis
Ignacio,

FUNCIONO EXCELENTE, MIL GRACIAS