Filtrar tabela selecionando itens no checklistbox

Delphi

PhpMyAdmin

19/06/2023

Pessoal trouxe uma coluna da minha tabela para o checklistbox usando
begin
SetoresTable.open;
SetoresTable.First;
while not setoresTable.Eof do
begin
ClbSetores.Items.Add(SetoresTablesetor.Value);
SetoresTable.Next;
end;
end;

Quando seleciono um item do checklistbox ele filtra legal,mas preciso que ele filtre todos os itens que estiver selecionado,no caso ele so esta filtrando um e o ultimo item que seleciono,alguem pode me dar um help nessa parte, segue meu codigo.
if ClbSetores.ItemIndex <> -1 then
begin
with IngressosTable do
begin
Close;
sql.Clear;
sql.Add('Select identificacao,hexa_identific, nome,setor,documento,numero_setor,criacao');
sql.Add('From Ingressos where setor= :psetor');
ParamByName('psetor').value := ClbSetores.items[ClbSetores.ItemIndex] ;
Open;
FetchAll;
end;
LbContador.Caption := IntToStr(Grid1.RowCount -1);
end;
end;

ja tentei usar o if ClbSetores.Checked[i] = true then , mas tambem não deu.
Alan

Alan

Curtidas 0

Melhor post

Arthur Heinrich

Arthur Heinrich

20/06/2023

A sintaxe "where setor = :psetor" funciona apenas com um valor mesmo.

O equivalente para múltiplos valores seria "where setor in (:psetor1,:psetor2,:psetor3,...,:psetorn)"

Tem que passar cada um dos valores que estão selecionados.

Da maneira como você fez "ParamByName('psetor').value := ClbSetores.items[ClbSetores.ItemIndex] ;", você filtrou o item "selecionado", mas não necessariamente escolhido.

Você precisa avaliar quais itens estão selecionados, utilizando a propriedade Checked.

for i:=0 to Pred(ClbSetores.Itens.Count) do
if ClbSetores.Checked[i] then ...

Dá um pouco de trabalho. Você pode fazer a varredura e, para cada setor selecionado, adiciona mais um parâmetro dinamicamente à query, guardando em outra estrutura o valor dos setores a filtrar. Depois, utiliza a query montada dinamicamente e seta cada um dos parâmetros.

Ou, você pode adotar uma outra abordagem, criando uma tabela temporária. Nela, você insere todos os códigos de setores que deseja e, neste caso, a query fica fixa e sem parâmetros. Ela fará um join com a tabela temporária para filtrar todos os valores inseridos.
GOSTEI 1

Mais Respostas

Alan

Alan

19/06/2023

A sintaxe "where setor = :psetor" funciona apenas com um valor mesmo.

O equivalente para múltiplos valores seria "where setor in (:psetor1,:psetor2,:psetor3,...,:psetorn)"

Tem que passar cada um dos valores que estão selecionados.

Da maneira como você fez "ParamByName('psetor').value := ClbSetores.items[ClbSetores.ItemIndex] ;", você filtrou o item "selecionado", mas não necessariamente escolhido.

Você precisa avaliar quais itens estão selecionados, utilizando a propriedade Checked.

for i:=0 to Pred(ClbSetores.Itens.Count) do
if ClbSetores.Checked[i] then ...

Dá um pouco de trabalho. Você pode fazer a varredura e, para cada setor selecionado, adiciona mais um parâmetro dinamicamente à query, guardando em outra estrutura o valor dos setores a filtrar. Depois, utiliza a query montada dinamicamente e seta cada um dos parâmetros.

Ou, você pode adotar uma outra abordagem, criando uma tabela temporária. Nela, você insere todos os códigos de setores que deseja e, neste caso, a query fica fixa e sem parâmetros. Ela fará um join com a tabela temporária para filtrar todos os valores inseridos.


Arthur consegue me mandar um exemplo disso que vc falou (''Dá um pouco de trabalho. Você pode fazer a varredura e, para cada setor selecionado, adiciona mais um parâmetro dinamicamente à query, guardando em outra estrutura o valor dos setores a filtrar. Depois, utiliza a query montada dinamicamente e seta cada um dos parâmetros''). se nao for pedir muito?
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

19/06/2023

Vou pressupor que a coluna Setor é do tipo varchar.

var
  s : String;
  i : Integer;
  setores : TStringList;
...
  setores:=TStringList.Create;
  for i:=0 to Pred(ClbSetores.Itens.Count) do
    if ClbSetores.Checked[i] then
      setores.add(ClbSetores.Itens[i]);
  if (setores.count>0) then
    begin
      s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
      for i:=0 to Pred(setores.Count) do
        s:=s+':psetor'+IntToStr(i)+',';
      s[Length(s)]:=')';
    end
  else
    s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos';

  IngressosTable.sql.Clear;
  IngressosTable.sql.Add(s);
  for i:=0 to Pred(setores.Count) do
    IngressosTable.ParamByName('psetor'+IntToStr(i)).value := setores[i];

  setores.free;
  IngressosTable.Open;
  ...
  IngressosTable.Close;
GOSTEI 0
Alan

Alan

19/06/2023

Vou pressupor que a coluna Setor é do tipo varchar.

var
  s : String;
  i : Integer;
  setores : TStringList;
...
  setores:=TStringList.Create;
  for i:=0 to Pred(ClbSetores.Itens.Count) do
    if ClbSetores.Checked[i] then
      setores.add(ClbSetores.Itens[i]);
  if (setores.count>0) then
    begin
      s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
      for i:=0 to Pred(setores.Count) do
        s:=s+':psetor'+IntToStr(i)+',';
      s[Length(s)]:=')';
    end
  else
    s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos';

  IngressosTable.sql.Clear;
  IngressosTable.sql.Add(s);
  for i:=0 to Pred(setores.Count) do
    IngressosTable.ParamByName('psetor'+IntToStr(i)).value := setores[i];

  setores.free;
  IngressosTable.Open;
  ...
  IngressosTable.Close;


Arthur,testei aqui o codigo,e da a mensagem de que o parametro 'psetor' nao foi encontrado.
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

19/06/2023

Vou pressupor que a coluna Setor é do tipo varchar.

var
  s : String;
  i : Integer;
  setores : TStringList;
...
  setores:=TStringList.Create;
  for i:=0 to Pred(ClbSetores.Itens.Count) do
    if ClbSetores.Checked[i] then
      setores.add(ClbSetores.Itens[i]);
  if (setores.count>0) then
    begin
      s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
      for i:=0 to Pred(setores.Count) do
        s:=s+':psetor'+IntToStr(i)+',';
      s[Length(s)]:=')';
    end
  else
    s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos';

  IngressosTable.sql.Clear;
  IngressosTable.sql.Add(s);
  for i:=0 to Pred(setores.Count) do
    IngressosTable.ParamByName('psetor'+IntToStr(i)).value := setores[i];

  setores.free;
  IngressosTable.Open;
  ...
  IngressosTable.Close;


Arthur,testei aqui o codigo,e da a mensagem de que o parametro 'psetor' nao foi encontrado.


O código que eu enviei não possui parâmetro chamado 'psetor'. Os parâmetros foram numerados: psetor0, psetor1, ...

Logo, não deve ser uma mensagem relacionada ao código que eu passei.
GOSTEI 1
Alan

Alan

19/06/2023

Vou pressupor que a coluna Setor é do tipo varchar.

var
  s : String;
  i : Integer;
  setores : TStringList;
...
  setores:=TStringList.Create;
  for i:=0 to Pred(ClbSetores.Itens.Count) do
    if ClbSetores.Checked[i] then
      setores.add(ClbSetores.Itens[i]);
  if (setores.count>0) then
    begin
      s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
      for i:=0 to Pred(setores.Count) do
        s:=s+':psetor'+IntToStr(i)+',';
      s[Length(s)]:=')';
    end
  else
    s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos';

  IngressosTable.sql.Clear;
  IngressosTable.sql.Add(s);
  for i:=0 to Pred(setores.Count) do
    IngressosTable.ParamByName('psetor'+IntToStr(i)).value := setores[i];

  setores.free;
  IngressosTable.Open;
  ...
  IngressosTable.Close;


Arthur,testei aqui o codigo,e da a mensagem de que o parametro 'psetor' nao foi encontrado.


O código que eu enviei não possui parâmetro chamado 'psetor'. Os parâmetros foram numerados: psetor0, psetor1, ...

Logo, não deve ser uma mensagem relacionada ao código que eu passei.


Desculpa amigo, tinha um comando aqui no meu codigo que acabei esquecendo de apagar, por isso estava dando essa mensagem, mas colocando de acordo com oque você me passou agora esta dizendo ''você tem um erro em sua sintaxe sql; verifique o manual que corresponde à sua versão do servidor MariaDB para obter a sintaxe correta para usar near in (?,?) na linha 1.''
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

19/06/2023

Eu me baseei no seu código para escrever este. Em princípio ele monta o comando dinamicamente, na variável "s".

Você pode colocar um ShowMessage(s); antes de atribuir a query no componente, para ver como ele montou o comando.

Tem que dar uma debbugada para entender o que saiu errado.
GOSTEI 0
Alan

Alan

19/06/2023

Eu me baseei no seu código para escrever este. Em princípio ele monta o comando dinamicamente, na variável "s".

Você pode colocar um ShowMessage(s); antes de atribuir a query no componente, para ver como ele montou o comando.

Tem que dar uma debbugada para entender o que saiu errado.


Arthur, eu fiz com o uso do ShowMessage(s) em cada etapa do codigo, e aparentemente o erro dele esta no s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
o banco parece que nao aceita o sinal de = antes do in, entao coloquei, :='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor in (")'; Só para verificar o restante do codigo ,e todos showmessage funcionou, porem com o que eu citei so pra testar, como de esperado nao teve resultado nenhum.
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

19/06/2023


Arthur, eu fiz com o uso do ShowMessage(s) em cada etapa do codigo, e aparentemente o erro dele esta no s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
o banco parece que nao aceita o sinal de = antes do in, entao coloquei, :='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor in (")'; Só para verificar o restante do codigo ,e todos showmessage funcionou, porem com o que eu citei so pra testar, como de esperado nao teve resultado nenhum.


Correto. "...setor = in (..." não funciona mesmo. Eu comi bola.
Porém, depois que você corrigiu isso, deveria ter passado.
GOSTEI 0
Alan

Alan

19/06/2023

Eu vou testar alguns comandos aqui no in ,para ver se dá certo, pq se eu não me engano tinha colocado um comando diferente no in, e dependendo do setor selecionado no CheckListBox ele dava a mensagem de psetor0 não encontrado,psetor8 não encontrado e por aí vai.
GOSTEI 0
Alan

Alan

19/06/2023

Arthur, tentei aqui sem resultado,consegue me mandar um exemplo da segunda opção que vc citou,da tabela temporária?
GOSTEI 0
Alan

Alan

19/06/2023


Arthur, eu fiz com o uso do ShowMessage(s) em cada etapa do codigo, e aparentemente o erro dele esta no s:='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor = in (';
o banco parece que nao aceita o sinal de = antes do in, entao coloquei, :='select identificacao, hexa_identific, nome, setor, documento, numero_setor, criacao from Ingressos where setor in (")'; Só para verificar o restante do codigo ,e todos showmessage funcionou, porem com o que eu citei so pra testar, como de esperado nao teve resultado nenhum.


Correto. "...setor = in (..." não funciona mesmo. Eu comi bola.
Porém, depois que você corrigiu isso, deveria ter passado.


Fala Arthur blz ?consegui resolver o problema aqui ,de uma outra maneira ,mas me atendeu , criei uns checkbox em tempo de execução,e nós caption deles,recebi os itens do CheckListBox que estão checados,na tabela também criei mais um campo de validação que só recebe 'Y' e 'N' , então quando seleciono os checkbox ele faz um UPDATE pra 'Y' caso esteja no 'N' e quando está desmarcado recebe 'N' e na hora de fazer o filtro,faço o filtro que está válido .
GOSTEI 0
POSTAR