【问题标题】:"Too many fields defined" when querying Excel using ADO使用 ADO 查询 Excel 时“定义的字段过多”
【发布时间】:2014-01-30 04:28:53
【问题描述】:

我正在使用以下 ADO 查询 Excel 2010 工作簿:

Function WorksheetRecordsetSQL(workbookPath As String, sheetName As String, selectSQL As String) As ADODB.Recordset

Dim objconnection As New ADODB.Connection
Dim objrecordset As New ADODB.Recordset

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H1

objconnection.CommandTimeout = 99999999

objconnection.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=" & workbookPath & ";" & _
        "Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"

objrecordset.Open selectSQL, _
    objconnection, adOpenStatic, adLockOptimistic, adCmdText

Set WorksheetRecordsetSQL = objrecordset

End Function

当我用这个 SQL 调用它时:

Select * FROM [someWorksheet$]

函数执行成功。但如果我这样称呼它:

Select *,cdate(someField) FROM [someWorksheet$]

然后我得到这个错误:

Too many fields defined.

我发现select * 查询生成的记录集包含 255 个字段(Access 引擎在查询中可以拥有的最大值),即使工作表中只有 58 列。这样一个额外的cdate() 列就会使引擎过载并产生错误。

有没有一种方法可以防止select * 查询从 Excel 工作表中提取空白列?或者我可以设置一些允许超过 255 个字段的参数?

【问题讨论】:

  • 你试过设置HDR=False吗?
  • 我不明白你为什么要获取“someFields 两次?如果你只想要“someField”然后写:“Select cdate(someField) FROM [someWorksheet$]”
  • @carleson,我需要单独获取someField,因为ADO 将其数据类型检测为文本,因此12/13/35 被逐字读取为字符串而不是12/13/1935。所以我还需要选择它作为日期。

标签: sql vba excel ado adodb


【解决方案1】:

您可以指定应读取的范围,从而减少进入查询的列数。这里从单元格 A1 到列 BF (58) 所有行:

来自 [Source_sheet$A1:BF]

Sub main()
    Dim reultingRecordset As ADODB.Recordset

    Set reultingRecordset = WorksheetRecordsetSQL( _
        "C:\Temp\VBA\ReadWithADOSource.xlsx", _
        "Source_sheet", _
        "Select * FROM [Source_sheet$]")

    Debug.Print "Select * FROM [Source_sheet$] >"
    Debug.Print "Fields: " & reultingRecordset.Fields.Count & " Records: " & reultingRecordset.RecordCount

    Set reultingRecordset = WorksheetRecordsetSQL( _
        "C:\Temp\VBA\ReadWithADOSource.xlsx", _
        "Source_sheet", _
        "Select *,cdate(Col2) FROM [Source_sheet$A1:BF]")

    Debug.Print "Select *,cdate(Col2) FROM [Source_sheet$A1:BC] > "
    Debug.Print "Fields: " & reultingRecordset.Fields.Count & " Records: " & reultingRecordset.RecordCount

End Sub

输出:

选择 * FROM [Source_sheet$] >
字段:255 条记录:8

从 [Source_sheet$A1:BC] 中选择 *,cdate(Col2) >
字段:59 条记录:8

【讨论】:

  • 优秀。这也解决了我遇到的另一个问题,即直到工作表中的几行才给出字段名称; select * from [source_sheet$a4:bc] 很好地完成了这一点。
猜你喜欢
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多