How can I update a row in a DataTable in VB.NET? - 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.

Related

Reference another cell in the same row having calculated the minimum value in a datatable column

Using VB, I've used the following line to successfully find the minimum value in a specific column (say column 5, where the values are all of double) in a datatable:
Dim test as double
test = datatable.Compute("min(sourcecolumn)", "")
I would now like to refer to the values in other columns (let's say column 2) along the row containing that minimum column value.
Any help would be much appreciated as I can't get my head round it!
Thanks
You can use the DataTable.Select() method to get the row(s) that contain the minimum value. DataTable.Select() returns a DataRow(). In the code below, I assumed only one column contains the minimum value hence Data(0).
Dim test as double
test = datatable.Compute("min(sourcecolumn)", "")
Dim Data() As DataRow = datatable.Select("sourcecolumn = " & test.ToString())
Dim column2 = Data(0)(1)
All you have is a value but you currently have no idea what row(s) contain that value. You can use the table's Select method to get the row(s) that contain that value in that column. Once you have the row(s), you can do whatever you want with it/them:
Dim minValue = CDbl(myDataTable.Compute("MIN(MyColumn)", Nothing))
Dim rows = myDataTable.Select($"MyColumn = {minValue}")
For Each row In rows
'Use row here.
Next
Select always returns an array, even if there is only one row, so the loop will always work. If you know that there will never be more than one match, you can just get the first element directly.

"This row already belongs to this table" even with new row inside loop

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)

Add column to DataGridView (VB.NET)

I would like to add a new column in my project, but a weird thing happened...
My code
adapter.fill(datatable)
dgv.datasource = datatable
dgv.columns.add("test","testHeader")
The column index of test column should be the last index.
However, I found the column index is 0 and the original 0th index turns to 1
I am not sure what happened. Is there any factor could cause this problem?
property settings of datagridview is wrong?
Try This Code For Adding the Column
Dim col As New DataGridViewTextBoxColumn
col.DataPropertyName = "PropertyName"
col.HeaderText = "SomeText"
col.Name = "colWhateverName"
DataGridView1.Columns.Add(col)
It's simple , get the total column count first and then add the column at the end :
Dim col as New DataGridViewColumn
col.HeaderText = "abc"
dgv.Columns.Insert(dgv.ColumnCount, col)
If the above code doesn't help , try adding column to the IDataTable itself :
datatable.Columns.Add("Header text", GetType(System.String)).SetOrdinal(datatable.Columns.Count)
Your code
adapter.fill(datatable)
dgv.datasource = datatable
dgv.columns.add("test","testHeader")
seems to be working properly.
I guess you are re-filling the datagridview that's why the added column is in index 0.
try to add
dgv.DataSource = Nothing
you will notice that the added column "test","testHeader" will be in index 0.
setting again
dgv.datasource = datatable
will cause the added column to remain at index 0 while the datatable will be added to the succeeding columns.
There's a DataGridViewColumn.DisplayedIndex property to control order of visible columns.
Keep in mind that DataGridView tracks theese values and update them for other columns in your grid. Chaning some of them to 0 will update all other columns to highter values.
This works because we clone an existing column while you cannot append a column that does already exist in a table. this also has the benefit of cloning all the column settings applied to the existing columns.
Clone a existing column:
Dim Newtestcolumn As DataGridViewColumn = Existingcolumn.Clone
Adjust header text:
Newtestcolumn.HeaderText = "test"
Add column to datagridview:
DataGridView1.Columns.Add(test)
If you add columns that does not match the current drawing format you need to update the datagridview object by calling:
DataGridView1.Update()
If you want to write to a specific column or you dont know the column name
you use this to return the amount of columns and then point to column 0 for cloning fx.
Dim Index = DataGridView1.Columns.GetColumnCount(DataGridViewElementStates.None)
You specify the column index like this:
DataGridView1.Columns.Item(index)
going back to the first line we would then write
Dim Newtestcolumn As DataGridViewColumn = DataGridView1.Columns.Item(index).clone

VB.Net Fill tables in dataset by data variables

Hi I need to fill a datatable(in data set) row by row by providing the the data by variables in VB.Net. The variables assigns its value by loop.. so the datatable row should be filled row by row until the loop ends. There are three columns in the table. so the table should fill with different kind of datatype variables. pls help.. I need the piece of code...
Sample code to do it:
Inserting a New Record into an Untyped Dataset
Dim newEmployeeRow As DataRow = DtEmployee.Tables("Employee").NewRow()
newEmployeeRow ("EmpNo") = value
newEmployeeRow ("EmpName") = value
newEmployeeRow ("Commission") = value
DtEmployee.Tables("Employee").Rows.Add(newEmployeeRow )
Inserting a New Record into a Typed Dataset
Dim newCustomersRow As NorthwindDataSet.CustomersRow
newCustomersRow = NorthwindDataSet1.Customers.NewCustomersRow()
newCustomersRow.CustomerID = "ALFKI"
newCustomersRow.CompanyName = "Alfreds Futterkiste"
NorthwindDataSet1.Customers.Rows.Add(newCustomersRow)

Get the BindingSource position based on DataTable row

I have a datatable that contains the rows of a database table. This table has a primary key formed by 2 columns.
The components are assigned this way: datatable -> bindingsource -> datagridview. What I want is to search a specific row (based on the primary key) to select it on the grid. I cant use the bindingsource.Find method because you only can use one column.
I have access to the datatable, so I do manually search on the datatable, but how can I get bindingsource row position based on the datatable row? Or there is another way to solve this?
Im using Visual Studio 2005, VB.NET.
I am attempting to add an answer for this 2-year old question. One way to solve this is by appending this code after the UpdateAll method(of SaveItem_Click):
Me.YourDataSet.Tables("YourTable").Rows(YourBindingSource.Position).Item("YourColumn") = "YourNewValue"
Then call another UpdateAll method.
Well, I end up iterating using bindingsource.List and bindingsource.Item. I didnt know but these properties contains the data of the datatable applying the filter and sorting.
Dim value1 As String = "Juan"
Dim value2 As String = "Perez"
For i As Integer = 0 To bsData.Count - 1
Dim row As DataRowView = bsData.Item(i)
If row("Column1") = value1 AndAlso row("Column2") = value2 Then
bsData.Position = i
Return
End If
Next