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()"