Colocar o DBGrid na primeira posição

Delphi

30/11/2005

usando um locate, durante a digitação em um edit, com lopartialkey, o objeto procurado sempre fica no fim do dbgrid, existe alguma maneira de fazer com que o mesmo fique na primeira posição?


Edilcimar

Edilcimar

Curtidas 0

Respostas

Edilcimar

Edilcimar

30/11/2005

sobe


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

usando um locate, durante a digitação em um edit, com lopartialkey, o objeto procurado sempre fica no fim do dbgrid, existe alguma maneira de fazer com que o mesmo fique na primeira posição?

como assim , fica sempre na ultima posição ????
Sera que não é alguma configuração do DbGrid ???


GOSTEI 0
Carlosrm

Carlosrm

30/11/2005

Edilcimar.

É só um palpite... Se o Locate está sendo aplicado em um campo SEM ÍNDICE, a pesquisa será feita, mas em ordem natural (de entrada / gravação no Dataset).
E, se o valor no Edit se refere a algum registro que foi incluído / alterado por último, certamente ele será o último registro desse Dataset, em ordem natural).
E o coitado do DBGrid só está fazendo o trabalho dele, que é refletir a situação atual do Dataset... (salvo o uso de DisableControls e outros recursos...).

Para fazer o DBGrid apresentar o registro pesquisado (quando encontrado) na primeira linha, poderia ser usado um filtro com a mesma condição do Locate (mas acho que isso só seria razoável em siatuações muito específicas).

Aproveitando o ensejo, gostei do seu exemplo de impressão!

carlosrm


GOSTEI 0
Carlosrm

Carlosrm

30/11/2005

Edilcimar,
DESCULPE, ignore o meu palpite. Depois que enviei a resposta eu
resolvi testar na prática e vi que o que eu disse não ocorre. Testei
com D6 e Paradox e com Firebird.
Na apresentação inicial do DBGrid, ele já reflete a mesma ordem (índice) que o Dataset. Se for aplicado um novo índice ou aplicar o locate e ele ´descobrir´ que existe um índice e usá-lo, o DBGrid atualizará sua ordem.
Se eu aplicar um locate em um campo sem índice, o locate fará a pesquisa registro a registro, em ordem natural. A ordenação do DBGrid, porém (e aqui eu cometi a principal besteira) não mudará para a ordem natural...! Continuará na mesma anterior...
Pensei que podia ser útil, mas falei asneira... Prometo ser mais cuidadoso...

carlosrm :oops:


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

Marcos, eu tenho um dbgrid, vamos supor com 30 linhas, tenho um edit ondo digito algo, se faço a pesquisa pelo locate, o nome (ainda que parcial) procurado fica na 30ª posição, estou querendo fazer com que fique na 1ª linha do dbgrid, tipo como fica com o setrange


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

ideias nunca são asneiras , de ideias asneiras que surgem grandes idéias... Mas vamos ao assunto

Eu posso estar falando asneiras , mas salvo erro conduto o locate é um método de pesquisa exato.. Ou acha ou não acha.. Então antes de passas para a segunda parte , caso eu esteja correto , não procede a colocação abaixo:

...se faço a pesquisa pelo locate, [b:54fa8ceb2a]o nome (ainda que parcial)[/b:54fa8ceb2a] procurado fica na 30ª posição....


A segunda parte é que estou ainda meio confuso .. Quando voce diz que ao achar o nome pelo método locate ele fica na 30 Linha , voce esta se referindo especificamente ao um registro que ja esta previamente na 30 Linha ... Porque se voce especificar um registro que previamente seje o decimo ele ao ser localizado ,estara na 10 linha , ou não estará ????


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

tenho uma ibtable com vamos supor 1000 registros, um dbgrid com 30 linhas, se eu buscar até o 30° ele fica na mesma ´página´ do dbgrid, porém se eu buscar o registro 100, locate(´nomecampo´, nomevariavel, [lopartialkey]), o referido registro fica na 30ª posição do dbgrid, e eu estou querendo que ele fica na 1ª posição do dbgrid, se vc algum dia usou o setrangestart, setrangeend, applyrange, sabe do que estou falando


GOSTEI 0
Adriano Santos

Adriano Santos

30/11/2005

tenho uma ibtable com vamos supor 1000 registros, um dbgrid com 30 linhas, se eu buscar até o 30° ele fica na mesma ´página´ do dbgrid, porém se eu buscar o registro 100, locate(´nomecampo´, nomevariavel, [lopartialkey]), o referido registro fica na 30ª posição do dbgrid, e eu estou querendo que ele fica na 1ª posição do dbgrid, se vc algum dia usou o setrangestart, setrangeend, applyrange, sabe do que estou falando


Eu entendi o que o [b:b25068171d]Edilcimar[/b:b25068171d] quer. O problema é que: quando o DBGrid ´encontra´ o registro ele exibe o ponteiro no final dele. O que o [b:b25068171d]Edilcimar[/b:b25068171d] precisa é mostrar este registro na primeira linha para que fique mais fácil de visualizar. Tô certo [b:b25068171d]Edilcimar[/b:b25068171d] ?

É como se você pudesse rolar o DBGrid para baixo mandando o registro encontrado para o topo da lista.


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

é isto aí adriano, a idéia é exatamente esta, não é só para visualisar, mas para facilitar também, vamos supor que estamos procurando uma Maria (existem tão poucas), aí o usuário digita o nome e na primeira linha do dbgrid tem uma Maria, aí ele dá 2 cliques no dbgrid e já seleciona o cliente desejado sem tem a necessidade de digitar o nome inteiro


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

Apos a consulta bem sucedida , tente colocar o codigo abaixo:

SendMessage(DbGrid1.Handle,WM_VSCROLL,SB_Lineup,0);



GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

lamento marcos mas não funcionou


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

Eu é que peço desculpas por não entender exatamente o que voce quer

Esta intrução

SendMessage(DbGrid1.Handle,WM_VSCROLL,SB_Lineup,0);

simplesmente rola o Registro selecionado para a primeira posição Visual do DbGrid

se voce clolocar este codigo no evento de um Botão e executa-lo o Registro Não Move ?????

Pensei que voce estava querendo fazer isto ??

usando um locate, durante a digitação em um edit, com lopartialkey, o objeto procurado sempre fica no fim do dbgrid, [b:7b893f7df5]existe alguma maneira de fazer com que o mesmo fique na primeira posição[/b:7b893f7df5]?


Mas eu não li o seu penultimo Post , onde voce escreve uma outra situação :

.... aí o usuário digita o nome e na primeira linha do dbgrid tem uma Maria, aí [b:7b893f7df5]ele dá 2 cliques no dbgrid [/b:7b893f7df5]e já seleciona o cliente desejado sem tem a necessidade de digitar o nome inteiro



GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

o locate está no onchange de um edit, eu coloquei no onchange o código, aí ele simplesmente dá foco no primeiro registro do dbgrid, o que eu preciso é que aquilo que esteja sendo digitado vá para a primeira posição do dbgrid para que a pessoa possa mais facilmente escolher algo que esteja depois daquilo que foi digitado, dando 2 cliques no dbgrid


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

Mas como eu disse anteriormente o Locate é um método Exato , Ou Acha ou não acha.. Para usar no evento onChange seria mais conveniente usar métodos de Aproximação , (FindNerest , GotoNearestO Ou mesmo instrução sql

Com o método Locate se voce digitar [color=darkred:b1c6967980]Mari[/color:b1c6967980] ele não localiza pessoas com o nome de [color=darkred:b1c6967980]MARIA[/color:b1c6967980] por exemplo..

tente fazer um teste com o método LOCATE :

if table1.locate(´Nome_Campo´,Edit1.Text,[LoPartialKey, 
LoCaseInsensitive]) then
  showmessage(´encontrado´)
else
  showmesage(´´Não encontrado´)


[b:b1c6967980]Veja que se digitar MAR ele não acha MARIA ... ETC..[/b:b1c6967980]


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

quando coloco o locate com lopartial key ele acha, se digito mari ele para o primeiro maria, que está exatamente na última posição do dbgrid, o que eu quero é que este registro fique na primeira posição(linha) do dbgrid!


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

Por gentileza , poderia disponizar o fragmento de código do evento onchange para que eu possa testa-lo aqui .


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

If Edit1.Focused = True then
Begin
IBTable1.First;
IBTable1.IndexFieldNames := ´NOME´;
With IBTable1 do
Begin
Locate(´NOME´, Edit1.Text, [loPartialKey]);
If Edit1.Text = FieldByName(´NOME´).AsString then
Begin
Edit1.Text := FieldByName(´NOME´).AsString;
Edit3.Text := FieldByName(´FABRICANTE´).AsString;
Edit5.Text := FieldByName(´DIVISAO´).AsString;
Edit7.Text := FieldByName(´CODIGOBARRA´).AsString;
Edit8.Text := FieldByName(´ATIVO´).AsString;
DBgrid1.SetFocus;
End;
End;
End;
quando coloco este linha abaixo ele dá foco no dbgrid
SendMessage(DbGrid1.Handle,WM_VSCROLL,SB_Lineup,0);


GOSTEI 0
Massuda

Massuda

30/11/2005

Talvez isso seja útil mas talvez eu não tenha entendido o problema...

Todo grid tem uma propriedade .TopRow que define qual é a primeira linha visível no grid; a princípio, basta obter qual linha do grid o Locate encontrou e torná-la o .TopRow do grid.


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

Ok Massuda, vou pesquisar


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

Massuda Citou
Talvez isso seja útil mas talvez eu não tenha entendido o problema... Todo grid tem uma propriedade .TopRow que define qual é a primeira linha visível no grid; a princípio, basta obter qual linha do grid o Locate encontrou e torná-la o .TopRow do grid.


Edicilmar Citou:
Ok Massuda, vou pesquisar


Amigo , Edicilmar , se voce pesquisar e encontrar algo que possa elucidar a questão , por favor passe a resposta para a gente... Terei a imensa satisfação em colocar a resposta no meu caderno de soluções.

:idea:
Mas nesse meio termo achei ou acho que achei uma outra resposta para o problema... [b:d5f6f151ed]Quando não se tem Cão deve se latir com o Gato[/b:d5f6f151ed]

Fiz alguns testes aqui e a principio parecem satisfazer .


:arrow:
[b:d5f6f151ed]Veja a figuara abaixo , que é antes da Pesquisa[/b:d5f6f151ed]
[URL=http://imageshack.us][img:d5f6f151ed]http://img229.imageshack.us/img229/4923/imagemparaedicilmar16hv.jpg[/img:d5f6f151ed][/URL]

:arrow: :arrow:
[b:d5f6f151ed]logo Abaixo a figura quando a tecla V (Maiscula) é preesionada[/b:d5f6f151ed]
[URL=http://imageshack.us][img:d5f6f151ed]http://img228.imageshack.us/img228/9648/imagemparaedicilmar25lk.jpg[/img:d5f6f151ed][/URL]

Abaixo o código que usei ;

procedure TForm1.Edit1Change(Sender: TObject);
var
i:Integer;
begin
  With IBTable1 do
    Begin
      //coloquei um if then aqui...
      if Locate(´Descricao_Produto´, Edit1.Text, [loPartialKey]) then
        begin
         If Edit1.Text = FieldByName(´Descricao_Produto´).AsString then
          Begin
            Edit1.Text := FieldByName(´Descricao_Produto´).AsString;
            DBgrid1.SetFocus;
         end
       //coloquei um else aqui
       else
          begin
            //desabilita o controle consciente de dados
            IBTable1.DisableControls;
            //Foco vai temporariamente para o DbGrid
           Dbgrid1.SetFocus;
           //Executo um laço , onde os parametros vai depender do 
          //tamanho do Grid e de onde o dado localizado aparece na Grid
         //No meu PC O Dado Localizado sempre aparecia no Meio e Nunca 
        //na final 
            for i:=0 to 9 do
              begin
                 //simulo o pressionamento da tecla Down , objetivando
                //abaixar os dados da Grid . Efetuo esse deslocamento ate 
               //o dado aparecer no top da grid . por isso os parametros do 
              //Laço deve ser calculados para o seu caso 
                 keybd_event(VK_DOWN,0,0,0);
             //finalizo toda mensagem pendende
                Application.ProcessMessages;
             end;
          // o laço acima move o registro para baixo , por isso devo 
         // deslocar a edição para cima novamente
          SendMessage(DbGrid1.Handle,WM_VSCROLL,SB_Lineup,0);
         //habilito o controle consciente de dados
          IBTable1.enablecontrols;
        //retorno o foco para o edit novamente
          edit1.setfocus;
        //posiciono o ponteiro do edit
         edit1.SelStart:=length(edit1.text);
      end;
  end;
end;


PS1 :[b:d5f6f151ed] Mais uma vez reitifico a necessidade de efetuar um controle no Loop For i:=0 To **** Do ....o Valor *** Vai depender do Seu Caso especifico[/b:d5f6f151ed]

P:S2 Coloquei a grid em[color=darkred:d5f6f151ed] DgRowSelect em True e DgAllShowSelectd [/color:d5f6f151ed]em True . Iso não é necessário e so para melhor destacar o registro dando um efeito de azulado
Se for conveniente , para que a [b:d5f6f151ed]Grid[/b:d5f6f151ed] fique em modo de [b:d5f6f151ed]edição [/b:d5f6f151ed], toda vez que ela receber o foco , volte as configuraçoes originais da Propriedade Options. E Toda vez que a grid perder o foco , volte novamente com o efeito Azulado.. Isto pode ser facilmente programado atraves dos eventos
onExit e OnEnter da Grid...

P:S3[b:d5f6f151ed] No seu código inicial não entendi o efeito da instrução[/b:d5f6f151ed]

If Edit1.Focused = True then 
Begin 
IBTable1.First; 
IBTable1.IndexFieldNames := ´NOME´; 


Toda vez que pressionar qualquer tecla no OnChange , Mover para a primeira posição e seguida indexar a tabela... Acho que esta indexação so é necessária fazer uma única vez , e não vejo necessidade mover o registro para a primeira posição ??????

Boa sorte


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

Marcos, vou testar o código, quanto a
P:S3 No seu código inicial não entendi o efeito da instrução Código: If Edit1.Focused = True then Begin IBTable1.First; IBTable1.IndexFieldNames := ´NOME´;


é que tenho diversos edit´s e cada um usa um índice diferente, por isto que tem o focused, para saber quem está mudando, pois eu preencho os outros campos com dados da ibtable, quanto a troca do indice, eu poderia ter colocado no onenter do edit , quanto ao first foi uma tentativa para mudar a posição no grid (afinal chutei de tudo para conseguir aquilo que queria)


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

Valeu Marcos, este funcionou corretamente, agora só preciso inventar um DBGRid.RowCount para fazer o loop tipo for i := 1 to dbgrid1.rowcount


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

se substituir esta linha
keybd_event(VK_DOWN,0,0,0);
por
keybd_event(VK_NEXT,0,0,0);
pode tirar o loop que funciona perfeitamente, seria o meu dbgrid.rowcount!


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

Valeu Marcos, este funcionou corretamente, agora só preciso inventar um DBGRid.RowCount para fazer o loop tipo for i := 1 to dbgrid1.rowcount


No meus testes , usando um Tamanho de dbGrid Fixo , o DBGRid.RowCount foi no Chutommetro... Fui modificando o loop ate chegar no Ponto que gostaria

se substituir esta linha keybd_event(VK_DOWN,0,0,0); por keybd_event(VK_NEXT,0,0,0); pode tirar o loop que funciona perfeitamente, seria o meu dbgrid.rowcount!


Melhor ainda... :P :P


GOSTEI 0
Marco Salles

Marco Salles

30/11/2005

:idea:
Gostaria de alertar que para tabelas com pouco registros (Cujo Numero seje inferior) á capacidade da area visivel do DbGrid , ocorrerá um efeito indesejável , que aparecá como bug da função
Nesse caso , suponhamos que se tenha tres registros e que a capacidade do Grid e de mostrar [b:b1c6478182]mais de tres registros[/b:b1c6478182], :arrow: logo a barra de rolagem esta desabilitada..
:wink:
Mesmo com tres registros o usuário resolva fazer uma pesquisa ,(Confesso que seria bem mais fácil olhar para o Grid) , suponha hipoteticamente que ele consulte o Ultimo registro , que nesse caso é o Terceiro
:arrow:
[b:b1c6478182]O Resultado da pesquisa nessa situação particular sera sempre , o primeiro Registro[/b:b1c6478182]
[b:b1c6478182][color=red:b1c6478182]A Razão disso é simples , visto que o Ultimo Registro (Nesse caso o Terceiro) não pode passar por cima do Primeiro.. Isto é , não há condiçoes de rolagem dos Registros da Grid[/color:b1c6478182][/b:b1c6478182]

[b:b1c6478182]A Saidá :[/b:b1c6478182]
Uma saida é limitar o Uso da Função na situação em que o Numero de registro For Maior que o Numero de Registros Que podem ser visiveil pelo DbGrid.
Em outras palavras :

if IBTable1.RecCount > NumeroRegistrosQuePodemSerVisiveisDbGrid
  begin
    blablabla..
  end


[b:b1c6478182]fui claro[/b:b1c6478182] ???? :?: :?: :?:


GOSTEI 0
Edilcimar

Edilcimar

30/11/2005

mas isto utilizando o for, pois com a minha substituição a coisa funciona como um simples page down (não testei)


GOSTEI 0
Caninha51

Caninha51

30/11/2005

[quote:b2aacca4b6=´Marco Salles´]
If Edit1.Text = FieldByName(´Descricao_Produto´).AsString then
          Begin
            Edit1.Text := FieldByName(´Descricao_Produto´).AsString;
            DBgrid1.SetFocus;
         end

[/quote:b2aacca4b6]

Muito interessante esse tópico!

Só naum entendi a utilidade do edit receber a mesma coisa, já q eh igual!![:)]


GOSTEI 0
Willerson Santos

Willerson Santos

30/11/2005

Amigos, vocês resolveram como fazer para o resultado do locate no dbgrid ficar na primeira opção? Ainda não consegui aqui.
O meu problema é o seguinte:
Tenho uma busca por referencias, de modo que existem as referencias,
5040.001
5040.002
5040.003
5040.004
5040.005
5040.006
Eu pesquisei por "5040", achou o primeira referencia 5040.001 mas essa fica na ultima posicão do dbgrid na tela, o ideal que ficasse em primeira, bem acima de modo que usuario
visse as outras em baixo sem ter que pressionar qualquer tecla. Ainda não descobri a solução pra isso. Se alguem poder me ajudar eu agradeço.

Willerson Wagner.
GOSTEI 0
POSTAR