编程语言
首页 > 编程语言> > c# – 有没有更好的方法在Excel中指示“null”值?

c# – 有没有更好的方法在Excel中指示“null”值?

作者:互联网

我有一个Excel 2007工作簿,其中包含我使用ADO.NET导入DataTable对象的数据表.

通过一些实验,我设法找到两种不同的方法来表明ADO.NET应该将一个单元格视为“null”:

>细胞完全空白.
>单元格包含#N / A.

不幸的是,这两个都是有问题的:

> Excel中的大多数数据列都是通过公式生成的,但在Excel中无法生成导致完全空白单元格的公式.并且只有一个完全空白的单元格将被视为null(空字符串将不起作用).
>任何计算结果为#N / A的公式(由于实际的查找错误或因为使用了NA()函数)都将被视为null.这似乎是理想的解决方案,直到我发现Excel工作簿必须打开才能工作.一旦关闭工作簿,OLEDB就会突然开始将所有#N / As视为字符串.这会在填充DataTable时引发类似以下的异常:

Input string was not in a correct format. Couldn’t store <#N/A> in Value Column. Expected type is Int32.

问题:如何通过Excel公式指示空值而不必在填充DataTable时打开工作簿?或者,即使工作簿关闭,也可以将#N / A值视为null?

如果它很重要,我的连接字符串是使用以下方法构建的:

var builder = new OleDbConnectionStringBuilder
{
    Provider = "Microsoft.ACE.OLEDB.12.0",
    DataSource = _workbookPath
};
builder.Add("Extended Properties", "Excel 12.0 Xml;HDR=Yes;IMEX=0");
return builder.ConnectionString;

(_workbookPath是工作簿的完整路径).

我已经尝试了IMEX = 0和IMEX = 1,但它没有任何区别.

解决方法:

你正在遇到许多非常沮丧的Excel用户正在经历的砖墙.遗憾的是Excel作为一种公司工具很普遍,看起来非常强大,不幸的是因为每个单元格/列/行都有一个变体数据类型,这使得它成为处理MySQL,SQL Server,R,RapidMiner,SPSS等其他工具的噩梦.列表继续.似乎Excel 2007/2010得不到很好的支持,在考虑32/64位版本时更是如此,这在当今时代是一个可耻的版本.

主要问题是,当ACE / Jet访问Excel中的每个字段时,他们使用注册表设置“TypeGuessRows”来确定用于评估数据类型的行数. “要扫描的行”的默认值为8行.注册表设置’TypeGuessRows’可以指定从一(1)到十六(16)行的整数值,或者您可以指定零(0)来扫描所有现有行.如果您无法更改注册表设置(例如在90%的办公室环境中),那么生活很困难,因为要猜测的行数限制在前8行.

例如,没有注册表更改
如果#N / A的第一次出现在前8行内,则IMEX = 1将错误返回为字符串“#N / A”.如果IMEX = 0,那么#N / A将返回’Null’.

如果#N / A的第一次出现超过前8行,那么IMEX = 0& IMEX = 1都返回’Null'(假设所需的数据类型是数字).

随着注册表的更改(TypeGuessRows = 0),那么一切都应该没问题.

也许有4种选择:

>更改注册表设置TypeGuessRows = 0
>将前8行中所有可能的类型变体列为“虚拟数据”(例如备注字段/ nchar(最大)/错误#N / A等)
>更正Excel中的所有数据类型异常
>不要使用Excel – 非常值得考虑!

编辑:
只是为了启动:)另外两件真让我烦恼的事情是;如果工作表上的第一个字段在前8行中是空白而您无法编辑注册表设置,那么整个工作表将返回为空白(许多有趣的对话告诉管理员他们是合并单元格的傻瓜!).此外,如果在Excel 2007/2010中您有一个部门返回一个包含> 255列/字段的工作表,那么如果您需要非连续导入(例如col 1中的键和cols 255中的数据),则会出现大问题

标签:c,excel,ado-net,excel-2007,oledb
来源: https://codeday.me/bug/20190531/1187726.html