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 Propiedad Valor

Label
Name lblFechaEntrada
Text Fecha Entrada:

DateTimePicker
Name dtpFechaEntrada
Format Custom
CustomFormat dd/MM/yyyy

Label
Name lblFechaFactura
Text Fecha Factura:

DateTimePicker
Name dtpFechaFactura
Format Custom
CustomFormat dd/MM/yyyy

Label
Name lblFolioFactura
Text Folio Factura:
TextBox Name txtFolioFactura
Label Name lblNombreProveedor
Text Nombre del Proveedor:
TextBox Name txtNombreProveedor
Label Name lblIdArticulo
Text Articulo:
TextBox Name txtIdArticulo
Label Name lblCantidad
Text Cantidad:
TextBox Name txtCantidad
Label Name lblPrecioCompra
Text Precio:
TextBox Name txtPrecioCompra
Button Name btnAgregar
Text Agregar
Button Name btnGrabar
Text Grabar
Button Name btnCancelar
Text Cancelar
ListView Name lvEntrada
FullRowSelect True
GridLines True
HideSelection False

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")}
        ''<termina la deficinicón de la tabla temporal
        generaColumnas()
        mostrarEntrada()

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:

Regresar a la parte 2|Ir a la parte 4

¡Hacer clic en +1 No te Cuesta Nada!

20 comentarios:

  1. Hola Que tal. Oye se que hacer este tipo de Tutoriales conlleva mucho esfuerzo y dedicación y créeme se te Agradece. Pero un favor me podrias apoyar diciendome donde pongo las Directivas Imports: y las Declaraciones la verdad soy nuevo en esto de la programación pero tengo muchas ganas de aprender. de ante mano te agradezco.

    ResponderEliminar
  2. Las directivas Imports las induces al inicio de la hoja de programación, antes de las letras :

    Public Class frmEntrada

    saludos y suerte con el desarrollo !!!

    PD: Muy buen tutorial !!!

    ResponderEliminar
  3. Hola buenas, excelente tutorial !!! Una consulta ? Donde debo poner el Form_Load, soy muy novato en esto. Saludos y gracias por compartir lo que sabes !!!

    ResponderEliminar
  4. El Form_Load es un evento LOAD lo que si es que he estado haciéndolo hoy y me da el error no se ha inicilizado la propiedad ConnectionString lastima tan bonito que se veía :(

    ResponderEliminar
  5. la verdad todo bacan pero no se conecta..la coneccion yo tengo el acces 2007 pero no me muestra nada x que

    ResponderEliminar
  6. no puedo hacerlo me sale la instruccion no es valida en un espacio de nombre

    ResponderEliminar
  7. Hola que tal, yo me baje el VS2013 y lo estoy realizando ahi, tambien soy nuevo en esto y justo me cae a pelo porque quiero algo asi para un pequeño almacen. Bueno cuando creo el proyecto me carga un Form1.vb (ya he creado lo demas como en tus imagenes), pero cuando le doy a ejecutar para probar el sistema me carga el Form1 vacio

    ResponderEliminar
  8. como hago para declarar el...
    Dim tmpEntrada As New DataTable
    y en donde lo agrago, este codigo

    ResponderEliminar
  9. Hola, buenas tardes con todos, kiero saber en donde coloco esta parte del codigo...
    por en realidad a mi me sale Private Sub y no Protected Sub y como hago eso, por favor necesito de sus ayudas urgente!!!

    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()

    ResponderEliminar
    Respuestas
    1. hola a todos a mi me funciono a la perfeccion esta chevere buen tutorial muchas gracias... A. Jhonatan Lopez ese codigo va dentro del Public Class frmEntrada

      Eliminar
  10. Hector, Te funciono perfecto el sistema?

    ResponderEliminar
  11. Hola muy bueno ,pero me sale un error...El Articulo no existe..me pueden ayudar por favor

    ResponderEliminar
    Respuestas
    1. elmismo error, al parecer no puedo agregar articulos ni grabarlos

      Eliminar
    2. Buen día, al querer agregar un producto sale el error: El Articulo no existe
      Por favor, podría alguien ayudarme. Gracias.

      Eliminar
  12. el codigo no concuerda con la base de datos ni con el diseño del from :/

    ResponderEliminar
  13. HOLA, SOY NUEVO EN ESTO DE LA POGRAMACION ALGUIEN PODRIA RECOMENDAR ME UN BUEN LENGUAJE DE PROGRAMACION

    ResponderEliminar
  14. Saludos a todos me estoy inicializando en la programacion me gustaria saber codigo largop a donde lo coloco si es clases es cuando tu dice Ahora escribiremos el código de las funciones y procedimientos: donde coloco ese codigo.

    ResponderEliminar
  15. Alguien sabe donde creo el form_load o donde lo coloco?

    ResponderEliminar