我有一个子例程,可以处理数据库的本地副本和网络存储的主副本(该副本始终是最新的,并且数据是实时处理的)。为了允许用户脱机运行我的excel加载项,我创建了一个本地“副本”,该表具有与主副本相同的表名,但只包含相关字段。我第一次编写时,子程序未按预期工作。它似乎正常工作(没有给出任何错误),但是当我查看本地数据库以确保确实删除并重新创建了表时,仅删除了4个表中的2个。我开发了一种变通方法,但是我想知道是否遗漏了一些东西或做错了什么,或者这仅仅是通过DAO使用访问数据库的怪癖
第一个Sub(无法正常工作,只会删除2个表而不是全部4个表):
Sub gUpdateDBTables()
Dim DBPath As String
Dim sSQL_Table1 As String
Dim sSQL_Table2 As String
Dim sSQL_Table3 As String
Dim sSQL_Table4 As String
Dim DB As DAO.Database
Dim DB2 As DAO.Database
Dim tblDef As DAO.TableDef
'Get DB File Locations From Registry
LocalDBPath = Interaction.GetSetting("Tools", "Settings\FileInfo", "Local_DB_Location")
DBPath = Interaction.GetSetting("Tools", "Settings\FileInfo", "DB_Location")
'Set SQL statements
sSQL_Table1 = "SELECT Table1.Field1, Table1.Field2, Table1.Field3, Table1.Field4, Table1.Field INTO Table1 IN '" & LocalDBPath & "' FROM Table1 WHERE (((Table1.Field1)='1') AND ((Table1.Field4)='A' Or (Table1.Field4)='T')) OR (((Table1.Field1)='1' Or (Table1.Field1)='20'));"
sSQL_Table2 = "SELECT Table2.Field1, Table2.Field2, Table2.Field3, Table2.Field4, Table2.Field5, Table2.Field6, Table2.Field7, Table2.Field8 INTO Table2 IN '" & LocalDBPath & "' FROM Table2 WHERE (((Table2.Field4)=99999) AND ((Table2.Field6)='1' Or (Table2.Field6)='20'));"
sSQL_Table3 = "SELECT Table3.Field1, Table3.Field2, Table3.Field3, Table3.Field4, Table3.Field5, Table3.Field6, Table3.Field7, Table3.Field8, Table3.Field9, Table3.Field10, Table3.Field11, Table3.Field12 INTO Table3 IN '" & LocalDBPath & "' FROM Table3 WHERE (((Table3.Field1)='1' Or (Table3.Field1)='20') AND ((Table3.Field12)=0 Or (Table3.Field12)=99999));"
sSQL_Table4 = "SELECT Table4.Field1, Table4.Field2, Table4.Field3, Table4.Field4, Table4.Field5, Table4.Field6, Table4.Field7, Table4.Field8 INTO Table4 IN '" & LocalDBPath & "' FROM Table4 WHERE (((Table4.Field8)='1' Or (Table4.Field8)='20'));"
'Open Local DB and Cycle Through Table Definitions and Delete as Needed
Set DB = OpenDatabase(LocalDBPath, False, False)
For Each tblDef In DB.TableDefs
Select Case tblDef.Name
Case "Table1`"
DB.TableDefs.Delete ("Table1")
Case "Table2"
DB.TableDefs.Delete ("Table2")
Case "Table3"
DB.TableDefs.Delete ("Table3")
Case "Table4"
DB.TableDefs.Delete ("Table4")
End Select
Next tblDef
DB.Close
'Open Networked Database and Process SQL Statements To Refresh Table Data in Local DB File
Set DB2 = OpenDatabase(DBPath, True, False)
With DB2
.Execute sSQL_Table1
.Execute sSQL_Table2
.Execute sSQL_Table3
.Execute sSQL_Table4
End With
DB2.Close
Set DB = Nothing
Set DB2 = Nothing
End Sub
第二个次级(解决方法):
Sub gUpdateDBTables()
Dim DBPath As String
Dim sSQL_Table1 As String
Dim sSQL_Table2 As String
Dim sSQL_Table3 As String
Dim sSQL_Table4 As String
Dim delTbl1 As Boolean
Dim delTbl2 As Boolean
Dim delTbl3 As Boolean
Dim delTbl4 As Boolean
Dim DB As DAO.Database
Dim DB2 As DAO.Database
Dim tblDef As DAO.TableDef
'Get DB File Locations From Registry
LocalDBPath = Interaction.GetSetting("Tools", "Settings\FileInfo", "Local_DB_Location")
DBPath = Interaction.GetSetting("Tools", "Settings\FileInfo", "DB_Location")
'Set SQL statements
sSQL_Table1 = "SELECT Table1.Field1, Table1.Field2, Table1.Field3, Table1.Field4, Table1.Field INTO Table1 IN '" & LocalDBPath & "' FROM Table1 WHERE (((Table1.Field1)='1') AND ((Table1.Field4)='A' Or (Table1.Field4)='T')) OR (((Table1.Field1)='1' Or (Table1.Field1)='20'));"
sSQL_Table2 = "SELECT Table2.Field1, Table2.Field2, Table2.Field3, Table2.Field4, Table2.Field5, Table2.Field6, Table2.Field7, Table2.Field8 INTO Table2 IN '" & LocalDBPath & "' FROM Table2 WHERE (((Table2.Field4)=99999) AND ((Table2.Field6)='1' Or (Table2.Field6)='20'));"
sSQL_Table3 = "SELECT Table3.Field1, Table3.Field2, Table3.Field3, Table3.Field4, Table3.Field5, Table3.Field6, Table3.Field7, Table3.Field8, Table3.Field9, Table3.Field10, Table3.Field11, Table3.Field12 INTO Table3 IN '" & LocalDBPath & "' FROM Table3 WHERE (((Table3.Field1)='1' Or (Table3.Field1)='20') AND ((Table3.Field12)=0 Or (Table3.Field12)=99999));"
sSQL_Table4 = "SELECT Table4.Field1, Table4.Field2, Table4.Field3, Table4.Field4, Table4.Field5, Table4.Field6, Table4.Field7, Table4.Field8 INTO Table4 IN '" & LocalDBPath & "' FROM Table4 WHERE (((Table4.Field8)='1' Or (Table4.Field8)='20'));"
'Open Local DB and Cycle Through Table Definitions and Delete as Needed
Set DB = OpenDatabase(LocalDBPath, False, False)
For Each tblDef In DB.TableDefs
If tblDef.Name = "Table1" Then delTbl1 = True
If tblDef.Name = "Table2" Then delTbl2 = True
If tblDef.Name = "Table3" Then delTbl3 = True
If tblDef.Name = "Table4" Then delTbl4 = True
Next tblDef
If delTbl1 = True Then DB.TableDefs.Delete ("Table1")
If delTbl2 = True Then DB.TableDefs.Delete ("Table2")
If delTbl3 = True Then DB.TableDefs.Delete ("Table3")
If delTbl4 = True Then DB.TableDefs.Delete ("Table4")
DB.Close
'Open Networked Database and Process SQL Statements To Refresh Table Data in Local DB File
Set DB2 = OpenDatabase(DBPath, True, False)
With DB2
.Execute sSQL_Table1
.Execute sSQL_Table2
.Execute sSQL_Table3
.Execute sSQL_Table4
End With
DB2.Close
Set DB = Nothing
Set DB2 = Nothing
End Sub
答案 0 :(得分:1)
当您遍历一个集合并删除/添加项目时,通常会得到奇怪的结果。您的第二种方法避免了这种情况,因为会在数值上循环回退整个集合,例如
For x = DB.TableDefs.Count to 1 Step -1
'Check DB.TableDefs(x)
Next x
或者只是尝试删除每个定义并忽略任何错误:
Dim arrTD, td
arrTD = Array("Table1","Table2","Table3","Table4")
For Each td in arrTD
On Error Resume Next
DB.TableDefs.Delete td
On Error Goto 0
Next td