Checking if datagridview already exist in another datagridview before inserting using checkbox - vb.net

i have two datagridview and i am trying to insert value in datagridview1 to datagridview2 using checkbox on button click.
For i As Integer = DataGridView1.Rows.Count - 1 To 0 Step -1
Dim c As Boolean
c = DataGridView1.Rows(i).Cells(0).Value
If c = True Then
With DataGridView1.Rows(i)
DataGridView2.Rows.Insert(0, .Cells(0).Value, .Cells(1).Value, .Cells(2).Value, .Cells(3).Value, .Cells(4).Value, .Cells(5).Value)
End With
End If
Next
My code will insert the data everytime i insert it. I want to prevent inserting the same data on datagridview2. As you can see the in the image below everytime i tried to insert the same checkbox i can add it multiple times.
Thank you so much.
This is how i populate my datagridview1.
Sub dgv1_SubjectList()
query = "SELECT subject_id AS '#', subject_name AS 'Descriptive Title', subject_units AS 'Units', sem AS 'Semester', year_level AS 'Year Level' " & _
" FROM subject WHERE course = '" & cmb_Course.Text & "' AND CURRICULUM = '" & curriculum & "' "
da = New MySqlDataAdapter(query, myconn)
da.Fill(ds, "subject")
DataGridView1.DataSource = ds.Tables(0)
DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
End Sub
On datagridview2 i add empty column directly in datagridview2.
Thank you. Sorry for late update.

I tried my best to reproduce your environment.
DataGridView1.AllowUserToAddRows = True
DataGridView2.AllowUserToAddRows = True
DataGridView1.Rows.Insert(DataGridView1.Rows.Count - 1, True, "Row1Col1", "Row1Col2", "Row1Col3", "Row1Col4", "Row1Col5", "Row1Col6")
DataGridView1.Rows.Insert(DataGridView1.Rows.Count - 1, True, "Row2Col1", "Row2Col2", "Row2Col3", "Row2Col4", "Row2Col5", "Row2Col6")
DataGridView2.Rows.Insert(DataGridView2.Rows.Count - 1, False, "Row1Col1", "Row1Col2", "Row1Col3", "Row1Col4", "Row1Col5", "Row1Col6")
For i As Integer = DataGridView1.Rows.Count - 2 To 0 Step -1
If DataGridView1.Rows(i).Cells(0).Value Then
Dim AlreadyInGrid As Boolean = False
Dim ColumnsCount As Integer = DataGridView1.Columns.GetColumnCount(DataGridViewElementStates.Displayed)
For j As Integer = DataGridView1.Rows.Count - 2 To 0 Step -1
For k As Integer = 1 To ColumnsCount - 1
If DataGridView1.Rows(i).Cells(k).Value <> DataGridView2.Rows(j).Cells(k).Value Then Exit For
AlreadyInGrid = (k = ColumnsCount - 1)
Next
If AlreadyInGrid Then Exit For
Next
If Not AlreadyInGrid Then
With DataGridView1.Rows(i)
DataGridView2.Rows.Insert(DataGridView2.Rows.Count - 1, False, .Cells(1).Value, .Cells(2).Value, .Cells(3).Value, .Cells(4).Value, .Cells(5).Value, .Cells(6).Value)
End With
End If
End If
Next

To me it looks like you want to move the row, if that is the case you need not worry about checking if it already exists because it would not be available to try and add it again.
Public Class Form1
Dim ds As New DataSet
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Begin sample setup
ds.Tables.Add(New DataTable With {.TableName = "Table1"})
With ds.Tables(0)
.Columns.Add("Select", GetType(Boolean))
.Columns.Add("ID", GetType(Integer))
.Columns.Add("Column2", GetType(String))
.Rows.Add(False, 1, "test1")
.Rows.Add(False, 2, "test2")
.Rows.Add(False, 3, "test3")
.Rows.Add(False, 4, "test4")
End With
Dim dt As DataTable = ds.Tables(0).Clone
dt.TableName = "Table2"
ds.Tables.Add(dt)
DataGridView1.DataSource = ds.Tables(0)
DataGridView2.DataSource = ds.Tables(1)
'end sample setup
End Sub
Private Sub ButtonAddToDT2_Click(sender As Object, e As EventArgs) Handles ButtonAddToDT2.Click
Validate()
Dim SelRows() As DataRow = ds.Tables(0).Select("Select=True")
For Each DtRow As DataRow In SelRows
ds.Tables(1).ImportRow(DtRow)
ds.Tables(0).Rows.Remove(DtRow)
Next
End Sub
End Class
If it is not your intention to remove the row and you really do want to see if the row exists in datagridview2 let me know and we can make some minor modifications to this code.

Related

vb.net DataGridView prevent user clicking on column

I have a DataGridView (DGV) that I am adding items to from a SQLite DB MANUALLY
My setting for the Selection Mode have been CellSelect and FullRowSelect may have tried others
The Errors and Issues are varied depending on where the user clicks on the DGV
The code as it is now the Errors only occur when an empty Column under Header PID is selected
And when the Column Header PID is selected See Posted Image
I have included the ERRORS as comments in the code
One of the issues I would like to FIX is to disable all sorting on all Columns
The Data added to the DGV is a primary key which is a Integer PID
And some text which is a NVARCHAR(2048) this text is from a RichTextBox
The two biggest issue to fix is preventing the ERRORS YES those are the Questions
Private Sub PopulateDGV()
For Each header As DataGridViewHeaderCell In dgvOne.Rows
'header.SortMode = DataGridViewColumnHeaderCell.NotSortable
Next
'The code Above NOT Working
'ERRORS
'System.InvalidOperationException 'Column's SortMode cannot be set to Automatic
'While the DataGridView control's SelectionMode is set to ColumnHeaderSelect.'
'Your app has entered a break state, but there is no code to show because all
'threads were executing external code (typically system Or framework code).
'dgvOne = DataGridViewColumnSortMode.NotSortable
Dim str2 As String
Dim s1 As Integer
Dim dbName As String = "Word.db"
Dim conn As New SQLiteConnection("Data Source =" & dbName & ";Version=3;")
Dim valuesList As ArrayList = New ArrayList()
'Read from the database
Dim cmd As SQLiteCommand = New SQLiteCommand("Select * FROM ParentTable", conn)
conn.Open()
Dim rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader
'Set Design of the DataGridView
dgvOne.DefaultCellStyle.Font = New Font("Tahoma", 10)
dgvOne.ColumnCount = 2
dgvOne.Columns(0).Width = 60
dgvOne.Columns(1).Width = 420
'Set Col Header Size Mode = Enabled
'Set Col Header Default Cell Styles DO in Properties
dgvOne.ColumnHeadersHeight = 34
'DGV Header Names
dgvOne.Columns(0).Name = "PID"
dgvOne.Columns(1).Name = "Entry Data"
'Read from DB Table add to DGV row
While rdr.Read()
valuesList.Add(rdr(1)).ToString()
lbOne.Items.Add(rdr(1)).ToString()
s1 = rdr(0).ToString
str2 = rdr(1)
dgvOne.Rows.Add(s1, str2)
End While
'Add Blank rows to DGV
For iA = 1 To 4
dgvOne.Rows.Add(" ")
Next
rdr.Close()
conn.Close()
End Sub
Private Sub dgvTwo_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvOne.CellMouseClick
If (e.RowIndex = -1) Then
MessageBox.Show("No Clicking Here")
Return
End If
If dgvOne.CurrentCell.Value Is Nothing Then
tbMessage.Text = "NO Data Here"
Return
ElseIf e.RowIndex >= 0 Then
tbMessage.Text = e.RowIndex
Dim str2 As String
Dim s2 As String
Dim row As DataGridViewRow = dgvOne.Rows(e.RowIndex)
s2 = row.Cells(0).Value.ToString
str2 = row.Cells(1).Value.ToString
strB = str2
rtbEnter.Text = strB
'ERRORS
'System.NullReferenceException
'HResult = 0x80004003
'Message = Object reference Not Set To an instance Of an Object.
'Source = TestSQL
'StackTrace:
'at TestSQL.frmThree.dgvTwo_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e) in C:\Users\Dwight\source\repos\TestSQL\TestSQL\frmThree.vb:line 117
End If
End Sub
To prevent sorting on columns, which appears to be your main question, do the following:
dgvOne.Columns(0).SortMode = DataGridViewColumnSortMode.NotSortable
dgvOne.Columns(1).SortMode = DataGridViewColumnSortMode.NotSortable
You also need to guard against null values in cells. So in the "CellMouseClick" event, add something like this:
If row.Cells(1).Value IsNot Nothing Then
str2 = row.Cells(1).Value.ToString
End If
#Brian M Stafford
Thanks for getting us headed in the correct direction Vector this is easy to figure out if someone would have shared a little information GREAT Questions's guess your were saving bytes
Because you only have three (3) Columns here are their names and positions in the DGV
Col -1 Col 0 Col 1 and YES they go Left to Right
Just So No One Gets Confused Rows go Top to Bottom
Row 0
Row 1
So all you really needed was one more test that delt with ColumnIndex
This code only permits clicking on Column 1 provided it has text in that CELL
Just manipulate the tests and you can provide the user additional selections
Public Sub dgvTwo_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvOne.CellMouseClick
If e.RowIndex = -1 Or e.ColumnIndex = -1 Then
'tbMessage.Text = "Col " & e.ColumnIndex & " ROW " & e.RowIndex
tbMessage.Text = "No Clicking Here"
Return
End If
If dgvOne.CurrentCell.Value Is Nothing Then
tbMessage.Text = "NO Data Here"
Return
End If
Dim s3 As Integer
s3 = e.ColumnIndex
If s3 = 0 Then
'tbMessage.Text = "S3 " & e.ColumnIndex
tbMessage.Text = "No Clicking Here"
Return
End If
Dim row As DataGridViewRow = dgvOne.Rows(e.RowIndex)
Dim col As DataGridViewColumn = dgvOne.Columns(e.ColumnIndex)
If e.RowIndex >= 0 And e.ColumnIndex <> -1 Then
tbMessage.Text = "Data Sent to RTB"
Dim str2 As String
str2 = row.Cells(1).Value.ToString
rtbEnter.Text = str2
End If
End Sub
After reading all the nice answers and looking for a way to accomplish my multitude of issues and a lot of trial and error here is one way to deal with preventing the user from clicking on various location on the DataGridView
Public Sub dgvTwo_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvOne.CellMouseClick
If e.RowIndex = -1 Or e.ColumnIndex = -1 Then
'tbMessage.Text = "Col " & e.ColumnIndex & " ROW " & e.RowIndex
tbMessage.Text = "No Clicking Here"
rtbEnter.Clear()
Return
End If
Dim str1 As String
Dim str2 As String
Dim s1 As Integer
Dim row As DataGridViewRow = dgvOne.Rows(e.RowIndex)
str1 = dgvOne.CurrentRow.Cells(0).Value.ToString
If str1 IsNot " " Then
If str1 Is " " Then
Return
End If
tbMessage.Text = "Text Sent to RTB"
s1 = row.Cells(0).Value
'Dim strInt As String
gv_passInt = s1.ToString
str2 = row.Cells(1).Value.ToString
rtbEnter.Text = str2
gv_passStr = str2
Return
End If
rtbEnter.Clear()
tbMessage.Text = "No Data Here"
End Sub

DataGridView add checkbox and allow to select only records based on variable value via checkbox

In vb.net I have DataGidView showing all columns from my Access database. Then in form Load event I added this code to add check box column to DataGridView.
Dim chk As New DataGridViewCheckBoxColumn()
DataGridView1.Columns.Add(chk)
chk.HeaderText = "Select Question"
chk.Name = "chk"
Here I want user to only select those many records as my maxquestions variable integer value and do not let user select more questions. I also want that user cannot change values of my DataGridView. And thereafter I want to export selected questions to a new table mynewtable already created in database.
Thanks, help appreciated.
I have done something and it somehow works fine...
Private Sub DataGridView1_CellValueChanged(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
If (TryCast(DataGridView1.CurrentCell, DataGridViewCheckBoxCell)) IsNot Nothing Then
Dim count As Integer = 0
For Each row As DataGridViewRow In DataGridView1.Rows
Dim isChecked As Boolean = CBool(row.Cells(6).EditedFormattedValue)
If isChecked Then
count = count + 1
Else
' count -= 1
End If
Next
If count > mark_1_questions Then
Label3.ForeColor = Color.Red
Else
Label3.ForeColor = Color.Black
End If
Label3.Text = "You Have Selected: " & count & " Questions."
If count = mark_11_questions Then
MessageBox.Show(Me, "Maximum/Required Questions Selected : " & mark_11_questions, "Caution")
'DataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically
Button1.Enabled = True
ElseIf count > mark_11_questions Then
MessageBox.Show(Me, "Please unselect some questions : " & count - mark_11_questions, "Caution")
Button1.Enabled = False
Else
End If
End If
End Sub
Now the question is how to export selected records through checkbox to table altogether.
You can get the count like this.
Private Function GetCheckedCount() As Integer
Dim CheckedRows As Integer
For Each row As DataGridViewRow In DataGridView1.Rows
If CBool(row.Cells(8).Value) Then
CheckedRows += 1
End If
Next
Return CheckedRows
End Function

Set DataGridViewComboBoxColumn Value Based on a Datatable

I read several article relating to setting the value of a combobox however I still couldn't come up with a solution.
Below is a basic example of what I want to do and in the comments is exactly what I want to do. Any help is appreciated.
Public Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim dt As New DataTable
dt.Columns.Add("ID")
dt.Columns.Add("Name")
dt.Columns.Add("Value")
dt.Columns(0).AutoIncrement = True
For i As Integer = 0 To 20
Dim R As DataRow = dt.NewRow
R("Name") = "Test" & Date.Now & "" & i
If i = 2 Or i = 5 Or i = 6 Or i = 8 Or i = 10 Then
R("Value") = "yes"
Else
R("Value") = "no"
End If
dt.Rows.Add(R)
DataGridView1.DataSource = dt
Next
DataGridView1.ReadOnly = False
Dim cmb As New DataGridViewComboBoxColumn()
cmb.HeaderText = "Select Data"
cmb.Name = "cmb"
cmb.MaxDropDownItems = 2
cmb.Items.Add("True")
cmb.Items.Add("False")
DataGridView1.Columns.Add(cmb)
For Each dr As DataRow In dt.Rows
If dr("Name").ToString = "Test" Then
'set the combo box value to True
Else
'set the combobox value to False
End If
Next
End Sub
You can set the value by setting the Cells.Value...
DataGridView1.Rows(whatrowdoyouwant).Cells("cmb").Value = True
On another note, you set the DataSource to the DataGridView, but loop through the DataTable. If you want to set each row in the DataGridView this wont work.
For Each dr As DataRow In dt.Rows
If dr("Name").ToString = "Test" Then
'set the combo box value to True
Else
'set the combobox value to False
End If
Next
You would need to loop through each DataGridViewRow in the DataGridView and set the ComboBox value. For example...
For i As Integer = 0 To DataGridView1.Rows.Count - 1
If DataGridView1.Rows(i).Cells("Name").Value.ToString = "Test" Then
DataGridView1.Rows(i).Cells("cmb").Value = True
Else
DataGridView1.Rows(i).Cells("cmb").Value = False
End If
Next

treeview disappeared when i reopen the form

I would like to ask for your help. I am stuck to this for more than two days, I've searched the net but unfortunately got no answer.
I have a program in vb 2008 and a database (SQL Server 2008). I have this form which contains treeview. The items display is selected from the database. When i run the program and open the form the treeview items displayed (at first), but when i closed the form and try to open it again the treeview disappear. I dont know why :( . Why is it disappearing? Can somebody help me please. Thank you.
Below is my code....
#form_load
Private Sub frmProfile_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call conecDB()
Call initCMD()
FillTable()
CreateTree() 'create the treeview node
findNode() 'find and checked the selected nodes that was given to the profile
End Sub
'the functions
Private Sub FillTable()
'tv1.Nodes.Clear()
dtable.Columns.Add("ID", GetType(Integer))
dtable.Columns.Add("NAME", GetType(String))
dtable.Columns.Add("PARENT", GetType(Integer))
dtable.Columns.Add("LEVEL", GetType(Integer))
qSQL = "select mod_id,name,parent,level,sort,mnu_name from module where status='A' and parent!=-1"
With comDB
.CommandText = qSQL
rdDB = .ExecuteReader
End With
Do While rdDB.Read
dtable.Rows.Add(rdDB!mod_id, rdDB!name.ToString(), rdDB!parent)
My.Application.DoEvents()
Loop
For i = 0 To dtable.Rows.Count - 1
Dim ID1 As String = dtable.Rows(i).Item("ID").ToString
dtable.Rows(i).Item("LEVEL") = FindLevel(ID1, 0)
Next
rdDB.Close()
End Sub
Private Function FindLevel(ByVal ID As String, ByRef Level As Integer) As Integer
For i = 0 To dtable.Rows.Count - 1
Dim ID1 As String = dtable.Rows(i).Item("ID").ToString
Dim Parent1 As String = dtable.Rows(i).Item("PARENT").ToString
If ID = ID1 Then
If Parent1 = 0 Then
Return Level
Else
Level += 1
FindLevel(Parent1, Level)
End If
End If
Next
Return Level
End Function
Private Sub CreateTree()
tv1.Nodes.Clear()
Dim MaxLevel1 As Integer = CInt(dtable.Compute("MAX(LEVEL)", ""))
Dim i, j As Integer
For i = 0 To MaxLevel1
Dim Rows1() As DataRow = dtable.Select("LEVEL = " & i)
For j = 0 To Rows1.Count - 1
Dim ID1 As String = Rows1(j).Item("ID").ToString
Dim Name1 As String = Rows1(j).Item("NAME").ToString
'Dim mName As String = Rows1(j).Item("mNAME").ToString
Dim Parent1 As String = Rows1(j).Item("PARENT").ToString
If Parent1 = 0 Then
tv1.Nodes.Add(ID1, Name1)
Else
Dim TreeNodes1() As TreeNode = tv1.Nodes.Find(Parent1, True)
If TreeNodes1.Length > 0 Then
TreeNodes1(0).Nodes.Add(ID1, Name1)
End If
End If
Next
Next
End Sub
Private Sub findNode()
Dim rName As String = String.Empty
Dim b As Boolean = True
qSQL = "select access_id,mnu_name from profile_details where prof_id=" & lblPID.Text & ""
With comDB
.CommandText = qSQL
rdDB = .ExecuteReader
End With
Do While rdDB.Read
rName = rdDB!access_id.ToString()
Try
Dim arr As TreeNode() = tv1.Nodes.Find(rName, b)
For i = 0 To arr.Length - 1
tv1.SelectedNode = arr(i)
tv1.SelectedNode.Checked = True
Next
Catch
MsgBox(Err)
End Try
Loop
rdDB.Close()
End Sub

Click column header

I want to order the items in listview by the time or payment or name I'm use now the combobox but i want to do it from the listview header when i clicked on header column i want the listview sorted by it , i'm use this code with the combo box please help me.
Private Sub OrderBy()
Try
Dim OB As String
If ComboBox1.Text = "ID" Then
OB = "ID"
ElseIf ComboBox1.Text = "Name" Then
OB = "StudentName"
ElseIf ComboBox1.Text = "Payment" Then
OB = "Payment"
ElseIf ComboBox1.Text = "Time" Then
OB = "LessonTime"
ElseIf ComboBox1.Text = "Date" Then
OB = "LessonDate"
End If
Dim dt As New DataTable
Dim ds As New DataSet
ds.Tables.Add(dt)
Dim da As New OleDbDataAdapter("select * from Tend order by " & OB & "", con)
da.Fill(dt)
Dim myrow As DataRow
For Each myrow In dt.Rows
ListView1.Items.Add(myrow.Item(0))
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myrow.Item(1))
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myrow.Item(2))
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myrow.Item(3))
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myrow.Item(4))
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myrow.Item(5))
Next
Explaining better, use the ColumnClick event and use e.Column to know the index of column that was clicked
EDIT: This isn't the best way to do it, but it is the easiest way for you now.
Private Sub OrderBy(Col as Integer)
Try
Dim OB As String
Select Case Col
'Depending on the order of columns in your table
Case 0
OB = "ID"
Case 1
OB = "StudentName"
Case 2
OB = "Payment"
Case 3
OB = "LessonTime"
Case 4
OB = "LessonDate"
End Select
Dim dt As New DataTable
Dim ds As New DataSet
ds.Tables.Add(dt)
Dim da As New OleDbDataAdapter("select * from Tend order by " & OB & "", con)
da.Fill(dt)
ListView1.Items.Clear
For Each myrow As DataRow In dt.Rows
Dim item = ListView1.Items.Add(myrow.Item(0))
item.SubItems.Add(myrow.Item(1))
item.SubItems.Add(myrow.Item(2))
item.SubItems.Add(myrow.Item(3))
item.SubItems.Add(myrow.Item(4))
item.SubItems.Add(myrow.Item(5))
Next
End Try
End Sub
Private Sub ColumnClick(ByVal o As Object, ByVal e As ColumnClickEventArgs) Handles ListView1.ColumnClick
OrderBy(e.Column)
End Sub
I experienced the same problem, I found a Microsoft tutorial in c# and converted to VB.NET a while back.
You can check out my converted open source project on: http://www.sourcecodester.com/visual-basic-net/5415/how-sort-listview-control-column-header-vbnet.html
It shows how to add new items, separated into columns, and you are able to sort the list view, by clicking on the column header. You can also set the default sort method.