Sistema de Almacén Visual Basic (Parte 1) Creamos nuestro proyecto:
Organizamos nuestro proyecto:
Ahora agregamos agregamos varios varios formularios formularios y un modulo modulo como se ve en en la imagen: imagen:
En el siguiente ejercicio diseñaremos la base de datos.
Creación de la Base de datos Creamos una base de datos con Microsoft Access, con las siguientes tablas: users Nombre del Campo
Tipo de Datos
Descripción
user_login
Texto(50)
Nombre de inicio de sesión
user_password
Texto(255)
Contraseña del usuario
nombre
Texto(255)
Nombre del usuario
activo
Si/No
Si está activo
administrar
Si/No
Si puede administrar el sistema
reportes
Si/No
Si puede ver reportes
articulos Nombre del Campo
Tipo de Datos
Descripción
id_articulo
Texto(50)
Id del artículo
articulo
Texto(255)
Nombre del artículo
localizacion
Texto(255)
Ubicación en el almacén
grupo
Texto(255)
Grupo del articulo
unidad_medida
Texto(255)
Unidad de medida
existencia
Número(Doble)) Número(Doble
Existencia
cant_min
Número(Doble)) Número(Doble
Existencia mínima
costo_promedio
Número(Doble)) Número(Doble
Costo promedio
Creación de la Base de datos Creamos una base de datos con Microsoft Access, con las siguientes tablas: users Nombre del Campo
Tipo de Datos
Descripción
user_login
Texto(50)
Nombre de inicio de sesión
user_password
Texto(255)
Contraseña del usuario
nombre
Texto(255)
Nombre del usuario
activo
Si/No
Si está activo
administrar
Si/No
Si puede administrar el sistema
reportes
Si/No
Si puede ver reportes
articulos Nombre del Campo
Tipo de Datos
Descripción
id_articulo
Texto(50)
Id del artículo
articulo
Texto(255)
Nombre del artículo
localizacion
Texto(255)
Ubicación en el almacén
grupo
Texto(255)
Grupo del articulo
unidad_medida
Texto(255)
Unidad de medida
existencia
Número(Doble)) Número(Doble
Existencia
cant_min
Número(Doble)) Número(Doble
Existencia mínima
costo_promedio
Número(Doble)) Número(Doble
Costo promedio
entradas Nombre del Campo
Tipo de Datos
Descripción
id_entrada
Autonumérico
Id de la entrada
fecha_registro fecha_registr o
Fecha/Hora
Fecha de registro en el sistema
fecha_entrada
Fecha/Hora
Fecha de la entrada en el almacen
proveedor
Texto(255)
Nombre del proveedor
folio_factura
Texto(50)
Folio de la factura de compra
fecha_factura
Fecha/Hora
Fecha de la factura
user_login
Texto(50)
Usuario que registra la entrada
entradas_detalle Nombre del Campo
Tipo de Datos
Descripción
id_entrada_detalle id_entrada_detall e
Autonumérico
Id del detalle de la entrada
id_entrada
Número
Id de la entrada
id_articulo
Texto(50)
Id del artículo
cantidad
Número(Doble)) Número(Doble
Cantidad que entra al almacén
precio_compra
Número(Doble)) Número(Doble
Precio de compra (segun factura)
iva
Número(Doble)
Impuesto que cobra el proveedor (en porcentaje)
salidas Nombre del Campo
Tipo de Datos
Descripción
id_salida
Autonumérico
Id de la salida
fecha_registro
Fecha/Hora
Fecha de registro en el sistema
fecha_salida
Fecha/Hora
Fecha de la salida
responsable
Texto(255)
Responsable de la salida
user_login
Texto(50)
Usuario que registra la salida
salidas_detalle Nombre del Campo
Tipo de Datos
Descripción
id_salida_detalle
Autonumérico
Id del detalle de la salida
id_salida
Número
Id de la salida
id_articulo
Texto(50)
Id del artículo
cantidad
Número(Doble)
Cantidad que sale
Una vez que diseñamos nuestras tablas, las relacionamos. Las relaciones deben de quedar así:
Especificaciones técnicas:
Todos los nombres de los campos son con minúsculas. Esto no afecta en la programación, pero deseamos poder llevar un estándar en todo lo que vayamos desarrollando.
Deberá respetar los tipos de datos, eso nos evitará posibles errores en tiempo de ejecución.
Sistema de Almacén Visual Basic (Parte 3)
Entradas al Almacén Diseño de la pantalla Empezaremos diseñando la pantalla de entradas (formulario frmEntrada), la apariencia debe de quedar mas o menos así:
A continuacion una tabla descriptiva con los nombres de los objetos: Objeto
Label
Propiedad
Valor
Name
lblFechaEntrada
Text
Fecha Entrada:
Name
dtpFechaEntrada
DateTimePicker
Format
Custom
CustomFormat
dd/MM/yyyy
Name
lblFechaFactura
Text
Fecha Factura:
Name
dtpFechaFactura
Format
Custom
CustomFormat
dd/MM/yyyy
Name
lblFolioFactura
Text
Folio Factura:
Name
txtFolioFactura
Name
lblNombreProveedor
Text
Nombre del Proveedor:
Name
txtNombreProveedor
Name
lblIdArticulo
Text
Articulo:
Name
txtIdArticulo
Name
lblCantidad
Text
Cantidad:
Name
txtCantidad
Name
lblPrecioCompra
Text
Precio:
TextBox
Name
txtPrecioCompra
Button
Name
btnAgregar
Label
DateTimePicker
Label TextBox
Label
TextBox
Label
TextBox
Label
TextBox
Label
Text
Agregar
Name
btnGrabar
Text
Grabar
Name
btnCancelar
Text
Cancelar
Name
lvEntrada
FullRowSelect
True
GridLines
True
HideSelection
False
Button
Button
ListView
Programación Directivas Imports: Imports System.Data Imports System.Data.OleDb
Ponemos elcódigo de "modMain.vb": Module modMain ''Proveedor para Access 2007-2010 (.accdb): ''Microsoft.ACE.OLEDB.12.0 ''Proveedor para 99-2003 .(mdb): ''Microsoft.Jet.OLEDB.4.0 Public CnnStr As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source={0};Persist Security Info=False" , "D:\DOCS\tyrodeveloper\Blogger\almacenVB\almacen.mdb" ) Public RptEntrada As String = "D:\DOCS\tyrodeveloper\Blogger\almacenVB\almacenVB\Reportes\rptEntrada.rdlc" Public RptSalida As String = "D:\DOCS\tyrodeveloper\Blogger\almacenVB\almacenVB\Reportes\rptSalida.rdlc" End Module
Vamos al código del formulario "frmEntrada.vb": Declaraciones Dim tmpEntrada As New DataTable
Ahora escribiremos el código de las funciones y procedimientos:
Protected Sub generaColumnas() lvEntrada.Clear() lvEntrada.View = View.Details lvEntrada.Columns.Add("", 0, HorizontalAlignment.Left) lvEntrada.Columns.Add( "Id ", 100, HorizontalAlignment.Left) lvEntrada.Columns.Add( "Producto", 240, HorizontalAlignment.Left) lvEntrada.Columns.Add( "Cantidad", 60, HorizontalAlignment.Right) lvEntrada.Columns.Add( "Precio", 60, HorizontalAlignment.Right) lvEntrada.Columns.Add( "Total", 80, HorizontalAlignment.Right) End Sub Protected Sub mostrarEntrada() Try Dim varIVA As Double = 0 Dim varTOTAL As Double = 0 lvEntrada.Items.Clear() Dim i As Integer = 0 For i = 0 To tmpEntrada.Rows.Count - 1 Step 1 lvEntrada.Items.Add(tmpEntrada.Rows(i)( "id").ToString()) lvEntrada.Items(i).SubItems.Add(tmpEntrada.Rows(i)( "id_articulo" ).ToString()) lvEntrada.Items(i).SubItems.Add(tmpEntrada.Rows(i)( "articulo").ToString()) lvEntrada.Items(i).SubItems.Add( String.Format("{0:N}", Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")))) lvEntrada.Items(i).SubItems.Add( String.Format("{0:C}", Convert.ToDouble(tmpEntrada.Rows(i)( "precio_compra" )))) lvEntrada.Items(i).SubItems.Add( String.Format("{0:C}", (Convert.ToDouble(tmpEntrada.Rows(i)( "precio_compra" )) * Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad"))))) varTOTAL += Convert.ToDouble(tmpEntrada.Rows(i)( "precio_compra" )) * Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")) varIVA += (Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")) * Convert.ToDouble(tmpEntrada.Rows(i)( "precio_compra" ))) ((Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")) * Convert.ToDouble(tmpEntrada.Rows(i)( "precio_compra" ))) / (1.16)) Next catch ex as Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub Protected Function agregarArticulo() As Boolean Dim cnn As New OleDbConnection(CnnStr) Dim row As DataRow Try Dim varId As String = "" Dim varNombre As String = "" cnn.Open() Dim strSQL As String = "select articulo from articulos " + "where id_articulo=@id" Dim cmd As New OleDbCommand(strSQL, cnn) cmd.Parameters.Add( "@id", OleDbType.VarChar, 50).Value = txtIdArticulo.Text Dim dr As OleDbDataReader = cmd.ExecuteReader() If (dr.Read()) Then varId = txtIdArticulo.Text varNombre = dr("articulo").ToString() ''agregamos la venta a la tabla temporal row = tmpEntrada.NewRow() row("id_articulo" ) = varId row("articulo") = varNombre row("cantidad") = CDbl(txtCantidad.Text) row("precio_compra" ) = CDbl(txtPrecioCompra.Text) row("iva") = 0.16 tmpEntrada.Rows.Add(row) Else Throw (New Exception("El articulo no existe")) End If dr.Close() Return True Catch ex As Exception Throw (ex) Finally
cnn.Close() End Try End Function Protected Function grabarEntrada() As Boolean Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() Dim tran As OleDbTransaction = cnn.BeginTransaction() Dim cmd As New OleDbCommand() cmd.Connection = cnn cmd.Transaction = tran ''insertamos el registro de la Entrada Try cmd.CommandText = "insert into entradas(fecha_entrada,fecha_factura,folio_factura,proveedor,user_login) " + " values (@fechaEntrada,@fechaFactura,@folioFactura,@nombreProveedor,@userLogin)" ''params cmd.Parameters.Add( "@fechaEntrada" , OleDbType.Date).Value = New DateTime(dtpFechaEntrada.Value.Year, dtpFechaEntrada.Value.Month, dtpFechaEntrada.Value.Day) cmd.Parameters.Add( "@fechaFactura" , OleDbType.Date).Value = New DateTime(dtpFechaFactura.Value.Year, dtpFechaFactura.Value.Month, dtpFechaFactura.Value.Day) cmd.Parameters.Add( "@folioFactura" , OleDbType.VarChar, 50).Value = txtFolioFactura.Text cmd.Parameters.Add( "@nombreProveedor" , OleDbType.VarChar, 50).Value = txtNombreProveedor.Text cmd.Parameters.Add( "@userLogin", OleDbType.VarChar, 50).Value = "admin" cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''Limpiar params ''obtenemos el folio Dim _FolioEntrada As Integer = 0 cmd.CommandText = "select @@identity" _FolioEntrada = Convert.ToInt32(cmd.ExecuteScalar()) ''insertamos el detalle de la entrada Dim i As Integer = 0 For i = 0 To tmpEntrada.Rows.Count - 1 Step 1 Dim _IdArticulo As String = Convert.ToString(tmpEntrada.Rows(i)( "id_articulo" )) Dim _Cantidad As Double = Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")) Dim _IVA As Double = Convert.ToDouble(tmpEntrada.Rows(i)("iva")) Dim _PrecioCompra As Double = Convert.ToDouble(tmpEntrada.Rows(i)( "precio_compra" )) Dim _CostoPromedio As Double = 0 ''insertamos el articulo cmd.CommandText = "insert into entradas_detalle(id_entrada,id_articulo,cantidad,precio_compra,iva) " + "values(@folioEntrada,@idArticulo,@cantidad,@precioCompra,@IVA)" cmd.Parameters.Add( "@folioEntrada" , OleDbType.Integer).Value = _FolioEntrada cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = _IdArticulo cmd.Parameters.Add( "@cantidad", OleDbType.Double).Value = _Cantidad cmd.Parameters.Add( "@precioCompra" , OleDbType.Double).Value = _PrecioCompra cmd.Parameters.Add( "@IVA", OleDbType.Double).Value = _IVA cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''Limpiar params ''actualizamosexistencias cmd.CommandText = "update articulos set " + " existencia=existencia + @cantidad" + " where id_articulo=@idArticulo" cmd.Parameters.Add( "@cantidad", OleDbType.Double).Value = _Cantidad cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = _IdArticulo cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''Limpiar params ''establecemos el costo promedio cmd.CommandText = "select avg(precio_compra) " +
" from entradas_detalle " + " where id_articulo=@idArticulo" cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = _IdArticulo _CostoPromedio = Convert.ToDouble(cmd.ExecuteScalar()) cmd.Parameters.Clear() ''Limpiar params cmd.CommandText = "update articulos set " + " costo_promedio=@costo" + " where id_articulo=@idArticulo" cmd.Parameters.Add( "@cantidad", OleDbType.Double).Value = _CostoPromedio cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = _IdArticulo cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''Limpiar params Next ''finalizamos la transaccion tran.Commit() MessageBox.Show( "Entrada grabada correctamente", "Información del Sistema", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As Exception tran.Rollback() Throw (ex) End Try Return True Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Function
Ahora damos doble clic sobre el botón Agregar (btnAgregar) y escribimos el siguiente código: Try If (agregarArticulo()) Then mostrarEntrada() End If Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
Ahora, agregaremos el código para grabar la entrada, hacemos doble clic sobre el botón Grabar (btnGrabar) y escribimos el siguiente código: Try ''validaciones If (txtFolioFactura.Text = "") Then Throw (New Exception("Falta folio de factura")) End If If (txtNombreProveedor.Text = "") Then Throw (New Exception("Falta nombre del provedor")) End If If (lvEntrada.Items.Count = 0) Then Throw (New Exception("No hay elementos")) End If ''grabar If (grabarEntrada()) Then Me.Close() End If Catch ex As Exception MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
El código que pondremos en el Form_Load es el siguiente: ''>Definimos la tabla para las ventas Temporales Dim idColumn As New DataColumn("id", GetType(Integer)) idColumn.Unique = True idColumn.AutoIncrement = True idColumn.AutoIncrementSeed = 1 idColumn.AutoIncrementStep = 1 tmpEntrada.Columns.Add(idColumn) ''declaramos el resto de los campos tmpEntrada.Columns.Add( "id_articulo" , GetType(String)) tmpEntrada.Columns.Add( "articulo", GetType(String)) tmpEntrada.Columns.Add( "cantidad", GetType(Double)) tmpEntrada.Columns.Add( "precio_compra" , GetType(Double)) tmpEntrada.Columns.Add( "iva", GetType(Double)) ''agregamos un primary key tmpEntrada.PrimaryKey = New DataColumn() {tmpEntrada.Columns("id")} ''
En el botón Salir (btnSalir) escribimos esto: Me.Close()
Para efectos de aprendizaje basico me aseguré de no poner funcionalidad demasiado complicada. Lo que tratamos de desarrollar es un sistema de almacén sencillo, no se trata de desarrollar un sistema comercial cero errores, tratamos de sentar las bases técnicas para, en un futuro, lograr un gran sistema de almacén con toda la funcionalidad comercial. Aqui un ejemplo de la pantalla funcionando:
Sistema de Almacén Visual Basic (Parte 4)
Reporte de Entradas
Diseño de la pantalla Para comenzar, le daremos diseño al formulario "frmEntradasLista" el cual nos servirá para mostrar un listado de las entradas que se hayan registrado, la apariencia debe de quedar mas o menos así:
Se agregaron tres Button, un ListView y un Label, las propiedades están descritas en la siguiente tabla: Objeto
Propiedad
Valor
Name
btnNueva
Text
Nueva
Name
btnMostrar
Text
Mostrar
Name
btnSalir
Text
Salir
Name
lvEntradas
Button
Button
Button
ListView
FullRowSelect
True
GridLines
True
HideSelection
False
Name
lblMensaje
Text
Doble clic para imprimir.
Label
Ahora procedemos con el diseño del reporte de entradas, lo primero que haremos será crear un DataSet el cual nos servirá para el posterior diseño del reporte. Agregamos un nuevo objeto del tipo DataSet y le asignamos el nombre dsRptEntrada como se muestra:
Le damos diseño para que quede como se muestra: El DataSet aparece vacío, debemos agregar un DataTable y darle el diseño para que quede como se muestra en la imagen. De entre las propiedades que debemos destacar es que el tipo de datos de los campos cantidad, precio_compra e iva son System.Double.
Los tipos de datos para los campos id_articulo y articulo son System.String.
Una vez terminado el diseño del DataSet agregamos un Reporte, pero utilizaremos un asistente, aqui muestro con imagenes todo el proceso:
Selecionamos que nuestro origen de datos es un objeto:
En la siguiente ventana, expanda todo y ubique el DataSet que acaba de crear anteriormente, como se muestra a continuación:
Luego, escriba un nombre para el DataSet (propiedad Name), se recomienda poner el
mismo que puso anteriormente:
Arrastre los campos que desea mostrar en el reporte a la sección Values como se muestra en la imagen:
Desactive la operación Sum:
Seleccione un formato (apariencia):
Elija a su gusto:
Agregue el encabezado y el pié del reporte:
Agregue los parametros prmFechaEntrada, prmFechaFactura, prmFolioFactura y prmProveedor
Ejemplo de como agregar un parametro (Repitalo con los demás):
Agregue cuatro TextBox al encabezado y organicelos ordenadamente:
Arrastre los parametros creados enfrente de los TextBox:
Agrege una columna al reporte:
Puede darle diseño al reporte, hagalo a su gusto, aqui se muestra algo muy básico:
Agregaremos una función para calcular el total:
En seguida se muestra como hacerla:
Agregaremos un nuevo formulario llamado frmVerReporte al cual agregaremos un control ReportViewer al cual estableceremos una propiedad Modifiers=Public (En la ventana de propiedades), aqui se muestra una imagen:
Hasta aqui todo ha sido diseño, ahora escribiremos el código que hace todo posible:
Ahora agregamos los siguientes procedimientos: Protected Sub generarColumnas() lvEntradas.Clear() lvEntradas.View = View.Details lvEntradas.Columns.Add( "Folio ", 40, HorizontalAlignment.Left) lvEntradas.Columns.Add( "Fecha Entrada", 85, HorizontalAlignment.Left)
lvEntradas.Columns.Add("Fecha Factura", 85, HorizontalAlignment.Left) lvEntradas.Columns.Add( "Folio Factura", 85, HorizontalAlignment.Left) lvEntradas.Columns.Add( "Proveedor", 200, HorizontalAlignment.Left) End Sub Protected Sub mostrarEntradas() Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() Dim cmd As New OleDbCommand() cmd.Connection = cnn cmd.CommandText = "select * from entradas" Dim dr As OleDbDataReader = cmd.ExecuteReader() Dim i As Integer = 0 lvEntradas.Items.Clear() While (dr.Read()) ''mostramos los datos lvEntradas.Items.Add(dr( "id_entrada").ToString()) lvEntradas.Items(i).SubItems.Add( String.Format("{0:dd/MM/yyyy}" , dr("fecha_entrada" ))) lvEntradas.Items(i).SubItems.Add( String.Format("{0:dd/MM/yyyy}" , dr("fecha_factura" ))) lvEntradas.Items(i).SubItems.Add(dr( "folio_factura" ).ToString()) lvEntradas.Items(i).SubItems.Add(dr( "proveedor").ToString()) i += 1 End While dr.Close() Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Sub Protected Sub mostrarReporte(ByVal idEntrada As Integer) Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() If Not File.Exists(RptEntrada) Then Throw (New Exception(String.Format("No existe el archivo: {0}", RptEntrada))) End If ''AHORA MOSTRAMOS EL REPORTE Dim cmd As New OleDbCommand() cmd.Connection = cnn cmd.CommandText = "select d.*,a.articulo " + " from entradas_detalle d,articulos a " + " where a.id_articulo=d.id_articulo and id_entrada=@idEntrada" cmd.Parameters.Add( "@idEntrada", OleDbType.Integer).Value = idEntrada Dim dsReporte As New DataSet() Dim da As New OleDbDataAdapter(cmd) da.Fill(dsReporte, "rptEntrada") If (dsReporte.Tables("rptEntrada").Rows.Count = 0) Then Throw (New Exception("No hay Datos")) End If Dim frm As New frmVerReporte frm.reportViewer1.LocalReport.DataSources.Clear() frm.reportViewer1.LocalReport.Dispose() frm.reportViewer1.Reset() frm.reportViewer1.LocalReport.DataSources. Add(New ReportDataSource("dsRptEntrada" , dsReporte.Tables( "rptEntrada"))) frm.reportViewer1.LocalReport.ReportPath = RptEntrada ''parametros ''List param = new List() Dim param As New List(Of ReportParameter) Dim cmdDet As New OleDbCommand("select * from entradas " + " where id_entrada=@idEntrada", cnn) cmdDet.Parameters.Add( "@idEntrada", OleDbType.Integer).Value = idEntrada
Dim dr As OleDbDataReader = cmdDet.ExecuteReader() If (dr.Read()) Then ''folio_factura Dim pFolioFactura As New ReportParameter() pFolioFactura.Name = "prmFolioFactura" pFolioFactura.Values.Add(dr( "folio_factura" ).ToString()) param.Add(pFolioFactura) ''fecha_entrada Dim pFechaEntrada As New ReportParameter() pFechaEntrada.Name = "prmFechaEntrada" pFechaEntrada.Values.Add(dr( "fecha_entrada" ).ToString()) param.Add(pFechaEntrada) ''fecha_factura Dim pFechaFactura As New ReportParameter() pFechaFactura.Name = "prmFechaFactura" pFechaFactura.Values.Add(dr( "fecha_factura" ).ToString()) param.Add(pFechaFactura) ''proveedor Dim pProveedor As New ReportParameter() pProveedor.Name = "prmProveedor" pProveedor.Values.Add(dr( "proveedor").ToString()) param.Add(pProveedor) End If dr.Close() ''agregamos los parametros a la coleccion frm.reportViewer1.LocalReport.SetParameters(param) frm.reportViewer1.RefreshReport() frm.ShowDialog() cnn.Close() Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Sub
Agregamos sl siguiente código en el Form_Load: Try generarColumnas() mostrarEntradas() Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
Luego, agregamos el siguiente código (Para el evento Doble Clic del ListView): Private Sub lvEntradas_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvEntradas.DoubleClick Try If (lvEntradas.SelectedItems.Count <> 0) Then Dim _FolioEntrada As Integer = Convert.ToInt32(lvEntradas.SelectedItems(0).Text) mostrarReporte(_FolioEntrada) End If Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub
El código para el botón btnNueva: Dim frm As New frmEntrada frm.StartPosition = FormStartPosition.CenterScreen frm.ShowDialog()
El código para el botón btnMostrar: Try mostrarEntradas() Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
El código para el botón btnSalir Me.Close()
Aqui un ejemplo de la pantalla funcionando:
Aqui un ejemplo del reporte:
Sistema de Almacén Visual Basic (Parte 5)
Salidas del Almacén
Diseño de la pantalla Empezaremos diseñando la pantalla de salidas (formulario frmSalida), la apariencia debe de quedar mas o menos así:
A continuacion una tabla descriptiva con los nombres de los objetos: Objeto
Propiedad
Valor
Name
lblFechaSalida
Text
Fecha Salida:
Name
dtpFechaSalida
Format
Custom
CustomFormat
dd/MM/yyyy
Name
lblResponsable
Text
Responsable de la Salida:
Name
txtResponsable
Name
lblIdArticulo
Text
Articulo:
Name
txtIdArticulo
Name
lblCantidad
Text
Cantidad:
Name
txtCantidad
Label
DateTimePicker
Label
TextBox
Label
TextBox
Label
TextBox
Name
btnAgregar
Text
Agregar
Name
btnGrabar
Text
Grabar
Name
btnCancelar
Text
Cancelar
Name
lvSalida
FullRowSelect
True
GridLines
True
HideSelection
False
Button
Button
Button
ListView
Programación La parte de la programación es la mas enredada. Voy a considerar que el lector es un novato con nociones bastante básicas e insuficientes como para comprender la estructura de la programación C#. Recomiendo al lector poner mucha atención a los pasos que aqui se describan y no omitir nada, leer y re-leer hasta que haya comprendido lo que tiene que hacer.
Declaramos las siguientes directivas: Imports System.Data Imports System.Data.OleDb Imports Microsoft.Reporting.WinForms Imports System.IO
Escribiremos el código de las funciones y procedimientos: Protected Sub generaColumnas() With lvSalida .Clear() .View = View.Details .Columns.Add("", 0, HorizontalAlignment.Left) .Columns.Add( "Id ", 100, HorizontalAlignment.Left) .Columns.Add( "Producto", 240, HorizontalAlignment.Left) .Columns.Add( "Cantidad", 60, HorizontalAlignment.Right) End With
End Sub Protected Sub mostrarEntrada() Try lvSalida.Items.Clear() Dim i As Integer = 0 For i = 0 To tmpEntrada.Rows.Count - 1 Step 1 With lvSalida .Items.Add(tmpEntrada.Rows(i)( "id").ToString()) .Items(i).SubItems.Add(tmpEntrada.Rows(i)( "id_articulo" ).ToString()) .Items(i).SubItems.Add(tmpEntrada.Rows(i)( "articulo").ToString()) .Items(i).SubItems.Add( String.Format("{0:N}", Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")))) End With Next Catch ex As Exception Throw (ex) End Try End Sub Protected Function agregarArticulo() As Boolean Dim cnn As New OleDbConnection(CnnStr) Try Dim varId As String = "" Dim varNombre As String = "" Dim varExistencia As Double = 0 Dim varCantidad As Double = CDbl(txtCantidad.Text) cnn.Open() Dim strSQL As String = "select articulo,existencia,id_articulo " + " from articulos " + " where id_articulo=@idArticulo" Dim cmd As New OleDbCommand(strSQL, cnn) cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = txtIdArticulo.Text Dim dr As OleDbDataReader = cmd.ExecuteReader() If (dr.Read()) Then varId = dr("id_articulo" ).ToString() varNombre = dr("articulo").ToString() varExistencia = Convert.ToDouble(dr("existencia")) If (varExistencia >= varCantidad) Then ''agregamos la venta a la tabla temporal Dim row As DataRow = tmpEntrada.NewRow() row("id_articulo" ) = varId row("articulo") = varNombre row("cantidad") = varCantidad tmpEntrada.Rows.Add(row) Else Throw (New Exception("No hay suficientes existencias")) End If Else Throw (New Exception("el articulono existe")) End If dr.Close() cnn.Close() Return (True) Catch ex As Exception Throw (ex) End Try End Function Protected Function grabarSalida() As Boolean Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() Dim tran As OleDbTransaction = cnn.BeginTransaction() Dim cmd As New OleDbCommand() cmd.Connection = cnn cmd.Transaction = tran ''insertamos el registro de la Entrada Try cmd.CommandText = "insert into " + "salidas(fecha_salida,responsable,user_login) " + " values (@fechaSalida,@responsable,@userLogin)"
cmd.Parameters.Add("@fechaSalida" , OleDbType.Date).Value = New Date(dtpFechaSalida.Value.Year, dtpFechaSalida.Value.Month, dtpFechaSalida.Value.Day) cmd.Parameters.Add( "@responsable" , OleDbType.VarChar, 50).Value = txtResponsable.Text cmd.Parameters.Add( "@userLogin", OleDbType.VarChar, 50).Value = "admin" cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''obtenemos el folio Dim _FolioSalida As Integer = 0 cmd.CommandText = "select @@identity" _FolioSalida = Convert.ToInt32(cmd.ExecuteScalar()) ''insertamos el detalle de laentrada Dim i As Integer For i = 0 To tmpEntrada.Rows.Count - 1 Step 1 Dim _IdArticulo As String = Convert.ToString(tmpEntrada.Rows(i)( "id_articulo" )) Dim _Cantidad As Double = Convert.ToDouble(tmpEntrada.Rows(i)( "cantidad")) ''insertamos el articulo cmd.CommandText = "insert into " + "salidas_detalle(id_salida,id_articulo,cantidad) " + "values(@folioSalida,@idArticulo,@cantidad)" cmd.Parameters.Add( "@folioSalida" , OleDbType.Integer).Value = _FolioSalida cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = _IdArticulo cmd.Parameters.Add( "@cantidad", OleDbType.Double).Value = _Cantidad cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''actualizamosexistencias cmd.CommandText = "update articulos set " + " existencia=existencia - @cantidad" + " where id_articulo=@idArticulo" cmd.Parameters.Add( "@cantidad", OleDbType.Integer).Value = _Cantidad cmd.Parameters.Add( "@idArticulo" , OleDbType.VarChar, 50).Value = _IdArticulo cmd.ExecuteNonQuery() cmd.Parameters.Clear() Next ''finalizamos la transaccion tran.Commit() cnn.Close() MessageBox.Show( "Salida grabada correctamente", "Información del Sistema", MessageBoxButtons.OK, MessageBoxIcon.Information) Return (True) Catch errEntrada As OleDbException tran.Rollback() Throw (errEntrada) Return (False) End Try Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Function
Ahora damos doble clic sobre el botón Agregar (btnAgregar) y escribimos el siguiente código: Try
If agregarArticulo() Then mostrarEntrada() End If Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
Ahora, agregaremos el código para grabar la entrada, hacemos doble clic sobre el botón Grabar (btnGrabar) y escribimos el siguiente código: Try ''validaciones If (lvSalida.Items.Count = 0) Then Throw (New Exception("No hay elementos")) End If If (txtResponsable.Text = "") Then Throw (New Exception("Falta el Responsable")) End If If (grabarSalida()) Then Me.Close() End If Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
El código que pondremos en el Form_Load es el siguiente: ''>Definimos la tabla para las salida Temporal Dim idColumn As New DataColumn("id", GetType(Integer)) idColumn.Unique = True idColumn.AutoIncrement = True idColumn.AutoIncrementSeed = 1 idColumn.AutoIncrementStep = 1 tmpEntrada.Columns.Add(idColumn) ''declaramos el resto de los campos tmpEntrada.Columns.Add( "id_articulo" , GetType(String)) tmpEntrada.Columns.Add( "articulo", GetType(String)) tmpEntrada.Columns.Add( "cantidad", GetType(Double)) ''agregamos un primary key tmpEntrada.PrimaryKey = New DataColumn() {tmpEntrada.Columns("id")} ''
En el botón Salir (btnSalir) escribimos esto: Me.Close()
Aqui un ejemplo de la pantalla funcionando:
Sistema de Almacén Visual Basic (Parte 6)
Reporte de Salidas
Diseño de la pantalla Para comenzar, le daremos diseño al formulario "frmSalidasLista" el cual nos servirá para mostrar un listado de las salidas que se hayan registrado, la apariencia debe de quedar mas o menos así:
Se agregaron tres Button, un ListView y un Label, las propiedades están descritas en la siguiente tabla: Objeto
Propiedad
Valor
Name
btnNueva
Text
Nueva
Name
btnMostrar
Text
Mostrar
Name
btnSalir
Text
Salir
Name
lvSalidas
FullRowSelect
True
GridLines
True
HideSelection
False
Name
lblMensaje
Text
Doble clic para imprimir.
Button
Button
Button
ListView
Label
Ahora procedemos con el diseño del reporte de salidas, este proceso se muestra en la parte 4 de este tutorial, el cual deberá quedar mas o menos así:
Directivas Imports: Imports System.Data Imports System.Data.OleDb
Imports Microsoft.Reporting.WinForms Imports System.IO
Ahora agregamos los siguientes procedimientos: Protected Sub generarColumnas() With lvSalidas .Clear() .View = View.Details .Columns.Add( "Folio ", 40, HorizontalAlignment.Left) .Columns.Add( "Salida", 85, HorizontalAlignment.Left) .Columns.Add( "Responsable" , 200, HorizontalAlignment.Left) End With End Sub Protected Sub mostrarSalidas() Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() Dim cmd As New OleDbCommand() cmd.Connection = cnn cmd.CommandText = "select * from salidas" Dim dr As OleDbDataReader = cmd.ExecuteReader() Dim i As Integer = 0 lvSalidas.Items.Clear() While (dr.Read()) ''mostramos los datos With lvSalidas .Items.Add(dr( "id_salida").ToString()) .Items(i).SubItems.Add( String.Format("{0:dd/MM/yyyy}" , dr("fecha_salida" ))) .Items(i).SubItems.Add(dr( "responsable" ).ToString()) End With i += 1 End While dr.Close() Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Sub Protected Sub mostrarReporte(ByVal idSalida As Integer) Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() If Not File.Exists(RptSalida) Then Throw (New Exception(String.Format("No existe el archivo: {0}", RptEntrada))) End If ''AHORA MOSTRAMOS EL REPORTE Dim cmd As New OleDbCommand() cmd.Connection = cnn cmd.CommandText = "select d.*,a.articulo " + " from salidas_detalle d,articulos a " + " where a.id_articulo=d.id_articulo " + " and id_salida=@idSalida" cmd.Parameters.Add( "@idSalida", OleDbType.Integer).Value = idSalida Dim dsReporte As New DataSet() Dim da As New OleDbDataAdapter(cmd) da.Fill(dsReporte, "rptSalida") If (dsReporte.Tables("rptSalida").Rows.Count = 0) Then Throw (New Exception("No hay Datos")) End If Dim frm As New frmVerReporte frm.reportViewer1.LocalReport.DataSources.Clear()
frm.reportViewer1.LocalReport.Dispose() frm.reportViewer1.Reset() frm.reportViewer1.LocalReport. DataSources.Add( New ReportDataSource("dsRptSalida" , dsReporte.Tables( "rptSalida"))) frm.reportViewer1.LocalReport.ReportPath = RptSalida ''parametros ''List param = new List() Dim param As New List(Of ReportParameter) Dim cmdDet As New OleDbCommand("select * " + "from salidas where id_salida=@idSalida" , cnn) cmdDet.Parameters.Add( "@idSalida", OleDbType.Integer).Value = idSalida Dim dr As OleDbDataReader = cmdDet.ExecuteReader() If (dr.Read()) Then ''id_Salida Dim pIdSalida As New ReportParameter() pIdSalida.Name = "prmIdSalida" pIdSalida.Values.Add(dr( "id_salida").ToString()) param.Add(pIdSalida) ''fecha_Salida Dim pFechaEntrada As New ReportParameter() pFechaEntrada.Name = "prmFechaSalida" pFechaEntrada.Values.Add(dr( "fecha_salida" )) param.Add(pFechaEntrada) ''responsable Dim pResponsable As New ReportParameter() pResponsable.Name = "prmResponsable" pResponsable.Values.Add(dr( "responsable" ).ToString()) param.Add(pResponsable) End If dr.Close() ''agregamos los parametros a la coleccion frm.reportViewer1.LocalReport.SetParameters(param) frm.reportViewer1.RefreshReport() frm.ShowDialog() cnn.Close() Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Sub
Agregamos sl siguiente código en el Form_Load: Try generarColumnas() mostrarSalidas() Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
Luego, agregamos el siguiente código: Private Sub lvSalidas_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvSalidas.DoubleClick Try If (lvSalidas.SelectedItems.Count <> 0) Then Dim _FolioSalida As Integer = Convert.ToInt32(lvSalidas.SelectedItems(0).Text) mostrarReporte(_FolioSalida) End If Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub
El código para el botón btnNueva: Dim frm As New frmSalida frm.StartPosition = FormStartPosition.CenterScreen frm.ShowDialog()
El código para el botón btnMostrar: Try mostrarSalidas() Catch ex As Exception MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
El código para el botón btnSalir Me.Close()
Aqui un ejemplo de la pantalla funcionando:
Aqui un ejemplo del reporte:
Hasta este punto ya hemos desarrollado la funcionalidad básica. En la siguiente parte haremos que aparesca una pantalla pricipal desde la que mandaremos llamar las que hasta hoy hemos desarrollado.
Sistema de Almacén Visual Basic (Parte 7)
Pantalla principal
Le daremos diseño al formulario frmPrincipal agregando un MenuStrip, un ToolStrip y estableciendo su pripiedad IsMdiContainer = true para que quede de la siguiente manera:
A continuación una tabla que describe los objetos:
Objeto
Propiedad
Valor
MenuStrip
Name
mnuPrincipal
Name
mnuArchivo
Text
Archivo
Name
mnuAyuda
Text
Ayuda
Name
mnuEntradas
Text
Entradas
Name
mnuSalidas
Text
Salidas
Name
mnuSalir
Text
Salir del Sistema
Name
barPrincipal
Name
btnEntradas
Text
Entradas
ToolStripMenuItem
ToolStripMenuItem
ToolStripMenuItem
ToolStripMenuItem
ToolStripMenuItem
ToolStrip
ToolStripButton DisplayStyle
ImageAndText
TextImageRelation
ImageAboveText
Image
(A su gusto)
Name
btnSalidas
Text
Salidas
ToolStripButton DisplayStyle
ImageAndText
TextImageRelation
ImageAboveText
Image
(A su gusto)
Name
btnSalir
Text
Salir
ToolStripButton DisplayStyle
ImageAndText
TextImageRelation
ImageAboveText
Image
(A su gusto)
Ahora crearemos los siguientes procedimientos: Protected Sub Salidas() Dim frm As New frmSalidaLista frm.MdiParent = Me frm.Show() End Sub Protected Sub Entradas() Dim frm As New frmEntradaLista frm.MdiParent = Me frm.Show() End Sub
Ahora solo resta poner el código en cada uno de los botones y menús, los ponemos de uno por uno, dando doble clic sobre cada uno, iniciamos con mnuEntradas: Entradas() Seguimos con mnuSalidas: Salidas() Asi lo hacemos también con los botones btnEntradas y btnSalidas
Aqui un ejemplo de la pantalla funcionando: