Página 2 de 3

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 00:47
por janio
Itamar,

A função q vc postou eh pra REALIZAR o filtro ou eh pra CONTAR os registros de um filtro?

Janio

PS: Nao tenho problema com filtros pq o OrdScope resolve este problema. A dificuldade eh saber a qtde de registros depois de um filtro. Quem programa para paf-ecf sabe q em algumas situaçoes precisamos comparar qtde de registros em tabelas para saber se foi inserido ou excluído algum registro 'por fora' do sistema.

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 01:07
por Itamar M. Lins Jr.
PS: Nao tenho problema com filtros pq o OrdScope resolve este problema. A dificuldade eh saber a qtde de registros depois de um filtro. Quem programa para paf-ecf sabe q em algumas situaçoes precisamos comparar qtde de registros em tabelas para saber se foi inserido ou excluído algum registro 'por fora' do sistema.
Então se usa ordscope, eu já disse qual é comando(função). Você já testou ?
No caso do set filter, é só usar a função postada ai em cima.

Saudações,
Itamar M. Lins Jr.

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 01:15
por Itamar M. Lins Jr.
Quando for criar o indice use "FOR !Deleted()" que OrdKeyC... vai funcionar!

Saudações,
Itamar M. Lins Jr.

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 02:17
por janio
Vc fala da função SpeedFlt???

Essa função eh pra fazer o filtro e não contar os registros do filtro. To errado?

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 08:29
por Itamar M. Lins Jr.
Ela faz as duas coisas. Vc nem leu(estudou) o fonte não é mesmo ?

Mas use como eu disse com "index bla,bla,bla... FOR XYZ >= HAHAH .AND. CCC <= JJJJ ... .AND. !DELETED() ... [temporary]"
E depois o tal ordkeycount, que funciona.

Saudações,
Itamar M. Lins Jr.

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 10:10
por janio
Rapaz, meu ingles num vale uma patavina, mas nada q um google tradutor num resolva!
Otimização de consultas por meio de arquivos de índice

Sabe-se, que algumas operações, tais como localizar, por, SUM PARA, movendo-se através da tabela filtrada são bastante lento e isso pode ser crucial para que o banco de dados é grande o suficiente, especialmente se ele está localizado em um servidor de arquivos. Usando de índices pode acelerar significativamente o processo, e, com certeza, se você sabe de antemão o localizar ou expressão de filtro, você vai tentar fazer isso em seu programa.

Mas o que, se a expressão não é conhecida de antemão, se for determinado, por exemplo, pelo utilizador final? É o caso, por que o método proposto se destina.

Programa verifica todos os índices abertos e pela análise das expressões-chave tries
para encontrar um índice, que permite optimizar a realização de uma determinada solicitação.
Ou seja, a função eh para fazer um filtro qndo de antemão não se sabe como os indices do bd foram construídos!

"É o caso, por que o método proposto se destina"

Primeiro a função vai verificando os indices e vendo qual melhor se adequa ao filtro desejado e no final SETA o melhor INDICE. Após, usa a outra função FINDREC para aplicar o filtro.

Eu NAO ENCONTREI nenhuma variável q retorne a quantidade de registros!

Nao sei onde vc viu onde nessas funções retorna a qtde de registros!

Mas tudo bem, ja estou estudando aqui outra forma de contornar isso! Refazer todos os meus índices colocando FOR !DELETED() eh q num será. Tenho banco de dados gigante e isso num eh viável.

Janio

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 10:21
por janio
Muito melhor se a função OrdKeyCount ja fizesse isso pra gente, ignorando os registros deletados. Ou se pelo menos tivesse algum parâmetro para isso. Mais viável q refazer todos os indices do sistema.

Mas fazer o q? pedir a quem pra implentar algo do tipo?

Resta usar a programação orientada a gabiarra!

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 18:30
por Itamar M. Lins Jr.
Rapaz esse bla, blá do inlglês eu não manjo muito também não rssrs.
Mas lá no código tem isso:
12 DO WHILE !Eof() .AND. &stusl
13 IF &expfnd
14 rez := .T // Suit record is found!
-> MeuContadorSeAchou++ //somar os registros encontrados.
15 EXIT
16 ENDIF
17 // Here you can insert something to animate the process of searching -> As firulas da barra de progresso
18 SKIP
Saudações,
Itamar M. Lins Jr.

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 20:03
por janio
Ahhhhhhh então seria uma modificação que teríamos q fazer acrescentando um contador! Mas ORIGALMENTE a função não eh pra contar registros, mas apenas filtrar. Pelo jeito naum fui eu q deixei de estudar os fontes, ne Itamar rsrsrs

No entanto, não vejo diferença nessa função para as outras soluções postadas nesse tópico PARA A PARTE DE CONTAR REGISTROS (no filtro nao testei), tendo em vista que terá q percorrer registro a registro dentro do "Do While".

Sendo assim, nao ha diferença nenhuma nessa função para o codigo abaixo:

Código: Selecionar todos

Conta := 0

Select bd
DbSetOrder(1)
DbGoTop()
OrdScope( 0, filtro )
OrdScope( 1, filtro )
Do While !Eof()

   Conta++
   DbSkip()

Enddo
Alguma diferença?? Nenhuma!

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 21:19
por janio
Consegui fazer um teste numa base considerável e optei por Alias->( DbEval( { || nRecs++ } ) )

Umas 15 tabelas, diversos filtros, base de dados considerável:

OrdKeyCount := 40 segundos
DbEval := 50 segundos

Ou seja, 'perdi' 10 segundos mas em compensação tenho dados corretos agora e a base de dados era consideravel. 10 segundos não eh de matar ninguem hehehehe

Janio

Retornar a qtde de registros filtrados com setfilter

Enviado: 04 Dez 2014 21:21
por Itamar M. Lins Jr.
Sei não, mas parece que essa, já faz tudo de vez.
Se seu filtro (ordScope) conter muitos registros 1.000.000... vai demorar da mesma forma.
O melhor é usar o index com o flag temporary for not deleted()... mais ai é uma questão de como estão as coisas por ai.
Tem também como criar direto na RAM o indice normal, usando:

Código: Selecionar todos

#require "hbmemio"

REQUEST HB_MEMIO

PROCEDURE Main()

   LOCAL nI
   FIELD F1

   dbCreate( "mem:test", { { "F1", "N", 9, 0 } }, , .T., "memarea" )
   FOR nI := 1 TO 1000
      dbAppend();  F1 := hb_Random() * 1000000
   NEXT
   INDEX ON F1 TAG f1
   dbEval( {|| QOut( F1 ) } )
   dbCloseArea()
   dbDrop( "mem:test" )  // Free memory resource

   RETURN
ou

Código: Selecionar todos

FUNCTION CRIA_MEMPROD()

*******************************************

/*

* Estrutura do arquivo: C:\MiniGUI\MEU_PRG\sistema\Televda1\LISTA.DBF

*/

LOCAL aField[26]

 

aField[01] := {"PCOD"      , "N",   6,  0}
aField[02] := {"PTIPOV"    , "N",   1,  0}
aField[03] := {"PDESCR"    , "C",  36,  0}
aField[04] := {"PUNID"     , "C",   2,  0}
aField[05] := {"PPRUNT"    , "N",  10,  3}
aField[06] := {"PRU_C3"    , "N",  10,  3}
aField[07] := {"PPROMO"    , "N",  10,  3}
aField[08] := {"PCOMIS"    , "N",   5,  2}
aField[09] := {"PGPFORN"   , "N",   4,  0}
aField[10] := {"PEMLIST"   , "C",   1,  0}
aField[11] := {"PDTATUA"   , "D",   8,  0}
aField[12] := {"PEMB"      , "N",   6,  2}
aField[13] := {"PABREMB"   , "C",   1,  0}
aField[14] := {"PPESOBRU"  , "N",   6,  2}
aField[15] := {"PIMAGE"    , "C",  15,  0}
aField[16] := {"PPAGE"     , "C",  15,  0}
aField[17] := {"PDESTAQUE" , "C",   1,  0}
aField[18] := {"PFLAGPROMO", "C",   1,  0}
aField[19] := {"POBS"      , "C", 255,  0}
aField[20] := {"PFORN"     , "N",   4,  0}
aField[21] := {"PNFORN"    , "C",  20,  0}
aField[22] := {"FLAG_PRN"  , "C",   1,  0}
aField[23] := {"FLAG1"     , "C",   1,  0}
aField[24] := {"DATA_ATZ"  , "D",   8,  0}
aField[25] := {"PORDGRP"   , "C",   6,  0}
aField[26] := {"PSEQGRP"   , "C",   4,  0}
/*

REQUEST HB_MEMIO

*rddsetdefault( "dbfcdx" )

DBCREATE("mem:PROTMP", aField,"dbfntx",.T.,"PROTMP")

rddsetdefault("ADS")

RETURN

 
REQUEST HB_MEMIO

*rddsetdefault( "dbfcdx" )

DBCREATE("mem:PROTMP", aField,"dbfntx",.T.,"PROTMP")

rddsetdefault("ADS")

Por: Sami Laham
No caso vc jogaria o DBF p/ RAM, via append... manipula, sem mexer no original.

Saudações,
Itamar M. Lins Jr.

Retornar a qtde de registros filtrados com setfilter

Enviado: 05 Dez 2014 10:10
por JoséQuintas
Não existe nada mágico.
Mas dependendo do que for fazer, dá pra agilizar.

Exemplo1: criar um índice com filtro

Código: Selecionar todos

INDEX ON PEDIDO TO lixo FOR cliente=10
COUNT TO nTotal // FOR .NOT. Deleted()
GOTO TOP
Browse()
Exemplo2: usar scope

Código: Selecionar todos

// produtos do pedido, indexado por pedido
SEEK NumPedido
SET SCOPE TO NumPedido
COUNT TO nTotal // FOR .NOT. Deleted()
GOTO TOP
Browse()
Tem coisas que pra agilizar, o melhor seria não contar o total.
Às vezes pra mostrar um gráfico de processamento pode fazer dobrar o tempo de processamento, só por causa de precisar saber o total.
E se for usar SET FILTER em modo Windows... se prepare pra efeitos parecidos com travamento do programa.

Retornar a qtde de registros filtrados com setfilter

Enviado: 05 Dez 2014 10:22
por janio
A questao eh saber qual seria o mais rapido:

1- Criar um indice temporario e contar os registros?

ou

2- Filtrar com Scope e contar os registros?

Janio

PS: Set Filter está descartado! Existe n maneiras alternativas

Retornar a qtde de registros filtrados com setfilter

Enviado: 05 Dez 2014 10:49
por aferra
como estava mexendo no sistema onde tinha um scope e precisava contar, porem não estava e o que eu entendi é o seguinte,

index on tipo + codi + dtos(dtem)

ordscope( 0, ctipo + cCodi )
ordscope( 1, ctipo + cCodi )

ordkeycount() //retorna 1.300.540 que não está errado é o que o banco tem mesmo. porem na tela mostra somente o que pedi para "scopar"

como a data de emissão não é tããããooooo importante

index on tipo + codi

e ai me trouxe corretamente 15.010

eu não sabia que dava essa diferença, então fica a dica.

Retornar a qtde de registros filtrados com setfilter

Enviado: 05 Dez 2014 10:54
por asimoes
Rápido,

No meu modo de ver é usar tabelas temporárias usando hbmemio, indices temporários (temporary) e filtros com ordscope

Eu uso esta combinação e funciona muito bem. os registros deletados já podem ser eliminados na clausula FOR usando "!deleted()"