kenny
kenny

Reputation: 173

Avoid duplicate data in datagridview vb.net

Good morning I have the following question, how can I validate that the record is not duplicated in my datagridview.

this is my code to send data from gridview list to gridview details

   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim rowSelected As List(Of DataGridViewRow) = New List(Of DataGridViewRow)()
    For Each row As DataGridViewRow In dgvlistarproductos.Rows
        Dim cellSelecion As DataGridViewCheckBoxCell = TryCast(row.Cells("SELECCIONAR"), DataGridViewCheckBoxCell)

        If Convert.ToBoolean(cellSelecion.Value) Then
            rowSelected.Add(row)
        End If
    Next

    For Each row As DataGridViewRow In rowSelected
        
            dgvdetalleproduc.Rows.Add(New Object() {row.Cells(1).Value, row.Cells(2).Value
                                                    })
    Next



End Sub

enter image description here

Any suggestion or help I know I have to validate but I don't know where to place it, thanks

Upvotes: 0

Views: 1915

Answers (4)

kenny
kenny

Reputation: 173

Thanks to both of you for giving me an idea of ​​how to solve this case.

I managed to solve and detect if the selected record is repeated or duplicated when passing to the Datagridview with the following code

   Dim existe = False
    Dim rowSelected As List(Of DataGridViewRow) = New List(Of DataGridViewRow)()
    For Each row As DataGridViewRow In dgvlistarproductos.Rows
        Dim cellSelecion As DataGridViewCheckBoxCell = TryCast(row.Cells("SELECCIONAR"), DataGridViewCheckBoxCell)

        If Convert.ToBoolean(cellSelecion.Value) Then
            rowSelected.Add(row)
        End If
    Next

    For Each row As DataGridViewRow In dgvdetalleproduc.Rows
        If Convert.ToString(row.Cells(0).Value).Equals(dgvlistarproductos.CurrentRow.Cells(1).Value) Then
            existe = True
        End If
    Next


    For Each row As DataGridViewRow In rowSelected
        If (existe = True) Then
            MsgBox("ESTE PRODUCTO YA FUE AGREGADO", MsgBoxStyle.OkOnly, "INFORMACIÓN")

        Else
            dgvdetalleproduc.Rows.Add(New Object() {row.Cells(1).Value, row.Cells(2).Value
                                                                })
        End If

    Next

Upvotes: 0

Caius Jard
Caius Jard

Reputation: 74730

The easiest way to do this is to just have both grids use a single data source(datatable) for their info and have a Boolean column in the datatable like "isChosen". Each grid binds to a separate bindingsource or dataview, one of which has its [Row]Filter set to "[isChosen] = True", the other filters for false. The >> button sets the selected row(s)' ischosen to true, the other button sets it false

Because there is only ever one row, and it doesn't "move" anywhere (it just appears in a different grid depending on the value of isChosen) there are no duplicates

To demonstrate this:

  • make a new form
  • put two datagridview on it
  • put two buttons on it
  • put this code in the constructor after InitializeComponent:
    Dim dt as New DataTable
    dt.Columns.Add("Name")
    dt.Columns.Add("IsChosen", GetType(Boolean))
    dt.Rows.Add("John", False)
    dt.Rows.Add("Mark", False)
    dt.Rows.Add("Luke", False)

    Dim bs1 = New BindingSource()
    bs1.Filter = "[IsChosen] = False"
    bs1.DataSource = dt
    dataGridView1.DataSource = bs1

    Dim bs2 = New BindingSource()
    bs2.Filter = "[IsChosen] = True"
    bs2.DataSource = dt
    dataGridView2.DataSource = bs2
  • double click button1 and put code DirectCast(DirectCast(dataGridView1.DataSource, BindingSource).Current, DataRowView)("IsChosen") = True
  • double click button2 and put code DirectCast(DirectCast(dataGridView2.DataSource, BindingSource).Current, DataRowView)("IsChosen") = False

Run the app, click on a name in dgv1 and click button1, it will move to dgv2

You can also toggle the state of the ✅ checkbox column in the grid and it will move - it doesn't matter how the datatable column comes to be True/False to move the row into dgv 2/1 respectively

Upvotes: 1

dr.null
dr.null

Reputation: 4695

If IDPRODUCTO means unique product ID as it sounds then use it to identify and skip the duplicates thru a LINQ query like so:

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim checkedRows = dgvlistarproductos.Rows.Cast(Of DataGridViewRow).
        Where(Function(r1) r1.Cells(0).Value IsNot Nothing AndAlso Convert.ToBoolean(r1.Cells(0).Value)).
        Where(Function(r1) Not dgvdetalleproduc.Rows.Cast(Of DataGridViewRow).
        Any(Function(r2) r2.Cells(0).Value IsNot Nothing AndAlso r2.Cells(0).Value.ToString().
        Equals(r1.Cells(1).ToString(), StringComparison.OrdinalIgnoreCase)))

    For Each row In checkedRows
        dgvdetalleproduc.Rows.Add(row.Cells(1).Value, row.Cells(2).Value)
    Next
End Sub

You can use the columns names rather than their indices to get the cells values.

Upvotes: 0

user16653463
user16653463

Reputation:

Try placing your validation code in the RowValidating event of the DataGridView control, or try this code below:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim rowSelected As List(Of DataGridViewRow) = New List(Of DataGridViewRow)()

    For Each row As DataGridViewRow In dgvlistarproductos.Rows
        Dim cellSelecion As DataGridViewCheckBoxCell = TryCast(row.Cells("SELECCIONAR"), DataGridViewCheckBoxCell)

        If Convert.ToBoolean(cellSelecion.Value) Then
            rowSelected.Add(row)
        End If
    Next
    For Each row As DataGridViewRow In rowSelected
        If dgvdetalleproduc.Rows.Contains(row) = False Then
            dgvdetalleproduc.Rows.Add(New Object() {row.Cells(1).Value, row.Cells(2).Value})
        End If
    Next
End Sub

Upvotes: 0

Related Questions