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版本就可以了.

  • 相关阅读:
    【Winform】Webservice调用服务器端EXE
    LeetCode: Word Ladder II
    LeetCode: Maximal Rectangle
    Algorithm: 拓扑排序
    Algorithm: 匈牙利算法
    LeetCode: Scramble String
    LeetCode: Integer to Roman
    LeetCode: Roman to Integer
    算法导论:基础知识。
    C++主函数main()讲解
  • 原文地址:https://www.cnblogs.com/liuruitao/p/4260530.html
Copyright © 2011-2022 走看看