Usar OrdScope?

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

Usar OrdScope?

Mensagem por rubens »

Bom dia....

Estou usando nesse relatório um set filter. Gostaria de usar um ordscope ou um índice temporário para ficar mais rápido... como tem muitos registros nessa base demora uma eternidade para gerar o relatório..

Primeiro filtrar a nota fiscal... depois chama essa rotina para filtrar os itens da nota fiscal.
Isso seria fácil, bastaria um ordscope no número da nota.
Só que nesse relatório específico é necessário um filtro composto por CSOSN+CFOP+ALIQUOTA, para totalizar os valores de cada tributação, quem fez o SPED conhece esse registro. Daí uso o set filter para filtrar os itens da venda. Daí já viram a lentidão...

Alguma idéia/dica para agilizar esse relatório?

Código: Selecionar todos

********************************************************************************
///////////////////////////////////////
// GRAVA REGISTRO C190SNFC - SOMA ITENS DA NFC DE  SAIDA //
///////////////////////////////////////
FUNCTION RC190SNFC()
MOSTRA('Somandos itens da NFCe - Cupom Fiscal Eletronico -> ' + cNUMERO)

DBSelectArea('INFC')
INFC->(DBSetFilter())
INFC->(DBSetOrder(5))  // CSOSN+CFOP+ALIQUOTA
INFC->(DBGoTop())
SET FILTER TO INFC->NUMERO==cNUMERO 
DBGoTop()

WHILE !EOF()

	cCFOP		:= INFC->CFOP
	cCST_ICMS 	:= INFC->CSOSN
	cALIQ		:= STRZERO( INFC->AI,2 )
	cLINHA		:= cCST_ICMS + cCFOP +  cALIQ 

	nVL_OPR		:= 0.00	
	nVL_IPI		:= 0.00	

	@ PROW()+1,00		SAY "|C190"		+"|" // 01 Tipo do Registro
	@ PROW()	 ,PCOL()	SAY IF( LEN( ALLTRIM( cCST_ICMS )  )<3, '0'+ALLTRIM(cCST_ICMS), cCST_ICMS )	+"|" // 02 Situacao Tributaria
	@ PROW()	 ,PCOL()	SAY cCFOP 		+"|" // 03 Codigo da Natureza na Tabela 0400
	@ PROW()	 ,PCOL()	SAY cALIQ		        +"|" // 04 Aliquota do Icms

	WHILE INFC->CSOSN+INFC->CFOP+STRZERO(INFC->AI,2) == (cLINHA)

		nVL_OPR		+= INFC->VT
		/*
		nVL_BC_ICMS	+= ICOM->VL_BC_ICMS
		nVL_ICMS		+= ICOM->VL_ICMS
		nVLBCICMSST	+= ICOM->VLBCICMSST
		nVL_ICMS_ST	+= ICOM->VL_ICMS_ST
		*/
		nVL_IPI		+= INFC->VLIPI

		DBSKIP()

	ENDDO

	@ PROW()	,PCOL() SAY PONVIRG2(nVL_OPR)	+"|" // 05 Valor Operação
	@ PROW()	,PCOL() SAY '0,00|'                                  // SAY PONVIRG2(nVL_BC_ICMS)+"|" // 06 B.C ICMS 
	@ PROW()	,PCOL() SAY '0,00|'                                  // SAY PONVIRG2(nVL_ICMS)	+"|" 	// 07 Valor ICMS
	* nVLICMSR110 += nVL_ICMS
	@ PROW()	,PCOL() SAY '0,00|' 				      // SAY PONVIRG2( nVLBCICMSST) +"|" // 08 VALOR DA BASE CALC ICMS ST
	@ PROW()	,PCOL() SAY '0,00|'                                  // SAY PONVIRG2( nVL_ICMS_ST) +"|" // 09 Valor ST
	* nVLICMSR210 += nVL_ICMS_ST 
	@ PROW()	,PCOL() SAY '0,00|'                                  // 10 Valor VL_RED_BC
	@ PROW()	,PCOL() SAY PONVIRG2( nVL_IPI)       +"|" // 11 Valor IPI
	@ PROW()	,PCOL() SAY					 		 "|"

	C190++
	C990++
	R999++

ENDDO
INFC->(DBSetFilter())

RETURN NIL 
Obrigado
Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Usar OrdScope?

Mensagem por Kapiaba »

Sem sombras de dúvidas, o melhor é usar indice na memória.

Uso assim é não importa o tamanho do BD, o filtro é instantaneo.

Código: Selecionar todos

         INDEX ON NFECOD               TAG 05 TO INFETEMP   ;
               FOR ( .NOT. EOF() )                    .AND. ;
                      CADNFE->NFECOD    >= NNOTAINI   .AND. ;
                      CADNFE->NFECOD    <= NNOTAFIN   .AND. ;
                      CADNFE->STATUS     = "IMP"      .AND. ;
                      CADNFE->TPFAT_OP   = "O"        .AND. ;
                      CADNFE->STATUS    != "   "      .AND. ;
                      CADNFE->STATUS    != "APR"      .AND. ;
                      CADNFE->STATUS    != "GER"      .AND. ;
                      CADNFE->STATUS    != "CAN"      .AND. ;
                      CADNFE->STATUS    != "ENV"      .AND. ;
                      CADNFE->STATUS    != "INU"      .AND. ;
                      CADNFE->STATUS    != "DEN"      .AND. ;
                      CADNFE->PROTOCOLO != [ ] MEMORY // TEMPORARY
Abs,
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

Usar OrdScope?

Mensagem por rubens »

Hum.... esse memory quer dizer que vai ficar na memoria e não vai criar arquivo...? Deve ficar mais rápido ainda né...

Mas mesmo assim não consegui visualizar como encaixaria isso aí no meu relatório... consegui fazer umas modificações e ficou bem rapidinho para esse relatório resolveu... mas ficou estático, queria deixar dinâmico...
A NFCe aqui só vai aceitar duas regras
CRT!=1
CSOSN=500 CFOP=5405 ALIQ=00
CSOSN=900 CFOP=5102 ALIQ=00
CRT=2 OU 3
CST=060 CFOP=5405 ALIQ=00
CST=090 CFOP=5102 ALIQ=00

Daí fica fácil mas a rotina é a mesma para nota de entrada.... e nota de entrada só Deus sabe o que vai vir nela..

Obrigado...

Como ficou

Código: Selecionar todos

FUNCTION RC190SNFC()
SET DEVICE TO SCREEN
MOSTRA2(2,'Somandos itens da NFCe - Cupom Fiscal Eletronico -> ' + cNUMERO)
SET DEVICE TO PRINT

DBSelectArea('INFC')
INFC->(DBSetOrder(3))    // indice por numero
INFC->(ORDSCOPE(0,cNUMERO))
INFC->(ORDSCOPE(1,cNUMERO))
INFC->(DBGoTop())

nVLCST60		:= 0.00
nVLCST90		:= 0.00

WHILE !EOF()  // WHILE INFC->CSOSN+INFC->CFOP+STRZERO(INFC->AI,2) == (cLINHA)
	cCST_ICMS:=IF( LEN( ALLTRIM( INFC->CSOSN )  )<3, '0'+ALLTRIM(INFC->CSOSN), INFC->CSOSN )
	IF cCST_ICMS == '060' .OR. cCST_ICMS == '500'
		nVLCST60	+= INFC->VT
	ELSE
		nVLCST90	+= INFC->VT
	ENDIF
	DBSKIP()
ENDDO

IF nVLCST60 > 0
	cCST_ICMS := IF( PERS->CRT='1','500','060')
	@ PROW()+1,00	 	SAY "|C190"		        +"|" 	// 01 Tipo do Registro
	@ PROW()	,PCOL()	SAY cCST_ICMS		        +"|" 	// 02 Situacao Tributaria
	@ PROW()	,PCOL()	SAY '5405' 			        +"|" 	// 03 Codigo da Natureza na Tabela 0400
	@ PROW()	,PCOL()	SAY '00'			        +"|" 	// 04 Aliquota do Icms
	@ PROW()	,PCOL() 	SAY PONVIRG2(nVLCST60) 	+"|" 	// 05 Valor Operação
	@ PROW()	,PCOL()	SAY '0,00|'                	                // SAY PONVIRG2(nVL_BC_ICMS)	+"|" // 06 B.C ICMS 
	@ PROW()	,PCOL() 	SAY '0,00|'                          	// SAY PONVIRG2(nVL_ICMS)		+"|" // 07 Valor ICMS
	@ PROW()	,PCOL() 	SAY '0,00|' 			  	// SAY PONVIRG2( nVLBCICMSST) +"|" // 08 VALOR DA BASE CALC ICMS ST
	@ PROW()	,PCOL() 	SAY '0,00|'                	                // SAY PONVIRG2( nVL_ICMS_ST) +"|" // 09 Valor ST
	@ PROW()	,PCOL() 	SAY '0,00|'                	                // 10 Valor VL_RED_BC
	@ PROW()	,PCOL() 	SAY '0,00|'				+"|" 	// 11 Valor IPI
	C190++
	C990++
	R999++
ENDIF

IF nVLCST90 > 0
	cCST_ICMS := IF( PERS->CRT='1','900','090')
	@ PROW()+1,00	 	SAY "|C190"				+"|" 	// 01 Tipo do Registro
	@ PROW()	,PCOL()	SAY cCST_ICMS				+"|" 	// 02 Situacao Tributaria
	@ PROW()	,PCOL()	SAY '5102' 					+"|" 	// 03 Codigo da Natureza na Tabela 0400
	@ PROW()	,PCOL()	SAY '00'					+"|" 	// 04 Aliquota do Icms
	@ PROW()	,PCOL() 	SAY PONVIRG2(nVLCST90) 	        +"|" 	// 05 Valor Operação
	@ PROW()	,PCOL()	SAY '0,00|'                	                        // SAY PONVIRG2(nVL_BC_ICMS)	+"|" // 06 B.C ICMS 
	@ PROW()	,PCOL() 	SAY '0,00|'                                    	// SAY PONVIRG2(nVL_ICMS)		+"|" // 07 Valor ICMS
	@ PROW()	,PCOL() 	SAY '0,00|' 				  	// SAY PONVIRG2( nVLBCICMSST) +"|" // 08 VALOR DA BASE CALC ICMS ST
	@ PROW()	,PCOL() 	SAY '0,00|'                    	                // SAY PONVIRG2( nVL_ICMS_ST) +"|" // 09 Valor ST
	@ PROW()	,PCOL() 	SAY '0,00|'                                  	// 10 Valor VL_RED_BC
	@ PROW()	,PCOL() 	SAY '0,00|'					+"|" 	// 11 Valor IPI
	C190++
	C990++
	R999++
ENDIF

INFC->(ORDSCOPE(0,))
INFC->(ORDSCOPE(1,))

RETURN NIL 

"Eu e minha casa servimos ao Senhor e você ???"
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Usar OrdScope?

Mensagem por Kapiaba »

Rubens, em minha opinião, com OrdScope(), está excelente, não se preocupe, com o tempo vc. dominará indices na memória, o importante é que agora, você sabe que existem duas maneiras de se fazer filtros rápidos.

Abs.
Responder