ADO: Excel: Is it possible to open recordset on table name?

a 夏天 提交于 2020-03-21 06:22:51

问题


I have looked on the web but did not find any answer. So i am putting it here.

Code snippet: ( where case 1 is not working.. )

_bstr_t    strCnn(L"Provider='Microsoft.ACE.OLEDB.12.0';DataSource=C:\\Book.xlsx;Extended Properties=\"Excel 12.0 Xml; HDR = YES\"");

hr = pConn->Open(strCnn, "", "", adConnectUnspecified); // success

**LPCSTR strQuery = "select * FROM Table1";          // case1: Not working**

LPCSTR strQuery = "select * FROM [Sheet1$]";       // case2: working

LPCSTR strQuery = "select * FROM [Sheet1$A1:D10]"; // case3: working

hr = pRst->Open(CComVariant(strQuery), _variant_t((IDispatch *)pConn, true),
                adOpenStatic, adLockOptimistic,adCmdText); // fails for case 1

Is this possible in excel? or there is something wrong in the above code.

NOTE: I have tried this with Microsoft Access and binding recorset to table name works fine there.


回答1:


The short version is:

A 'Table' inserted into an Excel Spreadsheet is not visible as a table in SQL.

You need a named range, or a named worksheet, or the full address of the 'table' data range and headers; and the apparent existence of a named range associated with an Excel table is misleading.


I guess that needs some explanation, starting with:

What, exactly, is this 'Table1'?

It's not a named range, it's not a sheet, and it cannot be resolved to an Excel Range object by your SQL. To recap that:

  • If you had created a named range, globally visible in the workbook, and called it 'Table1', it would be visible to your SQL query as Table1.
  • If you had renamed the worksheet to 'Table1', it would be visible to your SQL query as Table1$.
  • If you had created a named range, local to the scope of a worksheet named 'Sheet1', and named it 'Table1', it would be visible to your SQL as Sheet1$Table1.

An Excel 'Table' is none of those things, so it isn't visible as a table to the database engine.

Yes, it shows up in the 'Name Manager' dialog for named ranges: but 'Table1' is not the name of a named range, nor a worksheet, nor does it specify a range with an address recognisable to SQL: and it needs to be one of those three things in order to be visible as a database table to the OLEDB and ODBC database drivers available for Excel.

The object you've created as 'Table1' is a ListObject, and you can interrogate it in the Excel VBA IDE's debug window as:

Thisworkbook.Worksheets("Sheet1").ListObjects("Table1").Name

So what you need is the address of the ListObject's range, and that's a simple matter of...

Actually, it isn't simple at all.

...The ListObject has a DataBodyRange property, which covers the rows of data below the header; and a HeaderRowRange which refers to the headers. Both, being ranges, have an address; and you'd need to UNION them to get a single address that your SQL can read as a named table.

Or use Sheet1.ListObjects("Table1").Sort.Rng.address because every ListObject has a Sort object property, whether it's sorted or not; and the Rng property is the entire range, with a cavalier disregard for consistent object names and no hint as to the column or columns' address being sorted.

...And that information is useless for your question and your coding: there's nothing you can put into an SQL query that will parse the 'Table' object as a valid table.

You have to extract and parse the address of the full 'table' range before you run the SQL. The ADO and ODBC Excel drivers will work on a contiguous range address of the form 'SheetName$A1:Z1024' but they have no ability to extract that address from the parent workbook of the Excel 'Table' object.



Apologies for the disappointing answer.




By the way, you do know that querying Excel with any of the available ODBC and OLEDB SQL drivers gives you a memory leak? At least, it does if you do it from VBA: I would advise you not to run this repeatedly unless you run Purify or a similar tool on your code and isolate the problem.



来源:https://stackoverflow.com/questions/36855243/ado-excel-is-it-possible-to-open-recordset-on-table-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!