Getting a subset of DataRows from a DataTable

  • Thread starter Thread starter Nathan Sokalski
  • Start date Start date
N

Nathan Sokalski

I have a DataTable from which I only need a certain range of the DataRows.
What I would like to do is copy a range of rows from one DataTable to a new
DataTable like the following:

For i As Integer = start To last
table1.Rows.Add(table2.Rows(i))
Next

However, the code above gives an error saying the DataRow is already used in
another DataTable. Is there any easy way to copy a DataRow from one
DataTable to another? I tried to use the CopyTo method, but I was having
some trouble doing that. Can somebody help me here?
 
Nathan,

As you use versions later then 2003 you can use very simple use the
Overloaded DataView.ToTable for that.

However you cannot create a table and then add rows. A row exist from items
which are described in the column collection from a table. In the datarow is
stored what table contains the collection, therefore your error message.

Cor
 
Hi Nathan,

Try this method:
table1.Rows.Add(table2.Rows.ItemArray);

--
Miha Markic [MVP C#, INETA Country Leader for Slovenia]
RightHand .NET consulting & developmentwww.rthand.com
Blog:http://cs.rthand.com/blogs/blog_with_righthand/


I have a DataTable from which I only need a certain range of the DataRows.
What I would like to do is copy a range of rows from one DataTable to a new
DataTable like the following:
For i As Integer = start To last
table1.Rows.Add(table2.Rows(i))
Next
However, the code above gives an error saying the DataRow is already used
in another DataTable. Is there any easy way to copy a DataRow from one
DataTable to another? I tried to use the CopyTo method, but I was having
some trouble doing that. Can somebody help me here?


try this (untested):

dim table2 as new datatable

table2 = table1.clone()
for i = start to last
table2.importrow(table1.rows(i))
next

hope this helps
 
diego,

Is this not much easier?
dt2 = dt1.DefaultView.ToTable()

(The defaultview is the default dataview)

Cor
 
Is this not much easier?
dt2 = dt1.DefaultView.ToTable()


No because this wil copy all rows and the TS stated he wanted to have a
subset of the original rows


I just insert the itemarray from the source row in the destination table
this is afaik the shortest way and can be used in a table select or for each
loop without anny problems .

regards

michel
 
Michel,

With the defaultview you can select the rows by the rowfilter and the
columns by the overloading part of the ToTable, can you do it with less
commands?

Cor
 
AFAIK

This wil not work so easy as you tell it Cor as the Totable and then
select method wil return a datarow array

so then you must loop through the datarow array , then another problem
occurs couse the select method returns not a strongly typed datarow so you
must typecast the object
or just asume the datarows are the same and use in your loop construct also
the standard datarow object ,so some more coding is required to get it
functional

and that against this
For i As Integer = start To last

table1.Rows.Add(table2.Rows(i).ItemArray)

Next

i guess is hart to beat in terms of perfomance , readability and used
resources

Or i might be missing something here , always ready to learn something new
so correct me if i am wrong

regards

Michel
 
Michael,

The "DataTable.Select is returning an array of datarows.

The dataview.ToTable is returning a datatable.

You saw my sample, I seldom do this for this kind of messages, but I made it
in the designer, that is impossible if it cannot return a table.

However because it is you I extend it a little bit.

Private Sub Form1_Load(ByVal sender As System .Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

'To create a sample table
Dim dt1 As New DataTable
Dim dtc1 As New DataColumn("Michel")
Dim dtc2 As New DataColumn("Cor")
dt1.Columns.Add(dtc1)
dt1.Columns.Add(dtc2)
For i = 1 To 10
Dim dr As DataRow = dt1.NewRow
dr(0) = i.ToString & i.ToString
dr(1) = i
dt1.Rows.Add(dr)
Next
'End of building Datatable

'Therefore all you need is
dt1.DefaultView.RowFilter = "Michel > 33 And Michel < 66"
Dim dt2 As DataTable = dt1.DefaultView.ToTable(False, "Cor")


'To Show in a Grid
DataGridView1.DataSource = dt2
End Sub

The True would make a distinct table, I used 2008 beta, this overload is in
my mind not in VS2005 I thought that you need in that he new tablename as
first parameter. However you can do it for the rest exactly like this.

:-)

Cor
 
Back
Top