PDA

Ver la Versión Completa : Ventas por mes


Jorge Orozco
14-01-2014, 15:31:14
Hola a todos los Amigos de este Foro. Tengo la siguiente situación, y es que quiero obtener las ventas realizadas por mes de los productos. Esto de acuerdo a un parámetro de fecha dado.
Tengo el siguiente query, pero no se como realizar las sumas por cada mes, ya que ne da un error en la suma. Si alguien me puede ayudar, por favor.

begin
IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select extract(year from fafch) anio1, extract(month from fafch) meses1, sum(facantidad) as total_mes'+

'from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
'where a.ARCODIGO = '''+Codigo_Prod.Text+''' group by 1, 2'+
'order by 1, 2');

IBQuery4.Open;
end;

duilioisola
14-01-2014, 17:28:30
A qué te refieres con:
ya que ne da un error en la suma

¿El valor es incorrecto?
¿El SQL devuelve un error?
¿Otra cosa?


Si el valor es incorrecto, revisa lo que devuelve en SQL si hacer el GROUP BY y quitando "SUM(" para ver todos los valores que entran en la suma.
Si el SQL devuelve un error, sería necesario que nos dijeras el mensaje exacto, sin traducir.
Si es otra cosa, deberás explicarte un poco mejor.

Jorge Orozco
14-01-2014, 17:45:21
Gracias DUILIOISOLA por el interés.

El mensaje de error que me da es el siguiente: Attempt to execute an unprepared dynamic SQL statement. Si le quito al query el as total_mes, no me da el error, pero necesito cargar la variable, ya que lo despliego en un TStrinGrid el resultado de las ventas por mes y año.

Gracias de nuevo

duilioisola
14-01-2014, 18:01:43
Este error no tiene que ver con el SQL, sinó que tiene que ver con el componente.
Supongo que antes de ejecutar el SQL debes "preparalo".
Supongo que al ser un Query dinámico (creas el SQL a medida que ejecutas el programa) el componente necesita que se prepare para saber qué parámetros necesita, que campos devolverá, su tipo, estructura y demás.

Prueba con esto:

IBQuery4.Prepare;
IBQuery4.Open;
end;

Jorge Orozco
14-01-2014, 18:13:18
Amigo, disculpe y en que parte del código pongo el IBQuery4.Prepare; y el IBQuery4.Open;

look
14-01-2014, 18:44:08
Hola a todos los Amigos de este Foro. Tengo la siguiente situación, y es que quiero obtener las ventas realizadas por mes de los productos. Esto de acuerdo a un parámetro de fecha dado.
Tengo el siguiente query, pero no se como realizar las sumas por cada mes, ya que ne da un error en la suma. Si alguien me puede ayudar, por favor.

begin

IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select extract(year from fafch) anio1, extract(month from fafch) meses1, sum(facantidad) as total_mes'+

'from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
'where a.ARCODIGO = '''+Codigo_Prod.Text+''' group by 1, 2'+
'order by 1, 2');

IBQuery4.Open;
end;



With IBQuery4 do
begin
Close;
SQL.Clear;
SQL.Add('select extract(year from fafch) anio1, extract(month from fafch) meses1, sum(facantidad) as total_mes');
SQL.Add('from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) ');
SQL.Add('inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> :estado) and (c.FAFCH between :fecha1 and :fecha2) ');
SQL.Add('where a.ARCODIGO = :cod group by 1, 2');
SQL.Add('order by 1, 2');
ParamByname('cod').asString := Codigo_Prod.Text;
ParamByname('estado').asString := 'A'; /// estado, no se cual es :p
ParamByname('fecha1').AsDate := dtp1.Date; /// DateTymePicker fecha desde
ParamByname('fecha2').AsDate := dtp2.Date; /// DateTymePicker fecha hasta
Prepare;
Open;
end;

Jorge Orozco
14-01-2014, 19:55:03
Hola look, me funciona bien en el sentido que no me da ningún error, pero a la hora de cargar las celdas del TStringGrid, me las carga vacias. Ejemplo de la carga:

for i := 1 to conte do
begin
begin
sg1.Cells[1+c1,3] := IBQuery4.FieldByName('meses1').AsString+'-'+IBQuery4.FieldByName('anio1').AsString;

sg1.Cells[2+c1,3] := IBQuery4.FidByName('total_mes').AsString;

c1 := c1+2;
end;
IBQuery4.Next;
end;

Gracias por la ayuda

duilioisola
14-01-2014, 20:31:49
Antes que nada pon el código entre las etiquetas [ delphi ] y [ /delphi ]

Verifica cuantas veces pasa por el bucle.
No especificas como se carga la variable CONTE que determina la cantidad de veces que se realiza el bucle.
Tampoco inicializas la variable C1.

Normalmente se utiliza un bucle WHILE para estas cosas:

c1 := 0;
IBQuery4.First;
while (not IBQuery4.EOF) do
begin
begin
sg1.Cells[1+c1,3] := IBQuery4.FieldByName('meses1').AsString+'-'+IBQuery4.FieldByName('anio1').AsString;
sg1.Cells[2+c1,3] := IBQuery4.FidByName('total_mes').AsString;
c1 := c1+2;
end;
IBQuery4.Next;
end;

look
14-01-2014, 21:01:14
Hola look, me funciona bien en el sentido que no me da ningún error, pero a la hora de cargar las celdas del TStringGrid, me las carga vacias. Ejemplo de la carga:

Hola, ¿verificaste si la consulta te devuelve registros?, ¿Porque no utilizas mejor un DBGrid?.
No se que delphi estas usando pero eso te lo ahorrarias con el LiveBindings.

Jorge Orozco
14-01-2014, 21:57:25
Utilizo el Embarcadero RAD Studio 2010. Nunca he utilizado el DBGrid. Y en este caso no se como cargarlo.

Jorge Orozco
14-01-2014, 22:55:04
Look, la consulta si me devuelve registros. No se que podrá ser, ya que no me carga la información en el TStringGrid???????????????

ecfisa
14-01-2014, 23:07:42
Utilizo el Embarcadero RAD Studio 2010. Nunca he utilizado el DBGrid. Y en este caso no se como cargarlo.
Hola Jorge.


Agrega un TDBGrid (pestaña Data Controls).
Agrega un componente TDataSource (pestaña Data Access) y en su propiedad DataSet seleccióna "IBQuery4".
En la propiedad DataSource del DBGrid selecciona el nombre del DataSource anterior.

Y listo. Si "IBQuery4" está abierto, ya tendrías que estar viendo los datos en el TDBGrid .

Saludos :)

Jorge Orozco
15-01-2014, 23:14:01
Amigos he intentado todo para poder mostrar las ventas por mes y año y no me lo muestra. Aquí les dejo el procedimiento completo, para ver en que me pueden ayudar. Se los agradezco, ya que he hecho lo que esta a mi alcance y no he podido.


procedure TMovimiento_Pedidos.desglose_articulo_ventas;
var conte, i, c1 : integer;
compras3, estado1 : string;
fecha1, fecha2 : string; //TdateTime;
begin
estado1 := 'ANULADO';
fecha1 := datetostr(fechaini.DateTime);
fecha2 := datetostr(fechafin.DateTime);
c1 := 0;

IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select count(*) as entradas from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
' where a.ARCODIGO = '''+Codigo_Prod.Text+'''');

IBQuery4.Prepare;
IBQuery4.Open;
begin
conte := IBQuery4.FieldByName('entradas').AsInteger;


IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select extract(year from fafch) anio1, extract(month from fafch) meses1, sum(facantidad) as ventas_mes'+
'from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
'where a.ARCODIGO = '''+Codigo_Prod.Text+''' group by 1, 2'+
'order by 1, 2');

IBQuery4.Prepare;
IBQuery4.Open;
end;

for i := 1 to conte do
begin
begin
sg1.Cells[1+c1,3] := IBQuery4.FieldByName('meses1').AsString+'-'+IBQuery4.FieldByName('anio1').AsString;
sg1.Cells[2+c1,3] := IBQuery4.FieldByName('ventas_mes').AsString;

c1 := c1+2;
end;
IBQuery4.Next;
end;

end;

look
15-01-2014, 23:18:13
Amigos he intentado todo para poder mostrar las ventas por mes y año y no me lo muestra. Aquí les dejo el procedimiento completo, para ver en que me pueden ayudar. Se los agradezco, ya que he hecho lo que esta a mi alcance y no he podido.


procedure TMovimiento_Pedidos.desglose_articulo_ventas;
var conte, i, c1 : integer;
compras3, estado1 : string;
fecha1, fecha2 : string; //TdateTime;
begin
estado1 := 'ANULADO';
fecha1 := datetostr(fechaini.DateTime);
fecha2 := datetostr(fechafin.DateTime);
c1 := 0;

IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select count(*) as entradas from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
' where a.ARCODIGO = '''+Codigo_Prod.Text+'''');

IBQuery4.Prepare;
IBQuery4.Open;
begin
conte := IBQuery4.FieldByName('entradas').AsInteger;


IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select extract(year from fafch) anio1, extract(month from fafch) meses1, sum(facantidad) as ventas_mes'+
'from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
'where a.ARCODIGO = '''+Codigo_Prod.Text+''' group by 1, 2'+
'order by 1, 2');

IBQuery4.Prepare;
IBQuery4.Open;
end;

for i := 1 to conte do
begin
begin
sg1.Cells[1+c1,3] := IBQuery4.FieldByName('meses1').AsString+'-'+IBQuery4.FieldByName('anio1').AsString;
sg1.Cells[2+c1,3] := IBQuery4.FieldByName('ventas_mes').AsString;

c1 := c1+2;
end;
IBQuery4.Next;
end;

end;

No veo nada de lo que te recomendamos aqui.... ¡facepalm!

Jorge Orozco
15-01-2014, 23:28:54
Amigo si lo hice, pero tampoco me funciono, entonces le estoy pasando el procedimiento desde el principio. Inente hacerlo en DBGrid, pero es lo mismo, no me carga las celdas ono se sihice algo malo. La base de datos que uso es SQL Server 2008, y la comunicación con la base de datos lo hago por medio del IBQuery y el IBTransaction.

Gracias

Jorge Orozco
15-01-2014, 23:30:54
Amigo si lo hice, pero tampoco me funciono, entonces le estoy pasando el procedimiento desde el principio. Intente hacerlo en el DBGrid, pero es lo mismo, no me carga las celdas pero no se si hice algo malo. La base de datos que uso es SQL Server 2008, y la comunicación con la base de datos lo hago por medio del IBQuery y el IBTransaction.

Gracias

look
15-01-2014, 23:44:18
Amigo si lo hice, pero tampoco me funciono, entonces le estoy pasando el procedimiento desde el principio. Inente hacerlo en DBGrid, pero es lo mismo, no me carga las celdas ono se sihice algo malo. La base de datos que uso es SQL Server 2008, y la comunicación con la base de datos lo hago por medio del IBQuery y el IBTransaction.

Gracias

IBQuery, IBTransaction, SQL Server 2008?, creo que estas algo confundido, si no me equivoco esos son componentes para Firebird o Interbase :confused:

Jorge Orozco
16-01-2014, 00:27:08
Correcto son para Firebird, la base de datos esta en otro lado.

ecfisa
16-01-2014, 00:40:02
Hola Jorge.

Si el gestor de base de datos que usas es MS SQLServer 2008, podrías usar por ejemplo ADO o dbExpress para conectarte (revisa: dbExpress Driver for SQL Server (http://www.devart.com/dbx/sqlserver/)) . Pero como te comenta look mas arriba, no lo vas a lograr usando los componentes IBXpress.

Saludos :)

Jorge Orozco
16-01-2014, 22:37:18
Hola Amigos.

Sinceramente no creo que sea tan difícil o dificilisimo, hacer un procedimiento para obtener las ventas por mes y año y mostrarlo en un TStringGrid, como lo detalle a continuación.

Mes/Año Cant Mes/Año Cant Mes Año Cant
FACTURADO 01/2012 5 02/2012 10 04/2014 25

No se que es lo que estoy haciendo mal, que he intentado por todos los medios y no me funcione. He hecho varias consultas a GOOGLE y nada.

Por Favor Ayuda.

Gracias Amigos.

ecfisa
16-01-2014, 23:23:02
Hola Jorge.

Realmente no veo la necesidad de complicarte usando un TStringGrid...

De todos modos te hice esta función que pasa los campos de cualquier TIBQuery sin campos BLOB, a cualquier TStringGrid:

procedure IBQueryToStringGrid(IBQ: TIBQuery; Grd: TStringGrid);
var
c,r : Integer;
begin
Grd.ColCount := IBQ.FieldCount-1;
Grd.RowCount := IBQ.RecordCount;
r := 0;
IBQ.First;
while not IBQ.Eof do
begin
for c:= 0 to IBQ.RecordCount-1 do
Grd.Cells[Grd.FixedCols+c, Grd.FixedRows+r] := IBQ.Fields[c].AsString;
IBQ.Next;
Inc(r);
end;
end;


Ejemplo de uso:

procedure TForm1.Button1Click(Sender: TObject);
begin
IBQueryToStringGrid(IBQuery4, StringGrid1);
end;


Y por favor cuando pongas código Delphi usa las etiquetas tu_codigo como te mencionó antes duilioisola.

Saludos :)

Jorge Orozco
21-01-2014, 20:53:37
Gracias a todos los que me trataron de ayudar en este caso, pero la verdad lo intente por todos lados y no me funciona. Es decir no puedo obtener las ventas por mes y año de una fecha dada, es decir desde fecha, hasta fecha.

De todos modos mil gracias a todos. Y lo peor de todo es que no me encuentro algo similiar en GOOGLE.

No se donde esta mi problema.

Jorge Orozco
24-01-2014, 23:38:48
Quiero agradecer a todos;psque me dieron una luz, para poder resorver mi problema. Ya lo pude resolver. Aqui les dejo el procedimiento por si alguien lo va a nacesitar en algun momento. De nuevo gracias a todos.


procedure TMovimiento_Pedidos.desglose_articulo_ventas;
var conte, i, c1, fec1, fec2 : integer;
compras3, estado1, fec0 : string;
fecha1, fecha2 : string; //TdateTime;
fe1, fe2 : TDateTime;
Ano, Mes, Dia : Word;
begin
estado1 := 'ANULADO';
fecha1 := datetostr(fechaini.DateTime);
fecha2:= datetostr(fechafin.DateTime);
c1 := 0;

IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select count(*) as entradas from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+ //
' where a.ARCODIGO = '''+Codigo_Prod.Text+'''');
//' where a.ARCODIGO LIKE '+QuotedSTr('%'+Codigo_Prod.Text+'%')); //a.ARNOMBRE LIKE'+QuotedSTr('%'+nombre_prod.Text+'%'));
IBQuery4.Prepare;
IBQuery4.Open;
begin
conte := IBQuery4.FieldByName('entradas').AsInteger;

IBQuery4.Close;
IBQuery4.SQL.Clear;
IBQuery4.SQL.Add('select extract(year from c.fafch) annio, extract(month from c.fafch) mess, sum(b.facantidad) total_mes '+
'from ARTICULOS a inner join FACTURADT b on (b.FAARID = a.ARID) '+
'inner join FACTURAS c on (c.FAID = b.FAID) and (c.FAESTADO <> '''+estado1+''') and (c.FAFCH between '''+fecha1+''' and '''+fecha2+''') '+
'where a.ARCODIGO = '''+Codigo_Prod.Text+''' group by 1,2 order by 1,2 ');


IBQuery4.Prepare;
IBQuery4.Open;
end;

c1 := 0;
IBQuery4.First;
while not Movimiento_Pedidos.IBQuery4.EOF do
begin
begin
sg1.Cells[1+c1,3] := IBQuery4.FieldByName('mess').AsString+'-'+IBQuery4.FieldByName('annio').AsString;
sg1.Cells[2+c1,3] := IBQuery4.FieldByName('total_mes').AsString;
c1 := c1+2;
end;
IBQuery4.Next;
end;
end;


El problema estaba, en que no estaba utilizando el while, y lo que utilizaba era el for.


Gracias.

ecfisa
25-01-2014, 20:26:49
Hola Jorge.

Gracias por compartir como lo solucionaste ^\||/

Saludos :)