【问题标题】:ADO: Excel: Is it possible to open recordset on table name?ADO:Excel:是否可以在表名上打开记录集?
【发布时间】:2016-04-26 04:25:54
【问题描述】:

我在网上查看过,但没有找到任何答案。所以我把它放在这里。

代码 sn-p:(其中案例 1 不起作用..)

_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

这在 excel 中可能吗?或者上面的代码有问题。

注意:我已经在 Microsoft Access 中尝试过,并且将 recorset 绑定到表名在那里可以正常工作。

【问题讨论】:

    标签: excel vba ado recordset


    【解决方案1】:

    简短的版本是:

    插入 Excel 电子表格的“表格”在 SQL 中不显示为表格。

    您需要一个命名范围,或命名工作表,或“表”数据范围和标题的完整地址;并且与 Excel 表关联的命名范围的明显存在具有误导性。


    我想这需要一些解释,从:

    这个“Table1”到底是什么?

    它不是命名范围,也不是工作表,并且无法通过您的 SQL 解析为 Excel Range 对象。回顾一下:

    • 如果您创建了一个在工作簿中全局可见的命名范围, 并将其称为“Table1”,它对您的 SQL 查询可见 表 1
    • 如果您已将工作表重命名为“Table1”,它将对 您的 SQL 查询为 Table1$
    • 如果您创建了一个命名范围,则位于工作表范围内 命名为“Sheet1”,并将其命名为“Table1”,您可以看到它 SQL 为 Sheet1$Table1

    Excel“表格”不是这些东西,因此它对于数据库引擎来说是不可见的。

    是的,它显示在命名范围的“名称管理器”对话框中:但“Table1”不是命名范围的名称,也不是工作表,也没有指定具有 SQL 可识别地址的范围:和它必须是这三件事之一,才能作为数据库表对 Excel 可用的 OLEDB 和 ODBC 数据库驱动程序可见。

    您创建为“Table1”的对象是一个ListObject,您可以在 Excel VBA IDE 的调试窗口中查询它:

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

    所以你需要的是 ListObject 范围的地址,这很简单……

    其实一点都不简单。

    ...ListObject 有一个DataBodyRange 属性,它覆盖了表头下方的数据行;和一个HeaderRowRange,它指的是标题。两者都是范围,都有地址;并且您需要UNION 他们以获取您的 SQL 可以读取为命名表的单个地址。

    或者使用Sheet1.ListObjects("Table1").Sort.Rng.address,因为每个ListObject都有一个Sort对象属性,不管它是否排序;并且Rng 属性是整个 范围,不考虑一致的对象名称,也没有提示要排序的列或列的地址。

    ...而且这些信息对您的问题和编码毫无用处:您无法将任何内容放入 SQL 查询中,将“表”对象解析为有效表。

    在运行 SQL 之前,您必须提取并解析整个“表”范围的地址。 ADO 和 ODBC Excel 驱动程序将在“SheetName$A1:Z1024”形式的连续范围地址上工作,但它们无法从 Excel“表”对象的父工作簿中提取该地址.



    为令人失望的答案道歉。




    顺便说一句,您确实知道使用任何可用的 ODBC 和 OLEDB SQL 驱动程序查询 Excel 会导致内存泄漏?至少,如果您从 VBA 执行此操作,它会这样做:我建议您不要重复运行此操作,除非您在代码上运行 Purify 或类似工具并隔离问题。

    【讨论】:

    • 看起来 ListObject 也有一个 range 属性,它给出了完整的范围。所以,Sheet1.ListObjects("Table1").Range.Address 对我有用。
    • ListObjects 不是一个很好实现的对象,但是,如果您对古怪的界面有信心,那就去吧。但请注意,当您使用大型动态数据集时,它们会严重降低您的工作簿速度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多