在ExcelVBA运行SQL"SELECT ... INTO ... IN ...."声明

In Excel VBA run SQL "SELECT ... INTO ... IN ...." Statement

我似乎找不到任何好的参考资料或示例来说明如何让它工作。我有一个存储在 AS/400 上的数据库(我的本地 MS Access 数据库 [存储在网络驱动器上] 已使用 ODBC/DSN 将 table 链接到 400)。我的实用程序工作正常,通过 Access 传递 SQL 语句以使用链接的 tables 从 400 检索数据。问题在于,对于一​​些较大的报告以及 400 距离几个州的事实,运行 报告可能需要几个小时。解决这个问题的解决方案是创建一个本地 "copy" 所需的 table,只包含与报告相关的数据集,这是一个相当小的数据集。显然这有不是 "live" 数据的缺点,但我可以接受。最终我想要做的是从链接的 table 收集相关数据并将其保存到客户端本地的单独数据库中,以便在 offsite/offline 时可以使用它并提高速度报告。

网络位置存储数据库 = DB1(表链接到 AS/400) 本地客户端存储的数据库=DB2(下面SQL创建的相关数据集,非链接table与链接table同名)

下面是我尝试使用 VBA 和 DAO

开始工作的 SQL 声明
SELECT 
    DB1_TABLEA.FIELD1, 
    DB1_TABLEA.FIELD2, 
    DB1_TABLEA.FIELD3, 
    DB1_TABLEA.FIELD4, 
    DB1_TABLEA.FIELD5, 
    DB1_TABLEA.FIELD6, 
    DB1_TABLEA.FIELD7, 
    DB1_TABLEA.FIELD8 
INTO 
    DB1_TABLEA IN 'Local_DB_Copy.accdb'    <== Creating non-linked copy 
FROM 
    DB1_TABLEA
WHERE 
    (
        ((DB1_TABLEA.FIELD4) Like 99999) 
        AND 
        ((DB1_TABLEA.FIELD6)="02" Or (DB1_TABLEA.FIELD6)="22")
    )
;

我的程序已经运行良好,returning/processing 数据来自 AS/400 数据库。我只需要能够让上面的工作正常工作,这样人们就可以选择 运行 处理速度更快的本地副本。

下面是我试过的代码,但当然失败了,否则我就不会在这里了。

Sub gCreateLocalDBTables()
    Dim DBPath As String
    Dim LocalDBPath As String
    Dim sSQL As String
    Dim DB As DAO.Database
    Dim DB2 As DAO.Database
    Dim RS As DAO.Recordset
        LocalDBPath = "AS400_Local.accdb"
        sSQL = "SELECT DB1_TABLEA.FIELD1, DB1_TABLEA.FIELD2, DB1_TABLEA.FIELD3, DB1_TABLEA.FIELD4, DB1_TABLEA.FIELD5, DB1_TABLEA.FIELD6, DB1_TABLEA.FIELD7, DB1_TABLEA.FIELD8 INTO DB2_TABLEA IN '" & LocalDBPath & "' FROM DB1_TABLEA WHERE (((DB1_TABLEA.FIELD4) Like 99999) AND ((DB1_TABLEA.FIELD6)='02' Or (DB1_TABLEA.FIELD6)='22'));"
        Set DB = OpenDatabase(LocalDBPath, False, False)
        DB.TableDefs.Delete ("DB2_TABLEA")
        DB.Close
        DBPath = Interaction.GetSetting("Cust_Tools", "Settings\Report_Planning", "400DB_Location")
        Set DB2 = OpenDatabase(DBPath, False, False)
        Set RS = DB2.OpenRecordset(sSQL)
        RS.Close
        DB2.Close
        Set RS = Nothing
        Set DB = Nothing
        Set DB2 = Nothing
End Sub

我知道 SQL 可以正常工作,因为我已经在 MS Access 中对其进行了测试。我只是找不到有关如何让它工作的信息,这些信息来自 Excel VBA

您不能将诸如 make-table 查询(即 SELECTINTO 调用)之类的操作查询分配给记录集。考虑在本地 table 上打开记录集之前执行 DROPSELECT ... INTO 操作查询。此外,不清楚您为什么要打开第二个数据库或路径指向什么。下面在主机数据上打开一个记录集:

Set DB = OpenDatabase(LocalDBPath, False, False)

DB.Execute "DROP TABLE DB2_TABLEA", dbFailOnError
DB.Execute sSQL, dbFailOnError

Set RS = DB.OpenRecordset("SELECT * FROM DB2_TABLEA")

此外,您的 make-table 查询中的 IN 子句是不必要的,因为您当前连接到您正在执行 运行 操作的数据库。只需将其删除 ('" & LocalDBPath & "')。此外,不带通配符和数字的 LIKE 表达式应替换为 =

SELECT 
    DB1_TABLEA.FIELD1, 
    DB1_TABLEA.FIELD2, 
    DB1_TABLEA.FIELD3, 
    DB1_TABLEA.FIELD4, 
    DB1_TABLEA.FIELD5, 
    DB1_TABLEA.FIELD6, 
    DB1_TABLEA.FIELD7, 
    DB1_TABLEA.FIELD8 
INTO 
    DB2_TABLEA 
FROM 
    DB1_TABLEA
WHERE 
    (
        ((DB1_TABLEA.FIELD4) = 99999) 
        AND 
        ((DB1_TABLEA.FIELD6)='02' OR (DB1_TABLEA.FIELD6)='22')
    )
;

事实上,考虑将查询保存在 MS Access 数据库中(功能区 -> 创建 -> 查询设计 -> SQL 视图)并将其作为命名对象调用并避免任何长 SQL 在 VBA.

DB.Execute "DROP TABLE DB2_TABLEA", dbFailOnError
DB.Execute "mySavedQuery", dbFailOnError

Set RS = DB.OpenRecordset("SELECT * FROM DB2_TABLEA")