WPF程序以及并行比较数据

最近做了一个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;
        }
}

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

转帖请注明出处,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值