I have a subroutine that runs on a local copy of a database and a network stored master.
To allow users to run my Excel add-in offline, I create a local version that has the same table names as the master but with only the relevant fields.
The first sub does not give any errors however when I reviewed the local database to ensure that the tables were being deleted and recreated, only 2 of the 4 tables were being deleted.
I developed a work-around, but I’d like to know if there is something I missed or did incorrectly or is this just a quirk of working with Access databases via DAO?
First Sub (only deletes 2 tables instead of all 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", "SettingsFileInfo", "Local_DB_Location")
DBPath = Interaction.GetSetting("Tools", "SettingsFileInfo", "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
Second Sub (work-around):
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", "SettingsFileInfo", "Local_DB_Location")
DBPath = Interaction.GetSetting("Tools", "SettingsFileInfo", "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
Advertisement
Answer
You often get odd results when looping over a collection and deleting/adding items. Your second approach avoids that, as would looping backwards numerically through the collection e.g.
For x = DB.TableDefs.Count to 1 Step -1
'Check DB.TableDefs(x)
Next x
Alternatively just try to delete each definition and ignore any errors:
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