从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 该行已通过 DataRow 的 Delete 方法被删除。

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

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

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

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

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

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

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

时间: 2024-12-16 01:09:25

从Excel转Access的一个方法说开去(DataRow的state状态)的相关文章

从java main方法说开去

刚刚接触java语言时,接触的便为一个java main方法.我们知道这样程序就可以运行了,但是程序是怎么运行起来的我们却不知道. 众所周知,当执行一个java程序时,首先会启动一个JVM虚拟机进程,当程序执行完时,JVM进程则消亡.其他导致JVM进程消亡的还有以下情况: System.exit(int)方法,执行该方法时,虚拟机腿粗好.int参数为状态码,为0时,正常退出:若不为0,则异常退出. 遇到异常或错误时.若在程序过程中遇到异常时,不作处理会一直抛出异常到main函数,若main函数也

从java main方法说开去(转)

刚刚接触java语言时,接触的便为一个java main方法.我们知道这样程序就可以运行了,但是程序是怎么运行起来的我们却不知道. 众所周知,当执行一个java程序时,首先会启动一个JVM虚拟机进程,当程序执行完时,JVM进程则消亡.其他导致JVM进程消亡的还有以下情况: System.exit(int)方法,执行该方法时,虚拟机腿粗好.int参数为状态码,为0时,正常退出:若不为0,则异常退出. 遇到异常或错误时.若在程序过程中遇到异常时,不作处理会一直抛出异常到main函数,若main函数也

取EXCEL文件的3种方法

1.方法一:采用OleDB读取EXCEL文件: 把EXCEL文件当做一个数据源来进行数据的读取操作,实例如下: public DataSet ExcelToDS(string Path) { string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source="+ Path +";"+"Extended Properties=Excel 8.0;"; OleDb

C# 各种导入 Excel 文件的数据的方法总结

在导入之前都需要将上传的文件保存到服务器,所以避免重复的写这些代码,先贴出上传文件并保存到服务器指定路径的代码. protected void btnImport_Click(object sender, EventArgs e) { Random random = new Random(); ImportClass Import = new ImportClass(); //保存文件的虚拟路径 string path = "Import/"; //获取选择的文件名 string fi

Excel与Access的互作 - 1

Excel中恰当地使用空间来格式化.汇总数据.标记数据域 Excel表导入Access之间确保表格的连续性 文本文件的缺点:含冗余.不相关的数据列.空白或空的数据元素 给Excel表格加上索引列表,这样数据库的设计才更精致,数据分析才不容易出错 Access中Text字段不可用于计算,自动编号为长整型,自07版后添加了一个附件类型 Excel导入Access中时,Access会自动选择默认的数据类型,但还是有必要检查下 字段名最大长度64,具有描述性,不要出现!?等特殊字符 字段名和表明中不要出

详细解释VB连接access几种方法数据库

在VB在,连接ACCESS数据库的方法主要表现在以下三种 使用ADO对象.通过编写代码訪问数据库 Connection 对象 ODBC数据源 使用ADO Data 控件高速创建数据库连接 有三种连接方法 Data Link文件 使用ODBC数据源名称 使用连接字符串 使用数据环境设计器创建数据库连接 首先加入环境引用. 然后找到数据源进行连接 不管是哪一种连接,都是先有一个路径,通向要连接的数据源.和数据源建立关系,在连接.就好比从北京到上海,能够做汽车,能够做火车,还能够做飞机.汽车走快速.火

Excel连接Access查询不出数据

Excel和Access都是微软的重要产品,但是两者竟然在有些地方不兼容,真是无语. 放图,Access中放入这几条数据 并且新建一个查询,(查询姓名为王*的所有金额),下图为在Access中的查询结果,一切正常 这时候如果在Excel中直接连接这个Access查询,悲剧出现了 怎么回事呢,百般查找啊,发现是坑贴的Excel和Access不匹配 在Access中如果这样写(like “王*”),那么在Access中无问题,但是在Excel中查询不到数据: 但Access中如果这样写(like “

excel VLOOKUP函数的使用方法 .

VLOOKUP函数是Excel中几个最重函数之一,为了方便大家学习,兰色幻想特针对VLOOKUP函数的使用和扩展应用,进行一次全面综合的说明.本文为入门部分 一.入门级 VLOOKUP是一个查找函数,给定一个查找的目标,它就能从指定的查找区域中查找返回想要查找到的值.它的基本语法为: VLOOKUP(查找目标,查找范围,返回值的列数,精确OR模糊查找) 下面以一个实例来介绍一下这四个参数的使用 例1:如下图所示,要求根据表二中的姓名,查找姓名所对应的年龄. 公式:B13 =VLOOKUP(A13

数据由SqlServer2008转移到MySQL的一个方法

数据由SqlServer2008转移到MySQL的一个方法 1.将数据从SqlServer导出到Excel文件中,方法http://www.cnblogs.com/hewenwu/p/3684629.html 2.将得到的Excel打开,点击"文件"-->"另存为",选择csv(逗号分隔),保存 3.用记事本打开csv文件,点击另存为txt即可 4.将txt文件导出MySQLhttp://www.cnblogs.com/hewenwu/p/3715833.ht