Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Suma de una columna de un DBGRID (https://www.clubdelphi.com/foros/showthread.php?t=60955)

Pollo2004 20-10-2008 20:00:48

Suma de una columna de un DBGRID
 
Hola, nuevamente quisiera q alguien me corrija esto, xq me esta volviendo loco y no logro q haga lo q yo pretendo.
Quiero q al ingresar un producto y se calcule el precio de ese item, lo vaya a acumulando en y sumando en otro campo calculado de mi tabla para luego sacar el total a pagar.

1º codigo es este:

tengo un campo calculado para sacar el precio a pagar por item, entonces lo q hago es acumularlo y lo muestro (cre q el error esta q la acumulacion la hago en el procedimiento oncaculated de la tabla, en el mismo q calculo el precio del item entonces no me lo acumula.)
el codigo seria asi:
var
acum: currency;

procedure TForm4.Table4CalcFields(DataSet: TDataSet);
begin
table4Total.ascurrency:= table4Cantidad.AsInteger * Table4Precio.asCurrency;
acum:= acum + table4Total.ascurrency;
end;

2º creo q esta debe ser la correcta pero no se como hacerlo.
ah medida q se ingreso una fila acumularlo a una varible y mostrar eso.
No se como moverme fila por fila y ingresar al dato ese.
Mi idea es asi lo escribo es pseudocodigo:

cuando pasa a la siguiente fila
acumulador:= dbgrid1.columns[n] + acumulador;

Gracias!!!

Caral 20-10-2008 20:44:07

Hola
No estoy muy seguro, lo hice hace algun tiempo y no me acuerdo bien, pero creo que el tutorial de facturación hace lo que necesitas, revisalo, tal vez te sirva.
Saludos

enecumene 20-10-2008 20:50:38

Hola, colocar esto en los eventos AfterDelete y AfterPost de tu dataset, debes adaptarlo a tu manera:

Código Delphi [-]
procedure TFReposicion.cdDetallesAfterDelete(DataSet: TDataSet);
Var
Suma: Double;
Campo: TField;
Begin
     Suma:=0;
     Try
        With cdDetalles Do Begin
             DisableControls;
             Campo := FieldByName('valor');
             First;
             While Not EoF Do Begin
                   Suma := Suma + Campo.AsFloat;
                   Next;
             End;
        End;
     Finally
        cdDetalles.EnableControls;
     End;
     dsCaja.DataSet.FieldByName('total').AsFloat := Suma;
end;

Saludos.

Pollo2004 21-10-2008 11:16:17

hola enecumene, a ver si entiendo ...
campo: tfield; --->esto es la declarion de un acum de tipo tfield?
Campo := FieldByName('valor');---> le asigno a campo el valor q tengo en ese campo..(mi caso total?), y porq pusiste entre literales 'valor'
y donde pusiste cdDetalles y cdCaja te estas refiriendo al nombre de las tablas?
Perdon por todas las preguntas, pero prefiero preguntar y sacarme las dudas antes de decir q si como los locos!

enecumene 21-10-2008 14:03:53

Hola Pollo2004, TField es una clase tipo campo, Campo := FieldByName('valor'); donde "Valor" es el campo de la columna que vas a sumar y restar, cdDetalles es un dataset (Puede ser TTable o TQuery) y dsCaja es un datasource donde muestro el total (Pero eso es en mi caso, en tu caso puede ser un TTable o TQuery en el mismo Form), recordad colocarlos en los eventos mencionados anteriormente en el dataset asociado al DBGrid.

Saludos.

enecumene 22-10-2008 21:00:22

Hola, ¿te resultó? ¿Conseguiste otro código? :confused: :confused:

Saludos.

Pollo2004 23-10-2008 03:54:03

hola enecumene, no he logrado compilarlo, te paso como lo deje a tu codigo y te indico donde me sale el error
procedure TForm5.TDetaAfterDelete(DataSet: TDataSet);
var
Suma: Double;
Campo: TField;
Begin
Suma:=0;
Try
With DsDeta Do Begin
TDeta.DisableControls;
Campo := TDetaTotal;
TDeta.First;
While Not EoF Do Begin
Suma := Suma + Campo.AsFloat;
Next;
End;
End;
Finally
TDeta.EnableControls;
End;
TDeta.TDetaSinIva.AsCurrency := Suma; (aca tengo el error al compilar,TDetaSinIva es un campo calculado)
end;


Me larga un error diciendo q no esta declarado el identidicador TDetaSinIva.

mañana lo voy a ver con un poco mas tiempo, para ver si le encuentro la solucion, cualquier sugerencia es bienvenida!
saludos! Nos vemos!

enecumene 23-10-2008 13:54:45

Hola, Amigo no puedes mostrar un resultado en un campo calculado debes mostrarlo en un campo normal o en un edits, cuando tengas más tiempo estúdialo y verás que es un código muy sencillo ;).

Saludos.

jhonny 23-10-2008 14:12:23

Cita:

Empezado por enecumene (Mensaje 321813)
debes mostrarlo en un campo normal o en un edits...

O en un TAggregateField ;)

Pollo2004 28-10-2008 01:07:20

No me funciona la suma
 
Hola nuevamente, perdon por la demora....enecumene he logrado compilar tu idea, pero no me funciona, la verdad no se xq...
corregi mi error de esta manera, puse un label.caption:= currtostr(suma);

Bueno aca no me muestra nada.

Yo lo q me gustaria es recorrer el dbgrid y controlar desde ahi las filas q ingreso, pero no se como moverme x fila, si alguien lo sabe soy todo oido..

Por las dudas te paso mi form para q le hechen una miradita
Código Delphi [-]
unit Factura;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, StdCtrls, DBTables, Mask, DBCtrls, Grids, DBGrids, ExtCtrls,
  Buttons;
type
  TForm5 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    DBGrid1: TDBGrid;
    DBText1: TDBText;
    DBText2: TDBText;
    DBText3: TDBText;
    DBText4: TDBText;
    DBLookupComboBox1: TDBLookupComboBox;
    DBText5: TDBText;
    DBEdit1: TDBEdit;
    DBText6: TDBText;
    DSCliente: TDataSource;
    TCliente: TTable;
    DSProd: TDataSource;
    TProd: TTable;
    DSFact: TDataSource;
    TFact: TTable;
    DSDeta: TDataSource;
    TDeta: TTable;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    TClienteIdCliente: TStringField;
    TClienteRazonSocial: TStringField;
    TClienteDireccion: TStringField;
    TClienteLocalidad: TStringField;
    TClienteCodigoPostal: TFloatField;
    TClienteTelefono: TFloatField;
    TClienteCuitCuil: TFloatField;
    TProdCodProducto: TStringField;
    TProdDetalle: TStringField;
    TProdCosto: TCurrencyField;
    TProdPrecioLista: TCurrencyField;
    TProdStock: TFloatField;
    TProdStockMin: TFloatField;
    TFactNumFact: TFloatField;
    TFactTipo: TStringField;
    TFactFecha: TDateField;
    TFactTotal: TCurrencyField;
    TFactIdCliente: TStringField;
    TDetaIditem: TAutoIncField;
    TDetaCodProducto: TStringField;
    TDetaCantidad: TFloatField;
    TDetaNumFactura: TFloatField;
    TDetaPrecioLista: TCurrencyField;
    TDetaDetalle: TStringField;
    TDetaTotal: TCurrencyField;
    SpeedButton1: TSpeedButton;
    BitBtn1: TBitBtn;
    TDetaPrecio: TCurrencyField;
    Label4: TLabel;
    Label5: TLabel;
    TFactSubTot: TCurrencyField;
    TDetaSinIva: TCurrencyField;
    Label6: TLabel;
    procedure FormActivate(Sender: TObject);
    procedure TDetaCalcFields(DataSet: TDataSet);
    procedure DBGrid1Enter(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure TDetaCantidadValidate(Sender: TField);
    procedure BitBtn1Click(Sender: TObject);
    procedure TDetaAfterDelete(DataSet: TDataSet);
 

  
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form5: TForm5;
  NFact: integer;
implementation
{$R *.dfm}
procedure TForm5.FormActivate(Sender: TObject);
begin

  TFact.last;
  Tfact.edit;
  NFact:= TFactNumFact.asinteger;
  NFact:= NFact + 1;
  TFact.append;
  TFactFecha.AsDateTime:= now;
  TfactNumFact.AsInteger:= NFact;
end;
 
procedure TForm5.TDetaCalcFields(DataSet: TDataSet);
begin
  TDetaTotal.ascurrency:= TDetaCantidad.asinteger * TDetaPrecio.ascurrency;
end;
procedure TForm5.DBGrid1Enter(Sender: TObject);
begin
  if TFact.state in dseditmodes then
    TFact.post;
    TDeta.append;
end;
procedure TForm5.SpeedButton1Click(Sender: TObject);
begin
  TDeta.Append;
  TDeta.Post;
  if messagedlg ('LA FACTUA FUE CREADA CON EXITO', mtInformation, mbokCancel,0) = mrok
    then
      form5.close;
end;
 
procedure TForm5.TDetaCantidadValidate(Sender: TField);
begin
if TDetaCantidad.asinteger > TProdStock.asinteger then
    showmessage ('NO HAY SUFICIENTE STOCK PARA ESTE PEDIDO')
    else
      TProd.edit;
      TProdStock.AsInteger:= TProdStock.AsInteger - TDetaCantidad.asinteger;
       TProd.post;
end;
procedure TForm5.BitBtn1Click(Sender: TObject);
begin
  TFact.Cancel;
  TDeta.edit;
  TDeta.Prior;
  TDeta.Delete;
  Form5.Close;
end;
procedure TForm5.TDetaAfterDelete(DataSet: TDataSet);
var
  Suma: Double;
  Campo: TField;
Begin
     Suma:=0;
     Try
        With DsDeta Do Begin
             TDeta.DisableControls;
             Campo := TDetaTotal;
             TDeta.First;
             While Not EoF Do Begin
                   Suma := Suma + Campo.AsFloat;
                   Next;
             End;
        End;
     Finally
        TDeta.EnableControls;
     End;
     label6.caption := currtostr(Suma);
end;
 
 
end.

Gracias otra vez por el aguante y las pilas q le ponen!!!

Caral 28-10-2008 01:13:15

Hola
La verdad es que he seguido el hilo y cada vez entiendo menos.
No se exactamente lo que se pretende, me da la impresión de que se quiere sumar los datos que hay en un campo que presenta un dbgrid, pero no entiendo por que el uso de un campo calculado.
Me pongo a pensar: Que pasa si no se quiere calcular todos los campos del dbgrid o si hay algún error y se quiere corregir?.
No se, no lo capto.
Saludos

Pollo2004 28-10-2008 02:30:56

Tratar de aclarar!!!
 
Cita:

Empezado por Caral (Mensaje 322767)
Hola
La verdad es que he seguido el hilo y cada vez entiendo menos.
No se exactamente lo que se pretende, me da la impresión de que se quiere sumar los datos que hay en un campo que presenta un dbgrid, pero no entiendo por que el uso de un campo calculado.
Me pongo a pensar: Que pasa si no se quiere calcular todos los campos del dbgrid o si hay algún error y se quiere corregir?.
No se, no lo capto.
Saludos

Mira lo q yo pretendo hacer es una factura y a medida q ingreso un producto, calculo precio * cantidad y me da el resultado de ese producto, ok? hasta ahi todo claro, el tema es cuando ingreso otro producto tengo q hacer lo mismo, pero a su vez tengo q acumular un total general de la factura, q viene a ser todos los resultados de precio * cantidad de todos los productos q vendi.

Espero aclarar tu panorama y q puedas aportar tus ideas. gracias caral!

enecumene 28-10-2008 02:40:35

Hola, el código que te propuse hace exactamente eso que quieres hacer, lo uso y me funciona perfecto, te aconsejo revises bien donde está fallando.

Saludos.

Pollo2004 29-10-2008 02:06:35

I/O error 6
 
Cita:

Empezado por enecumene (Mensaje 322770)
Hola, el código que te propuse hace exactamente eso que quieres hacer, lo uso y me funciona perfecto, te aconsejo revises bien donde está fallando.

Saludos.

Estoy trantando de seguir paso a paso el codigo y me entro una duda con respecto a la sentencia WITH, funciona como un IF? o es de la ecepcion?
el disablecontrols coloca la tabla en q estado? despues el resto lo entiendo.

otra duda q me entro mirando detenidamente el codigo es el soguiente!
Table1.first, lo coloca en el inicio de la tabla, esto es correcto?
Entonces me pregunto, me sumaria todos los registros, viejos, nuevos de otras facturas completamentes todos?, o al existir una integridad referencial fijo un dominio q solamente me sume los q cargo en ultimo para ese num de factura?

Caral 29-10-2008 02:11:38

Hola
Es el problema con los maestros, hacen códigos y luego a nosotros los novatos nos toca tratar de entender de que se trata.
Estos Maestros, cuando aprenderán.:D:D
A ver Maestro enecumene, ilustranos:D;)
Saludos

enecumene 29-10-2008 02:15:03

Hola, el with sirve para trabajar con un objeto específico es útil para reducir el código, ejemplo:

Código Delphi [-]
With Tabla1 do
  begin
     Close;
     SQL.Clear;
     SQL.Text := 'sentencia....';
     Open;
  end;

Aquí sin el with...do:

Código Delphi [-]
 Tabla1.Close;
     Tabla1.SQL.Clear;
     Tabla1.SQL.Text := 'sentencia....';
     Tabla1.Open;

¿Ves la diferencia?, con el First se coloca desde el primer registro de la tabla, como estás tratando de realizar facturas es lógico que deberías estar usando tablas de memorias o una tabla temporal, porque si no, te sumará todos los registros viejos, por eso se recomienda usar tablas de memorias o temporales donde puedes trabajar solamente con esos registros de manera individual a los registros viejos. Espero que se te claro sino me avisas.

Saludos.

enecumene 29-10-2008 02:16:20

Cita:

Empezado por Caral (Mensaje 323030)
Hola
Es el problema con los maestros, hacen códigos y luego a nosotros los novatos nos toca tratar de entender de que se trata.
Estos Maestros, cuando aprenderán.:D:D
A ver Maestro enecumene, ilustranos:D;)
Saludos

Ya ilustré algo a ver si se entiende :D:D

Caro 29-10-2008 02:21:57

Hola Pollo2004, también lo puedes lograr creandote un campo Agregado en su propiedad Expression haces un sum de tu campo calculado SUM(CampoCalculado), activas el campo agregado y también AgregatesActive de tu DataSet.

Saluditos

Caral 29-10-2008 02:24:06

Hola
Cita:

Empezado por enecumene (Mensaje 323033)
........
¿Ves la diferencia?, con el First se coloca desde el primer registro de la tabla, como estás tratando de realizar facturas es lógico que deberías estar usando tablas de memorias o una tabla temporal, porque si no, te sumará todos los registros viejos, por eso se recomienda usar tablas de memorias o temporales donde puedes trabajar solamente con esos registros de manera individual a los registros viejos. Espero que se te claro sino me avisas.

Saludos.

Bueno en este caso tengo que diferir un poco del maestro.:D
Tener una tabla temporal es tener mas cosas de la cuenta, a veces es bueno, pero en este caso no lo veo necesario.
Se habla de facturas, estas siempre tienen un numero consecutivo y unico, se puede hacer referencia a este numero sin necesidad de otra cosa.
En mi primera intervención sugerí que se revisara el tutorial de facturacion, ahi se hacen los calculos sin usar tablas temporales ni otras cosas.
Lo siento enecumene, pero algo he aprendido de ti.:D
Saludos

enecumene 29-10-2008 02:33:47

Lo digo porque no se sabe si los detalles de las facturas lo esta registrando directamente a la tabla o en un stringgrid, en este caso es directo a la tabla entonces está involucrando los demás registros anteriores, digo yo no sé, hay muchas formas de realizar una factura, en mi caso la numeración la asigno luego de grabar y utilizo tablas de memorias, así cuando hago la suma, sumo lo que registro y no todos luego le asigno la numeración de la factura. :), pero bueno, dejemos que otro maestro nos ilumine con este asunto :D


La franja horaria es GMT +2. Ahora son las 17:53:23.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi