我似乎找不到任何好的参考资料或示例来说明如何使它工作。我有一个存储在AS / 400上的数据库(我的本地MS Access数据库[存储在网络驱动器上]已使用ODBC / DSN将表链接到400)。我的实用程序可以很好地将SQL语句传递给Access,从而可以使用链接表从400中检索数据。问题在于,对于一些较大的报告,以及400处于多个州的事实,运行这些报告可能要花费几个小时。解决此问题的解决方案是仅使用与报告相关的数据集创建所需表的本地“副本”,该数据集是相当小的数据集。显然,这样做不利于不“实时”数据,但我可以接受。最终,我要做的是从链接表中收集相关数据,并将其保存到客户端本地的单独数据库中,以便在异地/脱机时可以使用它,并提高报告的速度。
网络位置存储的数据库= DB1(表链接到AS / 400) 本地客户端存储的数据库= DB2(由下面的SQL创建的相关数据集,非链接表的名称与链接表相同)
下面是我正在尝试使用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")
)
;
我已经使我的程序运行正常,并从AS / 400 DB返回/处理数据。我只需要能够完成上述工作,以便人们可以选择运行本地副本,因此处理速度会更快。
下面是我尝试过的代码,但是当然失败了,否则我就不在这里。
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传递的信息
答案 0 :(得分:1)
您不能为记录集分配动作查询,例如生成表查询(即SELECT
和INTO
调用)。考虑在打开本地表上的记录集之前执行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视图),并将其作为命名对象调用,并避免在VBA中使用任何长的SQL。
DB.Execute "DROP TABLE DB2_TABLEA", dbFailOnError
DB.Execute "mySavedQuery", dbFailOnError
Set RS = DB.OpenRecordset("SELECT * FROM DB2_TABLEA")