Click here to Skip to main content
15,888,461 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I had retrieve two excel files from user upload using OleDb. I had produce the following result:

| Location | Item Type | AmountA | AmountB | Type |
|    A     |     A     |    5    |    4    |      |

But I want to produce the following result:
| Location | Item Type | AmountA | AmountB | Type |
|    A     |     A     |    5    |         |   A  |
|    A     |     A     |         |    4    |   B  |


What I have tried:

These are my codes:

C#
public DataTable CombineofAdjustmentNTransaction(DataTable A, DataTable B)
    {
        DataTable TableE = new DataTable();
        TableE.Columns.Add(new DataColumn("Location"));
        TableE.Columns.Add(new DataColumn("Item Type"));
        TableE.Columns.Add(new DataColumn("AmountA)"));
        TableE.Columns.Add(new DataColumn("AmountB"));
        TableE.Columns.Add(new DataColumn("TransactionType"));

        foreach (DataRow dtE in A.Rows)
        {
            foreach (DataRow rowB in B.Rows)
            {
                if (rowB["Location"].ToString() == dtE["Location"].ToString() && rowB["Item Type"].ToString() == dtE["Item Type"].ToString() 
                    )
                {
                    var newRow = TableE.NewRow();
                    newRow["Location"] = dtE["Location"];
                    newRow["Item Type"] = dtE["Item Type"];  

                    if(dtE["Type"].ToString() == "GRN")
                    {
                        newRow["AmountA"] = dtE["AmountA"];
                        newRow["Type"] = "GRN";
                    }

                    if (rowB["Type"].ToString() == "STK_ADJ")
                    {
                        newRow["AmountB"] = rowB["AmountB"];
                        newRow["Type"] = "STK_ADJ";
                    }
                    TableE.Rows.Add(newRow);
                }
            }
        }
        return TableE;
    }
}
Posted
Updated 10-Jan-19 23:25pm
v2
Comments
Wendelius 10-Jan-19 23:32pm    
Can you post an example for the source data. In order to solve the problem, we should see what is the data you're trying to convert from.
jaket-cp 11-Jan-19 4:53am    
Looking at the foreach loops
If first condition true (location and item type match)
when DataTable A row "Type" != "GRN"
and DataTable B row "Type" != "STK_ADJ"
I think a row of following will be produced:
| Location | Item Type | AmountA | AmountB | Type |
| A | A | | | |
Is this what you expect?

Another question:
If first condition true (location and item type match)
when DataTable A row "Type" == "GRN"
you want a row added?
when DataTable B row "Type" == "STK_ADJ"
you want a row added?

If that is the case, when testing for them - add new row for each true condition

1 solution

There's few ways to achieve that:

#1 - using proper Selet statement:
SQL
SELECT *
FROM (
    SELECT Location, [Item Type], AmountA As Amount, "A" AS [Type] FROM [Sheet#1]
    UNION ALL
    SELECT Location, [Item Type], AmountB As Amount, "B" AS [Type] FROM [Sheet#1]
);



#2 - using foreach loop:
C#
foreach(DataRow data in dt.Rows)
{
	foreach(string col in new string[]{"AmountA", "AmountB"})
	{
		DataRow dr = destdt.NewRow();
		dr["Location"] = data["Location"];
		dr["Item Type"] = data["Item Type"];
		dr["Amount"] = data[col];
		dr["Type"] = col.Substring(col.Length-1, 1);
		destdt.Rows.Add(dr);
	}
	
}


#3 - by using Linq Union[^] method + LoadDataRow[^] method to "convert" anonymous data type into DataRow[^]. Note: this solution is very similar to #1, but the main difference is that that below code is executed on client side (in memory) instead of database level.
See:
C#
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[]
	{
		new DataColumn("Location", typeof(string)),
		new DataColumn("Item Type", typeof(string)),
		new DataColumn("AmountA", typeof(int)),
		new DataColumn("AmountB", typeof(int)),
		new DataColumn("Type", typeof(string))
	});
dt.Rows.Add(new object[]{"A", "A", 5, 4, null});

//=====================
//destination table!!!
//=====================
DataTable destdt = new DataTable();
destdt.Columns.AddRange(new DataColumn[]
	{
		new DataColumn("Location", typeof(string)),
		new DataColumn("Item Type", typeof(string)),
		new DataColumn("Amount", typeof(int)),
		new DataColumn("Type", typeof(string))
	});

destdt = dt.AsEnumerable()
	.Select(x=> new 
		{
			Location = x.Field<string>("Location"),
			ItemType = x.Field<string>("Item Type"),
			Amount = x.Field<int>("AmountA"),
			Type = "A",
		})
	.Union(dt.AsEnumerable()
		.Select(x=> new 
			{
				Location = x.Field<string>("Location"),
				ItemType = x.Field<string>("Item Type"),
				Amount = x.Field<int>("AmountB"),
				Type = "B",
			}))
	.Select(x=>destdt.LoadDataRow(new object[]
		{
			x.Location,
			x.ItemType,
			x.Amount,
			x.Type
		}
		, false))
	.CopyToDataTable();

//destdt is ready to use ;)
 
Share this answer
 
v2

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