How to compare 2 dataTable in c# - c#

How can I compare the 2 dataTable in c#
For example
dataTable1
a,a,a,a,1,a,a,a,a,a
a,a,a,a,1,a,a,a,a,a
a,a,a,a,2,a,a,a,a,a
a,a,a,a,2,a,a,a,a,a
a,a,a,a,3,a,a,a,a,a
dataTable2
b,b,b,b,1,b,b,b,b,b
b,b,b,b,1,b,b,b,b,b
b,b,b,b,1,b,b,b,b,b
b,b,b,b,2,b,b,b,b,b
b,b,b,b,2,b,b,b,b,b
How do I run the 1st row in dataTable1 [5] which is = 1, if dataTable2 [5] also consists 1 then print out the line. Continue until finish. Then Continue loop to second one in dataTable1 check with dataTable2
Here is my code
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CompareLinuxWithWindow
{
class Program
{
static void Main(string[] args)
{
DataTable dt1 = ConvertToDataTable(#"C:\Users\manchunl\Desktop\Sample1.txt", 10);
DataTable dt2 = ConvertToDataTable2(#"C:\Users\manchunl\Desktop\Sample2.txt", 10);
foreach (DataRow row in dt1.AsEnumerable())
{
string temp_dt1 = "";
string[] words = temp_dt1.Split(',');
string.Join(",", row.ItemArray.Select(x => x.ToString()));
temp_Linux = (string.Join(",", row.ItemArray.Select(x => x.ToString())));
}
foreach (DataRow row in dt2.AsEnumerable())
{
string temp_dt2 = "";
string.Join(",", row.ItemArray.Select(x => x.ToString()));
temp_dt2 = (string.Join(",", row.ItemArray.Select(x => x.ToString())));
}
Console.WriteLine();
Console.WriteLine("Press enter to exit.");
Console.Read();
}
public static DataTable ConvertToDataTable(string filePath, int numberOfColumns)
{
DataTable tbl = new DataTable();
for (int col = 0; col < numberOfColumns; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
string[] lines = System.IO.File.ReadAllLines(filePath);
foreach (string line in lines)
{
var cols = line.Split(null);
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < numberOfColumns; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
public static DataTable ConvertToDataTable2(string filePath, int numberOfColumns)
{
DataTable tbl = new DataTable();
for (int col = 0; col < numberOfColumns; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
string[] lines = System.IO.File.ReadAllLines(filePath);
foreach (string line in lines)
{
var cols = line.Split(',');
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < numberOfColumns; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
}
}

You can try using the loop as below, please pay attention to comments as those are important
// assumption is that both dt1 and dt2 has same number of rows
// otherise while accessing dt2 we can get index out of range exception
for (int i = 0; i < dt1.Rows.Count; i++)
{
DataRow dr1 = dt1.Rows[i];
DataRow dr2 = dt2.Rows[i];
// accessing the column below would return a system.object variable,
// need to convert it to the right type using one of the convert calls, e.g. Convert.ToInt16(dr1["ColumnName"])
if (dr1["ColumnName"] == dr2["ColumnName"])
{
// do whatever you want to do here
}
}

You can return the data table which will be the difference of two input data table and later you can perform operations on the resulting data table.
CODE
/// <summary>
/// Compare two DataTables and return a DataTable with DifferentRecords
/// </summary>
/// <param name="FirstDataTable">FirstDataTable</param>
/// <param name="SecondDataTable">SecondDataTable</param>
/// <returns>DifferentRecords</returns>
public DataTable getDifferentRecords(DataTable FirstDataTable, DataTable SecondDataTable)
{
//Create Empty Table
DataTable ResultDataTable = new DataTable("ResultDataTable");
//use a Dataset to make use of a DataRelation object
using (DataSet ds = new DataSet())
{
var dataTable = new DataTable[] { FirstDataTable.Copy(), SecondDataTable.Copy() };
dataTable[0].TableName = "FirstTable";
dataTable[1].TableName = "SecondTable";
//Add tables
ds.Tables.AddRange(dataTable);
//Get Columns for DataRelation
DataColumn[] firstColumns = new DataColumn[ds.Tables[0].Columns.Count];
for (int i = 0; i < firstColumns.Length; i++)
{
firstColumns[i] = ds.Tables[0].Columns[i];
}
DataColumn[] secondColumns = new DataColumn[ds.Tables[1].Columns.Count];
for (int i = 0; i < secondColumns.Length; i++)
{
secondColumns[i] = ds.Tables[1].Columns[i];
}
//Create DataRelation
DataRelation r1 = new DataRelation(string.Empty, firstColumns, secondColumns, false);
ds.Relations.Add(r1);
DataRelation r2 = new DataRelation(string.Empty, secondColumns, firstColumns, false);
ds.Relations.Add(r2);
//Create columns for return table
for (int i = 0; i < FirstDataTable.Columns.Count; i++)
{
ResultDataTable.Columns.Add(FirstDataTable.Columns[i].ColumnName,
FirstDataTable.Columns[i].DataType);
}
//If FirstDataTable Row not in SecondDataTable, Add to ResultDataTable.
ResultDataTable.BeginLoadData();
foreach (DataRow parentrow in ds.Tables[0].Rows)
{
DataRow[] childrows = parentrow.GetChildRows(r1);
if (childrows == null || childrows.Length == 0)
{
ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
}
}
//If SecondDataTable Row not in FirstDataTable, Add to ResultDataTable.
foreach (DataRow parentrow in ds.Tables[1].Rows)
{
DataRow[] childrows = parentrow.GetChildRows(r2);
if (childrows == null || childrows.Length == 0)
ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
}
ResultDataTable.EndLoadData();
}
return ResultDataTable;
}

You need to first loop on the first data table
Then get row at specific index
Check whether current row exist in second data table
Get row from second data table at same index.
Read the column value from row to string variable.
Check if both value from both row are equal or not.
DataTable dt1 = ConvertToDataTable(#"C:\Users\manchunl\Desktop\Sample1.txt", 10);
DataTable dt2 = ConvertToDataTable2(#"C:\Users\manchunl\Desktop\Sample2.txt", 10);
for (int i = 0; i < dt1.Rows.Count; i++)
{
DataRow dr1 = dt1.Rows[i];
if (dt2.Rows.Count > i)
{
DataRow dr2 = dt2.Rows[i];
string value1 = Convert.ToString(dr1["Column5"]);
string value2 = Convert.ToString(dr2["Column5"]);
if (!string.IsNullOrEmpty(value1) && !string.IsNullOrEmpty(value2) && value1 == value2)
{
Console.WriteLine(value1);
}
else
{
//Do code when no matched.
}
}
}

Related

How to add a column wise row value in data table from for loop

How to add a row in the data table
Code
DataTable dt = new DataTable();
dt.Clear();
DataColumn dc = new DataColumn("day1", typeof(String));
dt.Columns.Add(dc);
dc = new DataColumn("day2", typeof(String));
dt.Columns.Add(dc);
dc = new DataColumn("day3", typeof(String));
dt.Columns.Add(dc);
tString[0] = "Sat,mon,tue";
tString[1] = "Fri,,wed";
tString[2] = "Thu,";
int lengthA = tString.Length;
for (int i = 0; i <= lengthA - 1; i++)
{
string s = tString[i];
string[] words = s.Split(',');
foreach (string word in words)
{
dt.Rows.Add(word);
}
}
The issue in dt.Rows.Add(word) because it is inserting a row
Expected Output
Datatable value should be
day1, day2, day3
sun,mon,tue
Fri,Wed
Thu
Hot to achieve this, can any one help me
Just create a NewRow() and then add the values to its Item indexer for each column.
for (int i = 0; i <= lengthA - 1; i++)
{
string s = tString[i];
string[] words = s.Split(',');
// here is the new row
var row = dt.NewRow();
for(int w = 0; w < words.Length; w++)
{
// set each column
row[w] = words[w];
}
// don't forget to add the Row to the Rows collection
dt.Rows.Add(row);
}

How to Convert String Data to Data Table in C# asp.net?

So far I have tried to convert DataTable to String as follow:-
public static string convertDataTableToString(DataTable dataTable)
{
string data = string.Empty;
int rowsCount = dataTable.Rows.Count;
for (int i = 0; i < rowsCount; i++)
{
DataRow row = dataTable.Rows[i];
int columnsCount = dataTable.Columns.Count;
for (int j = 0; j < columnsCount; j++)
{
data += dataTable.Columns[j].ColumnName + "~" + row[j];
if (j == columnsCount - 1)
{
if (i != (rowsCount - 1))
data += "$";
}
else
data += "|";
}
}
return data;
}
Now I want to convert returned string into DataTable again.
You can use String.Split to break your string into rows and cells. If the column setup is always the same (as it should be), then you can simply add the columns on your first iteration through the cells.
Here's a simple example:
public static DataTable convertStringToDataTable(string data)
{
DataTable dataTable = new DataTable();
bool columnsAdded = false;
foreach(string row in data.Split('$'))
{
DataRow dataRow = dataTable.NewRow();
foreach(string cell in row.Split('|'))
{
string[] keyValue = cell.Split('~');
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(keyValue[0]);
dataTable.Columns.Add(dataColumn);
}
dataRow[keyValue[0]] = keyValue[1];
}
columnsAdded = true;
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
Alternatively you could get a list of all columns prior to the loop, but this way is likely easier for your purpose.

changing Datatype of DataTable using decimal

I am comparing two Datatables and built a new table
I want to sort the values in the new table since it has -ve values(if not converted to decimal then -ve sign will not be considered)
I want to convert it to Decimal type from string and return the table for sorting. I am getting error as input string is not in correct format how solve this?And sort -ve values in Asc order
private static DataTable CompareTwoDataTable(DataTable table1, DataTable table2)
{
DataTable table3 = new DataTable();
DataRow dr = null;
string filterExp = string.Empty;
for (int i = 0; i < table1.Rows.Count; i++)
{
string col = table1.Rows[i]["Parameter Name"].ToString();
if (table2.Columns.Contains(col))
{
if (!table3.Columns.Contains(col))
{
table3.Columns.Add(col, typeof(string));
filterExp = filterExp + col + " asc ,";
}
for (int j = 0; j < table2.Rows.Count; j++)
{
if (table3.Rows.Count != table2.Rows.Count)
{
dr = table3.NewRow();
table3.Rows.Add(dr);
}
table3.Rows[j][col] = (table2.Rows[j][col].ToString());
}
}
}
DataView dv = new DataView(table3);
filterExp = filterExp.TrimEnd(',');
dv.Sort = filterExp;
table3 = dv.ToTable();
return table3;
}
`
private static DataTable CompareTwoDataTable(DataTable table1, DataTable table2)
{
DataTable table3 = new DataTable();
DataRow dr = null;
string filterExp = string.Empty;
for (int i = 0; i < table1.Rows.Count; i++)
{
string col = table1.Rows[i]["Par Name"].ToString();
if (table2.Columns.Contains(col))
{
if (!table3.Columns.Contains(col))
{
table3.Columns.Add(col, typeof(double));
filterExp = filterExp + col + " asc ,";
}
for (int j = 0; j < table2.Rows.Count; j++)
{
if (table3.Rows.Count != table2.Rows.Count)
{
dr = table3.NewRow();
table3.Rows.Add(dr);
}
table3.Rows[j][col] = table2.Rows[j][col];
}
}
}
`

c# Excelpackage reading cell range into a datatable

Using C# I can manage to read in range of cells using Excel interop. But it's having trouble keeping consistent with dollar values and percentages. So I'm trying out EEPLus.
FileInfo newFile = new FileInfo(#excelFilePath);
ExcelPackage pck = new ExcelPackage(newFile);
var Summary = workbook1.Worksheets[1];
and then using the following
Convert.ToString(Summary.Cells["I35"].Value);
I get a decent value.
But what I would like to do is something the following
Summary.Cells["E29:P32"].Value
and put that into a datatable. There is a method for ImportDataTable but it moves from datatable to excel. Does something similarly simple exist for excel to datatable?
Cheers.
There is no built in method, but you can try something like this:
var range = summary.Cells["E6:G7"];
DataTable tbl = GetDataTableFromRange(range);
and GetDataTableFromRange method:
public static DataTable GetDataTableFromRange(ExcelRange range)
{
DataTable tbl = new DataTable();
tbl.Columns.Add("Column1");
tbl.Columns.Add("Column2");
tbl.Columns.Add("Column3");
int dataTableColumn = 0;
DataRow newRow = null;
int currRow = -1;
foreach (var item in range)
{
if (currRow != item.Start.Row)
{
newRow = tbl.NewRow();
tbl.Rows.Add(newRow);
dataTableColumn = 0;
currRow = item.Start.Row;
}
newRow[dataTableColumn] = item.Value.ToString();
dataTableColumn++;
}
return tbl;
}
You can do like this:
public bool readXLS(string FilePath)
{
FileInfo existingFile = new FileInfo(FilePath);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
//get the first worksheet in the workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int colCount = worksheet.Dimension.End.Column; //get Column Count
int rowCount = worksheet.Dimension.End.Row; //get row count
string queryString = "INSERT INTO tableName VALUES"; //Here I am using "blind insert". You can specify the column names Blient inset is strongly not recommanded
string eachVal = "";
bool status;
for (int row = 1; row <= rowCount; row++)
{
queryString += "(";
for (int col = 1; col <= colCount; col++)
{
eachVal = worksheet.Cells[row, col].Value.ToString().Trim();
queryString += "'" + eachVal + "',";
}
queryString = queryString.Remove(queryString.Length - 1, 1); //removing last comma (,) from the string
if (row % 1000 == 0) //On every 1000 query will execute, as maximum of 1000 will be executed at a time.
{
queryString += ")";
status = this.runQuery(queryString); //executing query
if (status == false)
return status;
queryString = "INSERT INTO tableName VALUES";
}
else
{
queryString += "),";
}
}
queryString = queryString.Remove(queryString.Length - 1, 1); //removing last comma (,) from the string
status = this.runQuery(queryString); //executing query
return status;
}
}
Source: http://sforsuresh.in/read-data-excel-sheet-insert-database-table-c/
I'ill do like this to find the range and store the values in database.
bool hasHeader = true;
using (var pck = new OfficeOpenXml.ExcelPackage(file.InputStream))
{
var ws = pck.Workbook.Worksheets.First();
DataTable tbl = new DataTable();
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
{
if (firstRowCell.Text != "" && firstRowCell.Text != null)
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
else
{
break;
}
}
var startRow = hasHeader ? 2 : 1;
for (int rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
DataRow row = tbl.Rows.Add();
foreach (var cell in wsRow)
{
if (cell.Text != "" && cell.Text != null)
row[cell.Start.Column - 1] = cell.Text;
}
}
}

How to get numbers of rows in sql query?

string query = q;
SqlCommand queryCommand = new SqlCommand(query, Connection);
SqlDataReader queryCommandReader = queryCommand.ExecuteReader();
DataTable dataTable = new DataTable();
dataTable.Load(queryCommandReader);
List<string> rowText = new List<string>();
for (int i = 0; i < 4; i++)
{
foreach (DataColumn columns in dataTable.Columns)
{
rowText.Add(dataTable.Rows[i][columns.ColumnName] + "");
}
}
in this example I get 4 rows from database the condition in for loop i < 4
I wanna get really numbers of rows not just 4
Use foreach for the rows as well
See http://msdn.microsoft.com/en-us/library/system.data.datatable.rows.aspx
foreach(DataRow row in dataTable.Rows)
{
foreach (DataColumn column in dataTable.Columns)
{
rowText.Add( row[column] );
}
}
In your specific example simple replace the the 4 by dataTable.Rows.Count so that you get:
for(int i = 0; i < dataTable.Rows.Count; i++)
{
// ...
}
Or switch to foreach and use the answer of Gaby.

Categories