Ajuda com Filtro

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

braz
Usuário Nível 2
Usuário Nível 2
Mensagens: 53
Registrado em: 08 Jan 2011 17:39
Localização: piracicaba

Ajuda com Filtro

Mensagem 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))
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Ajuda com Filtro

Mensagem 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.
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Ajuda com Filtro

Mensagem 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.
[]´s
Alexandre Santos (AlxSts)
braz
Usuário Nível 2
Usuário Nível 2
Mensagens: 53
Registrado em: 08 Jan 2011 17:39
Localização: piracicaba

Ajuda com Filtro

Mensagem 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
esbaptista
Usuário Nível 1
Usuário Nível 1
Mensagens: 20
Registrado em: 06 Fev 2007 10:37

Ajuda com Filtro

Mensagem por esbaptista »

eu faria lacos com do while .. enddo
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Ajuda com Filtro

Mensagem 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))
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Ajuda com Filtro

Mensagem 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.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
braz
Usuário Nível 2
Usuário Nível 2
Mensagens: 53
Registrado em: 08 Jan 2011 17:39
Localização: piracicaba

Ajuda com Filtro

Mensagem 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
Responder