Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Ricardo25

Digitar num Edit e mostrar no DBGrid (Delphi 2009 + Firebird 1.5)

Recommended Posts

Boa noite, pessoal!

 

Tenho um programinha básico de cadastro com um dbgrid e dbnavigator.

 

O caso é que coloquei um Edit acima do DBGrid e gostaria que ao começar a digitar algo, o DBGrid exibisse o resultado, como se estivesse utilizando o "like".

 

Meu DBGrid exibe todos os cadastros, mas se eu digitar "a" no Edit, gostaria que só aparecessem os cadastros onde o campo "NOME" começasse com a letra "a"; Se digitar "ai", reduzisse para os que o "NOME" começam com "ai", e assim sucessivamente.

 

Já pesquisei e testei um monte de código que encontrei na internet, mas nenhum serviu. Não é possível que seja uma coisa tão complicada de se fazer, sendo que o meu programa tem uma estrutura bem simples e os componentes que utilizo para conexão e consulta também são simples.

 

Testei esse código que pesquisei, mas não deu certo:

DataModule1.IBQuery1.Active:=false; 
  DataModule1.SQL.Clear; 
  DataModule1.SQL.Add('SELECT * FROM CONTAS WHERE SITE starting with=' +quotedstr(Edit1.Text)); 
  DataModule1.active:=true;

Aqui dá esse erro:

Undeclared identifier 'Clear' at line 90 (90:19)
Undeclard identifier 'Add' at line 91 (90:19)

 

Também tentei colocar o componente IBTable e usar esse código, mas também não funcionou:

DataModule1.IBTable1.Locate('SITE',Edit1.Text,[loPartialKey,loCaseInsensitive]);

Aqui eu declarei o DB na uses do form, mas dava erro de "unsuported feature", aí substitui o "Locate" por "LocateNext". O erro parou, mas quando eu digitava, nada acontecia.

 

Por favor, me ajudem!!!

 

Obrigado a todos!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo.

 

Imaginando que você esteja utilizando um componente TQuery por exemplo, e sua Query se chame qryPesq.

 

Acredito que no evento OnChange do seu Edit1, você teria que utilizar algo semelhante a isso:

 

qryPesq.Close;

qryPesq.SQL.Text :='SELECT * FROM CONTAS WHERE SITE like :SITE';

qryPesq.Params[0].AsString := '%'+Edit1.Text+'%';
qryPesq.Open;

Até a próxima. :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo.

 

Imaginando que você esteja utilizando um componente TQuery por exemplo, e sua Query se chame qryPesq.

 

Acredito que no evento OnChange do seu Edit1, você teria que utilizar algo semelhante a isso:

 

qryPesq.Close;

qryPesq.SQL.Text :='SELECT * FROM CONTAS WHERE SITE like :SITE';

qryPesq.Params[0].AsString := '%'+Edit1.Text+'%';
qryPesq.Open;

Até a próxima. :thumbsup:

 

 

Pow, mas não tem um jeito de fazer isso usando o IBQuery, não???

 

Porque olha só, eu tentei usar um código desse jeito:

 

  DataModule1.IBQuery1.Close;
  DataModule1.IBQuery1.SQL.Clear;
  DataModule1.IBQuery1.SQL.Add('select * from CONTAS WHERE UPPER(SITE) LIKE ' + #39 + '%' +
  UpperCase(Edit1.Text)+ '%' + #39);
  DataModule1.IBQuery1.Open;

 

Pela lógica, o IBQuery1 deveria fechar (close), depois o SQL dele deveria ser limpo (Clear), a nova consulta adicionada (Add) e depois disso ele seria novamente reaberto (Open).

 

Só que quando eu digito dentro do Edit1, não acontece nada. É como se o SQL não fosse realmene limpado para uma nova consulta, já que os dados do DBGrid continuam todos lá sendo exibidos!

 

Está errada a lógica desse código que coloquei? Ou o problema é que preciso de outro IBQuery só para fazer essa consulta? E se eu precisar usar outro, como ficaria isso?

 

Vlw!!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fazer um select a cada onchange pode ficar lento.

Uma solução pode ser fazer um select e usar o FILTER do DATASET para filtrar as condições

Requeridas, troca-se o FILTER no onchange do edit, exemplos no help mesmo, creio.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Amigo Ricardo25, com base na dica que o colega Motta nos forneceu, acredito que esse tópico aqui do imasters poderá te orientar. Ao menos você não perderá desempenho trabalhando dessa maneira.

 

Ficaria algo semelhante a isso:

 

Na abertura do seu form:


DataModule1.IBQuery1.Close;
DataModule1.IBQuery1.SQL.Clear;
DataModule1.IBQuery1.SQL.Add('select * from CONTAS');
DataModule1.IBQuery1.Open;

 

No evento onChange do seu Edit:

 

DataModule1.IBQuery1.Filtered := false;
DataModule1.IBQuery1.Filter := ' SITE LIKE '+QuotedStr('*'+Edit1.Text+'*');
DataModule1.IBQuery1.Filtered := true;

 

Eu não realizei nenhum teste, e também não sabia dessa "dica" de utilizar o like dentro da instrução filter. Compartilhe conosco o resultado independente de qual seja.

 

Até a próxima. :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Amigo Ricardo25, com base na dica que o colega Motta nos forneceu, acredito que esse tópico aqui do imasters poderá te orientar. Ao menos você não perderá desempenho trabalhando dessa maneira.

 

Ficaria algo semelhante a isso:

 

Na abertura do seu form:

 

DataModule1.IBQuery1.Close;

DataModule1.IBQuery1.SQL.Clear;

DataModule1.IBQuery1.SQL.Add('select * from CONTAS');

DataModule1.IBQuery1.Open;

 

No evento onChange do seu Edit:

 

DataModule1.IBQuery1.Filtered := false;

DataModule1.IBQuery1.Filter := ' SITE LIKE '+QuotedStr('*'+Edit1.Text+'*');

DataModule1.IBQuery1.Filtered := true;

 

Eu não realizei nenhum teste, e também não sabia dessa "dica" de utilizar o like dentro da instrução filter. Compartilhe conosco o resultado independente de qual seja.

 

Até a próxima. :thumbsup:

 

Opa! A idéia parece interessante mesmo!

 

Mas tenho algumas dúvidas!

 

Quando eu abro meu programa, eu tenho um IBQuery que já está configurado para selecionar todos os campos da tablea CONTAS e mostrar na tela principal todos os dados no DBGrid o tempo todo. Eu configurei isso clicando com o botão direito em cima do IBQuery e selecionando "Edit SQL".

 

Esse quando eu digitar algo no Edit1, preciso que os dados que estavam no DBGrid sumam e apareçam apenas os registros que começarem com as letras que eu estiver digitando. Não seria o caso de ter que colocar um segundo IBQuery só pra fazer essa consulta?

 

Eu testei aqui Einsteim, do jeito que você falou, mas logo que executo o programa dá um erro dizendo "EAcessViolation at adress 0054351A in module..." .

 

Mas valeu a intenção!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já usei FILTER uma dúzia de vezes, funciona.

O erro deve ser outra coisa.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Bom, o amigo Motta trabalha dessa forma, então deve ser outro problema. De qualquer forma, vou criar um demo desse cenário e volto a compartilhar para você ver a maneira como o fiz.

 

Até a próxima. :thumbsup:



Olá amigos.

 

Amigo Ricardo25, para que funcione de acordo com o que você precisa, faça o seguinte:

 

No evento onChange do seu Edit1.Text

 

var

vFiltro: String;

begin

if Edit1.Text <> '' then

vFiltro := ' SITE LIKE '+QuotedStr('*'+ Edit1.Text +'*')

else

vFiltro := '';

 

IBQuery1.Filtered := false;

IBQuery1.Filter := vFiltro;

IBQuery1.Filtered := true;

end;

 

No evento FilterRecord da sua IBQuery1

 

if Edit1.Text <> '' then

Accept := Pos( Edit1.Text, IBQuery1Site.AsString ) > 0

else

Accept := true;

 

Consegui obter com exito o resultado que você espera trabalhando dessa maneira. Experimente, e compartilhe o resultado conosco.

 

Até a próxima. :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tivesse tempo te mandava um exemplo, mas tá f... aqui.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Bom, o amigo Motta trabalha dessa forma, então deve ser outro problema. De qualquer forma, vou criar um demo desse cenário e volto a compartilhar para você ver a maneira como o fiz.

 

Até a próxima. :thumbsup:

 

Olá amigos.

 

Amigo Ricardo25, para que funcione de acordo com o que você precisa, faça o seguinte:

 

No evento onChange do seu Edit1.Text

 

var

vFiltro: String;

begin

if Edit1.Text <> '' then

vFiltro := ' SITE LIKE '+QuotedStr('*'+ Edit1.Text +'*')

else

vFiltro := '';

 

IBQuery1.Filtered := false;

IBQuery1.Filter := vFiltro;

IBQuery1.Filtered := true;

end;

 

No evento FilterRecord da sua IBQuery1

 

if Edit1.Text <> '' then

Accept := Pos( Edit1.Text, IBQuery1Site.AsString ) > 0

else

Accept := true;

 

Consegui obter com exito o resultado que você espera trabalhando dessa maneira. Experimente, e compartilhe o resultado conosco.

 

Até a próxima. :thumbsup:

Agora uma pergunta mais boba: No OnFilterRecord da IBQuery, quando coloco o código e executo o programa, dá o erro: "Undeclared identifier 'Edit1' at line..."

 

É porque eu uso um datamodule, aí tem que informar o nome do form na frente? Eu testei por "If Form1.Edit1.Text.." mas continua o erro.

 

Vlw por ajudar!!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Amigo Ricardo25, nesse caso a sua IBQuery está dentro do datamodule, então o tratamento tem que ser feito dentro dele. Em todo caso, faça o seguinte:

 

Na sessão public do seu datamodule declare uma variável chamada vPesq: String

 

Agora faça a seguinte alteração no seu form:

 

No evento onChange do seu Edit1.Text

var

vFiltro: String;

begin

if Edit1.Text <> '' then

vFiltro := ' SITE LIKE '+QuotedStr('*'+ Edit1.Text +'*')

else

vFiltro := '';

 

SeuDataModule.vPesq := Edit1.Text;

 

IBQuery1.Filtered := false;

IBQuery1.Filter := vFiltro;

IBQuery1.Filtered := true;

end;

 

No evento FilterRecord da sua IBQuery dentro do seu DataModule

 

if vPesq <> '' then

Accept := Pos( vPesq, IBQuery1Site.AsString ) > 0

else

Accept := true;

 

Agora ficará de acordo com o que você precisa.

 

Até a próxima. :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Amigo Ricardo25, nesse caso a sua IBQuery está dentro do datamodule, então o tratamento tem que ser feito dentro dele. Em todo caso, faça o seguinte:

 

Na sessão public do seu datamodule declare uma variável chamada vPesq: String

 

Agora faça a seguinte alteração no seu form:

 

No evento onChange do seu Edit1.Text

var

vFiltro: String;

begin

if Edit1.Text <> '' then

vFiltro := ' SITE LIKE '+QuotedStr('*'+ Edit1.Text +'*')

else

vFiltro := '';

 

SeuDataModule.vPesq := Edit1.Text;

 

IBQuery1.Filtered := false;

IBQuery1.Filter := vFiltro;

IBQuery1.Filtered := true;

end;

 

No evento FilterRecord da sua IBQuery dentro do seu DataModule

 

if vPesq <> '' then

Accept := Pos( vPesq, IBQuery1Site.AsString ) > 0

else

Accept := true;

 

Agora ficará de acordo com o que você precisa.

 

Até a próxima. :thumbsup:

 

Obrigadão, Einstein!!!

Agora o Programa não apresenta mais erros, mas quando eu digito no Edit1 não acontece nada.

 

Esse "Accept" não tem que ser declarado em algum lugar?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tô enferrujado em Delphi mas pq precisa mesmo do event FilterRecord ?!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Amigo Ricardo25, nesse caso a sua IBQuery está dentro do datamodule, então o tratamento tem que ser feito dentro dele. Em todo caso, faça o seguinte:

 

Na sessão public do seu datamodule declare uma variável chamada vPesq: String

 

Agora faça a seguinte alteração no seu form:

 

No evento onChange do seu Edit1.Text

var

vFiltro: String;

begin

if Edit1.Text <> '' then

vFiltro := ' SITE LIKE '+QuotedStr('*'+ Edit1.Text +'*')

else

vFiltro := '';

 

SeuDataModule.vPesq := Edit1.Text;

 

IBQuery1.Filtered := false;

IBQuery1.Filter := vFiltro;

IBQuery1.Filtered := true;

end;

 

No evento FilterRecord da sua IBQuery dentro do seu DataModule

 

if vPesq <> '' then

Accept := Pos( vPesq, IBQuery1Site.AsString ) > 0

else

Accept := true;

 

Agora ficará de acordo com o que você precisa.

 

Até a próxima. :thumbsup:

 

Obrigadão, Einstein!!!

Agora o Programa não apresenta mais erros, mas quando eu digito no Edit1 não acontece nada.

 

Esse "Accept" não tem que ser declarado em algum lugar?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigos.

 

Amigo Ricardo25, a palavra "Accept" na verdade se você observar, é um parâmetro do método FilterRecord. Ele apenas vai dizer ao seu IBQuery o que trazer dentre o que foi passado pela instrução filter, e a nossa condição imposta de acordo com o que for digitado.

 

Até a próxima. :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites
Agradeço muito a todos que deixaram aqui uma resposta e aos que entraram no tópico também!


Resolvi o problema com uma dica de usar o locate. Ficou assim:




procedure TForm1.Edit1Change(Sender: TObject);
begin
if (Edit1.Text='') then
begin
DBNavigator1.BtnClick(nbFirst);
end
else
begin
dbgrid1.datasource.dataset.locate(dbgrid1.columns[0].fieldName,Edit1.text,[loPartialKey,locaseInsensitive]);
end;
end;

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.