Filtrar consulta (URGENTE)

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

masoft
Usuário Nível 1
Usuário Nível 1
Mensagens: 6
Registrado em: 20 Jan 2006 20:25

Filtrar consulta (URGENTE)

Mensagem por masoft »

Olá pessoal do Forum,

Bom, no Delphi para fazer uma consulta e exibir no resultado eu uso a seguinte sintaxe:

SELECT `NOME` FROM `CLIENTES` WHERE `NOME` LIKE '%VAR%'

Onde VAR = parte do nome da pessoa

o resultado me dará todos os nome que tenha a parte digitada.
Exemplo: se eu digito MAR
Vai aparecer todos os clientes que tenha MAR no nome. EX: MARCO, MARCIO, MARIA, ETC..

Então, eu queria fazer essa consulta em clipper.
já tentei o SET FILTER TO nome = "VAR"
so que mostra apenas se a pessoa digitaro nome completo, eu queria mesmo era a pessoa digitar pedaço do nome e aparecer os nomes correspondente.

Desde já muito obrigado a todos.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Mensagem por rochinha »

Amiguinho

Para simular a clausula LIKE utilize no Clipper o operador '$', quer dizer contido/contém, assim:

SET FILTER TO alltrim(SuaVar) $ NOME

Outro exemplo

Letra := 'D'
if Letra $ 'ABCDEFG'
? 'Verdadeiro'
endif

@braços :?)
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

Bom dia, amigos

Aqui tem uma função do Toledo que faz a pesquisa letra a letra.

https://pctoledo.org/download/funcoes.php


Espero que lhe ajude

Até breve
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Mensagem por alaminojunior »

Olá caro colega.
Só um detalhe:
Com Set Filter vai ficar muito lento, vc vai ficar com raiva.
Uma solução que encontrei ( inclusive foi aqui com nossos amigos ) é a seguinte, se estiver usando Clipper 5.3:
Se estiver usando Tbrowse ou DbEdit, use Set Scope to [argumento]
Ele listará apenas os registros que atenderem aquele argumento.
Um detalhe (O banco de dados tem de estar indexado pelo campo em questão)
Espero ter dado uma luz.
:xau
masoft
Usuário Nível 1
Usuário Nível 1
Mensagens: 6
Registrado em: 20 Jan 2006 20:25

Obrigado a todos

Mensagem por masoft »

Pessoal, muito obrigado a todos, estava tentando descobrir essas funcoes a uns 3 meses já, dai resolvi postar no forum e fui atendido em menos de 4 horas.

Muito obrigado!!!

Qualquer coisa estamos ai!!!
Avatar do usuário
Trazom
Usuário Nível 3
Usuário Nível 3
Mensagens: 277
Registrado em: 14 Ago 2003 01:01
Localização: Maceió/AL

Mensagem por Trazom »

mesmo com 5.2

voce pode indexar pelo campo desejado e cada toque do usuario fazer a pesquisa usando dbseek(var,.t.) que vai permitir a busca aproximada

valeu
Imagem

Harbour 3.2 HMG 1.2a NSX
Evandro
Pelo fato de exercitar bem a própria arte,
cada um pretendia ser sapientíssimo também nas
outras coisas de maior importância,
e esse erro obscurecia o seu saber

Platão, Apologia de Sócrates
masoft
Usuário Nível 1
Usuário Nível 1
Mensagens: 6
Registrado em: 20 Jan 2006 20:25

Melhor forma

Mensagem por masoft »

Pessoal, eu quero fazer essa consulta e mostra-la na funcao DBEDIT(). Tem como eu criar um indice usando o operador $ ou eu tenho que fazer pelo set filter mesmo?
Preciso de uma solucao pra isso agora, a pessoa vai digitarparte do nome e sera mostrado no DBEDIT.

Obrigado ae pessoal.
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Mensagem por alaminojunior »

Olá meu caro
Como já disse se vc usar SET FILTER TO a pesquisa ficara muito lenta (lenta demais)
No caso DbEdit() se vc estiver consultando registros poderá indexar o DBF usando "index on codigo to arq_cod"

daí é só usar DbSeek( var ) onde var corresponderia ao campo pelo qual o DBF foi indexado

Agora se vc quiser restringir a visualização de registros que satisfaçam uma condição, em Clipper 5.2, daí é só usar
index on codigo while codigo = var to arq_cod
e em seguida chamar DbEdit() (porem qualquer modificação feita não se aplicará ao indice principal, cuidado !)

ou se for em Clipper 5.3 mais fácil ainda
use SET SCOPE TO var
Espero ter esclarecido
Boa Sorte
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Dudu_XBase
Membro Master
Membro Master
Mensagens: 1071
Registrado em: 25 Ago 2003 16:55

Mensagem por Dudu_XBase »



________________________________________________________________________________________________________
(Aow Saudade) Clipper 5.2e, Blinker 7, RDD SIXNSX, DBFCDX /Xharbour 1.0, Rdd Mediator (Mysql) Free , RDD Sqlrdd (Sql Server) Comercial
(Hoje) C# Python Sql Server e Oracle




Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Mensagem por rochinha »

Amiguinho

Qual o seu Clipper pois dependendo da versõ algumas soluções colocadas neste topico não se aplicarão a voce.

Com Clipper 5.2 eu usei por muito tempo para minhas filtragens a SUBNTX. Ela trabalha sobre o indice atual, recebe os parametro passados por voce e faz a criação do novo indice retirando o que voce quer diretamente do indice. Pelos testes que fiz com ela em um .DBF com 100.000 registros, eu precisava filtrar 3 registros. Com SET FILTER demorou muito e com a SUBNTX levou menos de 2 segundos.

Usando INDEX ON também demorava demais até criar o indice.

Nos dois casos era necessário criar um arquivo extra e seta-lo junto aos indices abertos para que as modificações fossem inclusas em todos os indices.

Para isto era necessario sacar da funcao ordListAdd() para acrescentar o indice.

Para tal criei meu proprio comando que era basicamente assim:

SET SUBFILTER TO <xpr> [ON ORDER <SubOrder>] => ;
ordSetFocus( <SubOrder> ) ;;
M->SUBARQ := '_'+substr(ordName(),1,2)+substr(strtran(time(),":",""),4,3)+".NTX" ;;
SubNtx( ordBagName(), M->SUBARQ, <xpr> ) ;;
ordListAdd( M->SUBARQ ) ;;
ordSetFocus( M->SUBARQ )

Onde:

1- Eu setava o foco para SubOrder previamente aberta pelo USE...INDEX...
2 - Em M->SUBARQ dava um nome temporario para o novo indice
3 - Com SUBNTX gerava a filtragem dos registros
4 - Com ordListAdd() adicionava o novo indice no final da lista de indices
5 - Com ordSetFocus() fixava o foco no novo indice.

Ao final era necessário desvincular o indice da lista e resetar a lista para o original.

Ainda com Clipper 5.2 era possivel usar umas funções existentes no SIX2 que permitiam filtragem sobre indices de forma tão rápida quanto o SYBNTX que tinha o seguinte comando:

#command SET FILTER TO <x> SCOPED ;
=> if ( Empty(<(x)>) ) ;
; Sx_ClrScope( 0 ) ;
; Sx_ClrScope( 1 ) ;
; else ;
; Sx_SetScope( 0, <x> ) ;
; Sx_SetScope( 1, <x> ) ;
; end

Que funcionava mais ou menos assim:

USE ...
SET INDEX TO ...
SET ORDER TO ...
SET FILTER TO condicao SCOPED

Se voce apenas quizer usar esta função da SIX2 sem acrescenta-la como RDD basta acrescentar esta .LIB ao final da linha LIB de seu .LNK e usar diretamente as funções:

...
dbSetOrder( ... )
Sx_SetScope( 0, condicao )
Sx_SetScope( 1, condicao )
...

Ja no Clipper 5.3 o trabalho de filtragens com ESCOPO já é padrão usando-se para isto as a função OrdScope()
...
dbSetOrder( ... )
OrdScope( 0, condicao )
OrdScope( 1, condicao )
...

No caso de pesquisas se voce quizer encontrar uma frase em um determinado campo no .DBF voce deverá estipular alguns criterios.

Seu arquivo de dados possui os seguintes registros:

ABILIO DINIZ
ABRAAO SANTOS
JOSE CARLOS DA ROCHA
MARIA DAS FLORES
JOAO MARIA DOS SANTOS
PAULO JOSE DE AQUINO
ZENILDA OLIVEIRA DA CRUZ

Se voce tem um indice criado pelo campo que contem estes registros e quizer filtra-lo veja alguns exemplos:

cNome := "JOSE CARLOS DA ROCHA"
dbSeek( alltrim(cNome) )
? arquivo->CampoNome
Retorna JOSE CARLOS DA ROCHA

Neste exemplo usando SOFTSEEK.

SET SOFTSEEK ON
cNome := "JOSE CARLOS DOS SANTOS"
dbSeek( alltrim(cNome) )
? arquivo->CampoNome

Retorna MARIA DAS FLORES pois é o registro mais proximo apos o 'J'.

Caso queira criar indices dinamicos com INDEX ON...FOR/WHILE voce faria assim

INDEX ON arquivo->CampoNome FOR substr(arquivo->CampoNome,1,2) = "JO"
Retorna:

JOSE CARLOS DA ROCHA
JOAO MARIA DOS SANTOS

Neste outro caso:

INDEX ON arquivo->CampoNome FOR "JO"$ arquivo->CampoNome

Retorna:

JOSE CARLOS DA ROCHA
JOAO MARIA DOS SANTOS
PAULO JOSE DE AQUINO

Ou

INDEX ON arquivo->CampoNome FOR "JOSE" $ arquivo->CampoNome

Retorna:

JOSE CARLOS DA ROCHA
PAULO JOSE DE AQUINO

Veja que a string passada vem antes do campo em questão que significa veja se JOSE esta contido no campo arquivo->CampoNome.

Pelos exemplos passados voce poderá compreender melhor este operador muito mais importante que o '=' e pouco usado.

Se voce analisar o codigo da rotina de pesquisa letra-a-letra do Toledo verá que a mesma trabalha numa base parecida com as técnicas passadas aqui.

Para suas filtragens voce se dará melhor com o uso das funçòes de escopo.

@braços :?)
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
masoft
Usuário Nível 1
Usuário Nível 1
Mensagens: 6
Registrado em: 20 Jan 2006 20:25

Mensagem por masoft »

Valeu rochinha

Era isto mesmo que estava precisando, eu uso o clipper 5.3, e tenho o 5.2e tbm.

Um abração!


------------------------------------------------------------
Veja um exemplo simples + ou -

Tenho um DBF com os seguintes campos
COD LIVRO PAGINA NOME


Agora quando a pessoa digitar um nome na consulta, exemplo MAR
vou indexar um indice com os nome que tem MAR
dai vai o MARCO, MARCIO, MARIA, MARIO, ETC

E sera mostrado o resultado no DBEDIT o LIVRO A PAGINA E OS NOMES.

Tenho certeza que com esse tutorial que você me passou vai dar certinho.

T+
------------------------------------------------------------
Avatar do usuário
acelconsultoria
Usuário Nível 3
Usuário Nível 3
Mensagens: 231
Registrado em: 10 Jan 2006 17:05
Localização: Itápolis-SP

Mensagem por acelconsultoria »

Uma pergunta...


É possível usar o SET SCOPE e sem seguida usar o Set Filter pra afunilar ainda mais a filtragem ???

Por exemplo:

USE RECEBER
SET INDEX TO DATAREC

SET SCOPE TO DATAINI, DATAFIM

SET FILTER TO PAGOS = "S"

DBEDIT(...)

???????????
Adm. Maickon Sato
Consultoria e Projetos
-------------------------------------------------------
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Mensagem por rochinha »

Amiguinho

Pode usar este esquema pois eu uso e funciona que e uma beleza.

@braços
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Responder