Search code examples
vb.netselectdatatabledatagridview

How to DataTable Select for Columns That Are Null in VB.NET


I want to use DataTable Select for mutation from DataGridView source from Datatable to Form2 to DataGridView source from DataTable Form1 but the result in DataGridView in Form1 does not match what maybe there is wrong with my code.

Thanks

result in datagridview form1

DESIRED RESULT in datagridview form1

Column1 Column2 Column3 Column4 Qty
001 TEST1 TEST1 TEST1 1
001 TEST1 TEST1 1
001 TEST1 1
001 TEST1 TEST1 1
002 TEST2 TEST2 TEST2 1

Code in Form1

Public Class Form1
    Private table1 As New DataTable
   Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        table1.Columns.Add(New DataColumn("Column1", GetType(String)))
        table1.Columns.Add(New DataColumn("Column2", GetType(String)))
        table1.Columns.Add(New DataColumn("Column3", GetType(String)))
        table1.Columns.Add(New DataColumn("Column4", GetType(String)))
        table1.Columns.Add(New DataColumn("Qty", GetType(Integer)))
        DataGridView1.DataSource = table1
    End Sub
 Private Sub BTNAdd_Click(sender As Object, e As EventArgs) Handles BTNAdd.Click
        Dim Column2 As String = TextBox2.Text.Trim()
        Dim Column1 = TextBox1.Text.Trim()
        Using frm = New Form2(Column2)

            If frm.ShowDialog() = DialogResult.OK Then
                Dim datarow As DataRow = Nothing
                Dim Column3 = frm.DataGridView1.CurrentRow.Cells(3).Value?.ToString()
                Dim Column4 = frm.DataGridView1.CurrentRow.Cells(4).Value?.ToString()
                If table1.Rows.Cast(Of DataRow).Any() Then
                    datarow = table1.Select($"Column1 = '{Column1}' AND Column2 = '{Column2}' AND Column3 = '{Column3}' OR Column3 IS NULL AND Column4 = '{Column4}' OR Column4 IS NULL").FirstOrDefault()
                End If
                If datarow IsNot Nothing Then
                    Dim qty = If(datarow("Qty") Is DBNull.Value, 0, datarow.Field(Of Integer)("Qty"))
                    datarow.SetField("Qty", qty + 1)
                    Return
                Else
                End If
                Try
                    For Each row2 As DataGridViewRow In frm.DataGridView1.Rows
                        Dim isselect As Boolean = Convert.ToBoolean(row2.Cells("checkboxcolumn").Value)
                        If isselect Then
                            table1.Rows.Add(Column1, Column2, Column3, Column4, 1)
                            TextBox1.Clear()
                            TextBox2.Clear()
                        End If
                    Next
                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try
            Else

                Return
            End If
        End Using
    End Sub
End Class

Code in Form2

Public Class Form2
    Sub New()
        InitializeComponent()
    End Sub
    Public Function ConvertToList(Of T)(ByVal dt As DataTable) As List(Of T)
        Dim columnNames = dt.Columns.Cast(Of DataColumn)().Select(Function(c) c.ColumnName).ToList()
        Dim properties = GetType(T).GetProperties()
        Return dt.AsEnumerable().Select(Function(row)
                                            Dim objT = Activator.CreateInstance(Of T)()
                                            For Each pro In properties
                                                If columnNames.Contains(pro.Name) Then
                                                    Dim pI As PropertyInfo = objT.GetType().GetProperty(pro.Name)
                                                    pro.SetValue(objT, If(row(pro.Name) Is DBNull.Value, Nothing, Convert.ChangeType(row(pro.Name), pI.PropertyType)))
                                                End If
                                            Next pro
                                            Return objT
                                        End Function).ToList()
    End Function

    Public Sub New(Column2 As String)
        Me.New
        Dim table2 As New DataTable("Players")
        table2.Columns.Add(New DataColumn("Column1", GetType(String)))
        table2.Columns.Add(New DataColumn("Column2", GetType(String)))
        table2.Columns.Add(New DataColumn("Column3", GetType(String)))
        table2.Columns.Add(New DataColumn("Column4", GetType(String)))
        table2.Rows.Add("001", "TEST1", "TEST1", "TEST1")
        table2.Rows.Add("001", "TEST1", "TEST1", "")
        table2.Rows.Add("001", "TEST1", "", "")
        table2.Rows.Add("001", "TEST1", "", "TEST1")
        table2.Rows.Add("002", "TEST2", "", "TEST2")
        DataGridView1.DataSource = ConvertToList(Of Table2)(table2)
        Dim CheckedBoxColumn As New DataGridViewCheckBoxColumn
        CheckedBoxColumn.Width = 40
        CheckedBoxColumn.Name = "checkboxcolumn"
        CheckedBoxColumn.HeaderText = "Check"
        DataGridView1.Columns.Insert(0, CheckedBoxColumn)
    End Sub

    Private Sub BtnOK_Click(sender As Object, e As EventArgs) Handles BtnOK.Click
        DialogResult = DialogResult.OK
    End Sub
End Class
Public Class Table2

    Public Property Column1() As String
    Public Property Column2() As String
    Public Property Column3() As String
    Public Property Column4() As String

End Class

Solution

  • Problem solved after I replace the code below :

      If table1.Rows.Cast(Of DataRow).Any() Then
                        datarow = table1.Select($"Column1 = '{Column1}' AND Column2 = '{Column2}' AND Column3 = '{Column3}' AND Column4 = '{Column4}'").FirstOrDefault()
                    End If
                    If datarow IsNot Nothing Then
                        Dim qty = If(datarow("Qty") Is Nothing, 0, datarow.Field(Of Integer)("Qty"))
                        datarow.SetField("Qty", qty + 1)
                        Return
                    Else
                    End If