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

somar valores de uma dbgrid


dan_visualdm

Pergunta

olá pessoal, boa tarde!

fiz uma funçãozinha aqui, mais está dando um probleminha:

- ela faz um filtro na tabela - tbl_clientes_detalhes pelo código do cliente e os itens pra ele cadastrado na tablea detalhes e soma os valores da coluna de valor.

O que acontece:

- Quando clico em Next ou Prior sem fazer nenhuma inclusão, baixa ou estorno ele soma certinho

- Quando dou baixa ou estorno ele soma certinho, ele da um refresh na table e soma (já com o novo ítem incluído) e mostra o resultado.

Porém...

- Se incluir, baixa ou estornar e e tentar mudar de cliente clocando em Next ou Prior, ele não consegue fazer o filtro e somar os valores, o seguinte erro é apresentado:

q_relatorio_clientes: Cannot perform this operation on a closed database

essa programação está assim:

dentro do botão - next, prior:

var
soma1: Double;
soma2: Double;
begin
dm.q_clientes.Next;
begin
soma1 := 0;
soma2 := 0;
dm.q_relatorio_clientes.First;
dm.q_relatorio_clientes_pg.First;
with dm.q_relatorio_clientes do
begin
  Close;
  SQL.Clear;
  SQL.Add('select * from tbl_relatorio_clientes where codigo like'''+ DBEdit1.Text + '%''');
  Open;
while not dm.q_relatorio_clientes.Eof do
begin
  soma1 := soma1 + dm.q_relatorio_clientes.Fieldbyname('valor').Value;
  dm.q_relatorio_clientes.Next;
  end;
  v_total1.Caption := FloatToStrF(soma1,ffCurrency , 15,2);
  begin
  with dm.q_relatorio_clientes_pg do
begin
  Close;
  SQL.Clear;
  SQL.Add('select * from tbl_relatorio_clientes_pg where codigo like'''+ DBEdit1.Text + '%''');
  Open;
while not dm.q_relatorio_clientes_pg.Eof do
begin
  soma2 := soma2 + dm.q_relatorio_clientes_pg.Fieldbyname('valor').Value;
  dm.q_relatorio_clientes_pg.Next;
  end;
  v_total2.Caption := FloatToStrF(soma2,ffCurrency , 15,2);
end; end; end; end; end;

dentro dos botões - incluir, baixar e estornar não tem nenhuma função....

alguém pode me dar uma forcinha???

Link para o comentário
Compartilhar em outros sites

6 respostass a esta questão

Posts Recomendados

  • 0

Use desta maneira:

with dm.q_relatorio_clientes, SQL do begin

Close;

Clear;

Text := 'select * from tbl_relatorio_clientes where codigo like :param';

ParamByName('param').asstring := DBEdit1.Text + '%';

Open;

First; // é usado apois a abertura da tabela, antes do while.

DisableControls;

while not Eof do begin

soma1 := soma1 + Fieldbyname('valor').Value;

Next;

end;

EnableControls;

.

.

.

end;

Link para o comentário
Compartilhar em outros sites

  • 0
Use desta maneira:

with dm.q_relatorio_clientes, SQL do begin

Close;

Clear;

Text := 'select * from tbl_relatorio_clientes where codigo like :param';

ParamByName('param').asstring := DBEdit1.Text + '%';

Open;

First; // é usado apois a abertura da tabela, antes do while.

DisableControls;

while not Eof do begin

soma1 := soma1 + Fieldbyname('valor').Value;

Next;

end;

EnableControls;

.

.

.

end;

olá amigo... deu erro nessa linha:

ParamByName('param').asstring := DBEdit1.Text + '%';

e tb eu não entendi o que ela faz...

o erro que aapreceu é o segunte: undeclared identifier

Link para o comentário
Compartilhar em outros sites

  • 0

me intrometendo um pouquinho...

Porém...

- Se incluir, baixa ou estornar e e tentar mudar de cliente clocando em Next ou Prior, ele não consegue fazer o filtro e somar os valores, o seguinte erro é apresentado:

q_relatorio_clientes: Cannot perform this operation on a closed database

dan_visualdm, a mensagem sugere que na situação apresentada (por algum motivo) o componente TDataBase está fechado.

É conveniente citar os componentes de acesso ao banco que você está utilizando, bem como o banco de dados em uso.

... deu erro nessa linha:

ParamByName('param').asstring := DBEdit1.Text + '%';
e tb eu não entendi o que ela faz...
quanto ao que ele faz, o que o colega Eder Moraes lhe sugeriu é a utilização de parametrização da query (uso de parâmetros). Isto é feito quando você coloca os dois pontos (":") seguido de um identificador (no exemplo do colega, seria param) e antes de abrir a consulta, você deve inicializar o valor deste parâmetro normalmente utilizando o método ParamByName do dataset (lembrando que se o componente de acesso for da paleta ADO, ele deve ser antecedido por Parameters, ou seja, dataset.Parameters.ParamByName(<identificador>).Value := <valor>). Uma observação sobre o uso do LIKE: ele deve ser usado apenas quando você quer fazer uma pesquisa em um campo (texto) onde você terá apenas parte dele. Quanto você tem o valor exato, use o sinal de igualdade - é muito mais rápido! Nesta sua aplicação, observo que você te um componente para cada visualização (q_clientes, q_relatorio_clientes e q_relatorio_clientes_pg) e que o campo de relacionamento entre eles chama-se Codigo. Dê uma lida neste meu post e depois continue com o que segue e veja se você não vai poder usar este método em sua aplicação. Como os componentes q_relatorio_clientes e q_relatorio_clientes_pg já estão adicionados em seu projeto, e eles não mudam em momento algum, não faz sentido você estar sempre fazendo sua inicialização dinamicamente, a cada vez que o botão é pressionado. Baseado no post que citei, estes dois componentes ficariam vinculados ao dataset q_clientes através do uso da propriedade DataSource utilizando como vínculo o campo Codigo. Para isso, vou assumir que o componente DataSource que você usa para ligar o dataset q_clientes aos componentes data-aware (como é o caso do DBEdit1) chama-se DS_q_clientes. Assim, você configura os componentes em design-time deste modo: q_relatorio_clientes - SQL => select * from tbl_relatorio_clientes where codigo = :codigo - DataSource => DS_q_clientes q_relatorio_clientes_pg - SQL => select * from tbl_relatorio_clientes_pg where codigo = :codigo - DataSource => DS_q_clientes Antes de você abrir o seu dataset q_clientes, você deve também abrir q_relatorio_clientes e q_relatorio_clientes_pg. Com isto, cada vez que você mover uma linha em q_clientes (com Next/Prior/First/Last), automaticamente as consultas serão refeitas (você não precisará fazer nada - o filtro é automático). Com isto, poderíamos ajustar o código para algo assim:
// este evento ocorre sempre que há alteração/movimento no dataset q_clientes
// assim, podemos usá-lo para refazer o cálculo
procedure TForm1.DS_q_clientesDataChange(Sender: TObject; Field: TField);
begin
  SomaValores;
end;

// existindo o procedimento apenas para o cálculo, podemos chamá-lo 
// de qualquer parte do programa, quando necessário, e sem duplicar código
// OBS: este procedimento deverá ser declarado na sessão private do TForm
procedure TForm1.SomaValores;
var
  soma1: Double;
  soma2: Double;
begin
  with dm do
  begin
    soma1 := 0;
    soma2 := 0;
    q_relatorio_clientes.DisableControls; 
    while not q_relatorio_clientes.Eof do
    begin
      soma1 := soma1 + q_relatorio_clientes.Fieldbyname('valor').Value;
      q_relatorio_clientes.Next;
    end;
    q_relatorio_clientes.First;
    q_relatorio_clientes.EnableControls; 
    v_total1.Caption := FloatToStrF(soma1,ffCurrency , 15,2);

    q_relatorio_clientes_pg.DisableControls;
    while not q_relatorio_clientes_pg.Eof do
    begin
      soma2 := soma2 + q_relatorio_clientes_pg.Fieldbyname('valor').Value;
      q_relatorio_clientes_pg.Next;
    end;
    q_relatorio_clientes_pg.First;
    q_relatorio_clientes_pg.EnableControls;
    v_total2.Caption := FloatToStrF(soma2,ffCurrency , 15,2);
  end; 
end;

O uso de DisableControls e First/EnableControls é necessário caso os datasets em questão estejam ligados a componentes que mostrarão suas informações no form (como um TDBGrid ou TDBEdit's), pois assim, a movimentação no registro não gera atualização na tela desnecessáriamente.

Ficou meio extenso, mas se eu consegui explicar adequadamente, acredito que esta informação lhe será útil. Não sabendo o seu nível de conhecimento, tentei fazer um detalhamento intermediário.

OBS: no caso de tentar implementar, lembre-se de fazer um backup do que você tem atualmente.

Abraços

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

  • 0

oláa!!

poxa amigo, show de bola sua explicação!!! ajudou pra valer aqui viw... fiz igualzinho o que você ensinou e deu super certo!!!

era isso ai mesmo!!!

obrigadão por essa explicação super detalhadaaa!!

valeu mesmo!!!

é legal encontrar pessoas que nos ajudam. Pra falar a verdade eu trabalho com criação há mais de 5 anos e há muito tempo atrás cheguei a fazer um cursinho básico de Delphi, mas nem liguei muito... Agora que estou estudando, estou desenvolvendo um sistema aqui pra minha agencia... Está ficando bem legal, apesar de eu estar tendo algumas dificuldades... Mas com o forum aqui e com uns livros que comprei está indo legalzinho e estou aprendendo bastante!!

valeu!!

abraçosss!!!

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

  • 0

Vendo que você conseguiu compreender o que mencionei, tenho a acrescentar mais uma informação sobre um dos recurso que citei.

O evento OnDataChange, irá ocorrer também quando um dos campos do dataset em questão for alterado. Explicando... Além de ele ocorrer quando você movimenta entre os registros do seu dataset q_clientes (via next, prior,...), quando você estiver com este dataset em modo edição ou inserção, ao ser modificado o conteúdo de um dos campos este evento também ocorrerá.

Assim, quando os dados do dataset puderem ser alterados (há casos em que apenas o usamos em um DBGrid para visualização), torna-se conveniente que verifiquemos o estado do mesmo, pois deste modo, evitamos que o procedimento seja chamado mais vezes que o necessário.

Neste sentido, o exemplo anterior teria uma linha a mais:

procedure TForm1.DS_q_clientesDataChange(Sender: TObject; Field: TField);
begin
  if TDataSource(Sender).State = dsBrowse then
    SomaValores;
end;

O importante é tentar entender em que momento o evento ocorre. Isto entendido, você pode utilizar dele em diversas situações.

Abraços

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
      152,2k
    • Posts
      651,9k
×
×
  • Criar Novo...