Tutorial (Como hacer un programa de Facturacion) 3
#1
Escrito 23 febrero 2012 - 01:22
Esta vez vengo con otro cambio que me parece interesante que aprendáis.
En el tutorial 2 aprendimos a hacer una factura directa con el Dbgrid, esta vez vengo con su competencia, el StringGrid.
Este componente trabaja muy diferente que el dbgrid que solo se conecta al dataset y listo, al StringGrid hay que indicarle donde poner cada dato, eso lo hace mas especifico y aunque es mas código es mas manejable, para mi.
En este vamos a aprender (como hicimos con el dbgrid) a crear botones dentro del componente para poder usarlos posteriormente.
Ademas veremos como añadir registros de una tabla y también eliminarlos basándonos en las lineas, celdas o Rows.
Ademas crearemos otro StringGrid para que nos de los totales de la factura en vez de los edits que usamos con anterioridad.
Sigo también con la creación de procedimientos aparte para no repetir código.
Como siempre os sugiero que empecéis con el primer tutorial para que tengáis mas bases.
Espero os sea de utilidad y aprendáis algo mas de este Novato.
Seguimos........
Saludos
PD: Como siempre pondré el código completo al final de la explicacion.
Si tenéis dudas, publicarlas, os trataremos de ayudar.
#2
Escrito 23 febrero 2012 - 01:40
Seguimos con el nuevo form de factura para el StringGrid.
Primero cread un nuevo form y llamadlo FFacturaSTG (STG es por StringGrid..)
Abrid el form de factura anterior (FFacturaDBG) y copiad y pegad en el form nuevo los componentes que se ven en la foto.
Luego quitadle el DBgrid, cambiadlo por un StringGrid y también quitad los edits que generaban los totales y cambiadlo por otro StringGrid.
Al StringGrid que contendrá los Items de la factura ponedle el nombre de SGFact y al que mostrara los totales ponedle SGTotal.
Hacedlo como se ve en la foto:
Como veis en la foto se aprecian los dos botones que crearemos (por código) para agregar y eliminar items de la factura.
Para que los espacios se mantengan, como la foto, en el StrinGrid (SGFact) poned en la propiedad ColCout = 7 ,en FixedCols = 0 y en FixedRows = 1 (acomodad las celdas con el mouse según la foto)
En el StringGrid (SGTotal) poned en ColCout = 2 ,en FixedCols = 1 y en FixedRows = 0.
En la siguiente parte vamos con código.
Seguimos.......
Saludos
#3
Escrito 23 febrero 2012 - 01:54
Seguimos.....
Para que os quede claro, el botón Buscar (cliente) contiene el mismo código que el del form factura anterior, solo copiadlo y Pegadlo en el evento del botón Buscar.
Coloquemos unas variables que nos servirán para almacenar algunos datos:
Como siempre aquí:
var FFacturaSTG: TFFacturaSTG; Cuenta : Integer; Boton, Boton2: TButton; implementation
Ahora crearemos un Procedimiento (Etiquetas) que sera el que contendrá los nombres de las celdas de nuestros StringGrid:
Procedure TFFacturaSTG.Etiquetas; begin SGFact.Cells[0,0] := ' + '; SGFact.Cells[1,0] := 'Codigo'; SGFact.Cells[2,0] := 'Descripción'; SGFact.Cells[3,0] := 'Cantidad'; SGFact.Cells[4,0] := 'Precio'; SGFact.Cells[5,0] := 'STotal'; SGFact.Cells[6,0] := ' - '; SGTotal.Cells[0,0] := 'Sub Total'; SGTotal.Cells[0,1] := 'Descuento'; SGTotal.Cells[0,2] := 'Impuesto'; SGTotal.Cells[0,3] := 'Total'; SGTotal.Cells[1,0] := '0.00'; SGTotal.Cells[1,1] := '0.00'; SGTotal.Cells[1,2] := '0.00'; SGTotal.Cells[1,3] := '0.00'; end;
Vamos con el evento OnCreate del nuevo Form FFacturaSTG.
procedure TFFacturaSTG.FormCreate(Sender: TObject); begin Etiquetas; // llama al procedimiento Etiquetas DateTimePicker1.Date:= Now; // dia actual // Busca el ultimo numero de factura y le aumenta uno. ADOQuery2.SQL.Text:='SELECT DISTINCTROW Max([Factura].[CodFactura])AS [CodFacturaa]FROM Factura'; ADOQuery2.Open; ECodFactura.Text:= IntToStr(ADOQuery2.Fields[0].AsInteger+1); Cuenta := 1; // le da valor a la variable Cuenta. end;
Creamos un Procedimiento que a su vez nos creara los Botones de Agregar y Eliminar Items.
procedure TFFacturaSTG.CrearBoton(ACol: Integer); var i: Integer; begin for i := SGFact.FixedRows to SGFact.RowCount -1 do begin // boton añadir Boton := TButton.Create(nil); Boton.Caption := 'Agregar'; Boton.BoundsRect:= SGFact.CellRect(0, i); Boton.ControlStyle := [csClickEvents]; Boton.OnClick := BotonClick; Boton.Parent := SGFact; SGFact.Objects[0,i] := Boton; // boton eliminar Boton2 := TButton.Create(nil); Boton2.Caption := 'Eliminar'; Boton2.BoundsRect:= SGFact.CellRect(6, i); Boton2.ControlStyle := [csClickEvents]; Boton2.OnClick := Boton2Click; Boton2.Parent := SGFact; SGFact.Objects[6,i] := Boton2; end; end;
Seguimos........
Saludos
#4
Escrito 23 febrero 2012 - 02:10
Seguimos.
Vamos a crear los procedimientos que son llamados cuando se presionan los botones:
El Boton 1 (agregar):
Este botón llama al Form Busqueda de Articulos, es el mismo, la diferencia solo se dará en algunos nombres que cambiaran ya que esta vez sera llamado desde el form que acabamos de crear (FFacturaSTG), ya lo veremos adelante.
procedure TFFacturaSTG.BotonClick(Sender: TObject); var i : integer; cat, pre, stot: Real; begin i:=2; BuscaArticulo:=TBuscaArticulo.Create(self); try BuscaArticulo.ShowModal; cat := StrToFloat(BuscaArticulo.Edit2.Text); pre := StrToFloat(BuscaArticulo.Edit3.Text); stot := cat * pre; i:=i+1; SGFact.Cells[1,cuenta] := BuscaArticulo.ATArticulosCodProducto.asstring; SGFact.Cells[2,cuenta] := BuscaArticulo.ATArticulosDescripcion.asstring; SGFact.Cells[3,cuenta] := FloatToStr(cat); SGFact.Cells[4,cuenta] := FloatToStr(pre); SGFact.Cells[5,cuenta] := FloatToStr(stot); Cuenta := Cuenta +1; Suma; SGFact.RowCount:= SGFact.RowCount + 1; finally BuscaArticulo.Free; end; end;
Como veis, busca el articulo y coloca los datos en el StringGrid (SGFact), ademas aumenta en uno la variable cuenta lo mismo que las filas del StringGrid, también llama al procedimiento Suma.
El Boton 2 (Eliminar):
Este procedimiento es algo mas complejo asi que para no complicarnos la vida lo hice a lo novato, eso si, funciona perfectamente.
procedure TFFacturaSTG.Boton2Click(Sender: TObject); var i: integer; begin QTemp.SQL.Text:= ' Delete * From Factura '+ ' WHERE Factura.CodFactura = :Fact '+ ' And Factura.CodCliente = :Cli '+ ' And Factura.CodArticulo = :Art '+ ' And Factura.Descripcion = :Des '+ ' And Factura.Cantidad = :Cant '; QTemp.Parameters[0].Value:= ECodFactura.Text; QTemp.Parameters[1].Value:= ECodCliente.Text; QTemp.Parameters[2].Value:= SGFact.Cells[1,SGFact.Row]; QTemp.Parameters[3].Value:= SGFact.Cells[2,SGFact.Row]; QTemp.Parameters[4].Value:= SGFact.Cells[3,SGFact.Row]; QTemp.ExecSQL; // limpiar stringrid for i := 1 to SGFact.RowCount - 1 do SGFact.Rows[i].Clear; SGFact.RowCount:= SGFact.RowCount - SGFact.Rows[i].Count; Boton.Free; Boton2.Free; Cuenta := 0; CargarDatos; end;
Aqui lo que hace es borrar el contenido de la tabla basándose en el numero de factura, el cliente, la descripción etc.
Posteriormente limpia todo el Stringgrid, los botones y llama al procedimiento (CargarDatos) que volverá a cargar los datos ya actualizados.
QTemp es el nombre del Adoquery, podéis ponerle el que os guste.
Seguimos.....
Saludos
#5
Escrito 23 febrero 2012 - 02:23
Seguimos con dos procedimientos mas: Suma y CargarDatos:
El procedimiento Suma, esencialmente es igual que el del form facturaDBG, la diferencia esta en que envia los datos al StringGrid (SGTotal).
procedure TFFacturaSTG.Suma; var i:integer; begin ADOQuery3.SQL.Text:= 'SELECT DISTINCTROW Sum([Factura].[MntSubTotal]) AS [SubTotal], Sum([Factura].[MntDescuento]) AS [Descuento],'+ ' Sum([Factura].[MntImpuesto]) AS [Impuesto], Sum([Factura].[MntTotal]) AS [Total]'+ ' FROM Factura '; ADOQuery3.SQL.Add('WHERE Factura.CodFactura = '+ECodFactura.Text); AdoQuery3.Open; // escribe los valores en las celdas SGTotal.Cells[1,1] := Format('%8.2n',[ADOQuery3.Fields[1].asfloat]); SGTotal.Cells[1,2] := Format('%8.2n',[ADOQuery3.Fields[2].asfloat]); SGTotal.Cells[1,0] := Format('%8.2n',[ADOQuery3.Fields[0].asfloat]); SGTotal.Cells[1,3] := Format('%8.2n',[ADOQuery3.Fields[3].asfloat]); end;
Como veis, no hay mayor diferencia ni problema.
En el siguiente procedimiento se cargan los datos una vez que se eliminan, trabaja muy de la mano con el botón 2.
procedure TFFacturaSTG.CargarDatos; Begin Etiquetas; SGFact.RowCount:= 2; SGFact.FixedRows:= 1; Cuenta := Cuenta +1; ADOQuery3.SQL.Text:= 'SELECT * From Factura '; ADOQuery3.SQL.Add('WHERE Factura.CodFactura = '+ECodFactura.Text); AdoQuery3.Open; While not AdoQuery3.Eof do begin SGFact.Cells[1,cuenta] := AdoQuery3.Fields[3].Text; SGFact.Cells[2,cuenta] := AdoQuery3.Fields[4].Text; SGFact.Cells[3,cuenta] := AdoQuery3.Fields[5].Text; SGFact.Cells[4,cuenta] := AdoQuery3.Fields[9].Text; SGFact.Cells[5,cuenta] := AdoQuery3.Fields[11].Text; SGFact.RowCount:= SGFact.RowCount + 1; Cuenta := Cuenta +1; CrearBoton(SGFact.RowCount-1); AdoQuery3.Next; end; AdoQuery3.Active := False; Suma; end;
Como veis, ya que se limpio el StringGrid había que recuperar los datos y ordenarlos, para eso se hace un recorrido de la tabla según la factura.
Se repintan las etiquetas y se ordenan las celdas, ademas había que volver a actualizar los totales de la factura llamando al procedimiento Suma, crear Los botones y actualizar la variable Cuenta.
Seguimos.....
Saludos
#6
Escrito 23 febrero 2012 - 02:32
Seguimos.
Esta vez vamos a irnos al StringGrid (SGFact), vamos a buscar en sus eventos el evento OnSelectCell y le damos doble click.
Ahí vamos a poner este código:
procedure TFFacturaSTG.SGFactSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin CrearBoton(SGFact.RowCount-1); end;
Como veis es sencillo, creamos los botones para seguir añadiendo items.
Bien, como os habréis imaginado el botón imprimir contiene el mismo código que el anterior.
Cambios en el Botón aceptar del form búsqueda (BuscaArticulo) :
Lo único que se tiene que cambiar es la sentencia sql que guarda los cambios, lógicamente esta tiene que apuntar al nuevo form de factura (FFacturaSTG) que acabamos de crear, así:
// Inserta en la tabla factura AdoQuery1.SQL.Text := 'Insert into Factura Values ('+QuotedStr(FFacturaSTG.ECodFactura.Text)+', :fecha, '+QuotedStr(FFacturaSTG.ECodCliente.Text)+ ', '+QuotedStr(ATArticulosCodProducto.AsString)+ ', '+QuotedStr(ATArticulosDescripcion.AsString)+ ', '+QuotedStr(Edit2.Text)+ ', '+QuotedStr(FFacturaSTG.ComboBox1.Text)+', '+QuotedStr(FFacturaSTG.EOCompra.Text)+', '+ QuotedStr(FFacturaSTG.EVendedor.Text)+', '+QuotedStr(Edit3.Text)+', '+QuotedStr(Edit4.Text)+', '+FloatToStr(c)+', '+QuotedStr(Edit5.Text)+ ', '+FloatToStr(e)+ ', '+FloatToStr(g)+')'; AdoQuery1.Parameters.ParamByName('fecha').Value:= DateToStr(FFacturaSTG.DateTimePicker1.Date); AdoQuery1.ExecSQL;
Como veis es simplemente cambiar los nombres, fijaros en la diferencia, es muy sencillo pero importante.
Listo, Colocad otro item en el menu principal para llamar al nuevo form y a probarlo.
Para que se creen los botones (cuando inicia el form) hay que darle click a la celda del StringGrid (FFacturaSTG).
Ojala Os sirva de ejemplo y ayuda.
Saludos
Os dejo el código.
Archivos adjuntos
#7
Escrito 15 mayo 2012 - 01:16
A ver si te animas con un par de videos sobre el tema, si quieres yo te enseño a grabarlos, es re sencillo, te puedo pasar el camtasia studio tambien....
un saludo desde chago city
#8
Escrito 28 mayo 2012 - 08:51
quería proponer una variante del programa y vuestra ayuda para conseguirlo.
1. Dgrid , las celdas como "descripción" utilizarlo como celda Memo , ya que quiero trabajarlo como editar texto en tiempo de ejecución y,
en sub total darle el valor del servicio ( facturación de servicios de obras y rehabilitación).
2. validar con un botón el contenido de los valores de lineas en el Grid.
3. realizar un apartado de presupuestos y validar en este apartado con un botón (por ejemplo) el presupuesto guardado en facturación.
espero no exigir demasiado y poder entre todos , poder realizarlo..
#9
Escrito 28 mayo 2012 - 08:56
Bienvenido a DelphiAccess y ojalá te estemos viendo continuamente por aquí...
Qué te parece si abres un hilo con los apartados que comentas (para la mejora del sistema de Caral) y poco a poco vamos planteando las aportaciones que pudieramos darte entre todos y los avances que tu también puedas ir consiguiendo, de tal manera que podamos dejar éste sistema tal y como está y las adaptaciones que propones en otro hilo
Saludox !
#10
Escrito 20 noviembre 2012 - 02:31
#11
Escrito 13 agosto 2013 - 01:12
A mi, mi hermano me dijo que me iba a enseñar, pero sabes como son los hombres... Pzz y ahora se un poquito mas Muchas gracias, ando trabajando en eso aunque soy aprendiz nomas.
#12
Escrito 13 agosto 2013 - 08:29
Vaya Caral, que gran aporte, muchas gracias.
A mi, mi hermano me dijo que me iba a enseñar, pero sabes como son los hombres... Pzz y ahora se un poquito mas Muchas gracias, ando trabajando en eso aunque soy aprendiz nomas.
Hola maria_caruzo639, bienvenida a DelphiAccess
¿ Cómo somos los hombres ?
Saludos
PD, Cómo estás Caral preciosa
#13
Escrito 13 agosto 2013 - 08:37
Vaya Caral, que gran aporte, muchas gracias.
A mi, mi hermano me dijo que me iba a enseñar, pero sabes como son los hombres... Pzz y ahora se un poquito mas Muchas gracias, ando trabajando en eso aunque soy aprendiz nomas.
Hola maria_caruzo639, bienvenida a DelphiAccess
¿ Cómo somos los hombres ?
Saludos
PD, Cómo estás Caral preciosa
Jajajajaja puras promesas con los hombres amiga ???... Yo si te comprendo, dudo que Caral lo comprenda, es uno más del enemigo
Saludox !
#14
Escrito 13 agosto 2013 - 09:52
Vaya Caral, que gran aporte, muchas gracias.
A mi, mi hermano me dijo que me iba a enseñar, pero sabes como son los hombres... Pzz y ahora se un poquito mas Muchas gracias, ando trabajando en eso aunque soy aprendiz nomas.
Hola maria_caruzo639, bienvenida a DelphiAccess
¿ Cómo somos los hombres ?
Saludos
PD, Cómo estás Caral preciosa
Jajajajaja puras promesas con los hombres amiga ???... Yo si te comprendo, dudo que Caral lo comprenda, es uno más del enemigo
Saludox !
No todos son así amiga!
#15
Escrito 13 agosto 2013 - 09:56
Jajajajaja puras promesas con los hombres amiga ???... Yo si te comprendo, dudo que Caral lo comprenda, es uno más del enemigo
Saludox !
No todos son así amiga!
No ! Otros son peores
Saludox !
#16
Escrito 13 agosto 2013 - 10:00
Jajajajaja puras promesas con los hombres amiga ???... Yo si te comprendo, dudo que Caral lo comprenda, es uno más del enemigo
Saludox !
No todos son así amiga!
No ! Otros son peores
Saludox !
A bueno eso si! que cosas no? jejeje saludos
y que onda con esas "gorditas", ya ves como NO solamente los hombres...
-fíjate que encontré otras donde hasta le ponen carnitas arriba a las gorditas, y mmmm ricas...
#17
Escrito 13 agosto 2013 - 10:00
Jajajajaja puras promesas con los hombres amiga ???... Yo si te comprendo, dudo que Caral lo comprenda, es uno más del enemigo
Saludox !
No todos son así amiga!
No ! Otros son peores
Saludox !
Saludos