因为客户对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版本就可以了.
从Excel转Access的一个方法说开去(DataRow的state状态)的更多相关文章
-
从一个Bug说开去--解决问题的思路,Linked Server, Bulk Insert, DataTable 作为参数传递
声名— 部分内容为杜撰,如有雷同,不胜荣幸! 版权所有,如要引用,请标明出处! 如果打赏,请自便! 1 背景介绍 最近一周在忙一个SQL Server 的Bug,一个简单的Bug,更新两张 ...
-
从java main方法说开去(转)
刚刚接触java语言时,接触的便为一个java main方法.我们知道这样程序就可以运行了,但是程序是怎么运行起来的我们却不知道. 众所周知,当执行一个java程序时,首先会启动一个JVM虚拟机进程, ...
-
PHP导出Excel一个方法轻松搞定
/** * 导出数据为excel表格 *@param $data 一个二维数组,结构如同从数据库查出来的数组 *@param $title excel的第一行标题,一个数组,如果为空则没有标题 *@p ...
-
SharePoint Server 2013 Excel Web Access无法显示
环境信息:SharePoint Server 2013 中文版,版本为15.0.4420.1017 Windows Server 2008 r2中文版 Sql Server 2012 问题描述:在Sh ...
-
R语言读取excel文件的3种方法
R读取excel文件中数据的方法: 电脑有一个excel文件,原始的文件路径是:E:\R workshop\mydata\biom excel数据为5乘2阶矩阵,元素为 ...
-
详细解释VB连接access几种方法数据库
在VB中,连接ACCESS数据库的方法主要有以下三种 使用ADO对象,通过编写代码訪问数据库 Connection 对象 ODBC数据源 使用ADO Data 控件高速创建数据库连接 有三种连接方法 ...
-
将DataTable内容导出到Excel表格的两种方法
方法一:循环DataTable单元格内容拼接字符串,利用StreamWriter的Write方法将字符串写入Excel文件中 这种方法很实现很简单.拼接字符串时,每个单元格之间添加'\t'(表示一个占 ...
-
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 ...
-
多个EXCEL文件合并成一个
Python的numpy处理起来会比较方便,有空实现一下,这里是Excel内部代码的方式: 合并方法如下: 1.需要把多个excel表都放在同一个文件夹里面,并在这个文件夹里面新建一个excel.如图 ...
随机推荐
-
iOS开发之巧用Block和代理方法结合来传值
好久没写技术博客了,因为996的工作周期已经持续好几个月了.每天晚上回家都没有太多精力学习很多其他的东西,而且很多时候是接着完善工作的项目的模块开发.所以博客停歇了这么久,更新率也低了不少,今天补充一 ...
-
第一章 web应用程序开发原理
[总结] 1.计算机模式 :主机 哑端计算机模式 优点:速度快 反应快 维护修理方便 数据安全性高 缺点:单台计算机安全操作 应用程序难维护 难以跨出平台 客户端 客户计算机模式 优点:速度快 ...
-
loadrunner通过字符串左右边界切割字符串
void web_reg_save_param_custom(char *sourceStr, char* outpuStr, char *leftBdry, char *rightBdry){ ...
-
java中String类、StringBuilder类和StringBuffer类详解
本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html 版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...
-
swift基础--运算符
(1)加减乘除 (2)三目运算,切记后面的空格如果不加会报错的.估计是苹果的bug. (3)聚合运算符,省却了一个判断,很人性化 (4)区间运算符 //加减乘除等等 let a = 2 let b = ...
-
os.path.exists(path) 和 os.path.lexists(path) 的区别
使用os.path.exists()方法可以直接判断文件是否存在.代码如下:>>> import os>>> os.path.exists(r'C:\1.TXT') ...
-
ios开发之--valueForKeyPath的用法
1.获取数组中的平均值,最大值,最小值,总和,代码如下: NSArray *ary = @[@,@,@,@,@,@,@]; [self caculateArray:ary]; -(NSString * ...
-
android 应用商店
下面更多 http://wiki.youmi.net/Wiki/PromotionChannelIDs 小米 http://market.xiaomi.com/dev安智市场 http://dev.a ...
-
51nod-1227-平均最小公倍数
题意 定义 \(n\) 的平均最小公倍数: \[ A(n)=\frac{1}{n}\sum _{i=1}^n\text{lcm}(n,i) \] 求 \[ \sum _{i=L}^RA(i) \] \ ...
-
js 刷新后不提示并保留控件状态
保存后,想提示一下并保留查询条件的状态,发现可以用document.forms[0].submit();继续提交达到刷新的目的 代码如下: ScriptManager.RegisterStartupS ...