您的位置:首页 > 编程语言 > C#

WPF程序以及并行比较数据

2013-07-26 22:08 113 查看
最近做了一个WPF的小程序,界面如下:

大家赏析一下顺便提点意见。

主要业务逻辑是:很多合同的完成情况列在一个Excel文件中,需要使用此数据与原合同比较一下,找出没有完成的项目。

界面如下:

















。。。。

说一下使用感觉。

一直在做winform程序,wpf用的很少,所以初次用起来感觉很费劲,很多template和style都没有,这个关键靠积累了。

另外在处理数据的时候使用了Framework4.0的并行计算,现把代码贴下:

public class DataOperate
{
public static DataTable dtAllData = null;
public static Dictionary<string, DataTable> heTongInfoList = new Dictionary<string, DataTable>();
public static Dictionary<string, DataTable> anaInfoList = new Dictionary<string, DataTable>();

public static List<string> ColumNameList = new List<string>();

public static void CooperateData(string heTongName)
{
DataTable dthetong = heTongInfoList[heTongName];
if (dthetong != null)
{
DataTable resultDt = dthetong.Clone();

//比较所有。。。
var sw = Stopwatch.StartNew();
Parallel.ForEach(dthetong.AsEnumerable(),
row =>
{
if (ColumNameList.Count == 0)
{
//查找在比较Dt中是否存在此记录,若不存在则保存在结果中
StringBuilder strFilter = new StringBuilder();

for (int i = 0; i < dthetong.Columns.Count; i++)
{
if (!dtAllData.Columns.Contains(dthetong.Columns[i].ColumnName))
continue;
strFilter.Append(dthetong.Columns[i].ColumnName + "='" + row[i].ToString() + "' and");
}
string filter = strFilter.ToString();
if (filter.EndsWith("' and"))
filter = filter.Substring(0, filter.Length - 3);
DataRow[] rows = dtAllData.Select(filter);
if (rows.Length == 0)
{
DataRow newrow = resultDt.NewRow();
newrow.ItemArray = row.ItemArray;
resultDt.Rows.Add(newrow);
}
}
else//比较关键列
{
StringBuilder strFilter = new StringBuilder();
for (int i = 0; i < ColumNameList.Count; i++)
{
if (!dtAllData.Columns.Contains(ColumNameList[i]))
continue;
strFilter.Append(ColumNameList[i] + "='" + row[ColumNameList[i]].ToString() + "' and");
}
string filter=strFilter.ToString();
if (filter.EndsWith("' and"))
filter = filter.Substring(0, filter.Length - 3);
DataRow[] rows = dtAllData.Select(filter);
if (rows.Length == 0)
{
DataRow newrow = resultDt.NewRow();
newrow.ItemArray = row.ItemArray;
resultDt.Rows.Add(newrow);
}
}

});
//
DataView dv=resultDt.DefaultView;
dv.Sort=resultDt.Columns[0].ColumnName;
DataTable sortTable = dv.ToTable();
if (anaInfoList.Keys.Contains(heTongName))
anaInfoList[heTongName] = sortTable;
else anaInfoList.Add(heTongName, sortTable);
//
sw.Stop();
}
}

/// <summary>
/// 如果已存在则替换,而且分析数据删除
/// </summary>
/// <param name="hetongName"></param>
/// <param name="hetongDt"></param>
public static void AddHeTong(string hetongName, DataTable hetongDt)
{
if (heTongInfoList.Keys.Contains(hetongName))
{
heTongInfoList[hetongName] = hetongDt;
if (anaInfoList.Keys.Contains(hetongName))
anaInfoList.Remove(hetongName);
}
else heTongInfoList.Add(hetongName, hetongDt);
}

internal static void CooperateAllData()
{
foreach(string htName in heTongInfoList.Keys)
{
CooperateData(htName);
}
}
}


另外,再导入Excel文件时,如果是数字与字符混合的列时,最后一行为字符串,前面的都是数字,oledb一般会把此列认为是数字列而不是字符串列。没有什么好的解决办法,我一开始的想法是复制一个文件,然后更改所有单元格的格式为字符串,但是好像在Excel2003下行不通,还是读为数字列。所以只好不以第一行为标题,读取所有数据。这样第一行为字符串,那么所有列都是字符串的列,然后去掉第一行,换列名,这样有利于以后数据的比较。

先把读取代码贴下:

public class ExcelHelper
{
/// <summary>
/// 读取Excel文件到DataSet中
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns></returns>
public static DataSet FileToDataTable(string filePath)
{
//string fpath2 = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
//fpath2 +="//"+ System.IO.Path.GetFileName(filePath);
//File.Copy(filePath, fpath2, true);
//ChangeCellFormat(fpath2);//将所有列改为字符串型
//
string connStr = "";
string fileType = System.IO.Path.GetExtension(filePath);
if (string.IsNullOrEmpty(fileType)) return null;

if (fileType == ".xls")
connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath + ";" + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"";
else
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath + ";" + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"";
string sql_F = "Select * FROM [{0}]";

OleDbConnection conn = null;
OleDbDataAdapter da = null;
System.Data.DataTable dtSheetName = null;

DataSet ds = new DataSet();
try
{
// 初始化连接,并打开
conn = new OleDbConnection(connStr);
conn.Open();

// 获取数据源的表定义元数据
string SheetName = "";
dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

// 初始化适配器
da = new OleDbDataAdapter();
for (int i = 0; i < dtSheetName.Rows.Count; i++)
{
SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];

if (SheetName.Contains("$") && !SheetName.Replace("'", "").EndsWith("$"))
{
continue;
}

da.SelectCommand = new OleDbCommand(String.Format(sql_F, SheetName), conn);
DataSet dsItem = new DataSet();
da.Fill(dsItem, SheetName);
for (int j = 0; j < dsItem.Tables[0].Columns.Count; j++)
dsItem.Tables[0].Columns[j].ColumnName = dsItem.Tables[0].Rows[0][j].ToString();
dsItem.Tables[0].Rows.RemoveAt(0);
//foreach (DataColumn col in dsItem.Tables[0].Columns)
//{
//    col.DataType = typeof(string);
//}
ds.Tables.Add(dsItem.Tables[0].Copy());
}
}
catch (Exception ex)
{
//
//File.Delete(fpath2);
}
finally
{
// 关闭连接
if (conn.State == ConnectionState.Open)
{
conn.Close();
da.Dispose();
conn.Dispose();
//
//File.Delete(fpath2);
}
}
//
//File.Delete(fpath2);
return ds;
}
}


这样基本上可以解决问题了。

转帖请注明出处,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐