在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 查询(即 SELECT
和 INTO
调用)之类的操作查询分配给记录集。考虑在本地 table 上打开记录集之前执行 DROP
和 SELECT ... 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")
我似乎找不到任何好的参考资料或示例来说明如何让它工作。我有一个存储在 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 查询(即 SELECT
和 INTO
调用)之类的操作查询分配给记录集。考虑在本地 table 上打开记录集之前执行 DROP
和 SELECT ... 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")