Question

I have a question about comparing 2 tables. If in tables 1 doesn't contain column's name from tables 2, add the column with values. So i did it with my code, but don't know why it gives me error that the column already belongs to tables1. What did i do wrong here? Is there any better way to do it?

Example, table1:

Name   LastName
a       aa
b       bb

table2:

Name    Product
s       dd
a       ss

result:

Name   LastName    Product
a       aa         dd
b       bb         ss      

My code:

 for (int i = 0; i < excelTb2.Columns.Count; i++)
                {
                    for (int j = 0; j < Temp.Columns.Count; j++ )
                    {
                        if (Temp.Columns[j].ColumnName.ToString() != excelTb2.Columns[i].ColumnName.ToString())
                        {
                            excelTb2.Columns.Add(Temp.Columns[j].ColumnName.ToString());

                            for (int ok = 0; ok < 2; ok++)
                            {
                                excelTb2.Rows[ok][Temp.Columns[j].ColumnName] = Temp.Rows[ok][j];
                            }

                        }
                    }
                }
Was it helpful?

Solution

Columns is a collection. You could check if the column name is already present using Contains

for (int j = 0; j < Temp.Columns.Count; j++ )
{
    if(!excelTb2.Columns.Contains(Temp.Columns[j].ColumnName))
    {
        excelTb2.Columns.Add(Temp.Columns[j].ColumnName.ToString());
        ...
    }
}

This will remove the need of the nested loop that is the main cause of the error you get

OTHER TIPS

You could use this Merge method which merges the schema of two DataTables and joins data on row-index(if both tables contain a column, the data of table1 will be taken as requested):

public static DataTable MergeOnRowIndex(DataTable table1, DataTable table2)
{
    var data = table1.AsEnumerable()
        .Select((r, i) => new
        {
            Row1 = r,
            Row2 = i >= table2.Rows.Count ? null : table2.Rows[i]
        });
    DataTable table3 = new DataTable();
    foreach (DataColumn col in table1.Columns)
    {
        table3.Columns.Add(col.ColumnName, col.DataType);
    }
    foreach(DataColumn col in table2.Columns)
        if(!table3.Columns.Contains(col.ColumnName))
            table3.Columns.Add(col.ColumnName, col.DataType);

    if(data.Any())
    {
        foreach(var x in data)
        {
            var newRow = table3.Rows.Add();
            for (int i = 0; i < table1.Columns.Count; i++)
            {
                newRow[i] = x.Row1.ItemArray[i];
            }
            if (x.Row2 != null)
            {
                for (int i = table1.Columns.Count; i < table3.Columns.Count; i++)
                {
                    DataColumn currentColumn = table3.Columns[i];
                    newRow[currentColumn.ColumnName] = x.Row2[currentColumn.ColumnName];
                }
            }
        }
    }
    return table3;
}

Here i've used the method to get your desired result on your sample data:

var table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("LastName");
var otherTable = new DataTable();
otherTable.Columns.Add("Name");
otherTable.Columns.Add("Product");
table.Rows.Add("a","aa");
table.Rows.Add("b","bb");
otherTable.Rows.Add("s","dd");
otherTable.Rows.Add("a","ss");

DataTable result = MergeOnRowIndex(table, otherTable);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top