none
Error al ver si existe un registro RRS feed

  • Pregunta

  • Hola, estoy tratando de validar si existe o no un registro en un DGV mediante el campo "Producto".

    Este es el código que tengo en un botón.

       Dim exist As Boolean = DgvVenta.Rows.Cast(Of DataGridViewRow)().Any(Function(row) Convert.ToString(row.Cells("Column1").Value) = Nombre)
                            If Not exist Then
                                DgvVenta.Rows.Add(id, Nombre, Cantidad, PrecioUnitario, Total, GananciaProduc)
                            Else
                                Me.DgvVenta.Rows("Column4").Cells(0).Value = Me.DgvVenta.Rows("Column4").Cells(0).Value + Val(txtcant.Text)
                                Me.DgvVenta.Rows("Column3").Cells(0).Value = Me.DgvVenta.Rows("Column4").Cells(0).Value * DgvVenta.Rows("Column2").Cells(0).Value
                            End If

    Pero al ejecutarlo me aparece el siguiente error al ejecutarse la primer linea, se que el mensaje es claro pero no encuentro la solución.

    "La conversión de "Column4"" a integer no es valida"

    Como podría solucionarlo? o si existe otra manera de validar para que no se repitan los registro es un DGV.

    Saludos!

    viernes, 8 de septiembre de 2017 19:07

Respuestas

  • Federico,

    Se espera que cuando uno toma un código lo primero a hacer sea analizarlo, "destriparlo", tomarse la libertad de discrepar con algunas instrucciones o incluso con todas. Sólo cuando todo está claro se debe tomar como base para aplicarlo a nuestras soluciones, según nuestros requerimientos. Yo imagino que el código que nos adjuntas es el resultado de que no quedo nada claro la propuesta, de hecho noto que no sigues las pautas e insistes en agregar las filas mediante el método Add().

    Si insistes en hacerlo bajo tus formas entonces olvida la clase 'Venta', los datos enlazados y sigue los siguientes lineamientos:

    Dim CurrentRow = DgvProduc.CurrentRow
    
    If CurrentRow IsNot Nothing Then
    	'Entiendo que la columna de índice 0 contiene las celdas con el id del producto
    	Dim Codigo = CurrentRow.Cells(0).Value.ToString
    	'Entiendo que el precio unitario se encuentra también en DgvProduc
    	Dim PrecioUnitario = CurrentRow.Cells("ColPrecioUnitario").Value
    
    	'Busca si ya ha sido registrado el mismo código en DgvVenta
    	'Entiendo que la columna de índice 0 contiene las celdas con el id del producto
    	Dim Fila = DgvVenta.Rows.Cast(Of DataGridViewRow).
    		FirstOrDefault(Function(c) Convert.ToString(c.Cells(0).Value) = Codigo)
    
    	'Sí no existe una referencia se entiende que el producto no ha sido registrado
    	'en consecuencia se agrega la fila
    	If Fila IsNot Nothing Then
    		DgvVenta.Rows.Add(...)
    	Else
    		'Incrementar la cantidad
    		Fila.Cells("Column4").Value = CInt(Fila.Cells("Column4").Value) + CInt(txtCant.Text)
    		'Actualizar el subtotal
    		Fila.Cells("Column3").Value = CInt(Fila.Cells("Column4").Value) * PrecioUnitario		
    	End If
    End If

    Se agradecerá que los identificadores permitan conocer el valor contenido, ¿Column3? ¿Column4?


    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.
    • Marcado como respuesta Federico32113 domingo, 10 de septiembre de 2017 1:56
    sábado, 9 de septiembre de 2017 20:25

Todas las respuestas

  • Hola Federico, estas colocando mal  el Rown y Cell es Me.DgvVenta.Rows(0).Cells("Column4").Value en caso que desees que la primer fila de la columna 4 cambie el valor. Por otro lado no estoy seguro del boolean si fuciona tal cual, poro si así funciona ok. Evalúa también Convert.ToInt32 (Me.Dgv....) si no da como está

    Saludos


    viernes, 8 de septiembre de 2017 20:40
  • Me quedo así

      If DgvVenta.RowCount <> 0 Then
                                For i As Integer = 0 To DgvVenta.RowCount - 1
                                    If Me.DgvVenta.Rows(0).Cells("Column1").Value.ToString.Contains(Nombre) Then
                                        Me.DgvVenta.Rows(0).Cells("Column4").Value = Convert.ToInt16(Me.DgvVenta.Rows(0).Cells("Column4").Value) + CInt(Val(txtcant.Text))
                                        Dim Subtotal As Decimal = Me.DgvVenta.Rows(0).Cells("Column4").Value * Me.DgvVenta.Rows(0).Cells("Column2").Value
                                        Subtotal = CDec(Subtotal).ToString("N2")
                                        Me.DgvVenta.Rows(0).Cells("Column3").Value = Subtotal
                                    Else
                                        DgvVenta.Rows.Add(id, Nombre, Cantidad, PrecioUnitario, Total, GananciaProduc)
                                    End If
                                Next
                            Else
                                DgvVenta.Rows.Add(id, Nombre, Cantidad, PrecioUnitario, Total, GananciaProduc)
                            End If

    Pero no funciona como yo quiero, es decir si agrego un ProductoA a DGVVenta al momento de agregar un ProductoB a los valores de B me los suma a la fila que este seleccionada en DGVentas en este caso ProductoA.

    Como puedo solucionarlo?


    Saludos


    sábado, 9 de septiembre de 2017 16:17
  • ¿En qué manejador de evento estás escribiendo las instrucciones que adjuntas? ¿CellEndEdit? ¿CellValueChanged? ¿CellValidated?, ¿...?. ¿Podrías abrir el contexto del código que adjuntas?


    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.

    sábado, 9 de septiembre de 2017 16:40
  • En el evento Clic de un botón. Es decir cuando se ejecuta el evento el producto que esta en DGVProductos pasa a DGVentas.

    Donde me recomiendas sino? Cual opción me recomiendas de las que puse en el comentario anterior?


    sábado, 9 de septiembre de 2017 16:48
  • Hola Federico, debes replantearte como estructuras el código, no me queda claro todas las variables que actuan en este caso ya que necesitamos más información, pero por lo que veo si quieres pasar datos de un DGV a otro y que valla acumulando no puedes dejar el Rows siempre con indice 0 puesto que rescribirá cada valor en cada bucle y en la misma fila, por otro lado si el nuevo valór B lo escribes a mano y lo agregas tampoco te servirá de mucho el for Next, puedes agregar el nuevo valor tomando como indice del rows  count -1 del DGV Pero insisto que falta información como para ayudarte mejor

    Saludos

    sábado, 9 de septiembre de 2017 18:32
  • La validación es simple: buscar un valor igual y acumular, caso contrario agregar.

    Te recomiendo contener los datos en cualquier colección y que la grilla se ocupe únicamente de mostrarlos, por ejemplo:

    Private Sub btnAddProduct_Click(sender As Object, e As EventArgs) Handles btnAddProduct.Click
    
    	Dim CurrentRow = dgvProductos.CurrentRow
    
    	If CurrentRow IsNot Nothing Then
    		Dim DataSource = CType(dgvVentas.DataSource, List(Of Venta))
    
    		If DataSource Is Nothing Then DataSource = New List(Of Venta)
    
    		Dim ProductCode = CurrentRow.Cells("ProductCode").Value.ToString
    		Dim UnitPrice = Convert.ToDecimal(CurrentRow.Cells("UnitPrice").Value)
    		Dim Quantity = Int32.Parse(txtCantVenta.Text)
    
    		Dim Row = DataSource.FirstOrDefault(Function(c) c.CodigoProducto = ProductCode)
    
    		If Row IsNot Nothing Then
    			Row.Cantidad += Quantity
    		Else
    			DataSource.Add(New Venta() With
    			{
    				.CodigoProducto = ProductCode, .Cantidad = Quantity, .PrecioUnitario = UnitPrice
    			})
    		End If
    
    		dgvVentas.DataSource = Nothing
    		dgvVentas.DataSource = DataSource
    	End If
    
    End Sub

    Si precisas agregar las filas mediante el método Add() de la grilla el proceso es el mismo. 


    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.
    sábado, 9 de septiembre de 2017 18:54
  • Implemente el código brindado al evento clic de un botón por lo que me quedo así:

         Dim CurrentRow = DgvProduc.CurrentRow
                            Dim NombreProducto As String = Me.DgvVenta.Rows(0).Cells("Column1").Value
                            Dim CantProducto = Me.DgvVenta.Rows(0).Cells("Column4").Value
                            Dim PrecioUnitarioProducto = Me.DgvVenta.Rows(0).Cells("Column2").Value
                            Dim Codigo = Me.DgvVenta.Rows(0).Cells("Column5").Value
                            Dim CodigoCurrent = DgvProduc(0, DgvProduc.CurrentRow.Index).Value
                            If CurrentRow IsNot Nothing Then
                                Dim DataSource = CType(DgvVenta.DataSource)
                                Dim Row = DataSource.FirstOrDefault(Function(c) c.CodigoCurrent = Codigo)
                                If Row IsNot Nothing Then
                                    CantProducto = Convert.ToInt16(CantProducto) + CInt(Val(txtcant.Text))
                                    Dim Subtotal As Decimal = CantProducto * PrecioUnitarioProducto
                                    Subtotal = CDec(Subtotal).ToString("N2")
                                    Me.DgvVenta.Rows(0).Cells("Column3").Value = Subtotal
                                    DgvVenta.Rows(0).Cells("Column4").Value = CantProducto
                                Else
                                    DgvVenta.Rows.Add(id, Nombre, Cantidad, PrecioUnitario, Total, GananciaProduc)
                                End If
                            End If
                            DgvVenta.DataSource = Nothing
                            DgvVenta.DataSource = DataSource

    Pero no logre implementarlo del todo... por lo que me aparecen los siguientes errores:

    -Al momento de declarar la variable DataSource: Error 46 Error de sintaxis en el operador de conversión; se necesitan dos argumentos separados por coma.

    -Al momento de declarar la variable Row: error 4  "'DataSource' no está declarado. Puede que esté inaccesible debido a su nivel de protección."

    Como podría solucionarlo? Crees que funcione?

    Disculpa mi ignorancia...


    sábado, 9 de septiembre de 2017 20:11
  • Federico,

    Se espera que cuando uno toma un código lo primero a hacer sea analizarlo, "destriparlo", tomarse la libertad de discrepar con algunas instrucciones o incluso con todas. Sólo cuando todo está claro se debe tomar como base para aplicarlo a nuestras soluciones, según nuestros requerimientos. Yo imagino que el código que nos adjuntas es el resultado de que no quedo nada claro la propuesta, de hecho noto que no sigues las pautas e insistes en agregar las filas mediante el método Add().

    Si insistes en hacerlo bajo tus formas entonces olvida la clase 'Venta', los datos enlazados y sigue los siguientes lineamientos:

    Dim CurrentRow = DgvProduc.CurrentRow
    
    If CurrentRow IsNot Nothing Then
    	'Entiendo que la columna de índice 0 contiene las celdas con el id del producto
    	Dim Codigo = CurrentRow.Cells(0).Value.ToString
    	'Entiendo que el precio unitario se encuentra también en DgvProduc
    	Dim PrecioUnitario = CurrentRow.Cells("ColPrecioUnitario").Value
    
    	'Busca si ya ha sido registrado el mismo código en DgvVenta
    	'Entiendo que la columna de índice 0 contiene las celdas con el id del producto
    	Dim Fila = DgvVenta.Rows.Cast(Of DataGridViewRow).
    		FirstOrDefault(Function(c) Convert.ToString(c.Cells(0).Value) = Codigo)
    
    	'Sí no existe una referencia se entiende que el producto no ha sido registrado
    	'en consecuencia se agrega la fila
    	If Fila IsNot Nothing Then
    		DgvVenta.Rows.Add(...)
    	Else
    		'Incrementar la cantidad
    		Fila.Cells("Column4").Value = CInt(Fila.Cells("Column4").Value) + CInt(txtCant.Text)
    		'Actualizar el subtotal
    		Fila.Cells("Column3").Value = CInt(Fila.Cells("Column4").Value) * PrecioUnitario		
    	End If
    End If

    Se agradecerá que los identificadores permitan conocer el valor contenido, ¿Column3? ¿Column4?


    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.
    • Marcado como respuesta Federico32113 domingo, 10 de septiembre de 2017 1:56
    sábado, 9 de septiembre de 2017 20:25
  • Gracias pude solucionarlo, saludos!!
    domingo, 10 de septiembre de 2017 1:57