I'm trying to delete all tables except for one in Access. This is done locally, so there are no linked tables and no relationships. The table I am to keep is 'Log' (historical record).
I three tables and two import-error tables I aim to drop. This is a monthly process and the import error tables may be named differently each month, so a few daisy-chained DROP TABLE "Table1_ImportErrors" queries won't necessarily work.
The code here doesn't seem to apply since I can only really name the table I want to keep (this designates tables to drop by name - I won't have that in the case of import errors).
What I currently have is:
-dbo.Table1
-dbo.Table2
-dbo.Table3
-dbo.T2Sheetname_ImportErrors
-dbo.T3Sheetname_ImportErrors
-dbo.Log
-9 Queries
-4 Macros
-2 Modules
I want to keep all queries, macros, modules, and dbo.Log.
I'm just learning VBA, but unclear on what to do here. Open to using a query here as well or other approaches. I appreciate any input and am glad to answer any questions.
EDIT: The following worked for me.
Private Sub
DoCmd.DeleteObject acTable, "Table1"
DoCmd.DeleteObject acTable, "Table2"
DoCmd.DeleteObject acTable, "Table3"
Dim tdf as TableDef
For Each tdf In CurrentDb.TableDefs
If Right(tdf.Name, 12) = "ImportErrors" Then
DoCmd.DeleteObject acTable, tdf.Name
End If
Next tdf
End Sub
Here are the results of googling some phrases like "msaccess for all tables" and "msaccess vba delete table". Use Google, it is your friend.
Depending of what the msgbox sez, you may need to filter on "dbo.Log" or on "Log".
'From https://stackoverflow.com/questions/17555174/how-to-loop-through-all-tables-in-an-ms-access-db
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Set db = CurrentDb
For Each tdf In db.TableDefs
' ignore system and temporary tables
If Not (tdf.name Like "MSys*" Or tdf.name Like "~*") Then
If tdf.name <> "Log" Then
MsgBox("deleting " & tdf.name)
' from https://stackoverflow.com/questions/15945297/what-is-the-difference-between-docmd-deleteobject-actable-vs-drop-table
'DoCmd.DeleteObject acTable, tdf.name
End If
End If
Next
Set tdf = Nothing
Set db = Nothing
Related
So I'm converting an access back-end to SQL. I've tried a few different tools (SSMA, Upsizing Wizard, and a simple import). I've found so far that the SSMA tool and importing seem to work the best, eliminating most of the work necessary for me. However, I'm running into one issue I can't figure out how to overcome.
Two fields allow multiple values (dropdown with check boxes). In converting these, it errors in a way that it not only doesn't carry all of the information over, but also grabs information from another field (and doesn't carry that information over).
I've tried forcing access to only accept the first value (and get rid of multi-values all together), but it won't let me.
Any ideas?
This should get you started. It will turn all those values which are selected in the multi select field into their own table. You will need to establish the relationships between the three tables to create a true many to many relationship after the fact.
Sub ExtractMultiValueFields()
Dim JoinTable As New DAO.TableDef
JoinTable.Name = "JoinTable"
With JoinTable
.Fields.Append .CreateField("MainTableId", dbInteger)
.Fields.Append .CreateField("JoinToValue", dbText)
End With
Dim joinRs As DAO.Recordset
CurrentDb.TableDefs.Append JoinTable
Set joinRs = CurrentDb.OpenRecordset("JoinTable")
Dim rs As DAO.Recordset
Dim childrs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("select * from table1")
Do While Not rs.EOF
Debug.Print rs("ID")
Set childrs = rs("col1").Value
Do While Not childrs.EOF
Debug.Print childrs("value") 'always "value"
joinRs.AddNew
joinRs("MainTableId") = rs("ID")
joinRs("JoinToValue") = childrs("value")
joinRs.Update
childrs.MoveNext
Loop
rs.MoveNext
Loop
End Sub
I have the following procedure in Form_Load:
Dim accObject As Access.AccessObject
For Each accObject In CurrentData.AllTables
Me.cboSelectTable.AddItem accObject.Name
Next
This populates the combo box with ALL the tables including system tables and those linked to SQL Server. The problem is, I am only hoping to get back tables which can be edited. How can this be determined using VBA?
When retrieving your set of target table names you can ignore system tables (Like "MSys*") and temporary tables (Like "~*"). And ignore linked tables by checking whether the Connect property is anything other than a zero-length string.
Dim tdf As DAO.TableDef
For Each tdf In CurrentDb.TableDefs
With tdf
If Not (.Name Like "~*" Or .Name Like "MSys*") Then
If Len(.Connect) = 0 Then
Me.cboSelectTable.AddItem .Name
End If
End If
End With
Next
Set tdf = Nothing
If that doesn't give you everything you want, you can also check whether tdf.Updatable is True for each table.
I have already referenced other pages for my problem but I still can't get this to work. I feel a bit slow given that I have three examples below and still can't figure this out.
Changing linked table location programatically
Linked table ms access 2010 change connection string
Update an Access linked table to use a UNC path
Here is the code that I am using:
Dim tdf As TableDef
Dim db As Database
Set db = CurrentDb
Set tdf = db.TableDefs("DeviceListT")
tdf.Connect = "ODBC;DATABASE=" & CurrentProject.path _
& "\HarmonicProfileDatabase_be.accdb"
tdf.RefreshLink
The problem is that when I run it a window pops up.
I am not exactly sure what I am supposed to do with that nor do I want it to pop up in the first place as I will be giving the ms access files to someone else and they won't know what to do with this window either.
You are using SQL Server references but linking MS Access. For MS Access, you do not need an ODBC link, just refer to DATABASE:
DBFile = CurrentProject.path & "\HarmonicProfileDatabase_be.accdb
''Check the file exists
strFile = Dir(DBFile)
If strFile <> "" Then
With CurrentDb
For Each tdf In .TableDefs
''Check that this is a linked table
''It can be useful to use table of tables instead
If tdf.Connect Like "*HarmonicProfileDatabase_be.accdb*" Then
tdf.Connect = ";DATABASE=" & DBFile
tdf.RefreshLink
End If
Next
End With
MsgBox "Link HarmonicProfileDatabase_be.accdb"
Else
MsgBox "Problem"
End If
You could also use:
sConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& DBFile & ";Jet OLEDB:Database Password=pw;"
Hey.
I have the main access database located on a stand alone PC off the network and i have a access database with linked tables on the network linked back to the stand alone PC. I have linked the tables by creating a network share to the stand alone PC and linking them though a path. Can i set it up so that when the database is opened it automatically updates the linked tables.
Ben
You can. I often find it convenient to use a small check form that runs on start-up (set through start-up options) and checks a variety of things, including linked tables. To this end, I also hold a table of linked tables on the local machine, although a list of linked tables can be obtained by iterating through the TableDefs collection, I think it is slightly safer to keep a list.
The check form can check all links and if a link is broken or missing, either ask the user for a new location or use a fixed location. If no problems are found, the form can close itself and open a menu or other form.
In the case of linking to a linked table, it is possible to get the connection to use from:
CurrentDB.TableDefs("TableName").Connection
Here are some more notes:
Sub RelinkTables(Optional strConnect As String = "")
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL
Dim tdf As DAO.TableDef
On Error GoTo TrapError
Set db = CurrentDb
If strConnect = "" Then
''Where Me.txtNewDataDirectory is a control on the check form
strConnect = "MS Access;PWD=databasepassword;DATABASE=" & Me.txtNewDataDirectory
End If
''Table of tables to be linked with two fields TableName, TableType
Set rs = CurrentDb.OpenRecordset("Select TableName From sysTables " _
& "WHERE TableType = 'LINK'")
Do While Not RS.EOF
''Check if the table is missing
If IsNull(DLookup("[Name]", "MSysObjects", "[Name]='" & rs!TableName & "'")) Then
Set tdf = db.CreateTableDef(RS!TableName, dbAttachSavePWD, _
rs!TableName, strConnect)
''If the table is missing, append it
db.TableDefs.Append tdf
Else
''If it exists, update the connection
db.TableDefs(rs!TableName).Connect = strConnect
End If
db.TableDefs(rs!TableName).RefreshLink
RS.MoveNext
Loop
Set db = Nothing
RS.Close
Set RS = Nothing
Exit_Sub:
Exit Sub
TrapError:
HandleErr Err.Number, Err.Description, "Relink Tables"
End Sub
i have to create reports with certain data from an access database. i want to automate this process by the use of visual basic. i have created queries to achieve this but the problem is each time i have a different database(with same structure).
queries that i have has "create table", due to which i am unable to fire those queries from VB6 directly. Is there any way i can solve this problem?
You can use the IN clause in SQL queries to reference different MDB files. For example:
"SELECT srpID, srpServiceRecordID, srpInvoiceDate, srpInvoiceNumber, srpParts " & _
"FROM ServiceRecordParts IN '" & strDatabasePathandName & "';"
You can run a CREATE TABLE SQL DDL statement (not a query!) against the Access database engine from VB6 by using a data access technology. ADO is best for DDL (e.g. richer syntax than DAO).
You can create a new table, including data, using
SELECT * INTO MyTableClone FROM MyTable;
but it will not copy any constraints e.g. all columns will be nullable :(
You can also use SQL DDL to create a VIEW or a PROCEDURE depending on what you mean by 'query'.
You can run both queries and SQL from VBA. Here are a few notes.
Dim db As Database
Dim strSQL As String
Dim qdf As QueryDef
''Execute
Set db = CurrentDb
strSQL = "SELECT EmpID, EmpName INTO NewT FROM tblT WHERE EmpName Is Not Null"
''This will fail if the table already exists
''Only Action queries can be Executed
db.Execute strSQL, dbFailOnError
Debug.Print db.RecordsAffected
''This is not such a good approach
''Open query, will give warning
''that the table is about to be deleted.
DoCmd.OpenQuery "qryUpdate"
''Also not so good
''Open query, skip warning
DoCmd.SetWarnings False
DoCmd.OpenQuery "qryUpdate"
''This line is very important indeed
''never set warnings off, unless you
''set then on again
DoCmd.SetWarnings True
''Use query
Set qdf = db.QueryDefs("qryUpdate")
''The table in this SQL already exists, so
''a small diversion
db.Execute "DROP TABLE NewT", dbFailOnError
''Back on track
qdf.Execute dbFailOnError
Debug.Print qdf.RecordsAffected
''Change query SQL
qdf.SQL = strSQL
''Use SQL from query
strSQL = qdf.SQL
''The table in this SQL already exists, so
''a small diversion
db.Execute "DROP TABLE NewT", dbFailOnError
''Back on track
db.Execute strSQL, dbFailOnError
Debug.Print db.RecordsAffected
Your database will need a lot of compacting if you regularly add and delete tables and queries, so it is usually best to avoid this.