背景信息:基本上我正在编写一个程序,允许用户将两个excel文件加载到程序中,以便比较它们并轻松指出差异。 excel数据存储在每个excel文件的dataTable中。 dataTables具有以下字段:名称,IP地址,机箱名称,占用插槽等。 excel文件表示来自数据中心的每周数据转储。一个excel文件代表当前周,另一个代表前一周。我已经实现了一些方法来确定在两个excel文件之间删除或添加了哪些条目。
我的问题是实现一种检查行内数据变化的方法。名称列将是关键,其余列将是比较的基础,但是我需要动态实现它,因为excel格式可能会每周更改,例如为新信息添加新列。
我需要它做的是比较具有匹配名称的每个dataTable的行,并将相应的行添加到新的dataTable(如果它们不相等)。我不知道如何以动态方式执行此操作以考虑列数的潜在变化。
非常感谢任何帮助!
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.OleDb;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelComparator
{
public partial class ExcelComparatorGUI : Form
{
String prevFileName;
String currFileName;
BindingSource bsPrev;
BindingSource bsCurr;
BindingSource bsRemoved;
BindingSource bsAdded;
BindingSource bsChanged;
DataTable prevDataTable;
DataTable currDataTable;
DataTable removedDataTable;
DataTable addedDataTable;
DataTable changedDataTable;
public ExcelComparatorGUI()
{
InitializeComponent();
}
private void compareButton_Click(object sender, EventArgs e)
{
this.addPreviousData();
this.addCurrentData();
this.addRemovedData();
this.addAddedData();
//this.addChangedData();
this.addSearchTypes(this.prevDataGridView);
this.searchTypeComboBox.Enabled = true;
}
private void addRemovedData()
{
string prevCol0 = this.prevDataGridView.Columns[0].HeaderText;
string currCol0 = this.currDataGridView.Columns[0].HeaderText;
var itemsNotInCurr = prevDataTable.AsEnumerable().Select(r => r.Field<string>(prevCol0)).Except(currDataTable.AsEnumerable().Select(r => r.Field<string>(currCol0)));
try
{
removedDataTable = (from row in prevDataTable.AsEnumerable()
join name in itemsNotInCurr
on row.Field<string>(prevCol0) equals name
select row).CopyToDataTable();
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.ToString());
}
bsRemoved = new BindingSource();
bsRemoved.DataSource = removedDataTable;
this.removedDataGridView.DataSource = bsRemoved;
}
private void addAddedData()
{
string prevCol0 = this.prevDataGridView.Columns[0].HeaderText;
string currCol0 = this.currDataGridView.Columns[0].HeaderText;
var itemsNotInPrev = currDataTable.AsEnumerable().Select(r => r.Field<string>(currCol0))
.Except(prevDataTable.AsEnumerable().Select(r => r.Field<string>(prevCol0)));
try
{
addedDataTable = (from row in currDataTable.AsEnumerable()
join name in itemsNotInPrev
on row.Field<string>(currCol0) equals name
select row).CopyToDataTable();
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.ToString());
}
bsAdded = new BindingSource();
bsAdded.DataSource = addedDataTable;
this.addedDataGridView.DataSource = bsAdded;
}
private void addChangedData()
{
//IMPLEMENT NEXT
}
private void addPreviousData()
{
this.addData(this.prevDataGridView, this.prevFileName);
this.prevDataTable = (DataTable)this.prevDataGridView.DataSource;
this.bsPrev = new BindingSource();
this.bsPrev.DataSource = prevDataTable;
this.prevDataGridView.DataSource = bsPrev;
}
private void addCurrentData()
{
this.addData(this.currDataGridView, this.currFileName);
this.currDataTable = (DataTable)this.currDataGridView.DataSource;
this.bsCurr = new BindingSource();
this.bsCurr.DataSource = currDataTable;
this.currDataGridView.DataSource = bsCurr;
}
private void addData(DataGridView destination, String fileName)
{
try
{
OleDbConnection MyConnection;
DataSet DtSet;
OleDbDataAdapter MyCommand;
MyConnection = new OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + fileName + "';Extended Properties=Excel 8.0;");
MyCommand = new OleDbDataAdapter("select * from [" + this.GetExcelSheetNames(fileName)[0] + "]", MyConnection);
MyCommand.TableMappings.Add("Table", "TestTable");
DtSet = new System.Data.DataSet();
MyCommand.Fill(DtSet);
destination.DataSource = DtSet.Tables[0];
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void addSearchTypes(DataGridView Source)
{
for (int i = 0; i < Source.ColumnCount; i++)
{
this.searchTypeComboBox.Items.Add(Source.Columns[i].HeaderText);
}
}
private void prevButton_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Excel Worksheets 2003(*.xls)|*.xls";
if (ofd.ShowDialog() == DialogResult.OK)
{
this.prevFileName = ofd.FileName;
this.prevFileLabel.Text = ofd.FileName;
}
this.tryEnableCompare();
}
private void currButton_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Excel Worksheets 2003(*.xls)|*.xls";
if (ofd.ShowDialog() == DialogResult.OK)
{
this.currFileName = ofd.FileName;
this.currFileLabel.Text = ofd.FileName;
}
this.tryEnableCompare();
}
private void clearButton_Click(object sender, EventArgs e)
{
this.compareButton.Enabled = false;
this.searchTextBox.Text = "";
this.searchTextBox.Enabled = false;
this.searchTypeComboBox.SelectedText = "";
this.searchTypeComboBox.Items.Clear();
this.searchTypeComboBox.Enabled = false;
this.prevFileName = "";
this.currFileName = "";
this.prevFileLabel.Text = "";
this.currFileLabel.Text = "";
this.prevDataGridView.DataSource = null;
this.currDataGridView.DataSource = null;
this.removedDataGridView.DataSource = null;
this.removedDataTable = null;
this.addedDataGridView.DataSource = null;
this.addedDataTable = null;
this.changedDataGridView.DataSource = null;
}
private void tryEnableCompare()
{
if (this.prevFileName != "" && this.currFileName != "")
{
this.compareButton.Enabled = true;
}
}
private String getSelectedTab()
{
return this.dataTabControl.SelectedTab.Text;
}
private void searchTextBox_TextChanged(object sender, EventArgs e)
{
if (searchTextBox.Text != "")
{
String selectedTab = this.getSelectedTab();
if (selectedTab == "Previous")
{
bsPrev.Filter = "[" + this.searchTypeComboBox.SelectedItem.ToString() + "]" + " like '%" + this.searchTextBox.Text + "%'";
}
if (selectedTab == "Current")
{
bsCurr.Filter = "[" + this.searchTypeComboBox.SelectedItem.ToString() + "]" + " like '%" + this.searchTextBox.Text + "%'";
}
if (selectedTab == "Removed Entries")
{
bsRemoved.Filter = "[" + this.searchTypeComboBox.SelectedItem.ToString() + "]" + " like '%" + this.searchTextBox.Text + "%'";
}
if (selectedTab == "Added Entries")
{
bsAdded.Filter = "[" + this.searchTypeComboBox.SelectedItem.ToString() + "]" + " like '%" + this.searchTextBox.Text + "%'";
}
if (selectedTab == "Changed Entries")
{
bsChanged.Filter = "[" + this.searchTypeComboBox.SelectedItem.ToString() + "]" + " like '%" + this.searchTextBox.Text + "%'";
}
}
else
{
bsPrev.RemoveFilter();
bsCurr.RemoveFilter();
bsRemoved.RemoveFilter();
bsAdded.RemoveFilter();
//bsChanged.RemoveFilter();
}
}
private void dataTabControl_SelectedIndexChanged(object sender, EventArgs e)
{
this.searchTypeComboBox.Items.Clear();
this.searchTextBox.Clear();
String selectedTab = this.getSelectedTab();
if (selectedTab == "Previous")
{
this.addSearchTypes(this.prevDataGridView);
}
if (selectedTab == "Current")
{
this.addSearchTypes(this.currDataGridView);
}
if (selectedTab == "Removed Entries")
{
this.addSearchTypes(this.removedDataGridView);
}
if (selectedTab == "Added Entries")
{
this.addSearchTypes(this.addedDataGridView);
}
if (selectedTab == "Changed Entries")
{
this.addSearchTypes(this.changedDataGridView);
}
}
private void searchTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
this.searchTextBox.Enabled = true;
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Created by Ryan Peters. 2013");
}
private String[] GetExcelSheetNames(string excelFile)
{
OleDbConnection objConn = null;
System.Data.DataTable dt = null;
try
{
// Connection String. Change the excel file to the file you
// will search.
String connString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + excelFile + ";Extended Properties=Excel 8.0;";
// Create connection object by using the preceding connection string.
objConn = new System.Data.OleDb.OleDbConnection(connString);
// Open connection with the database.
objConn.Open();
// Get the data table containg the schema guid.
dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dt == null)
{
return null;
}
String[] excelSheets = new String[dt.Rows.Count];
int i = 0;
// Add the sheet name to the string array.
foreach (DataRow row in dt.Rows)
{
excelSheets[i] = row["TABLE_NAME"].ToString();
i++;
}
// Loop through all of the sheets if you want too...
for (int j = 0; j < excelSheets.Length; j++)
{
// Query each excel sheet.
}
return excelSheets;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return null;
}
finally
{
// Clean up.
if (objConn != null)
{
objConn.Close();
objConn.Dispose();
}
if (dt != null)
{
dt.Dispose();
}
}
}
}
}