我正在尝试使用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组件。
答案 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
我太老了,不想尝试猜测使用的适当值,所以它可以工作,直到有人在列中添加另一个数据混合。很抱歉浪费了每个人的时间。