有没有更好的方法在Excel中指示"null"值?

dev*_*xer 4 c# oledb excel ado.net excel-2007

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

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

  1. 细胞完全空白.
  2. 细胞包含#N/A.

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

  1. Excel中的大多数数据列都是通过公式生成的,但在Excel中生成的公式不可能生成完全空白的单元格.并且只有一个完全空白的单元格将被视为null(空字符串将不起作用).

  2. 任何计算结果的公式#N/A(由于实际的查找错误或因为使用了该NA()函数)都将被视为null.这似乎是理想的解决方案,直到我发现Excel工作簿必须打开才能工作.一旦关闭工作簿,OLEDB就会突然开始将所有这些#N/A视为字符串.这会在填充DataTable时引发类似以下的异常:

    输入字符串的格式不正确.无法在值列中存储<#N/A>.预期类型是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;
Run Code Online (Sandbox Code Playgroud)

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

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

osk*_*ows 6

你正在遇到许多非常沮丧的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种选择:

  1. 更改注册表设置TypeGuessRows = 0

  2. 将前8行中所有可能的类型变体列为"虚拟数据"(例如备注字段/ nchar(最大)/错误#N/A等)

  3. 更正Excel中的所有数据类型异常

  4. 不要使用Excel - 非常值得考虑!

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