Página 1 de 1

buscar ultimos quatro registros.help.

Enviado: 22 Mai 2007 22:48
por scom
ola amigos.


é o seguinte eu to precisando pegar os ultimos quatro fornecedores de um determinado produto no dbf de compras, eu tenho um indice pelo código do produto+data, será que tem como eu começar do final e ja pegar os quatro ultimos.

tipo ir pro ultimo resistro do indice e dar um bof() ou seja do final pro começo, ai faço um contador até 4 e pego.


acho que me expliquei...nunca fiz isso nem vi.





ROBSON

Enviado: 22 Mai 2007 22:56
por sygecom
Buenas...

Ex:

Código: Selecionar todos

SELE SEUDBF  // SELECIONA O SEU ARQUIVO
GOTO BOTT    // VAI ATÉ O FIM
SKIP-4           // VOLTA 4
Abraços...
Leonardo Machado

Enviado: 23 Mai 2007 00:32
por Maligno
sygecom escreveu:

Código: Selecionar todos

SELE SEUDBF  // SELECIONA O SEU ARQUIVO
GOTO BOTT    // VAI ATÉ O FIM
SKIP-4           // VOLTA 4
Isso talvez não dê certo, uma vez que o índice está para PRODUTO+DATA. Um simples GO BOTTOM apenas garante o posicionamento do ponteiro no fim do arquivo, que pode não ser o produto desejado. Mais garantido é ir ao EOF() e voltar procurando pelo última data do produto desejado. Ao encontrar o que seria o primeiro registro desse produto, na ordem inversa, ir coletando os códigos dos fornecedores, até conseguir quatro deles, ou encontrar BOF().

[]'s
Maligno
http://www.buzinello.com/prg

Enviado: 23 Mai 2007 09:01
por Eolo
Robson,

Fácil: indexe o arquivo usando o descend() na data. Quando vc mandar procurar o produto X, o ponteiro vai parar na data mais recente. Aí é só pegar os 4 registros...

Código: Selecionar todos

use vendas
inde on produto+descend(dtos(data)) to vendas
set inde to vendas
procura=pad("PRODUTO X",len(produto))
seek procura
if found()
  for x=1 to 4
    if !procura==produto
      exit
    endi
    ? data // "Mostra Venda X"
    skip
  next
else
  ? "Não achei nada"
endi
quit
Complementando: não precisa de preocupar com o EOF(). Se existir por exemplo só 3 vendas no arquivo, qdo vc fizer o 4o. SKIP o ponteiro vai parar no EOF(), onde procura#produto, aí o FOR/NEXT é terminado.

valeu...eolo

Enviado: 23 Mai 2007 10:04
por scom
obrigado a todos...

o Eolo vou testar do jeito que vc me passou...ok


depois eu posto o resultado...

muito obrigado.

Robson

Enviado: 23 Mai 2007 10:29
por gvc
Vc esta usando o Clipper 5.3.
O dbseek tem a opção de posicionar o cursor no último registro da sua chave de procura.

dbseek(<chave>, <softseek>, <descend>)

Mudando o código do amigo Eolo:

use vendas
if !file('vendas.ntx')
inde on produto + dtos(data) to vendas
else
set index to vendas
end

procura := pad("PRODUTO X",len(produto))

if dbseek(procura, .F., .T.)
for x := 1 to 4
if bof() .or. procura # produto
exit
end
? data // "Mostra Venda X"
dbskip(-1)
next
else
? "Não achei nada"
end
quit

Boa sorte. Espero ter ajudado.

Enviado: 23 Mai 2007 11:02
por Eolo
GVC,

Funciona tb, mas se o índice tem que ser criado, qual a diferença de usar ou não o descend() nele?

Aliás, uma observação: não precisa do if bof(), basta comparar procura/produto. Pelo seguinte: o EOF() e o BOF() são como se existissem dois registros "falsos" no começo e no fim do arquivo, vazios. Mesmo que o DBF não tenha nenhum registro, esses registros falsos "estão lá".

Faz o seguinte teste: cria o arquivo TESTE.DBF, com o campo NOME, caracter, tamanho 10, e não APPENDa nenhum registro nele. Agore rode o seguinte e confirme os resultados:

Código: Selecionar todos

use teste
? lastrec() // -> 0
? eof() // -> .T.
? bof() // -> .T.
? nome==pad("EOLO",10) // -> .F.
? nome==space(10) // -> .T.
Então, qdo bater no EOF ou BOF vai dar procura#produto. O if bof() não precisa, está a mais.

Enviado: 23 Mai 2007 11:15
por Eolo
Robson,
(vou postar aqui o que lhe falei no MSN, pode ajudar mais alguém...)

Se vc faz:

Código: Selecionar todos

use vendas
indice="produto+descend(dtos(data))"
index on (indice) to vendas
wait produto
quit
dá erro na execução ("undefined function descend") porque a função DESCEND, estando dentro do string, não é considerada pelo Clipper na hora da compilação.

Já se você fizer:

Código: Selecionar todos

use vendas
index on produto+descend(dtos(data)) to vendas
wait produto
quit
vai funcionar, porque o DESCEND tá "visível" pro compilador.

Uma saída, no primeiro caso, é tornar a função visível, avisando o Clipper que é pra compilar ela:

Código: Selecionar todos

a=descend()
use vendas
indice="produto+descend(dtos(data))"
index on (indice) to vendas
wait produto
quit

Enviado: 23 Mai 2007 11:28
por Maligno
Eolo escreveu:Uma saída, no primeiro caso, é tornar a função visível, avisando o Clipper que é pra compilar ela:

Código: Selecionar todos

a=descend()
use vendas
indice="produto+descend(dtos(data))"
index on (indice) to vendas
wait produto
quit
A forma mais "sadia" de avisar o compilador (e o linker) de que um símbolo precisa ser ligado ao executável, é usando o comando request. Mas a forma exemplificada por você também resolve, claro.

[]'s
Maligno
http://www.buzinello.com/prg

Enviado: 23 Mai 2007 11:55
por gvc
Eolo, usando esse recurso do 5.3, vc não tem que criar um novo índice.
Eu acretido que o índice já exista por código do produto e data de venda sem o descend na chave.
Estou exemplificando que é possível fazê-lo sem criar um novo índice.
O seek ou dbseek posiciona o ponteiro de arquivo na primeira ocorrência da chave de pesquisa. Com o uso do 3º parâmetro, o dbseek executa a pesquisa e posicina o ponteiro na última ocorrência da chave.

O BOF() é só por (in)segurança. Isso é vicio antigo.

Mas o que nós queremos realmente é saber se o Robson conseguiu resolver a dúvida.
Aguardamos a resposta dele.

Enviado: 23 Mai 2007 11:59
por Eolo
Maligno,
Ops! Vc tem razão. É que a gente usa "gambiarras" e acaba esquecendo do correto...

Robson,
Desculpe a falha. Altere aí:

Código: Selecionar todos

request descend 
use vendas 
indice="produto+descend(dtos(data))" 
index on &indice to vendas 
wait produto 
quit

obrigado

Enviado: 25 Mai 2007 07:29
por scom
obrigado a todos.

eu testei com o dbseek() mas não pegou os 4 mas vou ver novamente então fiz com o indice descend() ai ficou beleza. Mas vou veirificar com o dbseek() novamente é que o cliente tava com pressa. Acho que com o dbseek() é melhor por não precisar criar mais um indice.

mas muito obrigado a todos...show de bola.


ROBSON

Enviado: 25 Mai 2007 10:26
por gvc
Qual o seu problema com o DBSEEK?
Poste o código que vc criou ou mande por e-mail, para nós verificar-mos o que esta acontecendo.

gvcortez@uol.com.br