OrdScope perde o filtro

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

OrdScope perde o filtro

Mensagem por rubens »

Itamar... Boa tarde...

Segura as palavrão aí que a cuca aqui num tá te acompanhando muito bem não...

Seguinte quanto a questão do filtro consegui visualizar. Num é porque ele mudou de grupo que ele irá refazer o filtro usando somente a data.. ok.. Fiz o teste começando do grupo 002 e aconteceu exatamente o que você falou... o filtro é pro arquivo inteiro e não só para o grupo atual.

Agora se vai usar o filtro no arquivo inteiro não importa se ele usa minha lógica no relatório ou a sua certo...? no exemplo abaixo que voce passou, quando ele mudar de grupo vai continuar pegando a data inferior ao filtro porque ele está filtrando o arquivo inteiro... ou seja quando sair do grupo 001 e entrar no grupo 002 vai continuar pegando a data 10/06/2010. Pelo que entendi voce mandou filtrar, daí no laço ele pega o codigo do grupo e começa um laço interno enquanto o grupo do arquivo for igual ao grupo da memoria. Quando finaliza esse laço ele verifica se e o ultimo grupo se for ele sai do laço... Toda vez que termina um grupo ele faz uma comparação se é o ultimogrupo para sair do laço. Até aqui tudo bem...
Mas pelo que entendi não houve mudança no filtro continuou do jeito que tava, daí só vai pular de grupo mas a filtragem de data continua "errada" porque tá pegando datas que não deveria. Certo ?

* Depois que postei isso aí fui analisar de novo e consegui entender sua lógica... A cada mudança de grupo você refez a filtragem com o ordscope()... vou tentar implementar desse jeito aí para ver se funciona...

Obrigado

Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

OrdScope perde o filtro

Mensagem por Itamar M. Lins Jr. »

Pode usar ai sem medo de errar, é só correr p/ o abraço!

Código: Selecionar todos

DBSelectArea('IVEN')
 DBSetOrder(7)
lUltimoGrupo := .F.
WHILE !EOF()
 
 cCODGRU := IVEN->CODGRU_
 cNOMGRU := NOMGRU( cCODGRU)

 ORDSCOPE(0,cCodGru+DTOS(dDTINI))
 ORDSCOPE(1,cCodGru+DTOS(dDTFIM))
 DBGOTOP()
 
 MOSTRA('SOMANDO VENDAS DO GRUPO -> '+GRU->CODGRU_ + '-' + GRU->NOMGRU_ )
 
 nCUSTOGRU := 0.00
 nVENDAGRU := 0.00
 lACHOUVENDA := .F.
 
 WHILE IVEN->CODGRU_ = cCODGRU
 
  lACHOUVENDA := .T. 

  // ACHA PRECO DE CUSTO
  cCODPRO := IVEN->CODPRO_
  nCUSTOPRO := 0.00
  
  DBSelectArea('PRO')
  DBSetOrder(1)
  DBGOTOP()
  IF DBSEEK( cCODPRO )
  IF cPRECO = 'N'
   nCUSTOPRO := PRO->CUSTONT_
   ELSE
   nCUSTOPRO := PRO->PRCUSTO_
  ENDIF
  ELSE
  nCUSTOPRO := IVEN->VALOR_ 
  ENDIF
  
  nCUSTOGRU += (nCUSTOPRO * IVEN->QTDE_)
  nVENDAGRU += (IVEN->VALOR_ * IVEN->QTDE_)
  
  DBSelectArea('IVEN')
  DBSKIP()
  
 ENDDO 

 IF lUltimoGrupo 
   exit
 ENDIF

 IF inv->codGru_ == cCodGru2
   lUltimoGrupo := .T. 
 ENDIF

ENDDO

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

OrdScope perde o filtro

Mensagem por Itamar M. Lins Jr. »

Acordei hoje... ainda assim não vai funcionar, o melhor é com array(letras) e FOR NEXT no laço, como havia dito antes.

Código: Selecionar todos

Por exemplo cCodGru1 := "003" e cCodGru2 :="009"

FOR y := val(cCodGru1) to val(cCodGru2 )
 
//Faz o filtro do grupo por periodo
 ORDSCOPE(0,strzero(y,3)+DTOS(dDTINI))
 ORDSCOPE(1,strzero(y,3)+DTOS(dDTFIM))
 DBGOTOP() //Vai p/ inicio do filtro

 //mas nem precisa disso aqui porque não entra no DO While mesmo!!!
 IF bof() .or. eof()
   msg( "não achou nada desse grupo nesse periodo" )
   loop
 ENDIF
 
 cCODGRU := IVEN->CODGRU_
 cNOMGRU := NOMGRU( cCODGRU)

Do WHILE IVEN->CODGRU_ = cCODGRU .and. !eof()

skip

ENDDO

NEXT

Saudações,
Itamar M. Lins Jr.
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

OrdScope perde o filtro

Mensagem por rubens »

Itamar...

Agora que vi sua última postagem... Na verdade nem tentei porque usando a última postagem sua e fazendo uns ajustes com tecnologia gambiarrachion eu consegui rodar de forma que me deixou satisfeito. olha o código pronto:

Código: Selecionar todos

   DBSelectArea('IVEN')
   DBSetOrder(7)
   DBGOTOP()
	
	cProGrupo 	:= cCODGRU1  // - Necessário para criar o flag para o proximo filtro 

   WHILE !EOF()
   
   	cCODGRU 		:= cProGrupo 
      cNOMGRU 		:= NOMGRU(cCODGRU)
 		cProGrupo 	:= Strzero( Val (cProGrupo)+1,3 )  // - Já prepara o próximo grupo para o filtro
      
      DBSelectArea('IVEN')
	   ORDSCOPE(0,cCodGru+DTOS(dDTINI))
	   ORDSCOPE(1,cCodGru+DTOS(dDTFIM))
	   DBGOTOP()

	   lTEMVENDA := .F.    // - a mesma logica que voce pensou aí para grupo nao encontrado
	   WHILE !EOF()
	   	lTEMVENDA := .T.
	   	EXIT
			DBSKIP()
		ENDDO
	   IF !lTEMVENDA     // se nao encontrado zera o filtro e pula para proximo grupo
			ORDSCOPE(0,)
		   ORDSCOPE(1,)
	   	DBGOTOP()
	   	LOOP
   	ENDIF
	   DBGOTOP()
	   
   	MOSTRA('SOMANDO VENDAS DO GRUPO -> '+GRU->CODGRU_ + '-' + GRU->NOMGRU_ )
      
      nCUSTOGRU 	:= 0.00
      nVENDAGRU 	:= 0.00
      
      WHILE IVEN->CODGRU_ = cCODGRU
      
         // ACHA PRECO DE CUSTO
         cCODPRO 		:= IVEN->CODPRO_
         nCUSTOPRO 	:= 0.00
         
         DBSelectArea('PRO')
         DBSetOrder(1)
         DBGOTOP()
         IF DBSEEK( cCODPRO )
         	IF cPRECO = 'N'
         		nCUSTOPRO := PRO->CUSTONT_
        		ELSE
        			nCUSTOPRO := PRO->PRCUSTO_
				ENDIF
         ELSE
         	nCUSTOPRO := IVEN->VALOR_ 
        	ENDIF
        	
      	nCUSTOGRU += (nCUSTOPRO    * IVEN->QTDE_)
      	nVENDAGRU += (IVEN->VALOR_ * IVEN->QTDE_)
      	
         DBSelectArea('IVEN')
         DBSKIP()

      ENDDO
      
     	AADD(GRUPO    , cCODGRU )
      AADD(NOMGRU   , cNOMGRU )
      AADD(CUSTO    , nCUSTOGRU )
      AADD(VENDA    , nVENDAGRU )
      AADD(DIFE     , nVENDAGRU-nCUSTOGRU )
	   nTOTCUSTO += nCUSTOGRU
		nTOTVENDA += nVENDAGRU 
		nTOTDIFE	 += nVENDAGRU-nCUSTOGRU

	   IF cProGrupo > cCODGRU2    // -aqui nao precisou de um flag para o fim. Se o proximo grupo for maior do que segundo grupo já finaliza
	      EXIT
	   ENDIF

 		DBSelectArea('IVEN')
	   ORDSCOPE(0,)
	   ORDSCOPE(1,)
	   DBGOTOP()
  		
   ENDDO
Obrigado... sem sua ajuda não teria conseguido dessa forma...
As vezes o professor não pode perder a cabeça e nem desistir do aluno.. obrigado...
Ah... e prepara a água de coco porque nesse pedacinho de paraíso que você mora aí... qualquer hora dessa uns clipharbeiros batem aí na sua porta...

Obrigado
Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

OrdScope perde o filtro

Mensagem por Jairo Maia »

Fazer o que não é.....
rubens escreveu:Ah... e prepara a água de coco porque nesse pedacinho de paraíso que você mora aí...
Pois é, Para nós só aplaudir...
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

OrdScope perde o filtro

Mensagem por Itamar M. Lins Jr. »

É, aqui eu também sou aluno.
Então mesmo usando sua gabiarrechon ai não vai dar certo.
Tem que usar FOR NEXT! para ficar mais smart!!!
Imagine a seguinte situação:

001 2014 10 01
002 2014 10 01
002 2014 10 01
002 2014 10 01
002 2014 10 01
003 2014 10 01
003 2014 10 01
003 2014 10 01
004 2014 10 01
004 2014 10 01

cCodGru1 := "001"
cCodGru2 := "004"

Você tem apenas 4 grupos, não precisa dar DO WHILE (passar um por um dos registros) basta apenas 4 filtros entendeu ? Não precisa da 10 skip's OK!
Com 4 FOR NEXT vc resolve isso! ainda tem um GO TOP que vc colocou no final do DO WHILE...
Da forma que vc fez, em (1000)mil registros x 10 grupos, vai varrer o DBF todo sem necessidade 1000 vezes p/ cada grupo!!!

Código: Selecionar todos

FOR n:= val(cCodGru1) to val(cCodGru2)

//Faz o filtro!
ORDSCOPE(strzero(n,3)+dtos(dtINICIO)) //"001" + 2014 10 01
ODRSCOPE(strzero(n,3)+dtos(dtFIM))     //"001" + 2014 10 31
GO TOP
DO WHILE
SKIP
ENDDO

//VC colocou um GO TOP aqui no final, o LAÇO "DO WHILE" nunca vai chegar no EOF()

NEXT
O código é esse ai, o resto é enfeite!!!
O problema é se o usuário mudar a ordem rsrsrsr, colocar cCodGru1:="009" e cCodGru2:="003" rsrsrs, vc tem que checar se está na ordem crescente!

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
alejesus
Usuário Nível 1
Usuário Nível 1
Mensagens: 15
Registrado em: 09 Jun 2010 20:58
Localização: Osasco - SP
Contato:

OrdScope perde o filtro

Mensagem por alejesus »

Rubens / Itamar,

Apesar de já ter resolvido o caso, achei interessante e decidi mandar alguns comentários, espero que ajude a acrescentar algo para esclarecimento.

Rubens, na sua imagem do teste com a função browse() já é possível ver que o grupo 001 também estava "errado", se você verificar a imagem a última linha do grupo 001 mostra o registro do dia 01/nov, que "não deveria ser considerado".

O OrdScope não tem erro, houve somente a falha de interpretação do caso. Veja no código abaixo que de um modo ou de outro você teria problema e o resultado teria de ser tratado na lógica do seu relatório.

Quanto ao índice temporário indicado pelo João (Kapiaba) é uma saída interessante, sendo que este índice é criado em memória pelo [x]Harbour.

Código: Selecionar todos

SET DATE BRIT					// Isto não afeta o DTOS (Date TO String), pois a função sempre retornará no formato AAAMMDD
SET EPOC TO 1930
SET CENT ON 
USE IVENDAS ALIAS IVEN EXCL
INDEX ON CODGRU_+DTOS(DATA_) TO IVENDAS1		// Usei NTX, tanto faz o indice para o ORDSCOPE
INDEX ON DTOS(DATA_)+CODGRU_ TO IVENDAS2
SET INDEX TO IVENDAS1, IVENDAS2

cCODGRU1 := '001'
cCODGRU2 := '090'
D1 := CTOD('01/10/2014')
D2 := CTOD('31/10/2014')

Alert( "Agora com o indice 1 - Correto com o Grupo, problema com data" )
SET ORDER TO 1
ORDSCOPE(0,cCODGRU1+DTOS(D1))
ORDSCOPE(1,cCODGRU2+DTOS(D2))
DBGOTOP()
BROWSE()

Alert( "Agora com o indice 2 - Correto na data, problema com o Grupo" )

SET ORDER TO 2
ORDSCOPE(0,DTOS(D1)+cCODGRU1)
ORDSCOPE(1,DTOS(D2)+cCODGRU2)
DBGOTOP()
BROWSE()

Alert( "Suas opções são: 1 - indice temporário ou 2 - Rever a lógica do relatório" )
#Itamar, se o teste usasse o grupo 002 como inicial, só daria certo por não existir movimento em novembro pra este grupo (só como comentário).

Um abraço,

Alexandre
Anexos
Capture.JPG
Alexandre Bassanezi
Desenvolvimento Harbour/Lazarus/PHP e MySQL
http://www.cpen.com.br
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

OrdScope perde o filtro

Mensagem por rubens »

Grande Itamar....
Do jeito que passei tá funcionando... não precisa do for, veja por que:

Na realidade o while !eof() pode muito bem ser um while (.t.), porque a condição para sair desse não vai depender do inicio ou fim do arquivo e sim da linha em compara o proximo grupo com o grupo atual
IF cProGrupo > cCODGRU2 // -aqui nao precisou de um flag para o fim. Se o proximo grupo for maior do que segundo grupo já finaliza
EXIT
ENDIF

Essa linha (a da gambiarrachion) nao deixa ler os 1000 registros como você mencionou, pois se tiver não tiver nenhum registro filtrado ele já dá um loop.
Na questão do for ele incluiria grupos sem movimentação que teria que ter uma gambiarra parecida com esta para pular o grupo que não tem movimentos...

Código: Selecionar todos

lTEMVENDA := .F.    // - a mesma logica que voce pensou aí para grupo nao encontrado
    WHILE !EOF()
        lTEMVENDA := .T.
	EXIT
    ENDDO
    IF !lTEMVENDA     // se nao encontrado zera o filtro e pula para proximo grupo
        ORDSCOPE(0,)
	ORDSCOPE(1,)
	DBGOTOP()
	LOOP
   ENDIF
Só que analisando melhor o algoritimo nem precisa dessa gambiarra porque se o grupo não tiver movimentação ele ne entra no while !eof() depois de filtrado. Vou enchugar mais o código mudando a primeira condição pra while (.t.), tirando essa gambiarra e depois de limpar o filtro do grupo não colocar dbgotop().

Quanto ao seu ultimo comentario da ordem né... entrar grupo 10 e depois grupo 03 faz sentido mas eu já tinha me precavido validando no get a digitação do segundo grupo...
Valid cCodgru2 >= cCodgru1
Alexandre
Eu tava usando o index, mas queria um negócio mais rápido e tinha que 'funcionar' o ordscope para futuras implementações.
A Figura que você viu infelizmente foi um lapso meu na hora de filtrar os dados... ela pegou 01-10 até 01-11, por isso apareceu o 01/11/2014.
INDEX ON CODGRU_+DTOS(DATA_) TO IVENDAS1 // Usei NTX, tanto faz o indice para o ORDSCOPE

Isso eu não sabia... Migrei para o CDX justamente para ter só um arquivo de indice e porque nas pesquisas que eu havia feito, ordscope só com CDX ou usando a SIX, mas aí é outra função se não me engano SX_OrdScope()...

Obrigado

Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Responder