Página 1 de 2
OrdWildSeek
Enviado: 12 Set 2008 12:02
por asimoes
Senhores,
Alguém sabe me dizer se esta função está funcionando 100%.
Estou fazendo testes com ela e verifiquei um problema muito estranho.
Um dbF com a seguinte estrutura:
Campo Tipo Tamanho
Nome C 30
Fiz append para este DBF com 3 nomes:
1º REGISTRO ALEXANDRE
2º REGISTRO JOAO
3º REGISTRO MARIANA
Está Indexado pelo nome:
INDEX ON Nome TAG Ind01 TO TESTE
SET INDEX TO TESTE
SET ORDER TO TAG Ind01
Antes de chamar a função OrdWildSeek, faço um DBGOTOP()
DBGOTOP()
DO WHILE OrdWildSeek("*A*",.T.)
AADD(aNomes,TESTE->Nome)
ENDDO
ACHOICE(02,00,10,40,aNomes,.T.,,)
A função OrdWildSeek só acha: JOAO E MARIANA, exibidos no ACHOICE.
Falta alguma coisa, ou estou fazendo algo de errado.
:)Pos
[]´s
Re: OrdWildSeek
Enviado: 12 Set 2008 13:16
por Toledo
aSimões, da maneira como está o seu código, com um DBGOTOP() no início e o segundo parâmetro da OrdWildSeek() com .T., sempre o primeiro registro do banco de dados será desprezado, pois a função vai fazer a busca a partir do registro atual, que neste caso é o nome ALEXANDRE.
Bom, acho que para resolver isto você teria que dar um DBSKIP(-1) depois do DBGOTOP().
Exemplo:
Código: Selecionar todos
DBGOTOP()
DBSKIP(-1)
DO WHILE OrdWildSeek("*A*",.T.)
AADD(aNomes,TESTE->Nome)
ENDDO
Abraços,
Re: OrdWildSeek
Enviado: 12 Set 2008 13:25
por asimoes
Olá Toledo,
Fiz da forma que você sugeriu e nada feito, o resultado é o mesmo, parece que a função faz um skip de cara.
Alexandre
Re: OrdWildSeek
Enviado: 12 Set 2008 13:33
por Eolo
Alexandre, dá uma olhada na resposta do tópico ORDSCOPE. Vou repetir aqui, pra facilitar:
Testei e funciona.
"Achei uma saída (enquanto não aparece uma solução melhor): se é só o primeiro registro (do índice) que não é considerado, basta fazer WildSeek top/bott e depois bott/top. Na primeira passada, ele não vai aparecer. Mas, na segunda, sim. E, pra evitar eventuais duplicidades, é só filtrar com o ASCAN:"
Código: Selecionar todos
aCust:={}
GO TOP
DO WHILE OrdWildSeek( "*BE*", .T. ) // top/bottom
? "aqui"
AAdd( aCust, TESTE->Nome)
ENDDO
GO BOTTOM
DO WHILE OrdWildSeek( "*BE*", .T. , .T.) // bottom/top
IF ASCAN(ACUST, TESTE->NOME)=0
? "aqui"
AAdd( aCust, TESTE->Nome)
ENDIF
ENDDO
Re: OrdWildSeek
Enviado: 12 Set 2008 13:44
por asimoes
Olá Eolo,
Fiz como você sugeriu e funcionou, agora nos resta aguardar a correção da função.
Obrigado,
:)Pos
Re: OrdWildSeek
Enviado: 12 Set 2008 14:20
por Toledo
ASimões, a função OrdWildSeek é um seek melhorado, onde você pode usar caracteres coringas (? *) na chave de busca. Só que se você informa o segundo parâmetro como .T., ela sempre vai desprezar o registro atual, então da maneira como você fez o seu código, não vai dar certo, pois sempre o primeiro registro não vai fazer parte da busca. Agora se você não informar o segundo parâmetro ou informar .F., ai o registro atual será considerado na busca.
Então, para resolver o seu problema, faça o seguinte:
Código: Selecionar todos
DBGOTOP()
lSai:=OrdWildSeek( "*A*")
DO WHILE lSai
AADD(aNomes,TESTE->Nome)
lSai:=OrdWildSeek("*A*",.T.)
ENDDO
Este exemplo eu já testei e deu certo.
A sintaxe desta função:
OrdWildSeek(cBusca, lInicio, lOrdem)
cBusca = expressão para busca, onde você pode usar caracteres coringas (? ou *).
lInicio = se .T. faz a busca a partir do registro atual, se .F. a busca será a partir do início do arquivo.
lOrdem = informe .T. para decrescente ou .F. para crescente.
Se lInicio e lOrdem não forem informados, o default será .F.
Abraços,
Re: OrdWildSeek
Enviado: 12 Set 2008 15:05
por Eolo
Toledo, a sua solução é de fato mais simples e parece que dá certo também, mas não me parece ser o que o criador dela imaginou ou, pelo menos, não é o que está demonstrado no Help do XHarbour. Segundo o Help, vc roda uma vez a função e pronto. Não precisa fazer como você fez: rodar uma vez pra posicionar e depois rodar novamente, dentro do loop:
Código: Selecionar todos
GO TOP
aCust := {}
DO WHILE OrdWildSeek( "*EL*", .T. ) // assumindo o 3o. parâmetro como .F.
AAdd( aCust, FIELD->Lastname )
ENDDO
AEval( aCust, {|c| QOut(c) } )
// Found records:
// Feldman
// Hellstrom
// Keller
// Reichel
Também, você disse "...o segundo parâmetro como .T., ela sempre vai
desprezar o registro atual...", mas o Help parece dizer diferente: "This parameter defaults to .F. (false) causing OrdWildSeek() to begin the search
WITH THE FIRST record included in the controlling index. When .T. (true) is passed, the function begins the search
WITH the current record."
A propósito, eu tentei usar o argumento .F. (para começar pelo primeiro registro no topo do índice), mas também não funcionou. A primeira ocorrência, estando no TOP, é ignorada. Estranho.
Abraço.
Re: OrdWildSeek
Enviado: 12 Set 2008 16:06
por Toledo
Eolo, ficou estranho no help dizer que o registro atual vai fazer parte da busca quando o segundo parâmetro for .T., pois deste modo não faz sentido existe tal parâmetro. A função deste segundo parâmetro é de continuar uma busca a partir do registro seguinte ao último (registro) localizado em uma busca anterior.
Imagine como ficaria o exemplo do ASimões se o help estivesse correto. Se o registro atual fizesse parte da busca, o loop do While ficaria sempre no mesmo registro, pois não existe dentro do While um SKIP para mover o ponteiro para o próximo registro.
Exemplo:
Registro 1 = ALEXANDRE
Registro 2 = JOÃO
Registro 3 = MARIANA
1ª busca: OrdWildSeek("*A*",.T.) = vai parar em ALEXANDRE
2ª busca: OrdWildSeek("*A*",.T.) = se o registro atual contar, vai parar novamente em ALEXANDRE, pois tem a letra A.
3ª busca: Idem
e assim infinitamente...
O segundo parâmetro é exatamente para isto, para dar continuidade a busca até atingir o final do arquivo. É um LOCATE super mais rápido.
Então o Help está errado.
Abraços,
Re: OrdWildSeek
Enviado: 12 Set 2008 18:23
por Eolo
Pois é, então o Help que eu tenho está danado.
Onde eu arrumo um Help que funcione? Estou usando o Xh 1.0.0.
Abraço!
Re: OrdWildSeek
Enviado: 12 Set 2008 18:31
por Toledo
Eolo, a versão mais recente do Help é esta mesmo, eu só acho que no caso da função acima o help falhou neste pequeno detalhe.
Abraços,
Re: OrdWildSeek
Enviado: 12 Set 2008 18:32
por alaminojunior
O segundo parâmetro é exatamente para isto, para dar continuidade a busca até atingir o final do arquivo. É um LOCATE super mais rápido.
Então o Help está errado.
A função OrdWildSeek() pode ser chamada passando três parâmetros.
1º parâmetro, é a parte do que se quer encontrar;
2º parâmetro, de onde a pesquisa deve iniciar (.t. para registro corrente) ou (.f. para registro inicial do indice)
3º parâmetro, em qual direção você quer que o ponteiro ande (.t. em direção ao inicio) ou (.f. em direção ao fim)
Talvez na "primeira passada", seria interessante usar o segundo parametro estando em .f., para forçar a busca do inicio. E os demais estando em .t., fazendo a busca sempre do registro corrente.
Re: OrdWildSeek
Enviado: 12 Set 2008 20:14
por alaminojunior
Realmente colegas, segue aí o código por Eolo e eu, testado e aprovado:
No primeiro OrdWildSeek ele achou dois registros, e na segunda vez, três registros.
Código: Selecionar todos
PROCEDURE Main
LOCAL aCust := {}
USE cdcli000
INDEX ON clinom TO nomes
go top
DO WHILE OrdWildSeek( "*IO?", .T. )
AAdd( aCust, FIELD->clinom )
ENDDO
AEval( aCust, {|c| QOut(c) } )
wait "dinovo"
GO TOP
aCust := {}
passada:= 1
DO WHILE OrdWildSeek( "*IO?", iif(passada=1,.F.,.T.) )
AAdd( aCust, FIELD->clinom )
passada++
ENDDO
AEval( aCust, {|c| QOut(c) } )
USE
RETURN
Independente de ser o 1º registro no índice ou não, haveria o problema.
Mas a conclusão em que eu cheguei foi a seguinte:
o segundo parâmetro determina de onde deve partir a pesquisa, se .f., registro inicial incluindo o registro atual, se .t., a partir do registro corrente, não incluindo o mesmo;
vamos imaginar a cena....
o ordwildseek foi acionado;
ele está num registro que não satisfaz a condição; o que ele faz ? retorna found() = .f. e posiciona o ponteiro em lastrec()+1;
sendo assim, quando ele chegar no registro que atende a condição e estando o segundo parâmetro em .t., ele entende que a pesquisa deve partir daquele registro em diante, e não incluindo o mesmo.
Ao passo que se estivesse em .f., ele incluiria o mesmo e retornaria found() = .t.
Re: OrdWildSeek
Enviado: 12 Set 2008 22:53
por asimoes
Alamino e Eolo,
Muito inteligente a solução, gostei. Não desprezando também a do Toledo.
Obrigado a todos.
:)Pos
Re: OrdWildSeek
Enviado: 12 Set 2008 23:07
por alaminojunior
Só falta eu descobrir como saltar linhas entre os cupons nos ecf´s. :'( :'( :'(
Re: OrdWildSeek
Enviado: 15 Set 2008 10:25
por sygecom
alaminojunior escreveu:Só falta eu descobrir como saltar linhas entre os cupons nos ecf´s
Não entendi o que tem haver com a duvida sobre ( OrdWildSeek ). Alaminio favor abrir um novo topico sobre sua duvida.