Página 2 de 2

OrdScope perde o filtro

Enviado: 13 Nov 2014 15:28
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

OrdScope perde o filtro

Enviado: 13 Nov 2014 19:51
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.

OrdScope perde o filtro

Enviado: 14 Nov 2014 10:39
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


OrdScope perde o filtro

Enviado: 14 Nov 2014 17:54
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

OrdScope perde o filtro

Enviado: 14 Nov 2014 18:26
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...

OrdScope perde o filtro

Enviado: 14 Nov 2014 20:01
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.

OrdScope perde o filtro

Enviado: 16 Nov 2014 20:39
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

OrdScope perde o filtro

Enviado: 17 Nov 2014 09:33
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