Somar valores de uma tabela de acordo com criterios selecionados em campo Combobox

Banco de Dados

28/07/2019

Tenho uma tabela em Firebird com os seguintes campos. Mes, Ano, Item, Valor
Mes, vai de janeiro a dezembro (seleciono em um Combo) no Delphi
Ano, de 2019 ate 2030 por exemplo
Item, aqui registro tb em um Combo..... PrestacaoCasa, Alimento, Agua, Luz e varios outros.
Selecionando o mes de janeiro, ano 2019 e Item Alimento, por exemplo
Preciso retornar o valor total em alimentos gastos durante o mes de janeiro de 2019.
Estou levando uma surra para montar essa SQL, ou por outro metodo
Obs. No banco os valores estão em CHAR
Não estou conseguindo montar essa SQL,apos ter visto vários exemplos de SQL, mas são simples e não com varios filtros como esse
Alexandre

Alexandre

Curtidas 0

Melhor post

Emerson Nascimento

Emerson Nascimento

29/07/2019

você pode fazer de duas formas:
- montando a instrução em tempo-real, em função do filtro ou
- preparando a instrução para receber parâmetros conforme a seleção dos filtros.

vamos supor que o primeiro item de todos os combos é 'Todos'.
para exemplificar, no combo mês teríamos os itens:
Todos
Janeiro
Fevereiro
[....]
Novembro
Dezembro

- montando a instrução em tempo-real:
se o primeiro item de todos os combos é 'Todos', ao posicionar nesse item, nada precisa ser adicionado ao filtro.
   strQueryBase := 'select * from tabela ';
   strQueryFiltro := '';

   if ComboMes.ItemIndex > 0 then
   begin
      if strQueryFiltro <> EmptyStr then
         strQueryFiltro := strQueryFiltro + ' AND ';
      strQueryFiltro := strQueryFiltro + ' (Mes = '+ComboMes.Text+') ';
   end;
   if ComboAno.ItemIndex > 0 then
   begin
      if strQueryFiltro <> EmptyStr then
         strQueryFiltro := strQueryFiltro + ' AND ';
      strQueryFiltro := strQueryFiltro + ' (Ano = '+ComboAno.Text+') ';
   end;
Faça isso para todos os combos.
Ao final, faça a junção das variáveis para montar a instrução:
   if strQueryFiltro <> EmptyStr then strQueryFiltro := ' WHERE ' + strQueryFiltro;
   Dataset.SQL := strQueryBase + ' ' + strQueryFiltro
   Data.Open;


- uma unica instrução, preenchendo parâmetros:
   Dataset.SQL := 'select * from tabela where ( :parametromes='Todos' or mes = :parametromes ) '+
                              ' and ( :parametroano='Todos' or ano = :parametroano ) '
                              ' and ( :parametroitem='Todos' or item = :parametroitem ) '; // faça isso para todos os parâmetros possíveis

ao pesquisar, basta preencher os parâmetros:
   Dataset.ParamByName('parametromes').AsString := ComboMes.Text;
   Dataset.ParamByName('parametroano').AsString := ComboAno.Text;
   Dataset.ParamByName('parametroitem').AsString := ComboItem.Text;
   Dataset.Open;
GOSTEI 1

Mais Respostas

Washington Silva

Washington Silva

28/07/2019

Tenho uma tabela em Firebird com os seguintes campos. Mes, Ano, Item, Valor
Mes, vai de janeiro a dezembro (seleciono em um Combo) no Delphi
Ano, de 2019 ate 2030 por exemplo
Item, aqui registro tb em um Combo..... PrestacaoCasa, Alimento, Agua, Luz e varios outros.
Selecionando o mes de janeiro, ano 2019 e Item Alimento, por exemplo
Preciso retornar o valor total em alimentos gastos durante o mes de janeiro de 2019.
Estou levando uma surra para montar essa SQL, ou por outro metodo
Obs. No banco os valores estão em CHAR
Não estou conseguindo montar essa SQL,apos ter visto vários exemplos de SQL, mas são simples e não com varios filtros como esse


Cara to meio sem tempo pra criar algo aki mais sa uma olhada nessa script ele vai te ajudar ... ele conta os valorer de uma coluna sql e retorna em uma variavel no php.. ai e so vc usar essa variavel de resultado da forma que quiser...

.
.
.

$resultado = mysqli_query($conn, "SELECT sum(visita_total) FROM visitas WHERE id_loja='$id_loja'");
$linhas = mysqli_num_rows($resultado);

while($linhas = mysqli_fetch_array($resultado)){
$total_viz_perfil = $linhas['sum(visita_total)'];
}
.
.
.
GOSTEI 0
Alexandre

Alexandre

28/07/2019

Tenho uma tabela em Firebird com os seguintes campos. Mes, Ano, Item, Valor
Mes, vai de janeiro a dezembro (seleciono em um Combo) no Delphi
Ano, de 2019 ate 2030 por exemplo
Item, aqui registro tb em um Combo..... PrestacaoCasa, Alimento, Agua, Luz e varios outros.
Selecionando o mes de janeiro, ano 2019 e Item Alimento, por exemplo
Preciso retornar o valor total em alimentos gastos durante o mes de janeiro de 2019.
Estou levando uma surra para montar essa SQL, ou por outro metodo
Obs. No banco os valores estão em CHAR
Não estou conseguindo montar essa SQL,apos ter visto vários exemplos de SQL, mas são simples e não com varios filtros como esse




Ola amigos.
Ainda levando uma surra com SQL. Então fui por outro caminho.

procedureTfrmPrincipal.BotaoCalcularClick(Sender: Tobject);
begin
vvalor:=0;
vtotDespesa:=0;
vmes:=frmPiricipal.ComboMes.Text; // aqui seleciono o mes
vano:=frmPrincipal.ComboAno.Text; // aqui seleciono o ano
vItem:=frmPrincipal.ComboItem.Text;

frmPrincipal.IBTableDebito.First;
while not (frmPrincipal.IBTableDebito.Eof)do
begin
if(frmPrincipal.IBTableDebito.Locate ('MES; ANO; ITEM', varArrayof([vmes, vano, vitem]),[]))then // Aqui ele encontra a linha que tem o item Valor (string)
begin
vvalor:=srttofloat(frmPrincipal.IBTableDebito.FieldByName('VALOR').asString);
vtotDespesa:=vtotDespesa+vvalor;
EditSoma.Text:=floattostr(vtotDespesa);
frmPrincipal.IBTableDebito.Next;
end;
end;
end;

A idéia é ir para o começo do banco de dados e usar um while para varrer a soma (campo Valor) definida pelo MES, ANO e ITEM, ate o final da tabela
Por exemplo, seleciono o mes (janeiro), o Ano (2019) o Item (farmacia, por exemplo). Ele vai ate o final e mostra o mvalor durante o mes, quanto foi gasto de farmacia.

So que não está funcionando bem... So le a primeira linha e fica pulando do while para o If locate, incessantemente (só haviam 3 registros para ler)

Alguma santa alma pode ajudar... Acho que isso fnciona, mas deve ter algum erro aí nessas linhas e não encontro onde
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/07/2019

deve ser algo assim:
procedure TfrmPrincipal.BotaoCalcularClick(Sender: Tobject);
var
  instrucaoSQL: string;
  condicaoSQL: string;
begin
  vmes := trim(frmPrincipal.ComboMes.Text); // aqui seleciono o mes
  vano := trim(frmPrincipal.ComboAno.Text); // aqui seleciono o ano
  vitem := trim(frmPrincipal.ComboItem.Text);

  // instrução principal e condição de filtro
  instrucaoSQL := 'select sum(cast(valor as float)) valortotal from tabela';
  condicaoSQL := '';

  if vmes <> EmptyStr then
  begin
    if condicaoSQL <> EmptyStr then condicaoSQL := condicaoSQL + ' and ';
    condicaoSQL := condicaoSQL + 'mes = '+QuotedStr(vmes);
  end;

  if vano <> EmptyStr then
  begin
    if condicaoSQL <> EmptyStr then condicaoSQL := condicaoSQL + ' and ';
    condicaoSQL := condicaoSQL + 'ano = '+QuotedStr(vano);
  end;

  if vitem <> EmptyStr then
  begin
    if condicaoSQL <> EmptyStr then condicaoSQL := condicaoSQL + ' and ';
    condicaoSQL := condicaoSQL + 'item = '+QuotedStr(vitem);
  end;

  if condicaoSQL <> EmptyStr then condicaoSQL := ' where '+condicaoSQL;

  frmPrincipal.IBQuery.Close;
  frmPrincipal.IBQuery.SQL.Text := instrucaoSQL + condicaoSQL;
  frmPrincipal.IBQuery.Open;

  EditSoma.Text := frmPrincipal.IBQuery.FieldByName('valortotal').AsString;

  frmPrincipal.IBQuery.Close;
end;
GOSTEI 0
Alexandre

Alexandre

28/07/2019

deve ser algo assim:
procedure TfrmPrincipal.BotaoCalcularClick(Sender: Tobject);
var
  instrucaoSQL: string;
  condicaoSQL: string;
begin
  vmes := trim(frmPrincipal.ComboMes.Text); // aqui seleciono o mes
  vano := trim(frmPrincipal.ComboAno.Text); // aqui seleciono o ano
  vitem := trim(frmPrincipal.ComboItem.Text);

  // instrução principal e condição de filtro
  instrucaoSQL := 'select sum(cast(valor as float)) valortotal from tabela';
  condicaoSQL := '';

  if vmes <> EmptyStr then
  begin
    if condicaoSQL <> EmptyStr then condicaoSQL := condicaoSQL + ' and ';
    condicaoSQL := condicaoSQL + 'mes = '+QuotedStr(vmes);
  end;

  if vano <> EmptyStr then
  begin
    if condicaoSQL <> EmptyStr then condicaoSQL := condicaoSQL + ' and ';
    condicaoSQL := condicaoSQL + 'ano = '+QuotedStr(vano);
  end;

  if vitem <> EmptyStr then
  begin
    if condicaoSQL <> EmptyStr then condicaoSQL := condicaoSQL + ' and ';
    condicaoSQL := condicaoSQL + 'item = '+QuotedStr(vitem);
  end;

  if condicaoSQL <> EmptyStr then condicaoSQL := ' where '+condicaoSQL;

  frmPrincipal.IBQuery.Close;
  frmPrincipal.IBQuery.SQL.Text := instrucaoSQL + condicaoSQL;
  frmPrincipal.IBQuery.Open;

  EditSoma.Text := frmPrincipal.IBQuery.FieldByName('valortotal').AsString;

  frmPrincipal.IBQuery.Close;
end;


Olá Emerson. Essa linha edit soma, reclama que nção está encontrando essa var na IBQuery (valor total)
Na base de dados está como VALOR.... Ai substuitui e dá o mesmo erro tb.
Pode auxiliar? Grato
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/07/2019

Coloque uma IBQuery nova, sem qualquer instrução ou campo. Apenas relacione à conexão ao banco de dados. Utilize a IBQuery recém criada no código de cálculo.
GOSTEI 0
Alexandre

Alexandre

28/07/2019

Coloque uma IBQuery nova, sem qualquer instrução ou campo. Apenas relacione à conexão ao banco de dados. Utilize a IBQuery recém criada no código de cálculo.


Olá Emerson.
Ainda dando pau.
Não sei onde está esse erro.
Deve faltar ainda algo nessa SQL...
Agradeço sua resposta
GOSTEI 0
Alexandre

Alexandre

28/07/2019

Coloque uma IBQuery nova, sem qualquer instrução ou campo. Apenas relacione à conexão ao banco de dados. Utilize a IBQuery recém criada no código de cálculo.


Emerson... como ficaria? Sem código essa query nova? Não deu certo
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/07/2019

solte um objeto TIBQuery no form. Ligue-o à conexão do banco de dados.
depois use-a naquele código passado. onde está frmPrincipal.IBQuery troque pela ibquery que você adicionou.
GOSTEI 0
POSTAR