Página 1 de 1

comando seek

Enviado: 01 Nov 2010 16:14
por mhfferreira
Olá... eu uso o clipper 5.2
e gostaria de saber se exite a opção de busca de uma palavra no meio de uma frase
por exemplo

tenho uam tabela no meu banco vários registros com as seguintes informações...
codigo - descricao
099 - marta
100 - predo joão
101 - maria joão
102 - maria maria pedro joão
103 - catarina
104 - mata maria

quero que ele traga o primeiro joão q ele localizar que seria o registro 100

só que se eu faço um seek no campo descrição ele me diz q não existe pois nenhuma descrição começa com joão....

tem como fazer isso?
que o comando q utilizo?
obrigada

Re: comando seek

Enviado: 01 Nov 2010 16:24
por alxsts
Olá!

Seja bem-vinda ao fórum!

Com a versão 5.2 do Clipper, não será possível fazer isto.

Sugiro que você migre a tua aplicação para Clipper 5.3 ou, de preferência, [x]Harbour. Nessas ferramentas está disponível a função OrdWildSeek() que faz exatamente o que você precisa. Veja um exemplo em xHarbour:

Código: Selecionar todos

// The example uses two wildcard search strings to show
// possible search results of OrdWildSeek()

   PROCEDURE Main
      LOCAL aCust := {}

      USE Customer
      INDEX ON Upper(LastName) TO Cust01

      DO WHILE OrdWildSeek( "*MAN?", .T. )
         AAdd( aCust, FIELD->Lastname )
      ENDDO

      AEval( aCust, {|c| QOut(c) } )
      // Found records:
      //   Dormann
      //   Feldman

      GO TOP
      aCust := {}
      DO WHILE OrdWildSeek( "*EL*", .T. )
         AAdd( aCust, FIELD->Lastname )
      ENDDO

      AEval( aCust, {|c| QOut(c) } )
      // Found records:
      //   Feldman
      //   Hellstrom
      //   Keller
      //   Reichel
      USE
   RETURN

Re: comando seek

Enviado: 01 Nov 2010 17:59
por Maligno
No Clipper v5.2 pode-se usar a biblioteca SIX, que permite o uso de índices compostos e compactados. Ela contém, além de diversas ótimas funções, a função sx_WildSeek(), que permite esse tipo de busca. Aliás, a SIX foi uma das melhores bibliotecas que usei no Clipper.

Se puder, evite o uso do comando LOCATE, que é extremamente lento, justamente por ser seqüencial. Se bem que, com a SIX, podemos usar funções para configuração de escopo, o que torna até mesmo o LOCATE bem rápido.

Re: comando seek

Enviado: 02 Nov 2010 04:08
por Maligno
A quem se dá ao trabalho de conhecer a biblioteca SIX, certamente perceberá que, além de matar a mosca com canhão, ganha-se inúmeros recursos adicionais, que só trarão benefícios. Se o OP vir o demo rodando, aposto que vai querer usar.

O uso de LOCATE e qualquer pesquisa seqüencial é sempre um problema com bases grandes. Nesses casos (o OP não deu dica alguma se é uma base grande ou pequena) não existe momento conveniente. E nem há de se falar em momento conveniente, mas sim conveniências pessoais. O OP é quem deve decidir. Mas ainda assim, uma pesquisa seqüencial torna-se muito rápida mesmo em bases grandes se for usado um limitador de escopo (isso reduz a base). Aí voltamos aos benefícios da biblioteca SIX. Viu? Outro benefício. Aliás, um outro importante: um índice muito mais seguro que o velho NTX, que é do tempo do guaraná com rolha. Vade retro!

Mas o importante disso tudo é que o OP fez uma pergunta e levou mais de uma resposta. Cabe a ele decidir que caminho seguir. E que seja feliz. :)

Re: comando seek

Enviado: 13 Nov 2010 22:16
por Augusto
Olá pessoal... Olha eu aqui outra vez.. Quanto tempo né??

Bem, sobre o assunto do tópico, acho que se usarmos a função AT() combinada na chave do LOCATE "deve" funcionar... tipo:

Código: Selecionar todos

var="joao"

if LOCATE FOR AT(var, descricao) > 0
   "ACHEI!"
else
   "NÃO ACHEI"
endif
Lembrando que o Maligno tem razão (como sempre) quando diz...
Mas ainda assim, uma pesquisa seqüencial torna-se muito rápida mesmo em bases grandes se for usado um limitador de escopo (isso reduz a base).


Será que resolve??

Re: comando seek

Enviado: 14 Nov 2010 13:46
por ANDRIL
Augusto escreveu:LOCATE FOR AT(var, descricao) > 0
Outra forma semelhante:

Código: Selecionar todos

LOCATE FOR var$descricao
Abraços.

Re: comando seek

Enviado: 15 Nov 2010 10:57
por billy1943
Vejam este código que usa o set softseek aliado ao locate:

Código: Selecionar todos

// PESQUISA EM UM ARQUIVO DE FORNECEDORES com parte do nome ou ainda procurando em qualquer posição do nome
// o arquivo de fornecedores tem os seguintes campos principais:
// 1. codigo,c,5     - objeto do índice 1
// 2. nome,c,40      - objeto do índice 2
// nessa pesquisa se for informado um asterico (*) antes do nome ele pesquisa a ocorrência de todos eles no arquivo
// esse nome tem de ter no mínimo 4 caracteres, junto com o asterisco: exemplo: *JOAO encontrará todos os JOAO //do arquivo
// se não for informado o asterisco ele procura a string no início do nome
// a matriz obtida é objeto do ACHOICE onde o nome é escolhido entre os apresentados e retorna o código desse //fornecedor
// caso o arquivo a ser pesquisado tenha milhares de registros incluir um teste para nõ estourar a matriz que somete //poderá 
// ter 4096 elementos pois no último do while o arquivo inteiro será passado para a matriz

PROCEDURE pesquisafor
local matriz := {}
@ 2,07 say "Informe o nome: "
@ 2,23 get alfacli pict "@!" valid ! empty(alfacli)
read

if lastkey() == 27
   return
endif

@ 4,06 say "  Nome do fornecedor                     C¢digo "
@ 5,06 to 5,76
select forn
set order to 2 // ordem alfabética
go top
set softseek on
seek alfacli
set softseek off
i := len(trim(alfacli))

if i == 0
   i := 1
endif

if substr(alfacli,1,1) == "*" .and. i > 4

   go top
   nomecta := substr(alfacli,2,i)
   locate for rtrim(nomecta) $(upper(nome))

   do while (found()) .and. (! eof()) .and. (interromp())
      aadd(matriz,(nome + " " + strzero(codigo,5,0)))
      dbskip()
      locate rest for rtrim(nomecta) $(upper(nome))
  enddo

else

  if (! eof()) .and. (substr(nome,1,i) == substr(alfacli,1,i))

     do while ! eof() .and. (substr(nome,1,i) == substr(alfacli,1,i))
        aadd(matriz,(nome + " " + strzero(codigo,5,0)))
        dbskip()
     enddo

  else

     go top

     do while !eof()
        aadd(matriz,(nome + " " + strzero(codigo,5,0)))
      dbskip()
     enddo

  endif
 
endif

do while .t.
   escolhe := achoice(6,08,22,76,matriz)
   if escolhe == 0
      codpesq := space(5)
      exit
   endif
   codpesq := substr(matriz[escolhe],42,5) // posição do código do fornecedor
   exit
enddo

return codpesq