Report generator

Rochinha
Posts: 309
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo
Contact:

Post by Rochinha »

he!he!he!

I'm a Mathusalem, I begin with a FiveDOS, he!he!he!.

In the begining i create a script reader for my reports. simple and quick.

Script 1:

Code: Select all

--RPT1008N.FRM
HT **** INFORMATIVO COMERCIAL ****
HT -------------------------------------------------------------------------------------------------------------------
HT PEDIDO COMPRA   PRODUTO    DESCRICAO                                     QUANTDADE VALORVENDA VALORCUSTO VALORLUCRO
HT ------ -------- ---------- --------------------------------------------- --------- ---------- ---------- ----------
DT 999999 99/99/99 XXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 999999999 999,999.99 999,999.99 999,999.99
ET**** END OF REPORT ****
GT                               Total 999,999.99 999,999.99 999,999.99
TA es
NX es008
DC idpedido;dataped;substr(resumido,1,10);descricao;quantidade;quantidade*valorvenda;quantidade*customedio;quantidade*valorvenda-quantidade*customedio
GC 0;0;0;0;0;quantidade*valorvenda;quantidade*customedio;quantidade*valorvenda-quantidade*customedio
CQ dataped
--SM areceber
--RE NAO
ST SIM
LP 115
--WH MONTH(ARECEBER) > 3
Script 2:

Code: Select all

--RPT1007N.FRM
HT **** INFORMATIVO FINANCEIRO ****
HT -----------------------------------------------------------------------------------------------------------------
HT PEDIDO N.CHEQUE   DATA     VENCTO        VALOR  DESCONTO     JUROS     TOTAL    JA PAGO PAGO EM   RESTANTE DIA PG
HT ------ ---------- -------- -------- ---------- --------- --------- --------- ---------- -------- --------- --- --
DT 999999 XXXXXXXXXX 99/99/99 99/99/99 999,999.99 99,999.99 99,999.99 99,999.99 999,999.99 99/99/99 99,999.99 999 99
ET**** END OF REPORT ****
GT                               Total 999,999.99 99,999.99 99,999.99 99,999.99 999,999.99          99,999.99
TA contas
NX conta018
DC idpedido;idboleto;data;areceber;valor;desconto;juros;valor+juros-desconto;iif(flag,iif(valorpg>valor+juros-desconto,valorpg,valor+juros-desconto),0);recebido;valorpg;date()-areceber;idempresa
GC 0;0;0;0;valor;desconto;juros;valor+juros-desconto;iif(flag,iif(valorpg>valor+juros-desconto,valorpg,valor+juros-desconto),0);0;valorpg;0;0
--CQ areceber
--SM areceber
--RE NAO
ST SIM
LP 113
--WH MONTH(ARECEBER) > 3
My rpt reader analise the code below, open tables and using part of Rep32.prg, TxtPreview e Tprinter class print the results.

The code is here, for all:

Code: Select all

#include "FiveWin.ch"
#include "report.ch"
#include "label.ch"
#include "nfw.ch"

STATIC oReport, nLinMax

/*
 **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
 * Relatorio: Imprime relatorios baseados em scripts
 **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
 */
FUNCTION nfwrpt( cFile, cTextFile, lNoRel )
  //
  // -> Inicializar as varialveis principais      
  LOCAL oPrn,;
        aDC := {}
        aTA := {}
        aNX := {}
        aDT := {}
        aGC := {}
        cCQ := ''
        cSM := ''
        cRE := ''
        cST := ''
        cLP := ''
        aHT := {}
        cWH := ''
        cTI := ''
  /*
   **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
   * Le o arquivo de configuracao do relatorio, monta a chamada a funcao MyRPT
   **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
   */
  SET CENTURY OFF
  cEditFile := MemoRead(cFile)
  ntam_memo := MLCOUNT( cEditFile, 200 )
  nli_nha   := 1
  for I = 1 to ntam_memo
      cTexto1 := MemoLine( cEditFile, 200, I )
      cTag    := Substr( cTexto1, 1, 2 )
      cTexto2 := alltrim( Substr( cTexto1, 3, 197 ) )
      if cTag = 'DC'
         cTexto3 := ''
         for II = 1 to len(cTexto2)
             if (substr(cTexto2,II,1)=';' .or. len(cTexto2) = II)
                if len(cTexto2) = II
                   cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
                endif
                AADD( aDC, alltrim(cTexto3) )
                cTexto3 := ''
             else
                cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
             endif
         next
      endif
      if cTag = 'TA'
         cTexto3 := ''
         for II = 1 to len(cTexto2)
             if (substr(cTexto2,II,1)=';' .or. len(cTexto2) = II)
                if len(cTexto2) = II
                   cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
                endif
                AADD( aTA, alltrim(cTexto3) )
                cTexto3 := ''
             else
                cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
             endif
         next
      endif
      if cTag = 'NX'
         cTexto3 := ''
         for II = 1 to len(cTexto2)
             if (substr(cTexto2,II,1)=';' .or. len(cTexto2) = II)
                if len(cTexto2) = II
                   cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
                endif
                AADD( aNX, alltrim(cTexto3) )
                cTexto3 := ''
             else
                cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
             endif
         next
      endif
      if cTag = 'GC'
         cTexto3 := ''
         for II = 1 to len(cTexto2)
             if (substr(cTexto2,II,1)=';' .or. len(cTexto2) = II)
                if len(cTexto2) = II
                   cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
                endif
                AADD( aGC, alltrim(cTexto3) )
                cTexto3 := ''
             else
                cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
             endif
         next
      endif
      if cTag = 'DT'
         cTexto3 := ''
         for II = 1 to len(cTexto2)
             if (substr(cTexto2,II,1)=' ' .or. len(cTexto2) = II)
                nTira := 1
                if len(cTexto2) = II
                   nTira   := 0
                   cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
                endif
                AADD( aDT, { (II-len(alltrim(cTexto3)))-nTira, alltrim(cTexto3) } )
                cTexto3 := ''
             else
                cTexto3 := cTexto3 + substr( cTexto2, II, 1 )
             endif
         next
      endif
      if cTag = 'WH' ;       cWH := alltrim(cTexto2)      ;    endif
      if cTag = 'CQ' ;       cCQ := alltrim(cTexto2)      ;    endif
      if cTag = 'SM' ;       cSM := alltrim(cTexto2)      ;    endif
      if cTag = 'RE' ;       cRE := alltrim(cTexto2)      ;    endif
      if cTag = 'ST' ;       cST := alltrim(cTexto2)      ;    endif
      if cTag = 'LP' ;       cLP := alltrim(cTexto2)      ;    endif
      if cTag = 'HT' ;       AADD( aHT, alltrim(cTexto2) );    endif
      if cTag = 'TI' ;       cTI := alltrim(cTexto2)      ;    endif
  next
  oMeter := NIL
  oText  := NIL
  oDlg   := NIL
  lEnd   := NIL
  //MsgMeter( { |oMeter,oText,oDlg,lEnd|;
  MyRPT(        aTA , ; // Tabelas
                aNX , ; // Indices
                aDT , ; // Linha de impressao
                aDC , ; // Campos
                aGC , ; // Campos somados
                cCQ , ; // Campo Quebra
                cSM , ; // Sumarizar    Sim/Nao
                cRE , ; // Resumir      Sim,Nao
                cST , ; // SubTotalizar Sim,Nao
                cLP , ; // Largura da Pagina
                aHT , ; // Cabecalhos
                cWH , ;
                cTI , ;
                cTextFile,;
         oMeter,oText,oDlg,lEnd,lNoRel ) //;  // Expressao WHERE de avaliacao
         //},"Gerando arquivo..." )
   return .t.

FUNCTION MyRPT( aTA , ; // Tabelas
                aNX , ; // Indices
                aDT , ; // Linha de impressao
                aDC , ; // Campos
                aGC , ; // Campos somados
                cCQ , ; // Campo Quebra
                cSM , ; // Sumarizar    Sim/Nao
                cRE , ; // Resumir      Sim,Nao
                cST , ; // SubTotalizar Sim,Nao
                cLP , ; // Largura da Pagina
                aHT , ; // Cabecalhos
                cWH , ;
                cTI , ;
                cTextFile, ;
                oMeter,oText,oDlg,lEnd,lNoRel )   // Expressao WHERE de avaliacao

   local oPrn, cPorta, cFile
   local nLin, nPag, cTmp, nItens
   public TOT_000[15], TO1_000[15], SUM_000[15]
   cTextFile := "TXT"+substr(strtran(time(),":",""),4,3)+".PRN"
   FOR I = 1 TO LEN(aTA)
       USE (aTA[I]) NEW 
       IF LEN(aTA) > 0
          dbSetIndex( (aTA[I]) )
       ENDIF
   NEXT
   SELECT(aTA[1])
   OrdSetFocus( (aNX[1]) )
   //SET ORDER TO 1
   GOTO TOP
   NUM_RELATORIO := 1
   M->TIPO_PRN   := "I"
   cCQ := iif( EMPTY(cCQ), 'NONE', cCQ )
   cRE := iif( EMPTY(cRE), 'NAO' , cRE )
   cSM := iif( EMPTY(cSM), 'NAO' , iif( cRE='NAO', 'NAO' , cSM ) )
   cST := iif( EMPTY(cST), 'NAO' , cST )
   cLP := iif( EMPTY(cLP), 80    , cLP )
   cWH := iif( EMPTY(cWH), 'NONE', cWH )
   M->LI_NHA=1
   M->PAG=1
   IF cCQ <> 'NONE'
      M->QUEBRA_1 = &cCQ
   ENDIF
   IF LEN(aGC) <> 0
      M->TOT_000[ 1]=0
      M->TOT_000[ 2]=0
      M->TOT_000[ 3]=0
      M->TOT_000[ 4]=0
      M->TOT_000[ 5]=0
      M->TOT_000[ 6]=0
      M->TOT_000[ 7]=0
      M->TOT_000[ 8]=0
      M->TOT_000[ 9]=0
      M->TOT_000[10]=0
      M->TOT_000[11]=0
      M->TOT_000[12]=0
      M->TOT_000[13]=0
      M->TOT_000[14]=0
      M->TOT_000[15]=0
      IF cST = 'SIM'
         M->TO1_000[ 1]=0
         M->TO1_000[ 2]=0
         M->TO1_000[ 3]=0
         M->TO1_000[ 4]=0
         M->TO1_000[ 5]=0
         M->TO1_000[ 6]=0
         M->TO1_000[ 7]=0
         M->TO1_000[ 8]=0
         M->TO1_000[ 9]=0
         M->TO1_000[10]=0
         M->TO1_000[11]=0
         M->TO1_000[12]=0
         M->TO1_000[13]=0
         M->TO1_000[14]=0
         M->TO1_000[15]=0
      ENDIF         
   ENDIF
   M->SAI_DA="S"
   cEmpresa:= "**** FatAll eVolution - TXTPreview ****"
   cPorta  := "LPT1"
   cFile   := "TXT"+substr(strtran(time(),":",""),4,3)+".PRN" 
   nLin    := 0
   nPag    := 0
   nLinMax := 56 // Padrao A4
   nItens  := nTotal := 0
   oPrn    := TDosPrn():New( cTextfile )
oPrn:StartPage()
//if !file( "logo.bmp" )
//   oPrn:SayImage(0,0,"logo.bmp",300,400,0)
//endif
DO WHILE .NOT. EOF()
   IF cWH <> 'NONE'
      IF ! &(cWH)
         SKIP
         LOOP
      ENDIF
   ENDIF
   IF M->LI_NHA=1
      nPag++
      nLin++
      oPrn:Command( oPrn:cNormal )
      oPrn:Say( M->LI_NHA, 00, PadC( "**** "+alltrim(cTI)+" ****", 79 ) )
      iif( val(cLP)>80,oPrn:Command( oPrn:cCompress),)
      oPrn:Say( M->LI_NHA+1, 00, "Pagina: "+strzero(nPag,3) )
      oPrn:Say( M->LI_NHA+1, iif( EMPTY(cLP), 80, VAL(cLP) ) -14, "Data: "+DTOC(DATE()))
      oPrn:Say( M->LI_NHA+2, 00, REPL("-",iif( EMPTY(cLP), 80, VAL(cLP) ) ))
      oPrn:Say( M->LI_NHA+3, 00, aHT[3]) 
      oPrn:Say( M->LI_NHA+4, 00, aHT[4])
      M->LI_NHA=6
   ENDIF
   IF cCQ <> 'NONE'
      M->QUEBRA_1 = &cCQ
   ENDIF
   IF cRE = 'SIM'
      M->SUM_000[ 1]=0
      M->SUM_000[ 2]=0
      M->SUM_000[ 3]=0
      M->SUM_000[ 4]=0
      M->SUM_000[ 5]=0
      M->SUM_000[ 6]=0
      M->SUM_000[ 7]=0
      M->SUM_000[ 8]=0
      M->SUM_000[ 9]=0
      M->SUM_000[10]=0
      M->SUM_000[11]=0
      M->SUM_000[12]=0
      M->SUM_000[13]=0
      M->SUM_000[14]=0
      M->SUM_000[15]=0
      DO WHILE M->QUEBRA_1 = &cCQ
         M->SUM_000[ 1]=M->SUM_000[ 1]+IIF(LEN(aGC)>= 1, &(aGC[ 1]), 0 )
         M->SUM_000[ 2]=M->SUM_000[ 2]+IIF(LEN(aGC)>= 2, &(aGC[ 2]), 0 )
         M->SUM_000[ 3]=M->SUM_000[ 3]+IIF(LEN(aGC)>= 3, &(aGC[ 3]), 0 )
         M->SUM_000[ 4]=M->SUM_000[ 4]+IIF(LEN(aGC)>= 4, &(aGC[ 4]), 0 )
         M->SUM_000[ 5]=M->SUM_000[ 5]+IIF(LEN(aGC)>= 5, &(aGC[ 5]), 0 )
         M->SUM_000[ 6]=M->SUM_000[ 6]+IIF(LEN(aGC)>= 6, &(aGC[ 6]), 0 )
         M->SUM_000[ 7]=M->SUM_000[ 7]+IIF(LEN(aGC)>= 7, &(aGC[ 7]), 0 )
         M->SUM_000[ 8]=M->SUM_000[ 8]+IIF(LEN(aGC)>= 8, &(aGC[ 8]), 0 )
         M->SUM_000[ 9]=M->SUM_000[ 9]+IIF(LEN(aGC)>= 9, &(aGC[ 9]), 0 )
         M->SUM_000[10]=M->SUM_000[10]+IIF(LEN(aGC)>=10, &(aGC[10]), 0 )
         M->SUM_000[11]=M->SUM_000[11]+IIF(LEN(aGC)>=11, &(aGC[11]), 0 )
         M->SUM_000[12]=M->SUM_000[12]+IIF(LEN(aGC)>=12, &(aGC[12]), 0 )
         M->SUM_000[13]=M->SUM_000[13]+IIF(LEN(aGC)>=13, &(aGC[13]), 0 )
         M->SUM_000[14]=M->SUM_000[14]+IIF(LEN(aGC)>=14, &(aGC[14]), 0 )
         M->SUM_000[15]=M->SUM_000[15]+IIF(LEN(aGC)>=15, &(aGC[15]), 0 )
         SKIP
      ENDDO
      SKIP -1
   ELSE
      M->SUM_000[ 1]=IIF(LEN(aGC)>= 1, &(aGC[ 1]), 0 )
      M->SUM_000[ 2]=IIF(LEN(aGC)>= 2, &(aGC[ 2]), 0 )
      M->SUM_000[ 3]=IIF(LEN(aGC)>= 3, &(aGC[ 3]), 0 )
      M->SUM_000[ 4]=IIF(LEN(aGC)>= 4, &(aGC[ 4]), 0 )
      M->SUM_000[ 5]=IIF(LEN(aGC)>= 5, &(aGC[ 5]), 0 )
      M->SUM_000[ 6]=IIF(LEN(aGC)>= 6, &(aGC[ 6]), 0 )
      M->SUM_000[ 7]=IIF(LEN(aGC)>= 7, &(aGC[ 7]), 0 )
      M->SUM_000[ 8]=IIF(LEN(aGC)>= 8, &(aGC[ 8]), 0 )
      M->SUM_000[ 9]=IIF(LEN(aGC)>= 9, &(aGC[ 9]), 0 )
      M->SUM_000[10]=IIF(LEN(aGC)>=10, &(aGC[10]), 0 )
      M->SUM_000[11]=IIF(LEN(aGC)>=11, &(aGC[11]), 0 )
      M->SUM_000[12]=IIF(LEN(aGC)>=12, &(aGC[12]), 0 )
      M->SUM_000[13]=IIF(LEN(aGC)>=13, &(aGC[13]), 0 )
      M->SUM_000[14]=IIF(LEN(aGC)>=14, &(aGC[14]), 0 )
      M->SUM_000[15]=IIF(LEN(aGC)>=15, &(aGC[15]), 0 )
   ENDIF
   //
   FOR I = 1 to LEN(aDC)
       cCampo := &(aDC[i])
       //if cSM = 'NAO'
       IF cSM = 'SIM'
          IF I=1; oPrn:Say( M->LI_NHA, aDT[i,1], Transform( cCampo, aDT[i,2] ) ); ENDIF
       ELSE
          oPrn:Say( M->LI_NHA, aDT[i,1], Transform( cCampo, aDT[i,2] ) )
       ENDIF
       //   oPrn:Say( M->LI_NHA, aDT[i,1], iif(cSM='NAO',cCampo,Transform( M->SUM_000[i], aDT[i,2] ) ) )
       //else
       //   cSomar := aDC[i]
       //   if cSomar = aGC[i]
       //      IF LEN(aGC)>=1; oPrn:Say( M->LI_NHA, aDT[i,1], Transform( M->SUM_000[i], aDT[i,2] ) ) ; ENDIF
       //   else
       //      oPrn:Say( M->LI_NHA, aDT[i,1], cCampo )
       //   endif
       //endif
   NEXT
   IF (LEN(aGC)<>0 .OR. cST = 'SIM') // SE SOMA OU RESUMO
      M->TOT_000[ 1]=M->TOT_000[ 1]+M->SUM_000[ 1]
      M->TOT_000[ 2]=M->TOT_000[ 2]+M->SUM_000[ 2]
      M->TOT_000[ 3]=M->TOT_000[ 3]+M->SUM_000[ 3]
      M->TOT_000[ 4]=M->TOT_000[ 4]+M->SUM_000[ 4]
      M->TOT_000[ 5]=M->TOT_000[ 5]+M->SUM_000[ 5]
      M->TOT_000[ 6]=M->TOT_000[ 6]+M->SUM_000[ 6]
      M->TOT_000[ 7]=M->TOT_000[ 7]+M->SUM_000[ 7]
      M->TOT_000[ 8]=M->TOT_000[ 8]+M->SUM_000[ 8]
      M->TOT_000[ 9]=M->TOT_000[ 9]+M->SUM_000[ 9]
      M->TOT_000[10]=M->TOT_000[10]+M->SUM_000[10]
      M->TOT_000[11]=M->TOT_000[11]+M->SUM_000[11]
      M->TOT_000[12]=M->TOT_000[12]+M->SUM_000[12]
      M->TOT_000[13]=M->TOT_000[13]+M->SUM_000[13]
      M->TOT_000[14]=M->TOT_000[14]+M->SUM_000[14]
      M->TOT_000[15]=M->TOT_000[15]+M->SUM_000[15]
      IF cST = 'SIM' // .or. cSM = 'SIM'
         M->TO1_000[ 1]=M->TO1_000[ 1]+M->SUM_000[ 1]
         M->TO1_000[ 2]=M->TO1_000[ 2]+M->SUM_000[ 2]
         M->TO1_000[ 3]=M->TO1_000[ 3]+M->SUM_000[ 3]
         M->TO1_000[ 4]=M->TO1_000[ 4]+M->SUM_000[ 4]
         M->TO1_000[ 5]=M->TO1_000[ 5]+M->SUM_000[ 5]
         M->TO1_000[ 6]=M->TO1_000[ 6]+M->SUM_000[ 6]
         M->TO1_000[ 7]=M->TO1_000[ 7]+M->SUM_000[ 7]
         M->TO1_000[ 8]=M->TO1_000[ 8]+M->SUM_000[ 8]
         M->TO1_000[ 9]=M->TO1_000[ 9]+M->SUM_000[ 9]
         M->TO1_000[10]=M->TO1_000[10]+M->SUM_000[10]
         M->TO1_000[11]=M->TO1_000[11]+M->SUM_000[11]
         M->TO1_000[12]=M->TO1_000[12]+M->SUM_000[12]
         M->TO1_000[13]=M->TO1_000[13]+M->SUM_000[13]
         M->TO1_000[14]=M->TO1_000[14]+M->SUM_000[14]
         M->TO1_000[15]=M->TO1_000[15]+M->SUM_000[15]
      ENDIF
   ENDIF
   IF cSM = 'SIM'
   ELSE
      M->LI_NHA=M->LI_NHA+1
   ENDIF
   SKIP
   IF cCQ <> 'NONE'
      IF M->QUEBRA_1 <> &cCQ
         IF cST = 'SIM'
            IF cSM = 'SIM'
            ELSE
               oPrn:Say( M->LI_NHA,000, REPL("-",LEN(aHT[3])) )
               M->LI_NHA=M->LI_NHA+1
               oPrn:Say( M->LI_NHA, 000, "SUBTOTAL" )
            ENDIF
            FOR I = 1 to LEN(aDC)
                cSomar := aDC[i]
                if cSomar = aGC[i]
                   IF LEN(aGC)>=1; oPrn:Say( M->LI_NHA, aDT[i,1], Transform( M->TO1_000[i], aDT[i,2] ) ) ; ENDIF
                endif
            NEXT
            IF cSM = 'SIM'
            ELSE
               M->LI_NHA=M->LI_NHA+2
            ENDIF
            M->TO1_000[ 1]=0
            M->TO1_000[ 2]=0
            M->TO1_000[ 3]=0
            M->TO1_000[ 4]=0
            M->TO1_000[ 5]=0
            M->TO1_000[ 6]=0
            M->TO1_000[ 7]=0
            M->TO1_000[ 8]=0
            M->TO1_000[ 9]=0
            M->TO1_000[10]=0
            M->TO1_000[11]=0
            M->TO1_000[12]=0
            M->TO1_000[13]=0
            M->TO1_000[14]=0
            M->TO1_000[15]=0
         ENDIF
         M->QUEBRA_1 = &cCQ
         M->LI_NHA   = M->LI_NHA+1
      ENDIF
   ENDIF
   IF LEN(aGC) <> 0 // Se SOMA campos
      IF M->LI_NHA>nLinMax
         MyTOT_01(oPrn, 1, aDC, aDT, aHT, aGC )
         M->LI_NHA:=1
      ENDIF
   ELSE
      IF M->LI_NHA>nLinMax+2
         oPrn:Say( M->LI_NHA+0, 00, REPL("-",iif( EMPTY(cLP), 80, VAL(cLP) ) ))
         oPrn:Say( M->LI_NHA+1, 00, "5Volution Legacy" )
         oPrn:Say( M->LI_NHA+1, iif(EMPTY(cLP),80,VAL(cLP))-len("Av. Itaberaba 1016, sala 9"), "Telefone: 3902-7354" )
         //oPrn:Command( oPrn:cCompress )
         M->LI_NHA:=1
      ENDIF
   ENDIF
ENDDO
IF LEN(aGC) <> 0 // Se SOMA campos
   MyTOT_01(oPrn, 2, aDC, aDT, aHT, aGC )
ELSE
   M->LI_NHA := nLinMax+2
   oPrn:Say( M->LI_NHA+0, 00, REPL("-",iif( EMPTY(cLP), 80, VAL(cLP) ) ))
   oPrn:Say( M->LI_NHA+1, 00, "SoftClever Informatica Comercio Ltda" )
   oPrn:Say( M->LI_NHA+1, iif(EMPTY(cLP),80,VAL(cLP))-len("Av. Itaberaba 1016, sala 9"), "Av. Itaberaba 1016, sala 9" )
ENDIF
oPrn:EndPage()
oPrn:End()
if lNoRel <> NIL
   TxtPreview( cTextfile, "Teste", .t.,,, oPrn )
else
   CLOSE DATABASES
   TxtPreview( cTextfile, "Teste", .f.,,, oPrn )
endif
//if cTextfile <> NIL
//   //Rep23( cTextfile, iif( EMPTY(cLP), 80, 132 ) )
//   fRename( '\clever\fatall\clever\NFWSPOOL.TXT', '\clever\fatall\clever\SPOOL.SPL' )
//endif

FUNCTION MyTOT_01( oPrn, PAR1, aDC, aDT, aHT, aGC )
IF PAR1=2
//   M->LI_NHA=nLinMax // 59
ENDIF
oPrn:Say( M->LI_NHA, 000, REPL("-",LEN(aHT[3])) )
M->LI_NHA=M->LI_NHA+1
IF PAR1=2
   oPrn:Say( M->LI_NHA, 000, "TOTAL" )
ELSE
   oPrn:Say( M->LI_NHA, 000, "SUBTOTAL" )
ENDIF
FOR I = 1 to LEN(aDC)
    cSomar := aDC[i]
    if cSomar = aGC[i]
       IF LEN(aGC)>=1; oPrn:Say( M->LI_NHA, aDT[i,1], Transform( M->TOT_000[i], aDT[i,2] ) ) ; ENDIF
    endif
NEXT
M->LI_NHA=M->LI_NHA+1
oPrn:Say( M->LI_NHA, 000, REPL("-",LEN(aHT[3])) )
M->LI_NHA=M->LI_NHA+1
oPrn:Say( M->LI_NHA, 000, " " )
M->LI_NHA=M->LI_NHA+1
RETURN .T.

Function Rep23(cTextfile,cLargura)  // To make this a reusable module, we pass
                           // the name of the text file to this function,
                           // so it can be re-used for many different files
                           // with the same margin and font settings.

     LOCAL nRecno, oFont
     IF cTextfile = NIL .OR. UPPER(cTextfile) = "LPT1"
        RETURN .T.
     ENDIF
     DEFINE FONT oFont NAME "COURIER" SIZE 0,-6
            // Font sizes for PRINTING are given in "points" not pixels.
            // (Pixels are used for font width and height for SCREENS only.)
            // By using a "0" for width and a "-" in front of the "height" #
            // we tell FiveWin that we're using points instead of pixels.

            // Thus -12 means "12 point," which is used for "10 pitch"
            // non-proportionally spaced Courier type that prints at
            // 6 lines/inch.

            // -10 means a 10 point font printing at 7 lines/inch.

            // Use -9 for a "12 pitch" equal-spaced Courier font printing
            // at 8 lines per inch.


            // Note that in creating the report object, we are leaving out
            // any mention of title or header specs. because those are
            // already included in our .TXT file.
     REPORT oReport ;
          FONT oFont ;
          CAPTION "Relatorio em tela" ;
          PREVIEW
//          TO PRINTER
     COLUMN DATA " " SIZE cLargura // * Trick "Data" - we're fooling Mother 
                              // Nature here. The memo will go into the " ". *
     END REPORT
             // All title lines, page numbers and headings already exist in
             // our text file, so the next two code statements make sure that
             // FiveWin won't add its own title lines.
     oReport:nTitleUpLine := RPT_NOLINE
     oReport:nTitleDnLine := RPT_NOLINE
     oReport:Margin(.01,RPT_LEFT  ,RPT_INCHES)   // .15
     oReport:Margin(.01,RPT_TOP   ,RPT_INCHES)    // .25
     oReport:Margin(.01,RPT_BOTTOM,RPT_INCHES) // .25
     // I know the top/bottom margins shown here should mathematically cause
     // more than the desired 60 lines per page to print. However, in actual 
     // practice with my Panasonic KXP 4450 laser printer emulating the 
     // HP LaserJet Plus, this is what I had to use to get 60 lines.  Why?
     // Inscrutible printer driver!  Maybe your printer driver functions in
     // a more mathematically logical fashion.  If so, adjust accordingly.
     // The left margin is set so small here because a margin is already
     // built into the text file itself (in this particular case).

     ACTIVATE REPORT oReport ;
          ON INIT SayMemo2(cTextfile,cLargura)

     oFont:End()
   RETURN NIL

STATIC Function SayMemo2(cTextfile,cLargura)
     LOCAL cText, cLine
     LOCAL nFor, nLines, nPageln
     cText := MEMOREAD( (cTextfile) )
     nLines := MlCount(cText,cLargura) // Original text has up to 76 chars. per line.
     nPageln := 0
     *oReport:BackLine(1)     // Not needed here. If used, will cause printing
                              // of subsequent pages to get out of synch by
                              // pushing the start of printing down 1 line
                              // per page.
     FOR nFor := 1 TO nLines
          cLine := MemoLine(cText, cLargura, nFor)
          oReport:StartLine()
          oReport:Say(1,cLine)
          oReport:EndLine()
             // The following section checks to see if we've reached the
             // bottom of the page (60 lines). If so, it then calls
             // GetTop() to eliminate empty spaces in the text file between
             // the bottom of the outgoing page and the top line of the
             // next page.  The intent of this code is to get rid of the
             // empty lines that most report generators insert between pages
             // when output is to a text file -- otherwise our page printing
             // would get out of synch with the formating of the original
             // report. This approach only works where printing (including the
             // page number and other page heading data) is supposed to appear
             // at the same place at the top of every page.  
          nPageln := nPageln + 1
          IF nPageln = 60
             nFor := GetTop(cText,nFor,nLines,cLargura)
             nPageln := 0
          ENDIF
     NEXT
     *oReport:Newline()  // Only activate this line if you need to have the
                         // program eject another page upon completing printing.
   RETURN NIL

STATIC FUNCTION GetTop(cText,nFor,nLines,cLargura)
   LOCAL Test := .T.,cLine
   DO WHILE Test = .T. .AND. nFor <= nLines
      nFor := nFor + 1
      cLine := MemoLine(cText, cLargura, nFor)
      TEST := EMPTY(cLine)
   ENDDO
   nFor := nFor - 1
   SysRefresh()   // Inserted to allow Windows to catch up with housekeeping
                  // that was held up during the "DO WHILE."
   RETURN nFor
User avatar
Roger Seiler
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA
Contact:

Post by Roger Seiler »

I originally wrote Rep23, upon which Rochinha based some of his programming. Since then, I have greatly improved it and converted it to OOP. Improvements include capabilities for assigning a different font to each field of data and the use of graphics - lines, boxes, shadows and bitmaps.

Anyone who would like a copy of the current version (and its companion .PRGs) can get it by downloading from...

http://www.leadersoft.com/software/TstRpt23.zip

Together with TReport, it provides the basic report output engine. What it needs is a good graphical front end for designing reports. (I still use R&R and the R&R Clipper Code Generator for designing reports, and then convert the generated code so it can work with TRept23.) This approach enables providing reports completely within your main app .exe with complete control, instead of having to depend on someone else's runtime module (i.e. Crystal Reports).

One of the included PRGs - PrintAdj.prg - automatically determines which printer is the default for a workstation and then automatically enters printing adjustment factors into a "MyApp.ini" file so that printing with TRept23 will be properly aligned on that printer.

Feel free to use it. If you decide to use TRept23, please share any improvements that you make on this forum.

- Roger
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

GX Reports

Post by TimStone »

Reinaldo,

I worked closely with Rene testing the GX Reports and then his follow up project which still exists. I think its safe to say he was burned out with some unpleasant experiences "marketing" GX and so he moved on to the Visual Studio crowd hoping for a better audience for his products. I found GX to be stable and encouraged him to bring the same features to 32 bit.

I think its fair to say he was frustrated with the same type of line I often see on this forum which is "we need something for free." I'm not against Open Source projects, but I am amazed at how often people assume they should get professional products without paying. Most of us know we can't live in a home, eat a good diet, and care for our families without an income. Sometimes the idea that "it should be free" is quickly translated to "its ok to pass it around and not pay the programmer." When that happens, the 3rd party vendors finally walk away.

Over the years ( and I've seen many ... I've been writing programs since CP/M ) I've seen a lot of excellent 3rd party products be terminated because the developers could not earn enough to continue with their work.

I like the idea of a report generator that my clients can use. However, I do all of the reports in my software in my editor and they work fine. After all, reports are really data, not publications, so they are not hard to design using the tPrinter class.

:D
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
Ollie
Posts: 233
Joined: Sat Dec 30, 2006 6:10 am

Post by Ollie »

I found FAST REPORT which I thought may be interesting to this thread.

Their site is : http://fast-report.com/en/

They have a working XBase++ Demo, so I'm sure it can be used with FWH. See: http://www.hotsoft.ru/ALASKA/frax_eng.htm

Thanks to Angel Canudas, you can see a working demo at: http://www.canudas.com/xbase

There is a FREE Report Generator as well.

http://fast-report.com/en/products/free ... elphi.html

Another topic in this forum: http://fivetechsoft.com/forums/viewtopi ... ast+report
Many thanks
Ollie.

Using:
xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6406)
Borland C++ 5.5.1
FWH 9.04 (2009 Apr)
User avatar
dutch
Posts: 1395
Joined: Fri Oct 07, 2005 5:56 pm
Location: Thailand

Post by dutch »

Dear All,

I develop my program with R&R V.5 for DOS since 1997. All my program use R&R. I've no hardcode printing because all my client need to change some in all forms. While we use R&R and now R&R is version 12 with support SQL. I can import all form since DOS Version to Windows Version and I can distribute my Report Format to any client without any change in my program. I just send only setup screen image and report format file (.RRW). R&R can export to many format but not quite good in some format.

Anyway, The R&R support is very good and helpful.

This is the screen in my program.
Image
This is my Report Properties (my code) you can use Query in program or send Query from setup screen to override in R&R.
Image
This is the R&R Designer call from source code.
Image
This is user define prompt from setup screen.
Image

Best regards,
Dutch
User avatar
Patrick Mast
Posts: 244
Joined: Sat Mar 03, 2007 8:42 pm

Re: GX Reports

Post by Patrick Mast »

TimStone wrote:I think its fair to say he was frustrated with the same type of line I often see on this forum which is "we need something for free." I'm not against Open Source projects, but I am amazed at how often people assume they should get professional products without paying. Most of us know we can't live in a home, eat a good diet, and care for our families without an income. Sometimes the idea that "it should be free" is quickly translated to "its ok to pass it around and not pay the programmer." When that happens, the 3rd party vendors finally walk away.
FINALLY someone who understands.. ;-)

Patrick
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Understanding

Post by TimStone »

Patrick,

Its not just programmers and their tools. I have hundreds of clients who have used the DOS version of my program for 10, 15, 20 years and still think I should support it for Free. Since it works, they don't want to pay to upgrade to windows. I hear every excuse in the book, like "Bob didn't treat me right so you owe me." Of course, Bob hasn't been with the company for about 19 years.

THe problem is that I have to base my purchase decisions on being able to sell product which, when slow, means I can't afford to invest in new or updated tools. Its a delicate balancing act. Making improvements may satisfy my current client base, but means nothing to buyers of upgrades or new clients. Thats why I appreciate reasonable pricing for updates offered by many companies.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
Kleyber
Posts: 581
Joined: Tue Oct 11, 2005 11:28 am
Location: São Luiz, Brasil

Post by Kleyber »

Tim,
Its not just programmers and their tools. I have hundreds of clients who have used the DOS version of my program for 10, 15, 20 years and still think I should support it for Free. Since it works, they don't want to pay to upgrade to windows. I hear every excuse in the book, like "Bob didn't treat me right so you owe me." Of course, Bob hasn't been with the company for about 19 years.

THe problem is that I have to base my purchase decisions on being able to sell product which, when slow, means I can't afford to invest in new or updated tools. Its a delicate balancing act. Making improvements may satisfy my current client base, but means nothing to buyers of upgrades or new clients. Thats why I appreciate reasonable pricing for updates offered by many companies.
I have the same situation here in Brazil and I entirely agree with you.

Best regards,
Kleyber Derick

FWH / xHb / xDevStudio / SQLLIB
User avatar
dutch
Posts: 1395
Joined: Fri Oct 07, 2005 5:56 pm
Location: Thailand

Post by dutch »

I absolutely agree with you Tim. My client thought we don't do anything only keep the system stable (support). They do not get anything new, why they have to pay for help&support. I say, how can we serve (alive) you without pay (forever). It has nothing for free, you have to pay in some way (money or labor).

Regards,
Dutch
Randal
Posts: 250
Joined: Mon Oct 24, 2005 8:04 pm

Post by Randal »

Dutch,

Your customers are willing to pay for the R&R report designer?

Regards,
Randal
dutch wrote:Dear All,

I develop my program with R&R V.5 for DOS since 1997. All my program use R&R. I've no hardcode printing because all my client need to change some in all forms. While we use R&R and now R&R is version 12 with support SQL. I can import all form since DOS Version to Windows Version and I can distribute my Report Format to any client without any change in my program. I just send only setup screen image and report format file (.RRW). R&R can export to many format but not quite good in some format.

Anyway, The R&R support is very good and helpful.

This is the screen in my program.
Image
This is my Report Properties (my code) you can use Query in program or send Query from setup screen to override in R&R.
Image
This is the R&R Designer call from source code.
Image
This is user define prompt from setup screen.
Image

Best regards,
Dutch
User avatar
dutch
Posts: 1395
Joined: Fri Oct 07, 2005 5:56 pm
Location: Thailand

Post by dutch »

Dear Randal,

I give them only runtime, the designer is in my laptop. The customer site can only change the query and user prompt only. If they need to change just ask me to do it.

Regards,
Dutch
Randal
Posts: 250
Joined: Mon Oct 24, 2005 8:04 pm

Post by Randal »

Dutch,

I see. I've used R&R for a long time. One of my major gripes about it is you cannot create a report with a custom page size on one computer and have that report work on another computer. We have a lot of customers that use dot matrix printers with forms other than 11" in length. If I create a report with a page size other than 11" it will not work on their computer (unless they have the report designer). The way Windows handles page sizes changed in NT and above and R&R - well aware of this problem - will not update their program to fix this. Too bad.

Thanks,
Randal
dutch wrote:Dear Randal,

I give them only runtime, the designer is in my laptop. The customer site can only change the query and user prompt only. If they need to change just ask me to do it.

Regards,
Dutch
User avatar
dutch
Posts: 1395
Joined: Fri Oct 07, 2005 5:56 pm
Location: Thailand

Post by dutch »

I got it. It has other problem such as
- xBase edition report form save the database location in form. The problem is you cannot copy form one folder to another folder (two set of database)
- Export to Excel cannot to do all line (can only one selected line)

But it still have many good features and easy to distribute to customer.

I love it.

Regards,
Dutch
User avatar
Roger Seiler
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA
Contact:

Post by Roger Seiler »

Dutch and Randall,

A year ago you mentioned having used R&R to design reports, with pros and cons. Also mentioned distributing the R&R runtime to the customer to run the reports.

I also use R&R (last DOS version) to design reports. Then I use the R&R Clipper code generator, which converts the R&R report file into clipper code. I then make a few custom modifications to the Clipper code (where the page length problem Randall mentioned can be corrected). This Clipper code prg version of the report doesn't require distribution of the R&R runtime, and the report's prg module compiles as an xHarbour/FWH prg (with a few standard mods that I make to each report prg to make it work in xHb/FWH). The report created by running this prg module is passed as either a mem variable or a text file to TRept23.prg (my updated version of my original Rep23.prg) for preview and printing. I like this approach because I have complete control over it - no reliance on someone else's runtime engine - and I can change the inner workings of the report any way I want. Works great!

If you want to try this approach and don't have the R&R Clipper code generator, I think you can still get it from R&R at a very reasonable cost.

- Roger
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

I use Easy Report, which is written in FIVEWIN.
I don’t understand why not more of you use this product.

Is there a reason I don’t know about.
Regards,
Otto
Post Reply