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

我正在尝试使用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]给出了语法错误消息。

有没有办法告诉司机如何select工作表,而不是跳过空白? 或者,也许有一种方法来知道每个值从哪个单元格位置返回?

出于内部政策原因(我知道他们是坏的,但我不决定这些),不可能使用第三方库,我真的需要这个从标准的Delphi 7组件工作。

我假设,如果你的数据是在B2:D10的范围内说的,例如,你想包含列A作为一个空的列? 也许? 那是对的吗? 如果是这样的话,那么当你读取表单(SELECT * FROM [SheetName $])时,你的数据集也将返回100万行,16K列!

你不能执行一个查询:SELECT * FROM [SheetName $ B2:D10],并使用ADO GetRows函数来获得一个数组 – 这将给你的数据的大小。 那么你可以索引到数组中,以获得你想要的数据?

好的,正确的答案是

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

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

  • 使用IMEX=1忽略空行和空列
  • 使用IMEX=0有时不会忽略空行,但是现在,一些非空的单元格被视为字段名称而不是数据,尽pipeHDR=No 由于列中的值是混合types,因此无法工作。
  • 在单元格之间进行显式循环,并使SELECT * FROM [SheetName$A1:A1]工作,直到到达一个空单元格,然后就会出现访问违例(见下文)

 Access violation at address 1B30B3E3 in module 'msexcl40.dll'. Read of address 00000000 

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