none
Actualizar datos de una tabla, desde un datagridview. RRS feed

  • Pregunta

  • Hola con todos, tengo un problema.

    Este es el escenario: tengo un formulario donde se puede registrar los pedidos que el usuario tenga que realizar, el Pedido conforma con 2 tablas en la base de datos, "Cabecera Pedido"(idPedido,fechapedido,idsucursal)y "Detalle Pedido"(idproducto,producto,cantidad), Para registrar no tengo ningún problema, pero pasa que el usuario puede o tiene mejor dicho la necesidad de poder modificar el pedido que hizo, al modificar me refiero a que pueda eliminar, agregar o modificar algun producto que ingreso en el datagridview de la tabla "Detalle Pedido", he aqui el problema, no sé que debería hacer, ya que intente haciendo un procedure para modificar los datos de la tabla del datagridview, pero si agrego un nuevo item a la grilla del detalle, y guardo los cambios, resulta que modifica todos los registros al ultimo item ingresado.

    No sé si entendió muy bien el escenario por el cuál estoy enfrentándome, la idea básica sería como hacer para modificar, agregar o actualizar datos de la grilla de un detalle de (en mi caso Pedido) o una Venta con su detalle, o algo asi. Dado que en mi situación en un momento el usuario puede optar por agregar un producto más a su pedido ya registrado en la base de datos, o a lo mejor quitar algún producto de la grilla.

    Gracias por su atención.

    sábado, 3 de mayo de 2014 23:58

Respuestas

  • El datagrid que utilizas es solo para añadir los artículos? Lo tienes conectado a un dataSet?

    Yo hace muy poco tuve que hacer un formulario para guardar pedidos y solucioné el problema de la siguiente manera:

    El dataGrid lo hice con las siguientes propiedades:

    Propiedades AllowUserToAdRows, allowuserToDeleteRows, AllowUserToOrderColumns, allowusertoresizerows a False.

    Los artículos los añade el usuario desde otro formulario que se abre al pulsar la tecla + del teclado o al botón añadir que puse en el formulario.

    Le diseñé tres columnas: IdArtículo, nombre, cantidad.

    Los artículos se añaden desde el formulario que te dije antes.

    Lo que hago es que en el constructor de ese formulario le paso un objeto de tipo datagridViewRow y lo igualo a una variable private datagridview que tengo en ese formulario:

    Así:

    Private grdArticulos As DataGridView 'Esto está justo después de la palabra class del formulario que se abre desde el primero.

      Sub New(ByRef grdArticulos As DataGridView)

            InitializeComponent()

            Me.grdArticulos = grdArticulos
        End Sub

    En este formulario el usuario elige el articulo que quiere añadir y le pone la cantidad en texbox, luego al darle al botón aceptar pongo este código:

     If CajasVacias() = False Then
                If txtProducto.ReadOnly = True Then
                    If ogrdFila.Cells(3).Value = "NUEVO" Then
                        ogrdFila.Cells(0).Value = txtProducto.Text
                        ogrdFila.Cells(1).Value = txtDescripcion.Text
                        ogrdFila.Cells(2).Value = txtCantidad.Text
                        Me.Close()
                    Else
                        ogrdFila.Cells(0).Value = txtProducto.Text
                        ogrdFila.Cells(1).Value = txtDescripcion.Text
                        ogrdFila.Cells(2).Value = txtCantidad.Text
                        ogrdFila.Cells(3).Value = "ALMACENADO"
                        Me.Close()
                    End If
                Else
                    If Not ComprobarArticulo() Then
                        Me.grdArticulos.Rows.Add(txtProducto.Text, txtDescripcion.Text, txtCantidad.Text, "NUEVO")
                        Me.Close()
                    Else
                        MessageBox.Show("El artículo ya está añadido al pedido. No se puede añadir otra vez", "Artículo ya añadido", MessageBoxButtons.OK, MessageBoxIcon.Information)
                        txtCantidad.Select()
                    End If
                End If
                End If

    Cajasvacias es una función que comprueba que los texbox no estén vacíos.

    En el datagrid donde muestro los artículos, tengo una columna oculta en la que guardo una cadena con "NUEVO" si el articulo es nuevo o "Almacenado" si el artículo ya estaba guardado en la base de datos antes, y solo quiere modificar la cantidad.

    Después de eso se cierra el formulario y se añade al datagrid del formulario de crearpedido esos datos.

    Luego en ese formulario tendrás un botón para guardar el pedido. En ese botón hago lo siguiente:

     

    'Miramos el número de filas del datagrid, si es mayor o igual que uno quiere decir que tiene artículos.
            If grdArticulos.Rows.Count >= 1 And txtCliente.Text.Length > 0 And txtFecha.Text.Length = 10 Then
                If txtNumPedido.Visible = False Then 'Si este campo no es visible, el pedido es nuevo
                    oPedidos.CargarTablaPedido(poAdaptadorPedidos, poConexion, oDataSet) 'Cargamos en el dataSet la tabla pedidos
                    oTupla = oDataSet.Tables("Pedido").NewRow 'Creamos en la variable una referencia a una fila nueva de la tabla pedidos
                    oTupla("IdCliente") = txtCliente.Text 'Almacenamos en cada campo de la nueva fila su valor
                    oTupla("FechaPedido") = txtFecha.Text
                    oTupla("Impreso") = "False"
                    Try
                        oDataSet.Tables("Pedido").Rows.Add(oTupla) 'Guardamos la nueva fila en la tabla pedidos
                        poAdaptadorPedidos.Update(oDataSet, "Pedido")
                    Catch ex As System.Data.OleDb.OleDbException
                        MessageBox.Show(ex.Message)
                    Catch Ex As Exception
                        MessageBox.Show(Ex.Message)
                    End Try

                    Me.idPedido = Me.UltimoID() 'Obtenemos el último IdPedido insertado en la tabla pedidos
                Else 'Si esta visible es que el pedido ya estaba guardado y se va a modificar
                    Me.idYaPedido = CInt(txtNumPedido.Text) 'Si el campo txtNumPedido esta visible, es que ya estaba guardado el pedido, y por tanto ya sabemos su Id
                End If
                Me.GuardarArticulos()
                oPedidos.MostrarDatos(poAdaptadorPedidos, poConexion, oDataSet) 'Cargamos en el dataSet el nuevo pedido
                If txtNumPedido.Visible = False Then 'Solo refrescamos el grid de pedidos en caso de que se agregue un nuevo pedido
                    grdPedidos.Refresh() 'Refrescamos el datagrid del formulario lista pedidos para que lo muestre al cerrarse la ventana.
                End If
                Me.Close()
            Else
                MessageBox.Show("La fecha, el cliente o el número de artículos es incorrecto. Verifíquelo", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End Sub

        Private Function UltimoID() As Integer 'Esta función devuelve el último ID insertado en la base de datos.

            Using conexion As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Application.StartupPath & "\PanImpres.accdb;Persist Security Info=True")
                conexion.Open()
                Dim sSql As String = "SELECT MAX (IdPedido) As UltimoRegistro FROM Pedidos"
                Dim oComando As New OleDbCommand(sSql, conexion)
                Return CInt(oComando.ExecuteScalar())
            End Using

        End Function

        Private Sub GuardarArticulos()
            Dim lsSql As String = Nothing
            For Each Fila As DataGridViewRow In grdArticulos.Rows 'Bucle que pasa a través de todas las filas del datagrid
                If Fila.Cells("Estado").Value = "NUEVO" Then
                    If txtNumPedido.Visible = False Then
                        lsSql = "INSERT INTO DetallesPedido(IdPedido,IdArticulo,Cantidad)Values('" & idPedido & "','" & Fila.Cells("IdProducto").Value & "' ,'" & Fila.Cells("Cantidad").Value & "')"
                        Me.EjecutarComando(lsSql, poConexion)
                    Else
                        lsSql = "INSERT INTO DetallesPedido(IdPedido,IdArticulo,Cantidad)Values('" & Me.idYaPedido & "','" & Fila.Cells("IdProducto").Value & "' ,'" & Fila.Cells("Cantidad").Value & "')"
                        Me.EjecutarComando(lsSql, poConexion)
                    End If
                End If
                If Fila.Cells("Estado").Value = "ALMACENADO" Then
                    Dim sql As String = "UPDATE DetallesPedido SET Cantidad = '" & Fila.Cells("Cantidad").Value & "' WHERE IdPedido = " & Me.idYaPedido & " AND IdArticulo = " & Fila.Cells("IdProducto").Value & ""
                    Me.EjecutarComando(sql, poConexion)
                End If
            Next
        End Sub

        Private Sub EjecutarComando(ByVal sql As String, ByVal conexion As OleDbConnection)
            Dim oComando As OleDbCommand
            oComando = New OleDbCommand(sql, conexion)
            Try
                conexion.Open()
                oComando.ExecuteNonQuery()
                conexion.Close()
            Catch ex As OleDbException
                MessageBox.Show(ex.Message)
            End Try
        End Sub

    Ese código es el de mi programa, quita lo que yo hago que no tengas que hacer tú y mira a ver si te sirve.


    domingo, 4 de mayo de 2014 17:54

Todas las respuestas

  • El datagrid que utilizas es solo para añadir los artículos? Lo tienes conectado a un dataSet?

    Yo hace muy poco tuve que hacer un formulario para guardar pedidos y solucioné el problema de la siguiente manera:

    El dataGrid lo hice con las siguientes propiedades:

    Propiedades AllowUserToAdRows, allowuserToDeleteRows, AllowUserToOrderColumns, allowusertoresizerows a False.

    Los artículos los añade el usuario desde otro formulario que se abre al pulsar la tecla + del teclado o al botón añadir que puse en el formulario.

    Le diseñé tres columnas: IdArtículo, nombre, cantidad.

    Los artículos se añaden desde el formulario que te dije antes.

    Lo que hago es que en el constructor de ese formulario le paso un objeto de tipo datagridViewRow y lo igualo a una variable private datagridview que tengo en ese formulario:

    Así:

    Private grdArticulos As DataGridView 'Esto está justo después de la palabra class del formulario que se abre desde el primero.

      Sub New(ByRef grdArticulos As DataGridView)

            InitializeComponent()

            Me.grdArticulos = grdArticulos
        End Sub

    En este formulario el usuario elige el articulo que quiere añadir y le pone la cantidad en texbox, luego al darle al botón aceptar pongo este código:

     If CajasVacias() = False Then
                If txtProducto.ReadOnly = True Then
                    If ogrdFila.Cells(3).Value = "NUEVO" Then
                        ogrdFila.Cells(0).Value = txtProducto.Text
                        ogrdFila.Cells(1).Value = txtDescripcion.Text
                        ogrdFila.Cells(2).Value = txtCantidad.Text
                        Me.Close()
                    Else
                        ogrdFila.Cells(0).Value = txtProducto.Text
                        ogrdFila.Cells(1).Value = txtDescripcion.Text
                        ogrdFila.Cells(2).Value = txtCantidad.Text
                        ogrdFila.Cells(3).Value = "ALMACENADO"
                        Me.Close()
                    End If
                Else
                    If Not ComprobarArticulo() Then
                        Me.grdArticulos.Rows.Add(txtProducto.Text, txtDescripcion.Text, txtCantidad.Text, "NUEVO")
                        Me.Close()
                    Else
                        MessageBox.Show("El artículo ya está añadido al pedido. No se puede añadir otra vez", "Artículo ya añadido", MessageBoxButtons.OK, MessageBoxIcon.Information)
                        txtCantidad.Select()
                    End If
                End If
                End If

    Cajasvacias es una función que comprueba que los texbox no estén vacíos.

    En el datagrid donde muestro los artículos, tengo una columna oculta en la que guardo una cadena con "NUEVO" si el articulo es nuevo o "Almacenado" si el artículo ya estaba guardado en la base de datos antes, y solo quiere modificar la cantidad.

    Después de eso se cierra el formulario y se añade al datagrid del formulario de crearpedido esos datos.

    Luego en ese formulario tendrás un botón para guardar el pedido. En ese botón hago lo siguiente:

     

    'Miramos el número de filas del datagrid, si es mayor o igual que uno quiere decir que tiene artículos.
            If grdArticulos.Rows.Count >= 1 And txtCliente.Text.Length > 0 And txtFecha.Text.Length = 10 Then
                If txtNumPedido.Visible = False Then 'Si este campo no es visible, el pedido es nuevo
                    oPedidos.CargarTablaPedido(poAdaptadorPedidos, poConexion, oDataSet) 'Cargamos en el dataSet la tabla pedidos
                    oTupla = oDataSet.Tables("Pedido").NewRow 'Creamos en la variable una referencia a una fila nueva de la tabla pedidos
                    oTupla("IdCliente") = txtCliente.Text 'Almacenamos en cada campo de la nueva fila su valor
                    oTupla("FechaPedido") = txtFecha.Text
                    oTupla("Impreso") = "False"
                    Try
                        oDataSet.Tables("Pedido").Rows.Add(oTupla) 'Guardamos la nueva fila en la tabla pedidos
                        poAdaptadorPedidos.Update(oDataSet, "Pedido")
                    Catch ex As System.Data.OleDb.OleDbException
                        MessageBox.Show(ex.Message)
                    Catch Ex As Exception
                        MessageBox.Show(Ex.Message)
                    End Try

                    Me.idPedido = Me.UltimoID() 'Obtenemos el último IdPedido insertado en la tabla pedidos
                Else 'Si esta visible es que el pedido ya estaba guardado y se va a modificar
                    Me.idYaPedido = CInt(txtNumPedido.Text) 'Si el campo txtNumPedido esta visible, es que ya estaba guardado el pedido, y por tanto ya sabemos su Id
                End If
                Me.GuardarArticulos()
                oPedidos.MostrarDatos(poAdaptadorPedidos, poConexion, oDataSet) 'Cargamos en el dataSet el nuevo pedido
                If txtNumPedido.Visible = False Then 'Solo refrescamos el grid de pedidos en caso de que se agregue un nuevo pedido
                    grdPedidos.Refresh() 'Refrescamos el datagrid del formulario lista pedidos para que lo muestre al cerrarse la ventana.
                End If
                Me.Close()
            Else
                MessageBox.Show("La fecha, el cliente o el número de artículos es incorrecto. Verifíquelo", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End Sub

        Private Function UltimoID() As Integer 'Esta función devuelve el último ID insertado en la base de datos.

            Using conexion As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Application.StartupPath & "\PanImpres.accdb;Persist Security Info=True")
                conexion.Open()
                Dim sSql As String = "SELECT MAX (IdPedido) As UltimoRegistro FROM Pedidos"
                Dim oComando As New OleDbCommand(sSql, conexion)
                Return CInt(oComando.ExecuteScalar())
            End Using

        End Function

        Private Sub GuardarArticulos()
            Dim lsSql As String = Nothing
            For Each Fila As DataGridViewRow In grdArticulos.Rows 'Bucle que pasa a través de todas las filas del datagrid
                If Fila.Cells("Estado").Value = "NUEVO" Then
                    If txtNumPedido.Visible = False Then
                        lsSql = "INSERT INTO DetallesPedido(IdPedido,IdArticulo,Cantidad)Values('" & idPedido & "','" & Fila.Cells("IdProducto").Value & "' ,'" & Fila.Cells("Cantidad").Value & "')"
                        Me.EjecutarComando(lsSql, poConexion)
                    Else
                        lsSql = "INSERT INTO DetallesPedido(IdPedido,IdArticulo,Cantidad)Values('" & Me.idYaPedido & "','" & Fila.Cells("IdProducto").Value & "' ,'" & Fila.Cells("Cantidad").Value & "')"
                        Me.EjecutarComando(lsSql, poConexion)
                    End If
                End If
                If Fila.Cells("Estado").Value = "ALMACENADO" Then
                    Dim sql As String = "UPDATE DetallesPedido SET Cantidad = '" & Fila.Cells("Cantidad").Value & "' WHERE IdPedido = " & Me.idYaPedido & " AND IdArticulo = " & Fila.Cells("IdProducto").Value & ""
                    Me.EjecutarComando(sql, poConexion)
                End If
            Next
        End Sub

        Private Sub EjecutarComando(ByVal sql As String, ByVal conexion As OleDbConnection)
            Dim oComando As OleDbCommand
            oComando = New OleDbCommand(sql, conexion)
            Try
                conexion.Open()
                oComando.ExecuteNonQuery()
                conexion.Close()
            Catch ex As OleDbException
                MessageBox.Show(ex.Message)
            End Try
        End Sub

    Ese código es el de mi programa, quita lo que yo hago que no tengas que hacer tú y mira a ver si te sirve.


    domingo, 4 de mayo de 2014 17:54
  • hola

    Lo que puedes hacer es controlar que es lo que estaba ya registrado y lo que agrego y no esta en la base de datos.

    Por ejemplo:

    si traes los registros del detalle tienen un id de detalle, si lo agrego y no se guardo en la base no lo tiene, con eso puedes saber que registros nuevos insertar y cuales no.

    En cuanto a la eliminación, al quitar un producto del datagrid lo eliminaría directamente de la base de datos. 
    Si no, deberías crear dos list uno con los datos del detalle originales y otro con los modificados y compararlos.

    Saludos


    Martín Fabregues
    Córdoba, Argentina

    domingo, 4 de mayo de 2014 18:35
  • Hola Joaquín Domingo, Martin Fabregues.
    Gracias por responder y por compartir el código, lo analizaré, ya les avisaré si tengo alguna duda.
    Un abrazo.

    PD: una cosa que me olvidaba, Joaquín al momento de escribir una respuesta, hay una opción que te permite escribir código, para que el código que expongas en tus respuestas sean más legibles.


    domingo, 4 de mayo de 2014 22:40