"This row already belongs to this table" even with new row inside loop - vb.net

I've read previous posts regarding this but there is something else happening that I'm unaware of. All I'm trying to do is insert a new blank row at row 1 and 3. Also I'm pretty sure the row index numbers are wrong since this is going backwards.
Dim dsTemp As System.Data.DataSet
Dim dtTemp As System.Data.DataTable
Dim sheet As OfficeOpenXml.ExcelWorksheet = Nothing
dsTemp = CType(Me.uwgGeneratedMatrix.DataSource, System.Data.DataSet)
dtTemp = dsTemp.Tables(0)
If dsTemp.Tables(0).Columns.Contains("VerticalID") Then
dsTemp.Tables(0).Columns.Remove("VerticalID")
End If
If dsTemp.Tables(0) IsNot Nothing Then
For index As Integer = dsTemp.Tables(0).Rows.Count - 1 To 0 Step -1
Dim dsRow As System.Data.DataRow = dsTemp.Tables(0).Rows(index)
Dim value As Object = dsRow.Item(0)
If Not Microsoft.VisualBasic.IsDBNull(value) AndAlso String.Compare(value.ToString, "ColDes", True) = 0 Then
Dim newRow As System.Data.DataRow = dsTemp.Tables(0).NewRow
dsTemp.Tables(0).Rows.Remove(dsRow)
dsTemp.Tables(0).Rows.InsertAt(dsRow, 0)
dsTemp.Tables(0).NewRow()
dsTemp.Tables(0).Rows.InsertAt(dsRow, 2)
End If
Next
End If

Look at your code:
Dim dsRow As System.Data.DataRow = dsTemp.Tables(0).Rows(index)
'...
If Not Microsoft.VisualBasic.IsDBNull(value) AndAlso String.Compare(value.ToString, "ColDes", True) = 0 Then
Dim newRow As System.Data.DataRow = dsTemp.Tables(0).NewRow
dsTemp.Tables(0).Rows.Remove(dsRow)
dsTemp.Tables(0).Rows.InsertAt(dsRow, 1)
dsTemp.Tables(0).NewRow()
dsTemp.Tables(0).Rows.InsertAt(dsRow, 3)
End If
What is that code doing? Look at each line and actually ask yourself what it does.
First you get an existing row form the table and assign it to the
dsRow variable.
Inside the If block, you create a new row and assign it the
newRow variable. You never use that variable again, so what was the point of that?
You then remove the existing row from the table.
You then insert the existing row as the second row in the table.
You then create a new row and do nothing with it at all, so what was the point of that?
You then try to insert the existing row a second time, as the fourth row in the table.
Is it really unexpected that the error message is telling you that that row already belongs to the table?
For one thing, when you call NewRow, that simply creates a new row. That row is NOT added to the table automatically. How could it be? It's empty and the table may have non-nullable columns. You are supposed to populate it as required and then add it yourself.
Apart from that, you can't add or insert the same row twice.
If all you're trying to do is insert blank rows then you need to actually insert blank rows, not existing rows that you removed. You need to twice call NewRow followed by Insert, e.g.
myTable.Rows.Insert(myTable.NewRow(), 1)
myTable.Rows.Insert(myTable.NewRow(), 3)

I'm dumb, apparently you have to do dsTemp.Tables(0).Rows.InsertAt(newRow, 2)

Related

Compare DataTable and DataGridView and hightlight matching rows in DataGridView

I have a database table which contains a list of usernames and their current active location, an integer called SEQUENCE.
I get this list of sequence numbers into a datatable with a single column (e.g. "SELECT SEQUENCE FROM TABLE"):
dtUsers = CLS_USERS.GetUsers(User)
It excludes the current user, which is why I parse in User.
What I then do is loop through the datatable and for each number I want to set the matching row in a datagridview (which also has a SEQUENCE column) to a different colour. This is my current code:
For Each row As DataRow In dtUsers.Rows
intSeq = row("SEQUENCE")
For Each dgv_row As DataGridViewRow In dgvCandList.Rows
If dgv_row.Cells("CURRENT_SQ").Value = intSeq Then
dgv_row.DefaultCellStyle.BackColor = Color.Cyan
Else
dgv_row.DefaultCellStyle.BackColor = Color.Grey
End If
Next
Next
However, all rows are highlighted rather than just those where dgv_row.Cells("SV_CURRENT_CAND_SQ").Value = intSeq is True... I've verified that this loop is working correctly, so it must be dgv_row.DefaultCellStyle.BackColor = Color.Cyan which is incorrect?
If so, how should I correctly be assigning the row back colour of specific DataGridRow?
EDIT: This code works correctly, my issue was related to bug outside this loop causing the BackColor to be sent for everything, and then never setback to default if where BackColor wasn't being set back to the default if it wasn't in dtUsers.

Deleting and adding items in a table Excel VBA

I've got a problem with filling a table.
The table will be filled with data after a combobox is changed. First off I want to delete the data that's in the table and after that add the data I want.
What I have got is this (This is just a part of the code, the collection is already filled with data)
Dim TableListObject As ListObject
Dim TableObjectRow As ListRow
Dim i As Integer
Dim CollWerknemer as Collection
Set TableListObject = TheSheet.ListObjects(1)
Set TableObjectRow = TableListObject.ListRows.Add
TableListObject.DataBodyRange.Delete
i = 1
For Each vNum In CollWerknemer
TableObjectRow.Range(i, 1) = vNum
i = i + 1
Next vNum
The problem is that it does delete the table but doesn't add anything.
If I exclude the TableListObject.DataBodyRange.Delete from the code it does fill the table with the data that I want, but if I change my combobox the new data will be added at the bottom instead of clearing the table first.
First you could iterate each row in the current table, and remove its content, then use the ListRows.Add
With outTBL
If .ListRows.Count >= 1 Then
.DataBodyRange.Delete
End If
End With
Dim row as ListRow
Set row = outTBL.ListRows.Add
row.Range(x, x) = vNum

Remove A Row From A List Of DataRow

I am using a Dictionary to create a key to a List Of DataRow. I want to iterate through each key and remove rows in the List. This will throw an out of range exception when I explicitly try to remove a row. How can I alter my code to accomplish this?
For Each g As KeyValuePair(Of [String], List(Of DataRow)) In grouped
For Each row As DataRow In g.Value
If CInt(segment(1)) <= 4 Then
'THIS THROWS AN OUT OF RANGE EXCEPTION
g.Value.Remove(row)
End If
Next
Next
I only want to remove specific rows based on criteria. Can someone post an example? I am on an old browser the "add comment" function does not work
Can you show a code example of how to use a predicate based on row.Item("ID") with the RemoveAll function?
I tried this and am getting an exception
g.Value.RemoveAll(Function(l) l.Item(Con.ID) Is l.Item(Con.ID).ToString)
Use List.RemoveAll. Not only will this make the act of removing all of the items easier than trying to remove items in some form of looping construct, but it will be dramatically more efficient as the List can reorganize all of the items once at the end, rather than moving the items down one index at a time over and over.
I figured it out using a reverse For loop. I did not see an examlpe on how to use the RemoveAll. Please post an example if you have time
For i As Integer = g.Value.Count - 1 To 0 Step -1
Dim row As DataRow = CType(g.Value(i), DataRow)
Dim segment() As String = row.Item(c._ID).ToString.Split("-"c)
If CInt(segment(1)) <= 4 Then
g.Value.Remove(row)
End If
Next i

How to search in and edit Table by using DataGridView

I have a SQL database with a table "Employees" in it (with large number of rows). By using DataGridView, I want to search for specific "Employee's Name" and change it's "Job". How can I achieve that. I'm using VB.net. Please Help Me.
Not sure if this will help but write a loop that goes through all the values if it finds a match its true if not it is false ,if found the item can be displayed in a textbox and edited
if not a message is displayed saying "no match found"
the editing part can be done using a procedure that will update the value in your grid with what is entered
i can supply code for this if need be but i am unsure if this is what you wish
and there is most likely a better way of doing it
you can loop through your grid, and check if the data you wish to edit exists using the For loop:
Supposing you are using a textbox as the input, and you use a label to hold the employee ID:
Dim EmpIDColumn as Integer = 'array number of your EmpID Column
Dim EmpNameColumn as Integer = 'The array number of the column where your EmpName is
Dim JobColumn as Integer = 'The array number of your job column
For each dr as Datagridviewrow in Datagridview1.Rows
If dr.cells(EmpNameColumn).value = TxtSearchBox.text Then
txtEmpJob.text = dr.cells(JobColumn).value
lblEmpID.Text = dr.cells(EmpIDColumn).value
End if
Next
Okay, so you've searched the record successfully. Next step (after editing the job, and even other details like the name) would be to update the record in the grid. Remember you set the lblEmpID's text to empID in the column? Use it to find the
Record you wish to change in the grid using the same technique above!
Dim EmpIDColumn as Integer = 'array number of your EmpID Column
Dim EmpNameColumn as Integer = 'The array number of the column where your EmpName is
Dim JobColumn as Integer = 'The array number of your job column
For each dr as Datagridviewrow in Datagridview1.Rows
If dr.cells(EmpIDColumn).value = lblEmpID.text Then
dr.cells(JobColumn).value = txtEmpJob.text
dr.cells(EmpNameColumn).value = txtEmpName.text
'then, type in here your SQL Query Update!
End if
Next

How can I update a row in a DataTable in VB.NET?

I have the following code:
Dim i As Integer = dtResult.Rows.Count
For i = 0 To dtResult.Rows.Count Step 1
strVerse = blHelper.Highlight(dtResult.Rows(i).ToString, s)
' syntax error here
dtResult.Rows(i) = strVerse
Next
I want to add a strVerse to the current row.
What am I doing wrong?
The problem you're running into is that you're trying to replace an entire row object. That is not allowed by the DataTable API. Instead you have to update the values in the columns of a row object. Or add a new row to the collection.
To update the column of a particular row you can access it by name or index. For instance you could write the following code to update the column "Foo" to be the value strVerse
dtResult.Rows(i)("Foo") = strVerse
You can access columns by index, by name and some other ways:
dtResult.Rows(i)("columnName") = strVerse
You should probably make sure your DataTable has some columns first...
Dim myRow() As Data.DataRow
myRow = dt.Select("MyColumnName = 'SomeColumnTitle'")
myRow(0)("SomeOtherColumnTitle") = strValue
Code above instantiates a DataRow. Where "dt" is a DataTable, you get a row by selecting any column (I know, sounds backwards). Then you can then set the value of whatever row you want (I chose the first row, or "myRow(0)"), for whatever column you want.