Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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!
>
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!!!
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.
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:
>
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!
Já usei FILTER uma dúzia de vezes, funciona.
O erro deve ser outra coisa.
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:
Tivesse tempo te mandava um exemplo, mas tá f... aqui.
>
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!!!
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:
>
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?
Tô enferrujado em Delphi mas pq precisa mesmo do event FilterRecord ?!
>
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?
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:
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;
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:
Até a próxima. :thumbsup: