Página 1 de 1

Usar OrdScope?

Enviado: 09 Mar 2015 08:10
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

Usar OrdScope?

Enviado: 09 Mar 2015 09:36
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,

Usar OrdScope?

Enviado: 09 Mar 2015 13:31
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 


Usar OrdScope?

Enviado: 09 Mar 2015 14:33
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.