Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In my application I have a datatable named TB which contains the following columns: BL, PREP, NBLIG, QTY and ERRTYPE. here is an example of data from the table

BL		PREP	NBLIG	QTY		ERRTYPE
125485	P1		5		125		RNF
189654	P2		12		762		RNF
156985	P2		3		36		FNR
219874	P1		36		5423	OTH
123698	P3		6		112		OTH
719736	P1		25		998		RNF


I want, for each PREP, to calculate the number of BL the sum of NBLIG and QTY and the number of each ERRTYPE. Then put this data in a datagridview as following:

PREP	NB_BL	TOTLIG	TOTQTY	TOTRNF	TOTFNR	TOTOTH      
P1		3		66		6546	2		0		1
P2		2		15		798		1		1		0
P3		1		6		112		0		0		1


What I have tried:

Can you help me to find the right method to use in my code?

i'm new in using datatable

thanks
Posted
Updated 11-Jun-18 2:54am
v2

It's quite simple. All what you need to do is to group data by PREP field. Please, check out below solution:

DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[]
	{
		new DataColumn("BL", typeof(int)),
		new DataColumn("PREP", typeof(string)),
		new DataColumn("NBLIG", typeof(int)),
		new DataColumn("QTY", typeof(int)),
		new DataColumn("ERRTYPE", typeof(string))
	});
dt.Rows.Add(new object[]{125485, "P1", 5, 125, "RNF"});
dt.Rows.Add(new object[]{189654, "P2", 12, 762, "RNF"});
dt.Rows.Add(new object[]{156985, "P2", 3, 36, "FNR"});
dt.Rows.Add(new object[]{219874, "P1", 36, 5423, "OTH"});
dt.Rows.Add(new object[]{123698, "P3", 6, 112, "OTH"});
dt.Rows.Add(new object[]{719736, "P1", 25, 998, "RNF"});

var result = dt.AsEnumerable()
	.GroupBy(x=>x.Field<string>("PREP"))
	.Select(grp=>new
	{
		PREP = grp.Key,
		NB_BL = grp.Count(),
		TOTLIG = grp.Where(x=>x.Field<string>("PREP")==grp.Key).Sum(x=>x.Field<int>("NBLIG")),
		TOTQTY = grp.Where(x=>x.Field<string>("PREP")==grp.Key).Sum(x=>x.Field<int>("QTY")),
		TOTRNF = grp.Where(x=>x.Field<string>("ERRTYPE")=="RNF").Count(),
		TOTFNR = grp.Where(x=>x.Field<string>("ERRTYPE")=="FNR").Count(),
		TOTOTH = grp.Where(x=>x.Field<string>("ERRTYPE")=="OTH").Count()
	})
	.ToList();
 
Share this answer
 
Comments
[no name] 11-Jun-18 9:27am    
Thanks a lot
BillWoodruff 5-Oct-20 22:59pm    
+5 Came across this today while doing some research on DataTable.Compute. Great answer.
Maciej Los 6-Oct-20 1:25am    
Thank you very much, Bill.
If this is in a database then you should be able to use SQL COUNT(), AVG() and SUM() Functions[^]

See DataTable Class (System.Data)[^].
 
Share this answer
 
v2
Comments
[no name] 8-Jun-18 8:14am    
No it's not in database
Richard MacCutchan 8-Jun-18 8:34am    
Then you will have to write the code to find all the related items in your table and count them and calculate the totals.
You can use DataTable.Compute method.

Check this link for more information. DataTable.Compute Method (String, String) (System.Data)[^]
 
Share this answer
 
v2
This could be achieved in multiple ways. However, if you want to save your time, I would recommend the use of time-saving LINQ queries.

Here is the function that I have created for you :


public static DataTable BuildPrepData(DataTable sourceData)
        {
            try
            {
                DataTable outTable = new DataTable("PrepData");
                DataColumn[] dataColumn = {
                    new DataColumn("PREP", typeof(string)),
                    new DataColumn("NB_BL", typeof(int)),
                    new DataColumn("TOTLIG", typeof(int)),
                    new DataColumn("TOTQTY", typeof(int)),
                    new DataColumn("TOTRNF", typeof(int)),
                    new DataColumn("TOTFNR", typeof(int)),
                    new DataColumn("TOTOTH", typeof(int))
                };
                outTable.Columns.AddRange(dataColumn);

                var output = sourceData.AsEnumerable()
                    .GroupBy(Prep => Prep.Field<string>("PREP"))
                    .Select(PrepGroup => new
                    {
                        PREP = PrepGroup.Key,
                        NB_BL = PrepGroup.Count(),
                        TOTLIG = PrepGroup.Where(x => x.Field<string>("PREP") == PrepGroup.Key).Sum(x => x.Field<int>("NBLIG")),
                        TOTQTY = PrepGroup.Where(x => x.Field<string>("PREP") == PrepGroup.Key).Sum(x => x.Field<int>("QTY")),
                        TOTRNF = PrepGroup.Where(x => x.Field<string>("ERRTYPE") == "RNF").Count(),
                        TOTFNR = PrepGroup.Where(x => x.Field<string>("ERRTYPE") == "FNR").Count(),
                        TOTOTH = PrepGroup.Where(x => x.Field<string>("ERRTYPE") == "OTH").Count()
                    }).ToList();

                foreach (var dRow in output)
                {
                    DataRow row = outTable.NewRow();
                    row["PREP"] = dRow.PREP;
                    row["NB_BL"] = dRow.NB_BL;
                    row["TOTLIG"] = dRow.TOTLIG;
                    row["TOTQTY"] = dRow.TOTQTY;
                    row["TOTRNF"] = dRow.TOTRNF;
                    row["TOTFNR"] = dRow.TOTFNR;
                    row["TOTOTH"] = dRow.TOTOTH;
                    outTable.Rows.Add(row);
                }

                return outTable;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }


All you need to do here is to utilize this function and provide it with an object of datatable in the format you explained in your question.

BL		PREP	NBLIG	QTY		ERRTYPE
125485	P1		5		125		RNF
189654	P2		12		762		RNF
156985	P2		3		36		FNR
219874	P1		36		5423	OTH
123698	P3		6		112		OTH
719736	P1		25		998		RNF


Please ignore static and console.writeline() as I have just tried to do this using standard console application.

Hope this helps!
 
Share this answer
 
Comments
Maciej Los 11-Jun-18 9:21am    
What your answer differs from mine?
I'd say your linq query is exactly the same as mine! That's why i voted 1.
Nachiket G 11-Jun-18 9:43am    
Yeah, when I started writing my aswer I found myself ending up with almost the same solution. I though why not use good work already done by you. So helped in creating a separate function. I am also voting you the same now. :)
Maciej Los 11-Jun-18 15:56pm    
No comments...
Richard Deeming 12-Jun-18 12:04pm    
Taking somebody else's work and presenting it as your own is known as plagiarism.

We take a very dim view of that here.
Nachiket G 14-Jun-18 6:00am    
Come on guys! Could you not read the part on above comment where I have mentioned of "ending up with almost the same solution"! Yeah I agree that I am suggesting alomost same solution, but if I had to copy I would have used it as is. If you are an experienced professional, in the world of coding two or more people may have same way of thinking and/or writing the code. I would do Nothing but ignore further comments on this issue.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900