Página 1 de 1

Ajuda com Filtro

Enviado: 14 Jul 2011 14:35
por braz
Ola pessoal, sou novo no clipper e gostaria que vcs me dessem uma ajuda, tenho essa rotina no meu sistema, mas ta muito lento, eu sei que tem como melhorar isso, mas eu não sei, se alguem puder me ajudar , eu agradeço.

Eu uso clipper 5.3, rdd ntx,

abraços

Código: Selecionar todos

SELE 3

      set filter to cod_empr=xempresa .and. me_ano=xdata
      if ordem = "D"
          dbsetorder(1) //index on dt_entr to I_data2
      *   index on dt_entr to tmp1 while cod_empr=xempresa .and. me_ano = xdata
      else
          dbsetorder(4) //index on n_nf to I_nf
       *  index on n_nf to tmp1 while cod_empr=xempresa .and. me_ano = xdata
      endif

      DECLARE VETOR_CAMPOS[28]
      VETOR_CAMPOS[1] = 'CHAVE'
      VETOR_CAMPOS[2] = 'N_NF'
      VETOR_CAMPOS[3] = 'SERIE'
      VETOR_CAMPOS[4] = 'DT_ENTR'
      VETOR_CAMPOS[5] = 'ESPECIE'
      VETOR_CAMPOS[6] = 'DT_NF'
      VETOR_CAMPOS[7] = 'substr(EMITENTE,1,25)'
      VETOR_CAMPOS[8] = 'COD_FISC'
      VETOR_CAMPOS[9] = 'VR_CONTABI'
      VETOR_CAMPOS[10]= 'BC_ICMS'
      VETOR_CAMPOS[11]= 'ALI_ICMS'
      VETOR_CAMPOS[12]= 'ICMS'
      VETOR_CAMPOS[13]= 'ISENTOICMS'
      VETOR_CAMPOS[14]= 'OUTRASICMS'
      VETOR_CAMPOS[15]= 'IPI_ICMS'
      vetor_campos[16]= 'Icms_ret'
      VETOR_CAMPOS[17]= 'BC_IPI'
      VETOR_CAMPOS[18]= 'IPI'
      VETOR_CAMPOS[19]= 'ISENTOIPI'
      VETOR_CAMPOS[20]= 'OUTRASIPI'
      VETOR_CAMPOS[21]= 'VCONT'
      VETOR_CAMPOS[22]= 'BCICMS'
 *    VETOR_CAMPOS[23]= 'PETRO'
      VETOR_CAMPOS[23]= 'OUTRAS'
*      VETOR_CAMPOS[25]= 'OUTROS'
      VETOR_CAMPOS[24]= 'UFFORA'
      VETOR_CAMPOS[25]= 'cod_empr'
      VETOR_CAMPOS[26]= 'ME_ANO'
      VETOR_CAMPOS[27]= 'COD_CONT'
      VETOR_CAMPOS[28]= 'FORNECEDOR'
      @1,1 clear to 24,79
      @01,2 say 'Empresa: '+XNOME+space(3)+xdata+'   '+'Entradas'
      @2,1 to 21,77
      sum vr_contabi to aaaa
      sum bc_icms to bbbb
      sum icms to cccc
      sum isentoicms to dddd
      sum outrasicms to eeee
      sum ipi_icms to ffff
      sum icms_ret to gggg

      @22,02 say 'Vr.Cont: '+str(aaaa,12,2) color'gr+/w'
      @22,25 say 'BC.ICMS: '+str(bbbb,12,2) color'gr+/w'
      @22,50 say 'ICMS:    '+str(cccc,12,2) color'gr+/w'

      @23,02 say 'Isento:  '+str(dddd,12,2) color'gr+/w'
      @23,25 say 'Outras:  '+str(eeee,12,2) color'gr+/w'
      @23,50 say 'IPI:     '+str(ffff,12,2) color'gr+/w'

      @24,2 say 'ICMS Ret: '+str(gggg,12,2) color'gr+/w'
      @24,50 say 'Diferenca: '+str((diferenca/100),12,2) color'r+/w*'
      if diferenca > 0
         wait"cuidado tem diferencas"
      elseif diferenca < 0
         wait"cuidado tem diferencas"
      endi
      go top
      DBEDIT(3,2,20,76,VETOR_CAMPOS,"editabb",,,+CHR(196)+CHR(194)+CHR(196))

Ajuda com Filtro

Enviado: 14 Jul 2011 19:38
por sygecom
Olá Braz,

Se migrar para CDX você pode usar ORDSCOPE() que terá um ganho de performance enorme em filtros, e se migrar para Harbour ai nem se fala, você além de ter melhor desempenho, você vai ficar ilimitado.
Avalie a possibilidade, boa sorte.

Ajuda com Filtro

Enviado: 15 Jul 2011 00:21
por alxsts
Olá!

As recomendações do Leonardo são, sem dúvida, importantes. Mesmo que você não mude para [x]Harbour, se migrar para DBFCDX, já poderá fazer uso da função OrdScope() ou OrdWildScope().

Caso você não possa seguí-las, creio que, mesmo em Clipper, seja possível melhorar a performance do teu aplicativo.

Observando o código, ví que você invoca o comando SUM por sete vezes. Isto faz com que a tabela seja lida sete vezes, o que por si só já consome muito tempo. Se considerarmos que existem um índice e um filtro ativos... muito mais tempo é consumido.

Sugiro que você faça uma única leitura na tabela, acumulando os valores desejados para o filtro desejado. Para isto, use a função DBEval().

Se precisar de ajuda, poste novamente.

Ajuda com Filtro

Enviado: 15 Jul 2011 09:40
por braz
Obrigado pelas respostas.

Na verdade, eu ja compilo usando o xharbor, mesmo assim fica lento, na forma apresentada.

Como faço pra usar esses OrdScope() ou OrdWildScope(), ou esse dbeval().?

Grato

Ajuda com Filtro

Enviado: 15 Jul 2011 10:17
por esbaptista
eu faria lacos com do while .. enddo

Ajuda com Filtro

Enviado: 15 Jul 2011 12:34
por alxsts
Olá!
braz escreveu:Como faço pra usar esses OrdScope()
A função OrdScope( <ScopeTop>, <ScopeBottom> ) permite que você visualize apenas uma faixa dos dados de uma tabela. Para isto, deverá existir um índice que satisfaça a necessidade. Por exemplo: se quiser processar apenas os registros de um determinado período, deverá existir um índice por data (Index On DtoS( CampoData ).
braz escreveu:...ou esse dbeval()
Fiz algumas alterações no teu código. Veja:

Código: Selecionar todos

LOCAL nVlContabil   := 0
LOCAL nVlBcIcms     := 0
LOCAL nVlIcms       := 0 
LOCAL nVlIsentoicms := 0
LOCAL nVlOutrasicms := 0
LOCAL nVlIpi_icms   := 0
LOCAL nVlIcms_ret   := 0
LOCAL bFilter
LOCAL aCampos

SELE 3

      //set filter to cod_empr=xempresa .and. me_ano=xdata
      if ordem = "D"
          dbsetorder(1) //index on dt_entr to I_data2
      *   index on dt_entr to tmp1 while cod_empr=xempresa .and. me_ano = xdata
      else
          dbsetorder(4) //index on n_nf to I_nf
       *  index on n_nf to tmp1 while cod_empr=xempresa .and. me_ano = xdata
      endif

      aCampos := { 'CHAVE', ;
                   'N_NF', ;
                   'SERIE', ;
                   'DT_ENTR', ;
                   'ESPECIE', ;
                   'DT_NF', ;
                   substr(EMITENTE,1,25)', ;
                   'COD_FISC', ;
                   'VR_CONTABI', ;
                   'BC_ICMS', ;
                   'ALI_ICMS', ;
                   'ICMS', ;
                   'ISENTOICMS', ;
                   'OUTRASICMS', ;
                   'IPI_ICMS', ;
                   'Icms_ret', ;
                   'BC_IPI', ;
                   'IPI', ;
                   'ISENTOIPI', ;
                   'OUTRASIPI', ;
                   'VCONT', ;
                   'BCICMS', ;
                   'OUTRAS', ;
                   'UFFORA', ;
                   'cod_empr', ;
                   'ME_ANO', ;
                   'COD_CONT', ;
                   'FORNECEDOR', ;
                }   
         
      @1,1 clear to 24,79
      @01,2 say 'Empresa: '+XNOME+space(3)+xdata+'   '+'Entradas'
      @2,1 to 21,77

      //sum bc_icms to bbbb
      //sum icms to cccc
      //sum isentoicms to dddd
      //sum outrasicms to eeee
      //sum ipi_icms to ffff
      //sum icms_ret to gggg

      // monta o filtro  
      bFilter := { || cod_empr=xempresa .and. me_ano=xdata }

      // percorre o arquivo uma unica vez, acumulando os valores
      DbEval( { || nVlContabil    += vr_contabi, ;
                   nVlBcIcms     += bc_icms, ;
                   nVlIcms       += icms, ; 
                   nVlIsentoicms += isentoicms, ;
                   nVlOutrasicms += outrasicms, ;
                   nVlIpi_icms   += ipi_icms, ;
                   nVlIcms_ret   += icms_ret ;
              }, bFilter ;
            )   


      @22,02 say 'Vr.Cont: '+str(nVlContabil,12,2) color'gr+/w'
      @22,25 say 'BC.ICMS: '+str(nVlBcIcms,12,2) color'gr+/w'
      @22,50 say 'ICMS:    '+str(nVlIcms,12,2) color'gr+/w'

      @23,02 say 'Isento:  '+str(nVlIsentoIcms,12,2) color'gr+/w'
      @23,25 say 'Outras:  '+str(nVlOutrasicms,12,2) color'gr+/w'
      @23,50 say 'IPI:     '+str(nVlIpi_Icms,12,2) color'gr+/w'

      @24,2 say 'ICMS Ret: '+str(nVlIcms_ret,12,2) color'gr+/w'

      // onde é calculado o campo diferenca?

      @24,50 say 'Diferenca: '+str((diferenca/100),12,2) color'r+/w*'
      if diferenca > 0
         Alert( "cuidado tem diferencas" )
      elseif diferenca < 0
         Alert( "cuidado tem diferencas" )
      endif

      // se precisar do filtro...
      set filter to Eval( bFilter )
      go top

      DBEDIT(3,2,20,76,aCampos,"editabb",,,+CHR(196)+CHR(194)+CHR(196))

Ajuda com Filtro

Enviado: 15 Jul 2011 12:55
por Maligno
Uma observação: apesar da recomendação para troca de compilador ser válida, por vários aspectos, é importante dar-se conta de que essa troca por si só não garante nenhum ganho de performance, como você mesmo observou. Filtro é coisa pra ser utilizada em pequenos conjuntos de dados; coisa que é possível até mesmo com uma grande base de dados. A aparente incoerência se justifica pelo uso de um índice composto, com o qual se pode estabelecer um escopo, o que limita a visibilidade dos dados, aumentando a velocidade da filtragem tremendamente. Mas já indicaram o caminho: índices compostos e uma reavaliação do seu código.

Ajuda com Filtro

Enviado: 18 Jul 2011 09:15
por braz
Ola Alexandre, deu certinho, e ficou bem rapidinho.

Muito obrigado, vou usar esse dbeval() em outras partes do programa tambem.

Valeu mesmo. Abração