Member 14112460 Ответов: 1

Как создать datatable со следующим результатом?


Я должен был получить два файла excel из загрузки пользователя с помощью OleDb. Я должен был получить следующий результат:

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

Но я хочу получить следующий результат:
| Location | Item Type | AmountA | AmountB | Type |
|    A     |     A     |    5    |         |   A  |
|    A     |     A     |         |    4    |   B  |


Что я уже пробовал:

Это мои коды.:

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;
    }
}

Wendelius

Можете ли вы опубликовать пример для исходных данных. Чтобы решить эту проблему, мы должны посмотреть, какие данные вы пытаетесь преобразовать.

jaket-cp

Глядя на циклы foreach
Если первое условие истинно (местоположение и тип элемента совпадают)
когда DataTable строка "Type" != "GRN"
и DataTable B строка "Type" != "STK_ADJ"
Я думаю, что будет произведен ряд следующих действий:
| Местоположение | Тип Товара | Сумма | Сумма | Тип |
| А | А | | |
Это то, что вы ожидаете?

Другой вопрос:
Если первое условие истинно (местоположение и тип элемента совпадают)
когда DataTable строка "Type" == "GRN"
вы хотите добавить ряд?
когда DataTable B row "Type" == "STK_ADJ"
вы хотите добавить ряд?

Если это так, то при тестировании на них - добавьте новую строку для каждого истинного условия

1 Ответов

Рейтинг:
1

Maciej Los

Есть несколько способов достичь этого:

#1 - использование правильного оператора Selet:

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 - Использование foreach петля:
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 - с помощью Linq Союз[^] метод + LoadDataRow[^] метод "преобразования" анонимного типа данных в объект DataRow[^]. Примечание: это решение очень похоже на #1, но главное отличие заключается в том, что приведенный ниже код выполняется на стороне клиента (в памяти), а не на уровне базы данных.
Видеть:
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 ;)