在Delphi 7中使用ADO / ODBC读取Excel工作表

时间:2016-01-05 07:35:34

标签: excel delphi odbc delphi-7 ado

我正在尝试使用Delphi 7从内存中的XLS或XLSX文件中读取Excel工作表。如果可能,我会使用自动化逐个读取单元格,但是当未安装Excel时,我将恢复使用ADO / ODBC Jet驱动程序。 我用

连接
Provider=Microsoft.Jet.OLEDB.4.0; Data Source=file.xls;Extended Properties="Excel 8.0;Persist Security Info=False;IMEX=1;HDR=No";
Provider=Microsoft.ACE.OLEDB.12.0; Data Source=file.xlsx;Extended Properties="Excel 12.0;Persist Security Info=False;IMEX=1;HDR=No";

我的问题是当我使用以下查询时:

SELECT * FROM [SheetName$]

返回的结果不包含空行或空列,因此如果工作表包含此类行或列,则以下单元格将被移位,并且不会以正确的位置结束。我需要“按原样”加载工作表,即确切地知道每个值来自哪个单元格位置。

我尝试通过发出一个表单

的查询逐个读取单元格
SELECT F1 FROM `SheetName$A1:A1`

但现在驱动程序返回错误,说“所选区域之外有数据”。顺便说一下,我不得不使用反引号来包含名称,因为使用像[SheetName$A1:A1]这样的括号会给出语法错误消息。

有没有办法告诉司机按原样选择工作表,而不是跳过空白?或者也许是一种知道返回每个值的单元位置的方法?

出于内部政策原因(我知道它们很糟糕,但我不认为这些),不可能使用第三方库,我真的需要使用标准的Delphi 7组件。

2 个答案:

答案 0 :(得分:1)

我假设如果您的数据在B2:D10范围内说,您想要将A列包含为空列?也许?那是对的吗?如果是这种情况,那么当您阅读工作表(SELECT * FROM [SheetName $])时,您的数据集也将返回100万行16K列!

你不能执行如下的查询:SELECT * FROM [SheetName $ B2:D10]并使用ADO GetRows函数来获取一个数组 - 它将为您提供数据的大小。然后你可以索引数组以获得你想要的数据吗?

答案 1 :(得分:0)

好的,正确答案是

  

无论老板说什么,都要使用第三方库。甚至不   尝试使用ODBC / ADO加载任意Excel文件,迟早会碰壁。

它可能适用于包含单个数据表的excel文件,但是当你想在主要供人类消费的表格中挑选数据时(例如,单个列包含一些带有介绍性文本的单元格,有些包含数字数据) ,一些有评论等...)

  • 使用IMEX=1忽略空行和空列
  • 使用IMEX=0有时不再忽略空行,但现在一些非空单元格被认为是字段名称而不是数据,尽管HDR=No。无论如何都不会起作用,因为列中的valles是混合类型。
  • 明确地循环遍历单元格并使SELECT * FROM [SheetName$A1:A1]一直有效,直到您到达一个空单元格,然后您就会遇到访问冲突(见下文)
Access violation at address 1B30B3E3 in module 'msexcl40.dll'. Read of address 00000000

我太老了,不想尝试猜测使用的适当值,所以它可以工作,直到有人在列中添加另一个数据混合。很抱歉浪费了每个人的时间。