Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) QUERY + Dbgrid + Filtro Edits


pimpocvl

Pergunta

Boa tarde,

A 1 mes estou procurando algo neste sentido e não encontro.

Preciso criar uma consulta que liste o resultado no DBGRID, porem o filtro deve passar por mais de um Edit. ou seja exemplo: edit1.texte e edit2.text.

Estou tentando com os componente QUERY, DATASOURCE, DBGRID e Edit's normais. Meu banco e INTERBASE.

Veja, só, o mais proximo que consegui chegar foi utilizando esta SQL:

IBQueryfiltro.SQL.Add('SELECT * FROM CADASTRO_ATENDIMENTO WHERE NUMEROATENDIMENTO = '+Edit1.Text+' AND CODIGOCLIENTE = '+Edit2.Text+'');

...porem se eu deixo um dos campo em branco da erro, ao envez disso, eu gostaria que ao encontrar o campo em branco, então que fosse listado tudo.

...se por exemplo que preencher o edit1 e deixar o edit2 em branco da este erro:

[Project Project_Nomedomeuprojeto.exe raised exceptio class EIBInterBaseError with message 'Dynamic SQL Error SQL error code = -104

Unexpected end of command'. Process stopped. Use Step or Rum to continue.]

[Dynamic SQL Error

SQL error code = -104

Unexpected end of command.]

...desde já agradeço.

Editado por pimpocvl
Link para o comentário
Compartilhar em outros sites

17 respostass a esta questão

Posts Recomendados

  • 0

Boa Noite Na Query Você pode trabalha com parametros. Desta maneira você já deixara o sql montado dentro do componente na propriedade SQL. Nesta propriedade você coloca o código abaixo

SELECT *

FROM CADASTRO_ATENDIMENTO

WHERE NUMEROATENDIMENTO LIKE :pParametro1

AND CODIGOCLIENTE = :pParametro2

-Depois tem uma outra propriedade Params onde você ira informar o tipo para cada parametro no datatype.

-E no código quando a pesquisa for executada coloca o codigo abaixo

IBQueryfiltro.Close;

IBQueryfiltro.ParamByName('pParametro1').Value := edit1.Text;

IBQueryfiltro.ParamByName('pParametro2').Value := edit2.Text;

IBQueryfiltro.Open;

Espero ter ajudado.

Qualquer dúvida post ai

Abraços!!

Link para o comentário
Compartilhar em outros sites

  • 0

Primeiramente, agradeço por estar me ajudando Sr. Leonardo C. Cavalcante.

No entanto,

Deu na trave!!!, porem, ainda pode algo que fiz errado, talvez la onde você diz - ...informar o tipo para cada parametro no datatype! - , eu coloquei: ftString. O resultado foi o seguinte:

1 - Se eu preencher os "dois" campos aparece o resultado na grid.

2 - Se eu deixar os campos "edit1.text e edit2.text" em branco, não lista nada.

3 - Se eu deixar somente o campo "edit1.text" preenchido e o "edit2.text" em branco, então não lista nada.

4 - Se eu fizer o inverso do que descrivi na opcao 3. acontece a mesma coisa.

...então agora eu preciso fazer um ajuste para que quando os dois EDIT'S estiverem em branco, o sistema lista tudo, ou caso, somente um dos dois campos forem preenchidos, então que o sistema considere o outro campo como "todos".

...o q acha?

Editado por pimpocvl
Link para o comentário
Compartilhar em outros sites

  • 0

beleza agora não falta muito você só precisa alterar o sql da query e deixar desta maneira.

SELECT *

FROM CADASTRO_ATENDIMENTO

WHERE (NUMEROATENDIMENTO = :pParametro1 OR :pParametro1 = '')

AND (CODIGOCLIENTE = :pParametro2 OR :pParametro2 = '')

Isto deve resolver.

Só no local onde você passa os parametros não se esqueça de tirar os espaços em brancos utilizando TRIM

IBQueryfiltro.Close;

IBQueryfiltro.ParamByName('pParametro1').Value := Trim(edit1.Text);

IBQueryfiltro.ParamByName('pParametro2').Value := Trim(edit2.Text);

IBQueryfiltro.Open;

Caso precise utilizar parametros do tipo ftInteger deverá fazer desta maneira

SELECT *

FROM CADASTRO_ATENDIMENTO

WHERE (NUMEROATENDIMENTO = :pParametro1 OR :pParametro1 = 0)

AND (CODIGOCLIENTE = :pParametro2 OR :pParametro2 = 0)

IBQueryfiltro.Close;

if Trim(edit1.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro1').Value := Trim(edit1.Text)

else

IBQueryfiltro.ParamByName('pParametro1').Value := 0;

if Trim(edit2.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro2').Value := Trim(edit2.Text)

else

IBQueryfiltro.ParamByName('pParametro2').Value := 0;

IBQueryfiltro.Open;

Ok

Abraços!!

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite,

Eu testei das duas formas que me passou, a primeira deu erro, dai me liguei na questao do INTEGER. Estou empolgado =), avancamos mais um paço, agora o resultado ficou assim:

1 - Se eu deixo os EDIT'S em branco, o sistema lista tudo. OK

2 - Se eu filtro os EDIT'S informado o valor nos dois campos (edit1 e edit2), ele lista somente o registro solicitado. OK

...porem,

3 - Se eu informo o EDIT1 e deixo o EDIT2 em branco, o sistema lista tudo, mas eu gostaria que ele lista-se somente o que for referente ao EDIT1. Por exemplo:

Digamos que o EDIT1 e o filtro do cliente, e o EDIT2 e o filtro da cidade (isso e so um exemplo). Se eu filtra-se pegando o nome do cliente JOAO (edit1), e deixo o nome da cidade em branco (edit2), então o sistema deveria listar todos os JOAO's de todas as cidades. Mas se eu filtra-se buscando pelo nome JOAO (que seria o edit1) e também filtra-se pela cidade CURITIBA (que seria o edit2), o sistema deveria listar somente os JOAO'S que moram em CURITIBA, e vice versa, se eu filtra somente pela cidade (edit2), deixando o nome cliente em branco (edit1), o sistema deveria aparecer todos os clientes daquela cidade.

...novamente agradeço por estar disponibilizando seu tempo para me ajudar. E se ti tiver mais uma sugestao e bem provavel que eu agradeça novamente. =)

Editado por pimpocvl
Link para o comentário
Compartilhar em outros sites

  • 0

Funcionou, realmente eu devo ter feito algo errado.

Mas e agora Leonardo? se eu precisar misturar datatype ftINTEGER com ftSTRING como que fica, olha eu bem que tentei emendar o seu SQL e depois manipular o PARAMS e por ultimo o codigo no botao, mas não consegui não, da um erro muito extranho, antes de posta-lo talvez você poderia me ajudar complementando o seu codigo.

Novamente agradeço pelo tempo disposto.

Link para o comentário
Compartilhar em outros sites

  • 0

IBQueryfiltro.Close;

if Trim(edit1.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro1').Value := Trim(edit1.Text)

else

IBQueryfiltro.ParamByName('pParametro1').Value := 0; // Aqui um parametro ftInteger

IBQueryfiltro.ParamByName('pParametro2').Value := Trim(edit2.Text) // Aqui um parametro ftString

IBQueryfiltro.Open;

Este é um exemplo de como utilizar os dois tipos de parametros

O importante e você enteder que quando quiser desconsiderar um parametro(para que traga todos os registros) inteiro ele deve ser preechido com um valor 0.

ai no SQL você verifica se o campo e igual o valor do parametro ou o parametro esta preechido com 0.

Quando for string você quiser desconsiderar o parametro(para que traga todos os registros) você preenche com '' e no SQL verifica se o campo é igual ao parametro ou o parametro for igual ''.

Talvez possa te ajudar melhor se me explicar o que exatamente quer fazer.

Fico aguardando

Abraços!!!

Link para o comentário
Compartilhar em outros sites

  • 0

pimpocvl, uma outra abordagem, seria construir a consulta dinamicamente, conforme os parâmetros informados. O objetivo é evitar o uso da cláusula OR que degrada a consulta.

var
  Filtro,
  Param1,
  Param2 :string;
begin
  Filtro := '';
  Param1 := Trim(Edit1.Text);
  Param2 := Trim(Edit2.Text);
  if Param1 <> '' then
    Filtro := ' WHERE NUMEROATENDIMENTO = :pParametro1 ';
  if Param2 <> '' then
  begin
    if Param1 <> '' then
      Filtro := Filtro +'AND '
    else
      Filtro := ' WHERE ';
    Filtro := Filtro +'CODIGOCLIENTE = :pParametro2 ';
  end;
  IBQueryfiltro.Close;
  IBQueryfiltro.SQL.Clear;
  IBQueryfiltro.SQL.Add('SELECT *');
  IBQueryfiltro.SQL.Add('FROM CADASTRO_ATENDIMENTO');
  IBQueryfiltro.SQL.Add(Filtro);
  if Param1 <> '' then
    IBQueryfiltro.ParamByName('pParametro1').AsString := Param1;
  if Param2 <> '' then
    IBQueryfiltro.ParamByName('pParametro2').AsString := Param2;
  IBQueryfiltro.Open;
end;

Observe os espaços usados no início/fim da string atribuida a Filtro - são necessários para que o texto não fique "grudado" e gere erro de sintax na execução da query.

Eventualmente, também poderá ser necessário definir o tipo do parâmetro no código.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Micheus,

Com todo respeito, você poderia me passar um exemplo de como posso misturar esse codigo para filtrar tanto string, quanto integer? Gostaria de filtrar por exemplo, o codigo do cliente, e o status do atendimento (andamento, finalizado etc), desta forma eu posso pegar todos os clientes que estao com o atendimento em andamento, ou poderia pegar todos os atendimentos finalizados de um determinado cliente.

Desde agradeço.

Link para o comentário
Compartilhar em outros sites

  • 0
você poderia me passar um exemplo de como posso misturar esse codigo para filtrar tanto string, quanto integer? Gostaria de filtrar por exemplo, o codigo do cliente, e o status do atendimento (andamento, finalizado etc), desta forma eu posso pegar todos os clientes que estao com o atendimento em andamento, ou poderia pegar todos os atendimentos finalizados de um determinado cliente.
pimpocvl, não sei se seria a isso que você se refere, mas neste exemplo que postei antes, considerando que o seu Param1 é o Número do atendimento, Param2 é o Codigo do Cliente (Integer), então o status do atendimento (String) seria Param3. Eu acredito que fazendo as alterações abaixo (informar o tipo do parâmetro via As<tipo>) deva funcionar:

...
  if Param1 <> '' then
    IBQueryfiltro.ParamByName('pParametro1').AsInteger := StrToInt(Param1);
  if Param2 <> '' then
    IBQueryfiltro.ParamByName('pParametro2').AsInteger := StrToInt(Param2);
  if Param3 <> '' then
    IBQueryfiltro.ParamByName('pParametro3').AsString := Param3;
  IBQueryfiltro.Open;
end;

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
IBQueryfiltro.Close;

if Trim(edit1.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro1').Value := Trim(edit1.Text)

else

IBQueryfiltro.ParamByName('pParametro1').Value := 0; // Aqui um parametro ftInteger

IBQueryfiltro.ParamByName('pParametro2').Value := Trim(edit2.Text) // Aqui um parametro ftString

IBQueryfiltro.Open;

Este é um exemplo de como utilizar os dois tipos de parametros

O importante e você enteder que quando quiser desconsiderar um parametro(para que traga todos os registros) inteiro ele deve ser preechido com um valor 0.

ai no SQL você verifica se o campo e igual o valor do parametro ou o parametro esta preechido com 0.

Quando for string você quiser desconsiderar o parametro(para que traga todos os registros) você preenche com '' e no SQL verifica se o campo é igual ao parametro ou o parametro for igual ''.

Talvez possa te ajudar melhor se me explicar o que exatamente quer fazer.

Fico aguardando

Abraços!!!

-----------------------------------------------//-----------------------------------------------//-----------------------------------------------//-----------------------------------------------//

O Leonardo, tudo bem?

Seguinte, na minha santa ignorancia, pensava que se tivesse um exemplo de filtro, que busca-se os parametros em 2 edit's, já poderia sair por ai fazendo os filtros que bem entende-se, "santa ignorancia", a unica coisa que sei sobre DELPHI ou programação em si, e o que estou aprendendo via "google", exemplos pegos prontos, outras vezes documentacões mais tecnicas (que realmente detalham o porque disso ou daquilo), dai so me resta vazer uma alteraçãozinha aqui outra ali e pronto, outras vezes fico martelando um bom tempo em cima de uma coisa que depois, quando consigo resolver era um "detalhe" tão tosco que da ate vergonha hehehe. Pois bem, estou bolando um programa para controlar os ATENDIMENTOS prestados aos clientes. A pergunta que eu deveria ter feito desde a primeira vez que eu postei aqui no site SCRIPT"BRASIL", seria:

Se eu tenho:

edit1.text, ...que seria o campo para filtrar o NUMEROATENDIMENTO (numerico)

edit2.text, ...que seria o campo para filtrar o CODIGOCLIENTE (numerico)

edit3.text, ...que seria o campo para filtrar o SOLICITANTE (letras)

combobox1.text, ...que seria o campo para filtrar o STATUS (do atendimento, que pode ser tanto ANDAMENTO, ATENDIDO ou CANCELADO). (ao meu entender seria letras).

edit4.text e edit5.text ...que seriam os campos para filtrar o intervalo de data que este atendimento foi realizado. Acredito eu que incluir datas seja um procedimento mais complicado, portanto, de inicio talvez eu não implemente esta opcao para poder absoverver melhor os filtros feitos com numeros e letras, depois eu implemento datas.

Então pelo que o Sr. me passou ate agora, eu consegui fazer o filtro listar buscando pelo edit1 e edit2 (campos, integer correto?), ficou show de bola, porem agora, eu preciso implementar o codigo para que filtre também o edit3 e o combobox1. E futuramente o intervalo de data.

O Sr. havia respondi para mim com este codigo ali em cima, que esta anexado a esta msg. Porem eu testei fazendo desta forma:

[No componente IBQueryfiltro, no object inspetor / SQL deixei assim:]

SELECT *

FROM CADASTRO_ATENDIMENTO

WHERE (NUMEROATENDIMENTO = :pParametro1 OR :pParametro1 = 0)

AND (CODIGOCLIENTE = :pParametro2 OR :pParametro2 = 0) AND (STATUS = :pParametro3 OR :pParametro3 = '')

[No Params do object inspetor:]

0 - pParametro1, datatype = ftInteger

1 - pParametro1, datatype = ftInteger

2 - pParametro2, datatype = ftInteger

3 - pParametro2, datatype = ftInteger

4 - pParametro3, datatype = ftString

5 - pParametro3, datatype = ftString

[E no botao:]

IBQueryfiltro.Close;

if Trim(edit1.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro1').Value := Trim(edit1.Text)

else

IBQueryfiltro.ParamByName('pParametro1').Value := 0;

if Trim(edit2.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro2').Value := Trim(edit2.Text)

else

IBQueryfiltro.ParamByName('pParametro2').Value := 0;

if Trim(combobox1.Text) <> '' Then

IBQueryfiltro.ParamByName('pParametro3').Value := Trim(combobox1.Text)

else

IBQueryfiltro.ParamByName('pParametro3').Value := '';

IBQueryfiltro.Open;

[Ai ele retorna esse erro:]

Project Project_controleatendimentosolution.exe raised exception class EIBInterBaseError with message 'Dynamic

SQL Error SQL error code = -804

Incorrect values within SQLDA structure'. Process stopped. Use Step or run to continue.

Dynamic SQL Error

SQL error code = -804

Incorrect values within SQLDA structure.

...e agora, tens ai alguma dica?

Editado por pimpocvl
Link para o comentário
Compartilhar em outros sites

  • 0

já tentou rodar o comando por outro meio? por exemplo algum gerenciador de banco de dados etc..?

eu tinha um problema semelhante quando eu não usava QutoedStr(EditX.text); e deixava um campo em aberto sem preencher

IBQueryfiltro.SQL.Add('SELECT * FROM CADASTRO_ATENDIMENTO WHERE NUMEROATENDIMENTO = '+QuotedStr(Edit1.Text)+' AND CODIGOCLIENTE = '+QuotedStr(Edit2.Text));

Link para o comentário
Compartilhar em outros sites

  • 0
você poderia me passar um exemplo de como posso misturar esse codigo para filtrar tanto string, quanto integer? Gostaria de filtrar por exemplo, o codigo do cliente, e o status do atendimento (andamento, finalizado etc), desta forma eu posso pegar todos os clientes que estao com o atendimento em andamento, ou poderia pegar todos os atendimentos finalizados de um determinado cliente.
pimpocvl, não sei se seria a isso que você se refere, mas neste exemplo que postei antes, considerando que o seu Param1 é o Número do atendimento, Param2 é o Codigo do Cliente (Integer), então o status do atendimento (String) seria Param3. Eu acredito que fazendo as alterações abaixo (informar o tipo do parâmetro via As<tipo>) deva funcionar:

...
  if Param1 <> '' then
    IBQueryfiltro.ParamByName('pParametro1').AsInteger := StrToInt(Param1);
  if Param2 <> '' then
    IBQueryfiltro.ParamByName('pParametro2').AsInteger := StrToInt(Param2);
  if Param3 <> '' then
    IBQueryfiltro.ParamByName('pParametro3').AsString := Param3;
  IBQueryfiltro.Open;
end;

Abraços

Ola, Micheus.

Obrigado por esta me ajudando. Veja bem, fiz desta maneira que indicou, porem ao listar a consulta, o resultado e igual a "nada", ou seja, eu preenche os 3 campos (3 parametros), e quando mando listar, o resultado aparece em branco (nada). Quando os 3 parametros estao preenchidos o sql fica assim:

WHERE NUMEROATENDIMENTO = :pParametro1 AND CODIGOCLIENTE = :pParametro2 AND STATUS = :pParametro3

...teria mais alguma dica?

Link para o comentário
Compartilhar em outros sites

  • 0
Obrigado por esta me ajudando. Veja bem, fiz desta maneira que indicou, porem ao listar a consulta, o resultado e igual a "nada", ou seja, eu preenche os 3 campos (3 parametros), e quando mando listar, o resultado aparece em branco (nada). Quando os 3 parametros estao preenchidos o sql fica assim:

WHERE NUMEROATENDIMENTO = :pParametro1 AND CODIGOCLIENTE = :pParametro2 AND STATUS = :pParametro3

pimpocvl, aparentemente isto seria o correto.

Observe o seguinte, pelo nome da tabela e do campo NUMEROATENDIMENTO, imagino que em toda ela, exista a ocorrência de um determinado número uma única vez. Assim, caso você filtre este campo, passando um valor válido, mas filtre outros campos de modo que o valor não corresponda aos valores encontrados nesta única linha válida, então seu resultado será mesmo nulo.

Deixo no link a seguir exemplo que faz uso do método que lhe indiquei: Teste Filtro.zip (Descompacte-o um uma pasta específica. Já tem um executável dentro dele - apenas renomeie mudando a extensão de .ex_ para .exe)

Nele utilizei dois componentes, um da paleta Interbase e outro da ZeosLib.

Criei uma tabela com estrutura parecida com a sua e poucos dados - apenas para avaliação. Experimente inicialmente filtrar o campo STATUS. Observe o resultado. Depois, utilize outros campos, passando um dos valores obtidos neste resultado e observe que o filtro vai se ajustando.

É isso. Desculpe a demora em respondê-lo, mas estive ausente nos últimos 10 dias e queria montar um exemplo com o código que lhe exemplifiquei.

Abraços

p.s. a propósito, naquele código, na parte dentro do teste do Param2 <> '' o if deveria estar testando se Filtro não era nulo e não Param1:

...
  if Param2 <> '' then
  begin
    if Filtro <> '' then  // ****** AQUI
      Filtro := Filtro +'AND '
    else
      Filtro := ' WHERE ';
    Filtro := Filtro +'CODIGOCLIENTE = :pParametro2 ';
  end;

Link para o comentário
Compartilhar em outros sites

  • 0

Micheus, agradeco muito pela sua ajuda, principalmente por ter disponibilizado seu tempo para poder resolver um problema que nem era seu. Enfim, sou muito grato.

Consegui fazer funcionar aqui, agora vou dar uma pesquisada no forum para implementar o intervalor de data, caso não consiga hehehe, vo te enche mais um pouco.

Valeu.

Editado por pimpocvl
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...