Comparativa de diseñadores de reportes

User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Ya que es un interface gráfico sobre la clase TReport de FWH, fijaros que facilmente ya podemos hacerlo funcionar :-)
FiveReps.prg

Code: Select all

#include "FiveWin.ch"
#include "RichEdit.ch"
#include "xbrowse.ch"
#include "splitter.ch"
#include "report.ch"

static oWndMain

function Main()
  
   local oBmpTiled , oBar
   local hDLL := LoadLibrary( "Riched20.dll" )
  
   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"  
  
   DEFINE WINDOW oWndMain TITLE "Reports Builder" MDI ;
      MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION ReportNew()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION ReportOpen()

   DEFINE BUTTON OF oBar PROMPT "Run" RESOURCE "run" GROUP ;
      ACTION ReportRun()
      
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   ReportNew() 

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )   

   oBmpTiled:End()
   
   FreeLibrary( hDLL )
   
return nil

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Reports"
      MENU 
         MENUITEM "New" ACTION ReportNew()
      ENDMENU
   ENDMENU
   
return oMenu

function ReportNew()

   local oWndChild, cHeader := "Header", oHeader, oSplit1, oBrw
   local cFooter := "Footer", oFooter, oSplit2
   
   DEFINE WINDOW oWndChild TITLE "New report" MDICHILD
   
   @ 0, 0 RICHEDIT oHeader VAR cHeader SIZE oWndChild:nWidth, 70 OF oWndChild
   
   @ 5.3, 0 XBROWSE oBrw OF oWndChild SIZE oWndChild:nWidth, 150 
               
   oBrw:CreateFromCode()

   @ 15.2, 0 RICHEDIT oFooter VAR cFooter SIZE oWndChild:nWidth, 130 OF oWndChild

   @ 70,0  SPLITTER oSplit1 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oHeader ;
            HINDS CONTROLS oBrw ;
            TOP MARGIN 30 ;
            BOTTOM MARGIN oSplit2:nLast + 50 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE

   @ 225,0  SPLITTER oSplit2 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oBrw NOADJUST ;
            HINDS CONTROLS oFooter ;
            TOP MARGIN oSplit1:nFirst + 50 ;
            BOTTOM MARGIN 80 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE
   
   ACTIVATE WINDOW oWndChild ;
      ON RESIZE ( oSplit1:Adjust( .T., .F., .T., .T. ), oSplit2:Adjust( .F., .T., .T., .T. ) )
       
return nil   

function ReportOpen()

return nil

function ReportRun()

   local oRpt, aControls
   local oHeader, oFooter

   if oWndMain:oWndActive != nil

      aControls = oWndMain:oWndActive:aControls    
      oHeader   = aControls[ 1 ]
      oFooter   = aControls[ Len( aControls ) - 2 ]
   
      REPORT oRpt PREVIEW ;
         HEADER oHeader:GetText() ;
         FOOTER oFooter:GetText()

      COLUMN TITLE "" DATA ""

      END REPORT
      
      ACTIVATE REPORT oRpt
   endif

return nil
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Ya incluso podemos añadirle algunas columnas de prueba y ver como se comporta :-)

Image

FiveReps.prg

Code: Select all

#include "FiveWin.ch"
#include "RichEdit.ch"
#include "xbrowse.ch"
#include "splitter.ch"
#include "report.ch"

static oWndMain

function Main()
  
   local oBmpTiled , oBar
   local hDLL := LoadLibrary( "Riched20.dll" )
  
   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"  
  
   DEFINE WINDOW oWndMain TITLE "Reports Builder" MDI ;
      MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION ReportNew()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION ReportOpen()

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ACTION ReportAddColumn() GROUP

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ACTION ReportDelColumn()

   DEFINE BUTTON OF oBar PROMPT "Run" RESOURCE "run" GROUP ;
      ACTION ReportRun()
      
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   ReportNew() 

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )   

   oBmpTiled:End()
   
   FreeLibrary( hDLL )
   
return nil

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Reports"
      MENU 
         MENUITEM "New" ACTION ReportNew()
      ENDMENU
   ENDMENU
   
return oMenu

function ReportNew()

   local oWndChild, cHeader := "Header", oHeader, oSplit1, oBrw
   local cFooter := "Footer", oFooter, oSplit2
   
   DEFINE WINDOW oWndChild TITLE "New report" MDICHILD
   
   @ 0, 0 RICHEDIT oHeader VAR cHeader SIZE oWndChild:nWidth, 70 OF oWndChild
   
   @ 5.3, 0 XBROWSE oBrw ARRAY { Space( 20 ) } OF oWndChild SIZE oWndChild:nWidth, 150 
               
   oBrw:CreateFromCode()
   
   oBrw:aCols[ 1 ]:cHeader = "Empty"

   @ 15.2, 0 RICHEDIT oFooter VAR cFooter SIZE oWndChild:nWidth, 130 OF oWndChild

   @ 70,0  SPLITTER oSplit1 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oHeader ;
            HINDS CONTROLS oBrw ;
            TOP MARGIN 30 ;
            BOTTOM MARGIN oSplit2:nLast + 50 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE

   @ 225,0  SPLITTER oSplit2 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oBrw ;
            HINDS CONTROLS oFooter ;
            TOP MARGIN oSplit1:nFirst + 50 ;
            BOTTOM MARGIN 80 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE
   
   ACTIVATE WINDOW oWndChild ;
      ON RESIZE ( oSplit1:Adjust( .T., .F., .T., .T. ), oSplit2:Adjust( .F., .T., .T., .T. ) )
       
return nil   

function ReportOpen()

return nil

function ReportAddColumn()

   local oBrw
   
   if ! Empty( oWndMain:oWndActive )
      oBrw = oWndMain:oWndActive:aControls[ 2 ]
      ADD COLUMN TO oBrw TITLE "Test" DATA Time() SIZE 150
      if oBrw:aCols[ 1 ]:cHeader == "Empty"
         oBrw:DelCol( 1 ) 
      endif   
      oBrw:Refresh() 
   endif   

return nil

function ReportDelColumn()

return nil

function ReportRun()

   local oRpt, aControls, oBrw
   local oHeader, oFooter, n, cHeader, cValue

   if oWndMain:oWndActive != nil

      aControls = oWndMain:oWndActive:aControls    
      oHeader   = aControls[ 1 ]
      oBrw      = aControls[ 2 ]
      oFooter   = aControls[ Len( aControls ) - 2 ]
   
      REPORT oRpt PREVIEW ;
         HEADER oHeader:GetText() ;
         FOOTER oFooter:GetText()

      for n = 1 to Len( oBrw:aCols )
         cHeader = GetHeader( oBrw, n )
         cValue  = GetValue( oBrw, n ) 
         COLUMN TITLE cHeader DATA cValue
      next   

      END REPORT
      
      ACTIVATE REPORT oRpt
   endif

return nil

static function GetHeader( oBrw, n )

return oBrw:aCols[ n ]:cHeader

static function GetValue( oBrw, n )

return Eval( oBrw:aCols[ n ]:bStrData )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
FranciscoA
Posts: 1964
Joined: Fri Jul 18, 2008 1:24 am
Location: Chinandega, Nicaragua, C.A.

Re: Comparativa de diseñadores de reportes

Post by FranciscoA »

Hasta el momento, todo bien, con FWH1204 - XHARBOUR - BCC582 - XVERCE CW V 1.0.
Nunca he usado lib de terceros para mis reportes, todo con TReport o TPrinter.
Adelante, Antonio!
Saludos.
Francisco J. Alegría P.
Chinandega, Nicaragua.

Fwxh1204-MySql-TMySql
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Esta versión permite ya definir las bases de datos con las que vamos a construir el reporte:

Image

FiveReps.prg

Code: Select all

#include "FiveWin.ch"
#include "RichEdit.ch"
#include "xbrowse.ch"
#include "splitter.ch"
#include "report.ch"

static oWndMain, oWndDbfs

function Main()
  
   local oBmpTiled , oBar
   local hDLL := LoadLibrary( "Riched20.dll" )
  
   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"  
  
   DEFINE WINDOW oWndMain TITLE "Reports Builder" MDI ;
      MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION ReportNew()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION ReportOpen()

   DEFINE BUTTON OF oBar PROMPT "DataBases" RESOURCE "database" ACTION Databases() GROUP

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ACTION ReportAddColumn() GROUP

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ACTION ReportDelColumn()

   DEFINE BUTTON OF oBar PROMPT "Run" RESOURCE "run" GROUP ;
      ACTION ReportRun()
      
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   ReportNew() 

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )   

   oBmpTiled:End()
   
   FreeLibrary( hDLL )
   
return nil

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Reports"
      MENU 
         MENUITEM "New" ACTION ReportNew()
      ENDMENU
   ENDMENU
   
return oMenu

function DataBases( cFileName )

   local oBar, oBrw, aWorkAreas := GetWorkAreas(), cClrBack

   DEFINE WINDOW oWndDbfs TITLE "DataBases management" MDICHILD

   DEFINE BUTTONBAR oBar OF oWndDbfs 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( OpenDataBase(), oBrw:SetArray( GetWorkAreas() ), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndDbfs:End() GROUP
   
   @ 0, 0 XBROWSE oBrw OF oWndDbfs LINES ;
      ARRAY aWorkAreas AUTOCOLS
   
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:nArrayAt % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]
   oBrw:bClrSelFocus = { || { CLR_WHITE, cClrBack } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )

   oBrw:CreateFromCode()
      
   oBrw:aCols[ 1 ]:cHeader  = "Area"
   oBrw:aCols[ 1 ]:nWidth   = 100
   oBrw:aCols[ 1 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:nArrayAt, "" ) }
   
   ADD COLUMN TO oBrw HEADER "Alias" DATA oBrw:nArrayAt WIDTH 100
   oBrw:aCols[ 2 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:aArrayData[ oBrw:nArrayAt, 1 ], "" ) }
   
   oWndDbfs:oClient = oBrw
   
   ACTIVATE WINDOW oWndDbfs

return nil

function OpenDataBase( cFileName )

   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )

   if File( cFileName )
      USE ( cFileName ) NEW
   endif 

return nil

function GetWorkAreas()

   local aWorkAreas := {}, n := 1

   while ! Empty( Alias( n ) )
      AAdd( aWorkAreas, { Alias( n ), RddName( n++ ) } )
   end   

return aWorkAreas

function ReportNew()

   local oWndChild, cHeader := "Header", oHeader, oSplit1, oBrw
   local cFooter := "Footer", oFooter, oSplit2
   
   DEFINE WINDOW oWndChild TITLE "New report" MDICHILD
   
   @ 0, 0 RICHEDIT oHeader VAR cHeader SIZE oWndChild:nWidth, 70 OF oWndChild
   
   @ 5.3, 0 XBROWSE oBrw ARRAY { Space( 20 ) } OF oWndChild SIZE oWndChild:nWidth, 150 
               
   oBrw:CreateFromCode()
   
   oBrw:aCols[ 1 ]:cHeader = "Empty"

   @ 15.2, 0 RICHEDIT oFooter VAR cFooter SIZE oWndChild:nWidth, 130 OF oWndChild

   @ 70,0  SPLITTER oSplit1 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oHeader ;
            HINDS CONTROLS oBrw ;
            TOP MARGIN 30 ;
            BOTTOM MARGIN oSplit2:nLast + 50 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE

   @ 225,0  SPLITTER oSplit2 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oBrw ;
            HINDS CONTROLS oFooter ;
            TOP MARGIN oSplit1:nFirst + 50 ;
            BOTTOM MARGIN 80 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE
   
   ACTIVATE WINDOW oWndChild ;
      ON RESIZE ( oSplit1:Adjust( .T., .F., .T., .T. ), oSplit2:Adjust( .F., .T., .T., .T. ) )
       
return nil   

function ReportOpen()

return nil

function ReportAddColumn()

   local oBrw
   
   if ! Empty( oWndMain:oWndActive )
      oBrw = oWndMain:oWndActive:aControls[ 2 ]
      ADD COLUMN TO oBrw TITLE "Test" DATA Time() SIZE 150
      if oBrw:aCols[ 1 ]:cHeader == "Empty"
         oBrw:DelCol( 1 ) 
      endif   
      oBrw:Refresh() 
   endif   

return nil

function ReportDelColumn()

return nil

function ReportRun()

   local oRpt, aControls, oBrw
   local oHeader, oFooter, n, cHeader, cValue

   if oWndMain:oWndActive != nil

      aControls = oWndMain:oWndActive:aControls    
      oHeader   = aControls[ 1 ]
      oBrw      = aControls[ 2 ]
      oFooter   = aControls[ Len( aControls ) - 2 ]
   
      REPORT oRpt PREVIEW ;
         HEADER oHeader:GetText() ;
         FOOTER oFooter:GetText()

      for n = 1 to Len( oBrw:aCols )
         cHeader = GetHeader( oBrw, n )
         cValue  = GetValue( oBrw, n ) 
         COLUMN TITLE cHeader DATA cValue
      next   

      END REPORT
      
      ACTIVATE REPORT oRpt
   endif

return nil

static function GetHeader( oBrw, n )

return oBrw:aCols[ n ]:cHeader

static function GetValue( oBrw, n )

return Eval( oBrw:aCols[ n ]:bStrData )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Revisando _ a usar en el reporte:

Image

FiveReps.prg

Code: Select all

#include "FiveWin.ch"
#include "RichEdit.ch"
#include "xbrowse.ch"
#include "splitter.ch"
#include "report.ch"

static oWndMain, oWndDbfs

function Main()
  
   local oBmpTiled , oBar
   local hDLL := LoadLibrary( "Riched20.dll" )
  
   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"  
  
   DEFINE WINDOW oWndMain TITLE "Reports Builder" MDI ;
      MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION ReportNew()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION ReportOpen()

   DEFINE BUTTON OF oBar PROMPT "DataBases" RESOURCE "database" ACTION Databases() GROUP

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ACTION ReportAddColumn() GROUP

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ACTION ReportDelColumn()

   DEFINE BUTTON OF oBar PROMPT "Run" RESOURCE "run" GROUP ;
      ACTION ReportRun()
      
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   ReportNew() 

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )   

   oBmpTiled:End()
   
   FreeLibrary( hDLL )
   
return nil

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Reports"
      MENU 
         MENUITEM "New" ACTION ReportNew()
      ENDMENU
   ENDMENU
   
return oMenu

function DataBases( cFileName )

   local oBar, oBrw, aWorkAreas := GetWorkAreas(), cClrBack

   if ! Empty( oWndDbfs )
      oWndDbfs:SetFocus()
      return nil
   endif   

   DEFINE WINDOW oWndDbfs TITLE "DataBases management" MDICHILD

   DEFINE BUTTONBAR oBar OF oWndDbfs 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( OpenDataBase(), oBrw:SetArray( GetWorkAreas() ), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( Alias( oBrw:nArrayAt ) )->( Struct( cFileName, oBrw ) ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndDbfs:End() GROUP
   
   @ 0, 0 XBROWSE oBrw OF oWndDbfs LINES ;
      ARRAY aWorkAreas AUTOCOLS
   
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:nArrayAt % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]
   oBrw:bClrSelFocus = { || { CLR_WHITE, cClrBack } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )

   oBrw:CreateFromCode()
      
   oBrw:aCols[ 1 ]:cHeader  = "Area"
   oBrw:aCols[ 1 ]:nWidth   = 100
   oBrw:aCols[ 1 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:nArrayAt, "" ) }
   
   if Empty( aWorkAreas )
      ADD COLUMN TO oBrw HEADER "Alias" DATA oBrw:nArrayAt WIDTH 150
      oBrw:aCols[ 2 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:aArrayData[ oBrw:nArrayAt, 1 ], "" ) }

      ADD COLUMN TO oBrw HEADER "Rdd" DATA oBrw:nArrayAt WIDTH 100
      oBrw:aCols[ 3 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:aArrayData[ oBrw:nArrayAt, 3 ], "" ) }
   endif
   
   oWndDbfs:oClient = oBrw
   
   ACTIVATE WINDOW oWndDbfs ;
      VALID ( oWndDbfs := nil, .T. )

return nil

function OpenDataBase( cFileName )

   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )

   if File( cFileName )
      USE ( cFileName ) NEW
   endif 

return nil

function GetWorkAreas()

   local aWorkAreas := {}, n := 1

   while ! Empty( Alias( n ) )
      AAdd( aWorkAreas, { Alias( n ), Alias( n ), RddName( n++ ) } )
   end   
   
return aWorkAreas

function ReportNew()

   local oWndChild, cHeader := "Header", oHeader, oSplit1, oBrw
   local cFooter := "Footer", oFooter, oSplit2
   
   DEFINE WINDOW oWndChild TITLE "New report" MDICHILD
   
   @ 0, 0 RICHEDIT oHeader VAR cHeader SIZE oWndChild:nWidth, 70 OF oWndChild
   
   @ 5.3, 0 XBROWSE oBrw ARRAY { Space( 20 ) } OF oWndChild SIZE oWndChild:nWidth, 150 
               
   oBrw:CreateFromCode()
   
   oBrw:aCols[ 1 ]:cHeader = "Empty"

   @ 15.2, 0 RICHEDIT oFooter VAR cFooter SIZE oWndChild:nWidth, 130 OF oWndChild

   @ 70,0  SPLITTER oSplit1 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oHeader ;
            HINDS CONTROLS oBrw ;
            TOP MARGIN 30 ;
            BOTTOM MARGIN oSplit2:nLast + 50 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE

   @ 225,0  SPLITTER oSplit2 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oBrw ;
            HINDS CONTROLS oFooter ;
            TOP MARGIN oSplit1:nFirst + 50 ;
            BOTTOM MARGIN 80 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE
   
   ACTIVATE WINDOW oWndChild ;
      ON RESIZE ( oSplit1:Adjust( .T., .F., .T., .T. ), oSplit2:Adjust( .F., .T., .T., .T. ) )
       
return nil   

function ReportOpen()

return nil

function ReportAddColumn()

   local oBrw
   
   if ! Empty( oWndMain:oWndActive )
      oBrw = oWndMain:oWndActive:aControls[ 2 ]
      ADD COLUMN TO oBrw TITLE "Test" DATA Time() SIZE 150
      if oBrw:aCols[ 1 ]:cHeader == "Empty"
         oBrw:DelCol( 1 ) 
      endif   
      oBrw:Refresh() 
   endif   

return nil

function ReportDelColumn()

return nil

function ReportRun()

   local oRpt, aControls, oBrw
   local oHeader, oFooter, n, cHeader, cValue

   if oWndMain:oWndActive != nil

      aControls = oWndMain:oWndActive:aControls    
      oHeader   = aControls[ 1 ]
      oBrw      = aControls[ 2 ]
      oFooter   = aControls[ Len( aControls ) - 2 ]
   
      REPORT oRpt PREVIEW ;
         HEADER oHeader:GetText() ;
         FOOTER oFooter:GetText()

      for n = 1 to Len( oBrw:aCols )
         cHeader = GetHeader( oBrw, n )
         cValue  = GetValue( oBrw, n ) 
         COLUMN TITLE cHeader DATA cValue
      next   

      END REPORT
      
      ACTIVATE REPORT oRpt
   endif

return nil

static function GetHeader( oBrw, n )

return oBrw:aCols[ n ]:cHeader

static function GetValue( oBrw, n )

return Eval( oBrw:aCols[ n ]:bStrData )


function Struct( cFileName, oBrwParent )

   local oDlg, oBrw, aFields := DbStruct(), n

   if Empty( aFields ) .and. ! Empty( oBrwParent:oRS )
      for n = 0 to oBrwParent:oRS:Fields:Count - 1
         AAdd( aFields, { oBrwParent:oRS:Fields[ n ]:Name,;
                          oBrwParent:oRS:Fields[ n ]:Type,;
                          oBrwParent:oRS:Fields[ n ]:DefinedSize,;
                          oBrwParent:oRS:Fields[ n ]:NumericScale } )
      next
   endif

   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )

   oBrw:CreateFromCode()

   oDlg:oClient = oBrw

   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw, cFileName ), oDlg:Resize(), oBrw:SetFocus() )

return nil

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

function BuildStructBar( oDlg, oBrw, cFileName )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n

   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next

   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }" + CRLF + CRLF

   cCode += 'DbCreate( "myfile.dbf", aFields, "' + RddName() + '" )'

   MemoEdit( cCode, "Code" )

return nil

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

 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Comenzando a inspeccionar las columnas del reporte:

Image

Code: Select all

#include "FiveWin.ch"
#include "RichEdit.ch"
#include "xbrowse.ch"
#include "splitter.ch"
#include "report.ch"

static oWndMain, oWndDbfs

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

function Main()
  
   local oBmpTiled , oBar
   local hDLL := LoadLibrary( "Riched20.dll" )
  
   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"  
  
   DEFINE WINDOW oWndMain TITLE "Reports Builder" MDI ;
      MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION ReportNew()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION ReportOpen()

   DEFINE BUTTON OF oBar PROMPT "DataBases" RESOURCE "database" ACTION Databases() GROUP

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ACTION ReportAddColumn() GROUP

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ACTION ReportEditColumn()

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ACTION ReportDelColumn()

   DEFINE BUTTON OF oBar PROMPT "Run" RESOURCE "run" GROUP ;
      ACTION ReportRun()
      
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   ReportNew() 

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )   

   oBmpTiled:End()
   
   FreeLibrary( hDLL )
   
return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Reports"
      MENU 
         MENUITEM "New" ACTION ReportNew()
      ENDMENU
   ENDMENU
   
return oMenu

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

function DataBases( cFileName )

   local oBar, oBrw, aWorkAreas := GetWorkAreas(), cClrBack

   if ! Empty( oWndDbfs )
      oWndDbfs:SetFocus()
      return nil
   endif   

   DEFINE WINDOW oWndDbfs TITLE "DataBases management" MDICHILD

   DEFINE BUTTONBAR oBar OF oWndDbfs 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( OpenDataBase(), oBrw:SetArray( GetWorkAreas() ), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( Alias( oBrw:nArrayAt ) )->( Struct( cFileName, oBrw ) ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndDbfs:End() GROUP
   
   @ 0, 0 XBROWSE oBrw OF oWndDbfs LINES ;
      ARRAY aWorkAreas AUTOCOLS
   
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:nArrayAt % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]
   oBrw:bClrSelFocus = { || { CLR_WHITE, cClrBack } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )

   oBrw:CreateFromCode()
      
   oBrw:aCols[ 1 ]:cHeader  = "Area"
   oBrw:aCols[ 1 ]:nWidth   = 100
   oBrw:aCols[ 1 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:nArrayAt, "" ) }
   
   if Empty( aWorkAreas )
      ADD COLUMN TO oBrw HEADER "Alias" DATA oBrw:nArrayAt WIDTH 150
      oBrw:aCols[ 2 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:aArrayData[ oBrw:nArrayAt, 1 ], "" ) }

      ADD COLUMN TO oBrw HEADER "Rdd" DATA oBrw:nArrayAt WIDTH 100
      oBrw:aCols[ 3 ]:bStrData = { || If( Len( oBrw:aArrayData ) > 0, oBrw:aArrayData[ oBrw:nArrayAt, 3 ], "" ) }
   endif
   
   oWndDbfs:oClient = oBrw
   
   ACTIVATE WINDOW oWndDbfs ;
      VALID ( oWndDbfs := nil, .T. )

return nil

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

function OpenDataBase( cFileName )

   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )

   if File( cFileName )
      USE ( cFileName ) NEW
   endif 

return nil

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

function GetWorkAreas()

   local aWorkAreas := {}, n := 1

   while ! Empty( Alias( n ) )
      AAdd( aWorkAreas, { Alias( n ), Alias( n ), RddName( n++ ) } )
   end   
   
return aWorkAreas

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

function ReportEditColumn()

   local oDlg, oBrw := oWndMain:oWndActive:aControls[ 2 ]
   local oCol := oBrw:aCols[ oBrw:nColSel ]
   local cHeader := PadR( oCol:cHeader, 100 )
   
   DEFINE DIALOG oDlg TITLE "Column properties" SIZE 400, 300
   
   @ 0.5, 1 SAY "Header:"

   @ 0.6, 3.9 GET cHeader SIZE 150, 11
   
   @ 1.5, 1 SAY "Data:"

   @ 1.7, 3.9 GET oCol:cExpr SIZE 150, 11 ;
      ACTION MsgInfo( "expression builder" )

   @ 2.5, 1 SAY "Width:"

   @ 2.7, 3.9 GET oBrw:aCols[ oBrw:nColSel ]:nWidth SIZE 70, 4 SPINNER

   @ 7, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( oCol:cHeader := RTrim( cHeader ), oBrw:Refresh(), oDlg:End() )

   @ 7, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function ReportNew()

   local oWndChild, cHeader := "Header", oHeader, oSplit1, oBrw
   local cFooter := "Footer", oFooter, oSplit2
   
   DEFINE WINDOW oWndChild TITLE "New report" MDICHILD
   
   @ 0, 0 RICHEDIT oHeader VAR cHeader SIZE oWndChild:nWidth, 70 OF oWndChild
   
   @ 5.3, 0 XBROWSE oBrw ARRAY { Space( 20 ) } OF oWndChild SIZE oWndChild:nWidth, 150 
               
   oBrw:CreateFromCode()
   
   oBrw:aCols[ 1 ]:cHeader = "Empty"
   oBrw:aCols[ 1 ]:cExpr   = "nil"

   @ 15.2, 0 RICHEDIT oFooter VAR cFooter SIZE oWndChild:nWidth, 130 OF oWndChild

   @ 70,0  SPLITTER oSplit1 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oHeader ;
            HINDS CONTROLS oBrw ;
            TOP MARGIN 30 ;
            BOTTOM MARGIN oSplit2:nLast + 50 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE

   @ 225,0  SPLITTER oSplit2 ;
            HORIZONTAL ;
            PREVIOUS CONTROLS oBrw ;
            HINDS CONTROLS oFooter ;
            TOP MARGIN oSplit1:nFirst + 50 ;
            BOTTOM MARGIN 80 ;
            SIZE 500, 4  PIXEL ;
            OF oWndChild ;
            STYLE
   
   ACTIVATE WINDOW oWndChild ;
      ON RESIZE ( oSplit1:Adjust( .T., .F., .T., .T. ), oSplit2:Adjust( .F., .T., .T., .T. ) )
       
return nil   

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

function ReportOpen()

return nil

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

function ReportAddColumn()

   local oBrw
   
   if ! Empty( oWndMain:oWndActive )
      oBrw = oWndMain:oWndActive:aControls[ 2 ]
      ADD COLUMN TO oBrw TITLE "Test" DATA Time() SIZE 150
      ATail( oBrw:aCols ):cExpr = "Time()"
      if oBrw:aCols[ 1 ]:cHeader == "Empty"
         oBrw:DelCol( 1 ) 
      endif   
      oBrw:Refresh() 
   endif   

return nil

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

function ReportDelColumn()

return nil

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

function ReportRun()

   local oRpt, aControls, oBrw
   local oHeader, oFooter, n

   if oWndMain:oWndActive != nil

      aControls = oWndMain:oWndActive:aControls    
      oHeader   = aControls[ 1 ]
      oBrw      = aControls[ 2 ]
      oFooter   = aControls[ Len( aControls ) - 2 ]
   
      REPORT oRpt PREVIEW ;
         HEADER oHeader:GetText() ;
         FOOTER oFooter:GetText()

      for n = 1 to Len( oBrw:aCols )
         RptAddColumn( { GetHeader( oBrw, n ) },, { GetValue( oBrw, n ) } )
      next   

      END REPORT
      
      ACTIVATE REPORT oRpt
   endif

return nil

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

static function GetHeader( oBrw, n )

return { || oBrw:aCols[ n ]:cHeader }

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

static function GetValue( oBrw, n )

return { || oBrw:aCols[ n ]:bStrData }

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


function Struct( cFileName, oBrwParent )

   local oDlg, oBrw, aFields := DbStruct(), n

   if Empty( aFields ) .and. ! Empty( oBrwParent:oRS )
      for n = 0 to oBrwParent:oRS:Fields:Count - 1
         AAdd( aFields, { oBrwParent:oRS:Fields[ n ]:Name,;
                          oBrwParent:oRS:Fields[ n ]:Type,;
                          oBrwParent:oRS:Fields[ n ]:DefinedSize,;
                          oBrwParent:oRS:Fields[ n ]:NumericScale } )
      next
   endif

   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )

   oBrw:CreateFromCode()

   oDlg:oClient = oBrw

   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw, cFileName ), oDlg:Resize(), oBrw:SetFocus() )

return nil

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

function BuildStructBar( oDlg, oBrw, cFileName )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n

   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next

   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }" + CRLF + CRLF

   cCode += 'DbCreate( "myfile.dbf", aFields, "' + RddName() + '" )'

   MemoEdit( cCode, "Code" )

return nil

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

 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
manuelcalerosolis
Posts: 149
Joined: Mon Oct 10, 2005 9:30 am
Location: Huelva - Spain

Re: Comparativa de diseñadores de reportes

Post by manuelcalerosolis »

Intentas desarrollar un editor de informes?

FastReport hace miles de cosas y todas bien.

Lo interesante es escribir una lib para conectarlos a FastReport q si no estoy equivocado es free.

Saludos
User avatar
joseluisysturiz
Posts: 2024
Joined: Fri Jan 06, 2006 9:28 pm
Location: Guatire - Caracas - Venezuela
Contact:

Re: Comparativa de diseñadores de reportes

Post by joseluisysturiz »

Antonio, algo muy importante seria el control sobre el tamaño del papel, mas que todo para las impresiones de tickets e impresoras fiscales donde no hay limite, relativamente, de impresion, ademas de poder hacer etiquetas y obviamente asi como se usan DBF, puedan leerse array para los datos creados con los Querys de MYSQL, nose si eso esta procesado o ya tomado en cuenta, creo que le mejor ejemplo para un reporteador es FAST REPORT.

Nota al colega: F.R. no es free.
Dios no está muerto...

Gracias a mi Dios ante todo!
User avatar
FranciscoA
Posts: 1964
Joined: Fri Jul 18, 2008 1:24 am
Location: Chinandega, Nicaragua, C.A.

Re: Comparativa de diseñadores de reportes

Post by FranciscoA »

function Struct( cFileName, oBrwParent )

local oDlg, oBrw, aFields := DbStruct(), n
local cAlias:=Alias()

if empty(cAlias) .or. cAlias = NIL
MsgStop("Workarea not in use.")
return nil
endif
...
...
Francisco J. Alegría P.
Chinandega, Nicaragua.

Fwxh1204-MySql-TMySql
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Francisco,

gracias :-)

Manuel,

Es un GUI para la Clase TReport de FWH, a ver hasta donde se puede llegar :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
AngelSalom
Posts: 664
Joined: Fri Oct 07, 2005 7:38 am
Location: Vinaros (Castellón ) - España
Contact:

Re: Comparativa de diseñadores de reportes

Post by AngelSalom »

¿Alguna demo para probar FastReport? Lo cierto es que nunca he usado una librería externa y con tanto halago hacia esa utilidad me están entrando ganas de testearla.
Gracias,
Angel Salom
http://www.visionwin.com
---------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.0
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: Comparativa de diseñadores de reportes

Post by lucasdebeltran »

Antonio,

Muchas gracias, el prototipo tiene cada vez mejor pinta. Por favor, no te olvides de los márgenes del documento (Derecha, Izquierda, Superior e Inferior), así como de grabar todo el informe en un ini por ejemplo, y poder añadir imágenes en la cabecera y en el pie.


Amigos,

Fast Report es un producto muy complejo desarrollado por una compañía rusa que se dedica en exclusiva a ello durante muchos años. Sergey hizo la librería para poder conectarse a Fast Report (en versión Delphi) desde Harbour.

Fast Report es extraordinariamente complejo y no puede ser replicado en Fivewin así por las buenas. EasyReport sí está hecho en Fivewin, y podría lograrse algo similar, pero eso lleva tiempo y coste económico.

Carles también nos obsequió con MyReport, que sigue la línea de EasyReport, por lo que sería en mi opinión el modelo a seguir y consolidar. Otras metas son difícilmente alcanzables y hay que ser realista en lo que se puede y no se puede conseguir.
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
User avatar
Joaquim Ferrer
Posts: 58
Joined: Sat Jan 14, 2012 3:46 pm
Location: Barcelona

Re: Comparativa de diseñadores de reportes

Post by Joaquim Ferrer »

AngelSalom wrote:¿Alguna demo para probar FastReport? Lo cierto es que nunca he usado una librería externa y con tanto halago hacia esa utilidad me están entrando ganas de testearla.
Gracias,
Angel
http://www.spirins.com/
Fivewinner desde 1.9, programador PHP y Javascript, HTML5 evangelista
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Comparativa de diseñadores de reportes

Post by Antonio Linares »

Mi idea es muy simple, ver hasta donde podemos llegar haciendo un GUI para la Clase TReport de FWH.

Es solo un punto de partida, y de paso entre todos analizamos lo que de verdad se necesita y lo que es superfluo :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
AngelSalom
Posts: 664
Joined: Fri Oct 07, 2005 7:38 am
Location: Vinaros (Castellón ) - España
Contact:

Re: Comparativa de diseñadores de reportes

Post by AngelSalom »

Joaquim Ferrer wrote: Angel
http://www.spirins.com/
Gracias!
Angel Salom
http://www.visionwin.com
---------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.0
Post Reply