Ricardo25 0 Denunciar post Postado Junho 18, 2013 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
Eisenheim 67 Denunciar post Postado Junho 18, 2013 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
Ricardo25 0 Denunciar post Postado Junho 19, 2013 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
Motta 645 Denunciar post Postado Junho 19, 2013 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
Eisenheim 67 Denunciar post Postado Junho 19, 2013 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
Ricardo25 0 Denunciar post Postado Junho 19, 2013 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
Motta 645 Denunciar post Postado Junho 20, 2013 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
Eisenheim 67 Denunciar post Postado Junho 20, 2013 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
Motta 645 Denunciar post Postado Junho 20, 2013 Tivesse tempo te mandava um exemplo, mas tá f... aqui. Compartilhar este post Link para o post Compartilhar em outros sites
Ricardo25 0 Denunciar post Postado Junho 20, 2013 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
Eisenheim 67 Denunciar post Postado Junho 21, 2013 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
Ricardo25 0 Denunciar post Postado Junho 21, 2013 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
Motta 645 Denunciar post Postado Junho 22, 2013 Tô enferrujado em Delphi mas pq precisa mesmo do event FilterRecord ?! Compartilhar este post Link para o post Compartilhar em outros sites
Ricardo25 0 Denunciar post Postado Junho 22, 2013 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
Eisenheim 67 Denunciar post Postado Junho 24, 2013 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
Ricardo25 0 Denunciar post Postado Junho 30, 2013 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