Insert a new row into DataTable - c#

I have a datatable filled with staff data like..
Staff 1 - Day 1 - Total
Staff 1 - Day 2 - Total
Staff 1 - Day 3 - Total
Staff 2 - Day 1 - Total
Staff 2 - Day 2 - Total
Staff 2 - Day 3 - Total
Staff 2 - Day 4 - Total
I want to modify so that the result would be sth like..
Staff 1 - Day 1 - Total
Staff 1 - Day 2 - Total
Staff 1 - Day 3 - Total
Total - - Total Value
Staff 2 - Day 1 - Total
Staff 2 - Day 2 - Total
Staff 2 - Day 3 - Total
Staff 2 - Day 4 - Total
Total - - Total Value
to be concluded, I need to insert the total row at the end of each staff record.
So, my question is how to insert a row into a datatable? Tkz..

#William You can use NewRow method of the datatable to get a blank datarow and with the schema as that of the datatable. You can populate this datarow and then add the row to the datatable using .Rows.Add(DataRow) OR .Rows.InsertAt(DataRow, Position). The following is a stub code which you can modify as per your convenience.
//Creating dummy datatable for testing
DataTable dt = new DataTable();
DataColumn dc = new DataColumn("col1", typeof(String));
dt.Columns.Add(dc);
dc = new DataColumn("col2", typeof(String));
dt.Columns.Add(dc);
dc = new DataColumn("col3", typeof(String));
dt.Columns.Add(dc);
dc = new DataColumn("col4", typeof(String));
dt.Columns.Add(dc);
DataRow dr = dt.NewRow();
dr[0] = "coldata1";
dr[1] = "coldata2";
dr[2] = "coldata3";
dr[3] = "coldata4";
dt.Rows.Add(dr);//this will add the row at the end of the datatable
//OR
int yourPosition = 0;
dt.Rows.InsertAt(dr, yourPosition);

// get the data table
DataTable dt = ...;
// generate the data you want to insert
DataRow toInsert = dt.NewRow();
// insert in the desired place
dt.Rows.InsertAt(toInsert, index);

// create table
var dt = new System.Data.DataTable("tableName");
// create fields
dt.Columns.Add("field1", typeof(int));
dt.Columns.Add("field2", typeof(string));
dt.Columns.Add("field3", typeof(DateTime));
// insert row values
dt.Rows.Add(new Object[]{
123456,
"test",
DateTime.Now
});

In c# following code insert data into datatable on specified position
DataTable dt = new DataTable();
dt.Columns.Add("SL");
dt.Columns.Add("Amount");
dt.rows.add(1, 1000)
dt.rows.add(2, 2000)
dt.Rows.InsertAt(dt.NewRow(), 3);
var rowPosition = 3;
dt.Rows[rowPosition][dt.Columns.IndexOf("SL")] = 3;
dt.Rows[rowPosition][dt.Columns.IndexOf("Amount")] = 3000;

You can do this, I am using
DataTable 1.10.5
using this code:
var versionNo = $.fn.dataTable.version;
alert(versionNo);
This is how I insert new record on my DataTable using row.add (My table has 10 columns), which can also includes HTML tag elements:
function fncInsertNew() {
var table = $('#tblRecord').DataTable();
table.row.add([
"Tiger Nixon",
"System Architect",
"$3,120",
"2011/04/25",
"Edinburgh",
"5421",
"Tiger Nixon",
"System Architect",
"$3,120",
"<p>Hello</p>"
]).draw();
}
For multiple inserts at the same time, use rows.add instead:
var table = $('#tblRecord').DataTable();
table.rows.add( [ {
"Tiger Nixon",
"System Architect",
"$3,120",
"2011/04/25",
"Edinburgh",
"5421"
}, {
"Garrett Winters",
"Director",
"$5,300",
"2011/07/25",
"Edinburgh",
"8422"
}]).draw();

Related

Get count of occurrence of certain value in DataTable column

I am creating a DataTable dynamically, NOT from SQL. I need to count the number of times the value of '0' appears in the 'testresult' column. So far everything I've tried returns a count of 0, even though the table has 1 entry of '0' in the testresult column. HELP! :)
I've tried:
1)
DataRow[] rows = dtMerged.Select("testresult Like '%0%'");
int rowcount = rows.Length;
int rowcount = dtMerged.Select("testresult = 0").Count();
int rowcount = Convert.ToInt32(dtMerged.Compute("Count(testresult)", "testresult Like '%0%'"));
var rowcount = dtMerged.AsEnumerable()
.GroupBy(r => r.Field<string>("testresult"))
.Select(r => new
{
Str = r.Key,
Count = r.Count()
});
All of these options give me a rowcount of '0' except number 4, which resulted in a value of 'null'. Here is an image of the DataTable in question.
Thanks!
Here is a sample of code that will create essentially the same DataTable that I'm working with, my creation method is a bit complicated for copy/pasting:
DataTable dtMerged= new DataTable();
dtMerged.Columns.Add("ID", typeof(int));
dtMerged.Columns.Add("hbserial", typeof(string));
dtMerged.Columns.Add("testresult", typeof(string));
dtMerged.Rows.Add(0, "testhashboard1", "1");
dtMerged.Rows.Add(1, "samplehashboard1", "1");
dtMerged.Rows.Add(2, "samplehashboard2", "0");
return dtMerged;
//Attempt 1
DataRow[] rows = dtMerged.Select("testresult Like '%0%'");
int rowcount = rows.Length;
//Attempt 2
int rowcount = dtMerged.Select("testresult = 0").Count();
//Attempt 3
int rowcount = Convert.ToInt32(dtMerged.Compute("Count(testresult)", "testresult Like '%0%'"));
//Attempt 4
var rowcount = dtMerged.AsEnumerable()
.GroupBy(r => r.Field<string>("testresult"))
.Select(r => new
{
Str = r.Key,
Count = r.Count()
});

Group and Sum DataTable

I have Data Table with the following data
Number Type Order count
1 1 R 1
1 1 R 1
1 1 R 1
1 2 R 1
I am looking to get to this result
Number Type Order count
1 1 R 3
1 2 R 1
How can I group by three columns
var result = dt.AsEnumerable()
.GroupBy(x => {x.Field<string>("Number"))//need to group by Type and order also need to sum te total counts
rgoal
Your question made me curious, so I did some digging on Stack Overflow.
esc's answer appears will also solve your issue. It is posted under: How do I use SELECT GROUP BY in DataTable.Select(Expression)?:
Applying his method to your problem gave me this solution:
DataTable dt2 = dt.AsEnumerable()
.GroupBy(r => new { Number = r["Number"], Type = r["Type"], Order = r["Order"] })
.Select(g =>
{
var row = dt.NewRow();
row["Number"] = g.Key.Number;
row["Type"] = g.Key.Type;
row["Order"] = g.Key.Order;
row["Count"] = g.Count();
return row;
}).CopyToDataTable();
This will return a DataTable matching the schema of the input DataTable with the grouping and counts you requested.
Here is the full code I use to verify in LINQPad:
DataTable dt = new DataTable("Demo");
dt.Columns.AddRange
(
new DataColumn[]
{
new DataColumn ( "Number", typeof ( int ) ),
new DataColumn ( "Type", typeof ( int ) ),
new DataColumn ( "Order", typeof ( string ) ),
new DataColumn ( "Count", typeof ( int ) )
}
);
dt.Rows.Add(new object[] { 1,1,"R", 1 });
dt.Rows.Add(new object[] { 1,1,"R", 1 });
dt.Rows.Add(new object[] { 1,1,"R", 1 });
dt.Rows.Add(new object[] { 1,2,"R", 1 });
DataTable dt2 = dt.AsEnumerable()
.GroupBy(r => new { Number = r["Number"], Type = r["Type"], Order = r["Order"] })
.Select(g =>
{
var row = dt.NewRow();
row["Number"] = g.Key.Number;
row["Type"] = g.Key.Type;
row["Order"] = g.Key.Order;
row["Count"] = g.Count();
return row;
}).CopyToDataTable();
foreach (DataRow row in dt2.Rows)
{
for (int i = 0; i < dt2.Columns.Count; i++)
Console.Write("{0}{1}",
row[i], // Print column data
(i < dt2.Columns.Count - 1)? " " : Environment.NewLine); // Print column or row separator
}
Here are the results:
1 1 R 3
1 2 R 1

Sort datatable based on value in the column

I have a datatable,
PId PName Qty
123 XYZ 2
223 ABC 4
434 PQR 33
I want to sort it on "PName" but not asc/ desc order,
If I pass PName as "PQR", then PQR should come first and then rest of the rows,
same if I pass "ABC" then "ABC" should come first and then rest of the rows.
Basically wants to reshuffle the rows where first row should be the "PName" which I am holding in a variable.
Thanks
Desired output
If I have "ABC", then the above datatable should reshuffle as,
PId PName Qty
223 ABC 4
123 XYZ 2
434 PQR 33
If I have "PQR", then the above datatable should reshuffle as,
PId PName Qty
434 PQR 33
123 XYZ 2
223 ABC 4
DataTable dt = new DataTable();
dt.Columns.Add("PId", typeof(Int32));
dt.Columns.Add("PName", typeof(string));
dt.Columns.Add("Qty", typeof(Int32));
dt.Rows.Add(123, "XYZ", 2);
dt.Rows.Add(223, "ABC", 4);
dt.Rows.Add(434, "PQR", 33);
var stkLists = dt.AsEnumerable().ToList();
var matchList = stkLists.Where(m => m["PName"].ToString().StartsWith("PQR")).ToList();
var FinalList = matchList.Concat(stkLists.Except(matchList).ToList());
Try like this:
DataTable dt = new DataTable();
dt.Columns.Add("PId", typeof(Int32));
dt.Columns.Add("PName", typeof(string));
dt.Columns.Add("Qty", typeof(Int32));
dt.Rows.Add(123, "XYZ", 2);
dt.Rows.Add(223, "ABC", 4);
dt.Rows.Add(434, "PQR", 33);
string Name = "PQR";
DataTable newDt = dt.Rows.Cast<DataRow>().Where(r => r.ItemArray[1] == Name).CopyToDataTable();
dt = dt.Rows.Cast<DataRow>().Where(r => r.ItemArray[1] != Name).CopyToDataTable();
newDt.Merge(dt);

slice a datatable for daterange , sum up counts and create a custom table?

Is there any easy way to slice a datatable for a range and sum up counts for a range?
let say I have below datatable
Date Count
5/9/2016 5
5/10/2016 1
5/11/2016 2
5/12/2016 4
5/13/2016 3
5/14/2016 2
5/15/2016 1
5/16/2016 4
If I slice it by 2 then it will club 2 rows ..something like
DateRange Count
5/9/2016-5/10/2016 6
5/11/2016-5/12/2016 6
5/13/2016-5/14/2016 5
5/15/2016-5/16/2016 5
If I slice it by 3 then it will club 3 rows ..something like
DateRange Count
5/9/2016-5/11/2016 8
5/12/2016-5/14/2016 9
5/15/2016-5/16/2016 5
I am trying to show my data in a asp:Chart (StackedColumn) chart for a date range. date range varies between 7,15,30,60,90,150,365 days ..almost each day there are some data entries and there are a custom date control to select date also . let say a user select a date range for 200 days , for 200 days their will 200 records . now is there any way to club up the data and show in that chart .Currently I am trying to do it by month but as I know there are a custom date range so I need to come up with a different workaround , any help on it .
public DataTable GetTable()
{
// Here we create a DataTable with four columns.
DataTable table = new DataTable();
table.Columns.Add("Date", typeof(DateTime));
table.Columns.Add("R", typeof(int));
table.Columns.Add("C", typeof(int));
// Here we add five DataRows.
for (int i = 0; i <= dayschunk; i++)
{
table.Rows.Add(DateTime.Now.Date.AddDays(-i).ToString("MMM-dd"), new Random().Next(0, 99), new Random().Next(0, 99));
}
var results = from row in table.AsEnumerable()
group row by new { Date = row.Field<DateTime>("Date").Month } into rowgroup
select new
{
rowgroup.Key.Date,
Remidiated = rowgroup.Sum(r => r.Field<int>("R")),
Stucked = rowgroup.Sum(r => r.Field<int>("C"))
};
DataTable filtered = new DataTable();
filtered.Columns.Add("DateRange", typeof(int));
filtered.Columns.Add("R", typeof(int));
filtered.Columns.Add("C", typeof(int));
foreach (var item in results)
{
table.Rows.Add(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(item.Date), item.Remidiated, item.Stucked);
}
//table.Rows.Add(2,new DateTime(2016, 05, 02), 50, 50);
//table.Rows.Add(2,new DateTime(2016, 05, 07), 3, 4);
//table.Rows.Add(2,new DateTime(2016, 05, 05), 16, 10);
return filtered;
}
You could do this using Select overload to pass an index and creating chunks with the given size.
DataTable result = new DataTable();
result.Columns.Add("DateRange", typeof(string));
result.Columns.Add("Count", typeof(int));
int chunk = 2;
result = table.AsEnumerable()
.Select((row,i) => new {gid= i/chunk, row})
.GroupBy(x=>x.gid)
.Select(x=>
{
var row= result.NewRow();
row["DateRange"] = string.Format("{0}-{1}", x.First().row.Field<DateTime>("Date"), x.Last().row.Field<DateTime>("Date"));
row["Count"]= x.Sum(r=>r.row.Field<int>("R"));
return row;
}).CopyToDataTable<DataRow>();
Check this Example
Note: I have not applied output formatting, but you could this easily and I will leave it to you.

How to Compare Two dataTable and Update non matched rows in a DataTable which gives the resultDataTable?

MasterData
Id Name
1 CENTRAL
2 EAST
3 EAST CENTRAL
4 EAST COASTAL
5 NORTH
6 NORTH WEST
7 SOUTH
8 SOUTH CENTRAL
9 WEST
Data Received
Id Name Value
1 CENTRAL 125.65
5 NORTH 553.21
i want the Result to be as followes
Id Name Value
1 CENTRAL 125.65
2 EAST 0.0
3 EAST CENTRAL 0.0
4 EAST COASTAL 0.0
5 NORTH 553.21
6 NORTH WEST 0.0
7 SOUTH 0.0
8 SOUTH CENTRAL 0.0
9 WEST 0.0
Please note all are Datatable how can i Get the Result
Let say your DataTable are declared as following:
var dt1 = new DataTable();
dt1.Columns.Add(new DataColumn("Id", typeof(int)));
dt1.Columns.Add(new DataColumn("Name", typeof(string)));
var dt2 = new DataTable();
dt2.Columns.Add(new DataColumn("Id", typeof(int)));
dt2.Columns.Add(new DataColumn("Name", typeof(string)));
dt2.Columns.Add(new DataColumn("Value", typeof(double)));
You can join it and get what you want with LINQ to objects:
var query = from r1 in dt1.AsEnumerable()
join r2 in dt2.AsEnumerable() on r1.Field<int>("Id") equals r2.Field<int>("Id") into r3
from r4 in r3.DefaultIfEmpty()
select new
{
Id = r1.Field<int>("Id"),
Name = r1.Field<string>("Name"),
Value = r4 == null ? 0.00 : r4.Field<double>("Value")
};
With that IEnumerable<Anonymous_Type> you can get DataTable object back, using ToDataTable<T> extension method:
public static class EnumerableToDataTableConverter
{
public static DataTable ToDataTable<T>(this IEnumerable<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
//Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
//Setting column names as Property names
dataTable.Columns.Add(prop.Name);
}
foreach (T item in items)
{
var newRow = dataTable.NewRow();
for (int i = 0; i < Props.Length; i++)
{
//inserting property values to datatable rows
newRow[Props[i].Name] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(newRow);
}
//put a breakpoint here and check datatable
return dataTable;
}
}
You can get DataTable from query with following statement:
var result = query.ToDataTable();

Categories