zoukankan      html  css  js  c++  java
  • 从Excel转Access的一个方法说开去(DataRow的state状态)

    因为客户对access不太熟悉,更喜欢玩EXCEL。但是系统要求导入ACCESS。所以我们得做个把EXCEL转换成Access的小工具。(别问我为啥不让系统直接导入excel....我不知道!),然后耗费了点时间写了个公用的方法,如下:

      /// <summary>
            /// 
            /// </summary>
            /// <param name="excelpath">excel路径</param>
            /// <param name="exceltablename">Excel表名</param>
            /// <param name="accessmodelpath">access模版路径</param>
            /// <param name="accesspath">access输出路径</param>
            ///  <param name="accesstablename">access表名</param>
            /// <param name="msg">错误信息</param>
            /// <returns></returns>
            public static bool ExcelToAccess(string excelpath, string exceltablename, string accessmodelpath, string accesspath, string accesstablename, ref string msg)
            {
    
                try
                {
                    DataTable dt = ExcelToDataTable(excelpath, exceltablename);
                    if (dt == null)
                    {
                        msg = "Excel没有任何内容";
                        return false;
                    }
                    accesspath = accesspath + "\生成的access.mdb";
                    System.IO.File.Copy(accessmodelpath, accesspath, true);
                    string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + accesspath + ";User Id=admin;Password=;";
                    string sql = "Select * from " + accesstablename + "";
                    System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(connStr);
                    System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter(sql, conn);
                    System.Data.DataTable acedt = new DataTable();
               
                    da.Fill(acedt);
    
                    System.Data.OleDb.OleDbCommandBuilder ocb = new System.Data.OleDb.OleDbCommandBuilder(da);
                    da.InsertCommand = ocb.GetInsertCommand();
                    DataRow[] drs = dt.Select();
                    foreach (DataRow r in drs)
                    {
                        acedt.ImportRow(r);
                    }
                   // acedt.AcceptChanges();//此处不能有
                    da.Update(acedt);
                  
                    da.Dispose();
                    conn.Close();
                    conn.Dispose();
                    return true;
                }
                catch (Exception ex)
                {
                    msg = ex.Message;
                    return false;
                }
            }
    

     这里用了模版,用IO的创建代替用sql创建access,应该是个比较好点的办法,当然,前提是你得实现有个模版。

    然后是 ExcelToDataTable方法的代码:

        /// <summary>
            /// Excel转换成datatable
            /// </summary>
            /// <param name="excelpath"></param>
            /// <param name="exceltablename"></param>
            /// <returns></returns>
            public static DataTable ExcelToDataTable(string excelpath, string exceltablename)
            {
                try
                {
                    //
    
                    string strCon =string.Format(  "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;IMEX=1'",excelpath);
                    OleDbConnection Conn = new OleDbConnection(strCon);
                    string strCom = "SELECT distinct  * FROM [" + exceltablename + "$]  where 1=1 ";
                    OleDbDataAdapter da = new OleDbDataAdapter(strCom, Conn);
                    DataTable dt = new DataTable();
                    da.AcceptChangesDuringFill = false;
                    da.Fill(dt);
                    return dt;
                }
                catch(Exception ex)
                {
                    return null;
                }
            }
    

     关键点是 da.AcceptChangesDuringFill = false;这句。最初的时候,我并没有写这一局。

    一开始我没主意到这个,跑这个方法的时候,运行起来没有任何问题,但是,打开生成的access,是空数据!

     查阅资料外加问人,发现了此时dt的datarow的rowstate为unchanged;

    知道问题所在了,就去百度,添加该句后状态改变为added;

    然后终于可以添加到access了。

    现在看起来不是很难,但是,为了找到这个原因,耗费了一天的时间。

    下面是我查找参考资料的时候从MSDN看到的关于DataRow.RowState的一些代码:

      static void Main(string[] args)
            {
                // Run a function to create a DataTable with one column.
                DataTable table = MakeTable();
                DataRow row;
    
                // Create a new DataRow.
                row = table.NewRow();
                // Detached row.
                Console.WriteLine("New Row " + row.RowState);
    
                table.Rows.Add(row);
                // New row.
                Console.WriteLine("AddRow " + row.RowState);
    
                table.AcceptChanges();
                // Unchanged row.
                Console.WriteLine("AcceptChanges " + row.RowState);
    
                row["FirstName"] = "Scott";
                // Modified row.
                Console.WriteLine("Modified " + row.RowState);
    
                row.Delete();
                // Deleted row.
                Console.WriteLine("Deleted " + row.RowState);
    
        
                Console.ReadKey();
            }
            private static  DataTable MakeTable()
            {
                // Make a simple table with one column.
                DataTable table = new DataTable("table");
                DataColumn dcFirstName = new DataColumn(
                    "FirstName", Type.GetType("System.String"));
                table.Columns.Add(dcFirstName);
                return table;
            }
    

     才知道原来不同的操作,datarow的状态是不同的。

    下面来说说他的状态:

    DataRowState枚舉有如下几种状态:

            add  该行已添加到 DataRowCollection 中,AcceptChanges 尚未调用

            Deleted 该行已通过 DataRowDelete 方法被删除。

            Detached  该行已被创建,但不属于任何 DataRowCollectionDataRow 在以下情况下立即处于此状态:创建之后添加到集合中之前;或从集合中移除之后。

            Modified 该行已被修改,AcceptChanges 尚未调用。

            Unchanged 该行自上次调用 AcceptChanges 以来尚未更改。

    要正確理解上面這集中狀態應該對AcceptChanges有很好的理解:

            提交自上次调用 AcceptChanges 以来对该行进行的所有更改。(意思就是对以上做的更改的确认)

            在调用 AcceptChanges 时,EndEdit 方法被隐式调用,以便终止任何编辑。如果行的 RowState 是“Added”或“Modified”,则 RowState 变成“Unchanged”。如果 RowState 是“Deleted”,则该行将被移除。

     如何获取已删除行的信息:获取行的DataRowVersion.Original版本就可以了.

  • 相关阅读:
    POJ1239
    HDU 2829 四边形不等式优化
    返回数字二进制的最高位位数o(n)
    矩阵快速幂 模板
    HDU4718 The LCIS on the Tree(LCT)
    HDU4010 Query on The Trees(LCT)
    HDU3487 Play With Chains(Splay)
    CF444C DZY Loves Colors
    HDU4836 The Query on the Tree(树状数组&&LCA)
    HDU4831&&4832&&4834
  • 原文地址:https://www.cnblogs.com/liuruitao/p/4260530.html
Copyright © 2011-2022 走看看