Automatically updating/duplicating a table in Microsoft Access with VBA - sql

Back again! So I am currently trying to programmatically have a table (Table2) update after a button is pressed. I would like for Table2 to resemble exactly another table (Table1). I'm going through this effort because Access does not allow double relationships and I have need to create one. I will therefore have two tables containing all the contact info.
I tried deleting Table2 and then creating another copy of Table1 and saving it as Table2. This would have worked is Microsoft Access didn’t throw an error because I am deleting a Table that has established relationships. So I then tried to programmatically delete and then create the appropriate relationships. However, this turns out to be a tedious exercise. A little too tedious for my taste.
My next thought is to create an append query that automatically looks for differences between the two tables and updates Table2 accordingly. The problem is that I have no idea how to structure the SQL statement for such an append query. Also is there an easier way to do this using VBA that I am missing? Thanks in advance for your help!

There is no need to go to all this trouble. You can have double relationships in MS Access. Simply add the table as many times as you need it to the relationship design window, you will get Table1, Table1_1, Table1_2 and so on, but they are all just aliases for Table1. You can now add self-joins and as many relationships as you need.
Like so:
*People*
PersonID *People_1*
ManagerID -- > PersonID

It sounds like you are able to append from Table1 to Table2 without running afoul of any relationship. If that is true, you can empty out Table2, then append all the rows from Table1.
Dim cn As Object
Set cn = CurrentProject.Connection
cn.Execute "DELETE FROM Table2"
If Table2 includes an autonumber field, reset its seed value.
cn.Execute "ALTER TABLE Table2" & vbCrLf & _
"ALTER COLUMN autonum_fld COUNTER(1, 1)"
Then do the append ...
cn.Execute _
"INSERT INTO Table2 (autonum_fld, text_field, long_int_field)" & vbCrLf & _
"SELECT autonum_fld, text_field, long_int_field" & vbCrLf & _
"FROM Table1;"
... or if the two table structures are identical, you don't even have to list the field names ...
cn.Execute "INSERT INTO Table2" & vbCrLf & _
"SELECT *" & vbCrLf & _
"FROM Table1;"
And finally ...
Set cn = Nothing
AFAICT, that could work. However, I don't understand the background details of your question, for example "Access does not allow double relationships". So I may be completely off the mark.

Related

MS Access: How to set outer join in constraint in VBA?

When I create a relationship between two tables manually at Database Tools > Relationships, Access lets me set the join properties so that it is either an inner join or a left or right outer join:
But when I create the relationship in VBA:
sSQL = "ALTER TABLE [" & sTable1 & "] ADD CONSTRAINT [" & sTable1 & "] " & _
"FOREIGN KEY ([" & sKey & "]) REFERENCES [" & sTable2 & "]([" & sKey & "]);"
oDB.Execute sSQL
it creates the relationship as an inner join. I can see this by going to Database Tools > Relationships and looking at the relationship created by VBA:
I do not see a way to tell VBA what join properties to use, and it apparently decides on its own to make an inner join. (Another problem is that the little infinity symbol on the left side of the connector line means that Access thinks this is a one-to-many relationship, but since the linked fields are the primary key, it's one-to-one, as seen in the first image above.)
Microsoft has documentation on this process at:
ALTER TABLE statement (Microsoft Access SQL)
CONSTRAINT clause (Microsoft Access SQL)
Modify a table's design using Access SQL
Create Foreign Key Relationships
There is also documentation on how to do this in DAO instead of SQL:
Database.CreateRelation method (DAO)
I don't see anything in any of that that allows me to choose the join properties.
I need the table relationship to be an outer join so that it includes all the records of one table and only the records of the second table in which the primary keys are equal. How can I create that relationship in VBA?
Updates:
Looking at this more, you will need the attributes value of the relation object.
Problem is, the attribute constants are bitwise and a bit elusive in the documentation. A value of 0 is the default you see and the rest have to be added up.
So this is what you can do:
Create a relationship in your database in the way you want it (left join, right join etc) and save. Assuming northwind is your database, in a function or module:
Set dbsNorthwind = OpenDatabase("Northwind.mdb")
With dbsNorthwind
' Display the attributes of the Northwind database's
' relations.
Debug.Print "Attributes of relations in " & _
.Name & ":"
For Each relLoop In .Relations
Debug.Print " " & relLoop.Name & " = " & _
relLoop.Attributes
Next relLoop
.Close
End With
The relation you created should show the attribute value you need.
There is also a reference you can use here.
Now when you go to create your own relation, you simply use the CreateRelation function (as in the documentation) and set the attributes you need like so:
Set dbsNorthwind = OpenDatabase("Northwind.mdb")
With dbsNorthwind
Set relNew = .CreateRelation(Name, Table, ForeignTable, Attributes)
' Add join fields
relNew.Fields.Append relNew.CreateField("newFieldName")
relNew.Fields!newFieldName.ForeignName = "joinfieldName"
.Relations.Append relNew
.Close
End With
If for example you wanted a left join, the value you set for "Attributes" would be a combination of dbRelationLeft + another attribute constant represented as one numeric value.

OleDBCommands: executing two commands and checking

I am trying to perform some OLEDB commands between a list of dictionary values and an access database. I am wondering if it is possible to check if one column in the access database matches the key of a dictionary, if you find the key that matches check the keyvalue in the dictionary to the access database quantity in another column. I am just wondering if this is possible since I am new to the SQL in vb.net commands.
I wanted to run these two queries but I am not sure if this is even possible. I tried to find some documents on this but I came out short. Anything would help!
sqlQry = "SELECT Column1 FROM [Table] WHERE Column1 = '" & Key & "' "
sqlQry = "SELECT Column2 FROM [Table] WHERE Column2 < " & Value & " "

adding records to a table using VBA

I send out a newsletter each month and would like to record the contact id, date sent in a separate table. This table will record a history of all the newsletter sent. What is the best way to do this...Append to table or just create a do loop and add new records?
This should be pretty easy. Now, you didn't say is you are appending records into Access, or SQL Server, or something else. The example below assumes you are using Access, but you can easily modify the code just slightly to insert into any kind of structured database.
Dim dbs As DAO.Database
Set dbs = OpenDatabase("Full path to your db")
'You can then "execute" a SQL statement:
dbs.Execute "INSERT INTO Employees(Name, Number) VALUES('" & Worksheets("Sheet1").Range("A2").Value & "','" & Worksheets("Sheet1").Range("A3") & "')"

Access VBA dump recordset into an existing table

I have a recordset and a table, both in exactly the same format. What is the syntax to dump everything in the recordset to the table? This seems to be a very simple procedure but somehow I can't find any useful information online.
Edit1: to clarify, the recordset is obtained from Table A, now I want to dump it into Table B (which is empty). Table A and B have exactly the same format.
Edit2: I am working in Access.
here is the code I used to open the recordset:
Set Table_B_rs = CurrentDb.OpenRecordset("Table_B")
I didn't make any changes to the recordset.
Thanks for the help!
You don't do this with recordsets, but with SQL by running an INSERT INTO query.
CurrentDb.Execute "INSERT INTO TableB SELECT * FROM TableA " & _
"WHERE <same conditions you used to open the recordset>"
If there is no condition, it's simply
CurrentDb.Execute "INSERT INTO Table_B SELECT * FROM Table_A"

How to delete contents of mulitple tables in Microsoft Access?

I need to clear the contents of multiple tables in an Access db using VBA.
Below is the code I am attempting to use, but it throws a "Syntax error in FROM clause." The SQL syntax (DELETE * FROM [table name];) works in a query.
Dim tbl As TableDef
Dim sqlstr As String
DoCmd.SetWarnings False
For Each tbl In CurrentDb.TableDefs
If tbl.Name Like "*_drop" Then
sqlstr = "DELETE * FROM " & tbl.Name
DoCmd.RunSQL sqlstr
End If
Next tbl
I found a similar problem and answer here, but it did not solve my problem.
I have also tried it without the sqlstr and received the same error.
For Each tbl In CurrentDb.TableDefs
If tbl.Name Like "*_drop" Then
DoCmd.RunSQL "DELETE * FROM " & tbl.Name
End If
Next tbl
You confirmed a query like this works without error.
DELETE * FROM [table name];
However the query your code builds does not bracket table name. Therefore, any table name which includes a space or contains nearly any character other than letters, digits, and underscore will result in a DELETE statement which triggers that error. If the table name matches a reserved word, that could also trigger the error. (Unfortunately it's difficult to predict exactly when reserved words will cause trouble.) It's safer to bracket all troublesome words in queries when they are used as field or table names. And for those which are troublesome because they are reserved words, you can alias them instead of bracketing.
But wherever practical, the safest practice is to rename all such objects: avoid reserved words; and use only letters, digits, and underscore.
Meanwhile, code defensively to cope with problem names. Revise the code to always bracket the table name.
sqlstr = "DELETE FROM [" & tbl.Name & "]"
I think you just need DELETE FROM without the *