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

  1. /// <summary>
  2. ///
  3. /// </summary>
  4. /// <param name="excelpath">excel路径</param>
  5. /// <param name="exceltablename">Excel表名</param>
  6. /// <param name="accessmodelpath">access模版路径</param>
  7. /// <param name="accesspath">access输出路径</param>
  8. /// <param name="accesstablename">access表名</param>
  9. /// <param name="msg">错误信息</param>
  10. /// <returns></returns>
  11. public static bool ExcelToAccess(string excelpath, string exceltablename, string accessmodelpath, string accesspath, string accesstablename, ref string msg)
  12. {
  13.  
  14. try
  15. {
  16. DataTable dt = ExcelToDataTable(excelpath, exceltablename);
  17. if (dt == null)
  18. {
  19. msg = "Excel没有任何内容";
  20. return false;
  21. }
  22. accesspath = accesspath + "\\生成的access.mdb";
  23. System.IO.File.Copy(accessmodelpath, accesspath, true);
  24. string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + accesspath + ";User Id=admin;Password=;";
  25. string sql = "Select * from " + accesstablename + "";
  26. System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(connStr);
  27. System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter(sql, conn);
  28. System.Data.DataTable acedt = new DataTable();
  29.  
  30. da.Fill(acedt);
  31.  
  32. System.Data.OleDb.OleDbCommandBuilder ocb = new System.Data.OleDb.OleDbCommandBuilder(da);
  33. da.InsertCommand = ocb.GetInsertCommand();
  34. DataRow[] drs = dt.Select();
  35. foreach (DataRow r in drs)
  36. {
  37. acedt.ImportRow(r);
  38. }
  39. // acedt.AcceptChanges();//此处不能有
  40. da.Update(acedt);
  41.  
  42. da.Dispose();
  43. conn.Close();
  44. conn.Dispose();
  45. return true;
  46. }
  47. catch (Exception ex)
  48. {
  49. msg = ex.Message;
  50. return false;
  51. }
  52. }

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

然后是 ExcelToDataTable方法的代码:

  1. /// <summary>
  2. /// Excel转换成datatable
  3. /// </summary>
  4. /// <param name="excelpath"></param>
  5. /// <param name="exceltablename"></param>
  6. /// <returns></returns>
  7. public static DataTable ExcelToDataTable(string excelpath, string exceltablename)
  8. {
  9. try
  10. {
  11. //
  12.  
  13. string strCon =string.Format( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;IMEX=1'",excelpath);
  14. OleDbConnection Conn = new OleDbConnection(strCon);
  15. string strCom = "SELECT distinct * FROM [" + exceltablename + "$] where 1=1 ";
  16. OleDbDataAdapter da = new OleDbDataAdapter(strCom, Conn);
  17. DataTable dt = new DataTable();
  18. da.AcceptChangesDuringFill = false;
  19. da.Fill(dt);
  20. return dt;
  21. }
  22. catch(Exception ex)
  23. {
  24. return null;
  25. }
  26. }

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

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

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

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

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

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

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

  1. static void Main(string[] args)
  2. {
  3. // Run a function to create a DataTable with one column.
  4. DataTable table = MakeTable();
  5. DataRow row;
  6.  
  7. // Create a new DataRow.
  8. row = table.NewRow();
  9. // Detached row.
  10. Console.WriteLine("New Row " + row.RowState);
  11.  
  12. table.Rows.Add(row);
  13. // New row.
  14. Console.WriteLine("AddRow " + row.RowState);
  15.  
  16. table.AcceptChanges();
  17. // Unchanged row.
  18. Console.WriteLine("AcceptChanges " + row.RowState);
  19.  
  20. row["FirstName"] = "Scott";
  21. // Modified row.
  22. Console.WriteLine("Modified " + row.RowState);
  23.  
  24. row.Delete();
  25. // Deleted row.
  26. Console.WriteLine("Deleted " + row.RowState);
  27.  
  28. Console.ReadKey();
  29. }
  30. private static DataTable MakeTable()
  31. {
  32. // Make a simple table with one column.
  33. DataTable table = new DataTable("table");
  34. DataColumn dcFirstName = new DataColumn(
  35. "FirstName", Type.GetType("System.String"));
  36. table.Columns.Add(dcFirstName);
  37. return table;
  38. }

才知道原来不同的操作,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版本就可以了.

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

  1. 从一个Bug说开去--解决问题的思路,Linked Server, Bulk Insert, DataTable 作为参数传递

    声名— 部分内容为杜撰,如有雷同,不胜荣幸! 版权所有,如要引用,请标明出处! 如果打赏,请自便! 1       背景介绍 最近一周在忙一个SQL Server 的Bug,一个简单的Bug,更新两张 ...

  2. 从java main方法说开去(转)

    刚刚接触java语言时,接触的便为一个java main方法.我们知道这样程序就可以运行了,但是程序是怎么运行起来的我们却不知道. 众所周知,当执行一个java程序时,首先会启动一个JVM虚拟机进程, ...

  3. PHP导出Excel一个方法轻松搞定

    /** * 导出数据为excel表格 *@param $data 一个二维数组,结构如同从数据库查出来的数组 *@param $title excel的第一行标题,一个数组,如果为空则没有标题 *@p ...

  4. SharePoint Server 2013 Excel Web Access无法显示

    环境信息:SharePoint Server 2013 中文版,版本为15.0.4420.1017 Windows Server 2008 r2中文版 Sql Server 2012 问题描述:在Sh ...

  5. R语言读取excel文件的3种方法

    R读取excel文件中数据的方法: 电脑有一个excel文件,原始的文件路径是:E:\R workshop\mydata\biom excel数据为5乘2阶矩阵,元素为                ...

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

    在VB中,连接ACCESS数据库的方法主要有以下三种 使用ADO对象,通过编写代码訪问数据库 Connection 对象 ODBC数据源 使用ADO Data 控件高速创建数据库连接 有三种连接方法 ...

  7. 将DataTable内容导出到Excel表格的两种方法

    方法一:循环DataTable单元格内容拼接字符串,利用StreamWriter的Write方法将字符串写入Excel文件中 这种方法很实现很简单.拼接字符串时,每个单元格之间添加'\t'(表示一个占 ...

  8. Microsoft Office Excel cannot access the file, There are several possible reasons

    今天在做EXCEL打印读取模板时报错了,错误信息如下: Microsoft Excel cannot access the file 'D:\xx.xlsx'. There are several p ...

  9. 多个EXCEL文件合并成一个

    Python的numpy处理起来会比较方便,有空实现一下,这里是Excel内部代码的方式: 合并方法如下: 1.需要把多个excel表都放在同一个文件夹里面,并在这个文件夹里面新建一个excel.如图 ...

随机推荐

  1. 10-2[RF] OOB validation

    main idea: 在使用bootstrap生成gi的训练集时,会有一部分数据没有被选中,使用这一部分数据(OOB)进行validation. 1.数据没有被选中的概率 假设训练集大小为N,使用bo ...

  2. Spring、基本类型属性和集合类型属性的注入

    Spring 还可以对基本属性和集合类型属性进行注入: public interface PersonIService { public String getBaseProperty(); publi ...

  3. 全国计算机等级考试二级教程-C语言程序设计_第6章_字符型数据

    #include <stdio.h> main() { char c; char d; c = ; d = '; if (c == d) { printf("yes\n" ...

  4. 调magento自定义模板发邮件

    1. 设置邮件模板 <global> <template> <email> <custom_email_template1 module="Samp ...

  5. 产品专家Marty Cagan:不做仅仅会编码的人

    Marty Cagan是享有世界声誉的产品管理专家,曾担任Netscape副总裁.eBay产品管理及设计高级副总裁. 近日,记者在"PM-China首届产品经理高峰论坛"上对他做了 ...

  6. Math.round(11.5)等于()Math.round(-11.5)等于()

    几天前去面试,这道简单的题目居然做错了,看来基础就是慢慢积累的.并不断使用和复习才会成为高手,假设基础不是那么熟练.恐怕在成为高手的路上会困难重重.所以在做项目的间歇时间.偶尔回顾一下最基础的知识.是 ...

  7. C#中使用日志类,添加dll时出现错误

    警告 1 未能解析引用的程序集 “log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, proces ...

  8. MongoDB无法启动的解决方法

    http://dmyz.org/archives/423 遇到MongoDB突然无法启动,第一反应是删除mongod.lock.这个文件在MongoDB的数据库目录下,默认是/data/db.这是最常 ...

  9. Java Tomcat Glassfish Weblogic远程debug(remote debug)

    tomcat ./catalina.sh jpda start 这条命令启动tomcat,它就会监听8000端口,等待调试器的连接. 默认监听8000端口,通过设置环境变量JPDA_ADDRESS指定 ...

  10. EC读书笔记系列之11:条款20、21

    条款20 宁以pass-by-reference-to-const替换pass-by-value 记住: ★尽量以pass-by-reference-to-const替换pass-by-value.前 ...