Member 14112460 Ответов: 2

Как объединить несколько datatable в один datatable?


Я хочу сравнить несколько файлов с помощью приложения Windows Form в C#. Это коды, которые я пробовал. 3 цикла foreach работают, но когда я добавляю 4-й цикл foreach, он выходит из строя без каких-либо ошибок. Интересно, есть ли какие-то другие методы для объединения нескольких таблиц данных? Я ищу в интернете, что они в основном являются решениями для объединения 2 таблиц данных.

Как вы можете видеть, мне нужно найти разницу между суммами из разных таблиц и провести сравнение.

Пожалуйста, помогите, спасибо!

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

public DataTable Comparison(DataTable A, DataTable B, DataTable C, DataTable D)
    {
        var tableC = new DataTable();

        tableC.Columns.Add(new DataColumn("Location"));
        tableC.Columns.Add(new DataColumn("Item Type"));
        tableC.Columns.Add(new DataColumn("Type"));
        tableC.Columns.Add(new DataColumn("PO Total Cost(Qty Received)"));
        tableC.Columns.Add(new DataColumn("Qty Received Actual Cost"));
        //tableC.Columns.Add(new DataColumn("Total Average Cost (Adjustment)"));
        //tableC.Columns.Add(new DataColumn("Qty Adjusted Average Cost"));
        tableC.Columns.Add(new DataColumn("Amount from FlatFile"));
        tableC.Columns.Add(new DataColumn("Amount (Transaction - Movement)"));
        tableC.Columns.Add(new DataColumn("Amount (Transaction - FlatFile)"));

        foreach (DataRow rowA in A.Rows)
        {
            foreach (DataRow rowB in B.Rows)
            {
                foreach (DataRow rowC in C.Rows)
                {                                                                                                
                    //foreach (DataRow rowD in D.Rows)
                    //{

                    if (rowA["Location"].ToString() == rowB["Location"].ToString() && rowA["Item Type"].ToString() == rowB["Item Type"].ToString() &&
                        rowA["Location"].ToString().Substring(0, 5).Trim() == rowC["Location"].ToString() && rowA["Item Type"].ToString() == rowC["Item_Type"].ToString())
                         //&& rowA["Location"].ToString() == rowD["Location"].ToString() && rowA["Item Type"].ToString() == rowD["Item Type"].ToString()
                         //&& rowB["Location"].ToString() == rowD["Location"].ToString() && rowB["Item Type"].ToString() == rowD["Item Type"].ToString())
                        {
                            var newRow = tableC.NewRow();

                            newRow["Location"] = rowB["Location"];
                            newRow["Item Type"] = rowB["Item Type"];
                            newRow["Type"] = rowC["Type"];
                            if (rowC["Type"].ToString() == "GRN")
                            {
                                newRow["PO Total Cost(Qty Received)"] = rowA["PO Total Cost(Qty Received)"];
                                newRow["Qty Received Actual Cost"] = rowB["Qty Received Actual Cost"];
                                newRow["Amount from FlatFile"] = rowC["Amount"];
                                newRow["Amount (Transaction - Movement)"] = Convert.ToDouble(rowA["PO Total Cost(Qty Received)"]) - Convert.ToDouble(rowB["Qty Received Actual Cost"]);
                                newRow["Amount (Transaction - FlatFile)"] = Convert.ToDouble(rowA["PO Total Cost(Qty Received)"]) - Convert.ToDouble(rowC["Amount"]);
                            }
                            else if (rowC["Type"].ToString() == "STK-ADJ")
                            {
                                //newRow["Qty Adjusted Average Cost"] = rowB["Qty Adjusted Average Cost"];
                                //newRow["Total Average Cost (Adjustment)"] = rowD["Total Average Cost3"];
                            }

                            tableC.Rows.Add(newRow);

                        }
                    }

                //}
            }
        }
        return tableC;
    }

2 Ответов

Рейтинг:
13

Maciej Los

Да, вы можете присоединиться к таблицам с помощью В LINQ[^] и тогда вы сможете сравнивать ряд за рядом.

var resultset = (from d1 in datatable1.AsEnumerable()
    join d2 in datatable2.AsEnumerable() on new {d1.Field<string>("Location"), d1.Field<string>("Item Type")} equals new {d2.Field<string>("Location"), d2.Field<string>("Item Type")} 
    join d3 in datatable3.AsEnumerable()  on new {d1.Field<string>("Location"), d1.Field<string>("Item Type")} equals new {d2.Field<string>("Location"), d2.Field<string>("Item Type")} 
    select new {
        Location = d1.Field<string>("Location"),
        ItemType = d1.Field<string>("Item Type"),
        Type = d1.Field<string>("Type"),
        Cost1 = d1.Field<double>("Cost"),
        Cost2 = d2.Field<double>("Cost"),
        Cost3 = d3.Field<double>("Cost")
    }).ToList();

foreach(var data in resultset)
{
    if (data.Type == "GRN")
    {
        //your logic here
    }
}


Для получения более подробной информации, пожалуйста, смотрите:
Запрос наборов данных (LINQ to DataSet) | Microsoft Docs[^]
Примеры LINQ to DataSet | Microsoft Docs[^]
Создание таблицы данных из запроса (LINQ to DataSet) | Microsoft Docs[^]
101 LINQ Samples in C#[^]


RickZeeland

5d :)

Maciej Los

Спасибо :)

Рейтинг:
1

RickZeeland

Смотрите ответы здесь: Как объединить несколько объектов datatable с другими объектами datatable ?[^]

А здесь: asp.net - слияние таблицы из 3 наборов данных в 1 - переполнение стека[^]

Другой подход состоял бы в том, чтобы сначала создать набор данных это выбирает из таблиц, которые вы хотите, см.: c# - Как заполнить набор данных несколькими таблицами? - переполнение стека[^]


Member 14112460

но в моих файлах excel у меня есть два первичных ключа, мне нужно одно и то же местоположение и тип элемента, а затем получить их количество и найти разницу.

Maciej Los

Пожалуйста, смотрите мой ответ.

Maciej Los

Хорошая попытка, но я думаю, что ОПУ нужно что-то еще. Пожалуйста, посмотри мой ответ, Рик.