Code:
Option Compare Database
Private Sub go_Click()
' Initialize variables
Dim tableOne, tableTwo, fieldName As String
Dim valueOne, valueTwo, strValueOne, strValueTwo As String
Dim db As Database
Dim rstOne, rstTwo, rstDataOne, rstnoMatch, rstDataOutPut As DAO.Recordset
Dim match As Boolean
Set db = CurrentDb()
tableOne = Me.tableOne
tableTwo = Me.tableTwo
fieldName = Me.fieldName
idField = Me.ID
DoCmd.SetWarnings False
DoCmd.RunSQL ("DROP TABLE DataTwo;")
DoCmd.RunSQL (" CREATE TABLE DataTwo;")
DoCmd.RunSQL ("ALTER TABLE DataTwo ADD ID AUTOINCREMENT (1,1), Compared Text, Identifier Number, TableName Text, strValue Text ;")
DoCmd.RunSQL ("INSERT INTO DataTwo (Compared, Identifier, TableName, strValue) SELECT " & fieldName & ", " & idField & ", '" & tableTwo & "', strValue FROM " & tableTwo & " ; ")
'Delete Tables from previous run and recreate new tables. DataOne holds the matched values from table Two
'DataTwo holds the values of TableOne, this may seem unneccisary but it allows to do a left join on the autoincrement, which is nice.
DoCmd.RunSQL ("DROP TABLE DataOutput;")
DoCmd.RunSQL ("DROP TABLE DataOne;")
DoCmd.RunSQL ("DROP TABLE DataThree;")
DoCmd.RunSQL ("DROP TABLE noMatch;")
DoCmd.RunSQL (" CREATE TABLE DataOutPut;")
DoCmd.RunSQL (" CREATE TABLE DataOne;")
DoCmd.RunSQL (" CREATE TABLE DataThree;")
DoCmd.RunSQL (" CREATE TABLE noMatch;")
DoCmd.RunSQL ("ALTER TABLE DataOutput ADD ID AUTOINCREMENT (1,1), TableName1 Text, Identifier1 Number, Compared Text, TableName2 Text, Identifier2 Number, strValueOne Text, strValueTwo Text ;")
DoCmd.RunSQL ("ALTER TABLE DataOne ADD ID AUTOINCREMENT(1,1), Compared Text, Identifier Number, TableName Text, strValue Text ;")
DoCmd.RunSQL ("ALTER TABLE DataThree ADD ID AUTOINCREMENT(1,1), Compared Text, Identifier Number, TableName Text, strValue Text ;")
DoCmd.RunSQL ("ALTER TABLE noMatch ADD Identifier2 Number, Compared Text, TableName2 Text, strValueTwo Text ;")
'Populate DataThree with the required elements of Table1
'Set Used = 0, Used allows us to see if a element of Table 2 has been matched or not.
DoCmd.RunSQL ("INSERT INTO DataThree (Compared, Identifier, TableName, strValue) SELECT " & fieldName & ", " & idField & ", '" & tableOne & "', strValue FROM " & tableOne & " ; ")
DoCmd.RunSQL ("UPDATE " & tableTwo & " Set Used = 0; ")
DoCmd.SetWarnings True
Set rstOne = db.OpenRecordset(tableOne, dbOpenDynaset)
Set rstTwo = db.OpenRecordset(tableTwo, dbOpenDynaset)
Set rstDataOne = db.OpenRecordset("DataOne", dbOpenDynaset)
match = False
LastId = 0
' Setup Do Loop to cycle through the entries of the first table
Do While Not rstOne.EOF And match = False
' Grab values from the first entry in both tables
valueOne = rstOne.Fields(fieldName)
idOne = rstOne.ID
rstTwo.MoveFirst
valueTwo = rstTwo.Fields(fieldName)
idTwo = rstTwo.ID
strValueOne = rstOne.strValue
strValueTwo = rstTwo.strValue
' If the string values match, then write them into the output table, we dont have to worry about preserving order
' since this is the first entry
If valueOne = valueTwo Then
rstDataOne.AddNew
rstDataOne![Compared] = valueOne
rstDataOne![TableName] = tableTwo
rstDataOne![identifier] = idTwo
rstDataOne![strValue] = strValueOne
rstDataOne.Update
rstTwo.Edit
rstTwo![Used] = 1
rstTwo.Update
match = True
LastId = idTwo
End If
rstTwo.MoveNext
' Setup Do Loop to look for the first match between the entry in the first table, and the entries in the second table
Do While match = False And Not rstTwo.EOF
valueTwo = rstTwo.Fields(fieldName)
' If we have a match then we want to check that the match preserves order, if it does then we want to write it to the output
' If there is no match that is order preserving we leave the field blank
If valueOne = valueTwo Then
idTwo = rstTwo.ID
If LastId < idTwo + 1 Then
rstDataOne.AddNew
rstDataOne![Compared] = valueOne
rstDataOne![TableName] = tableTwo
rstDataOne![identifier] = idTwo
rstDataOne![strValue] = strValueOne
rstDataOne.Update
rstTwo.Edit
rstTwo![Used] = 1
rstTwo.Update
LastId = idTwo
match = True
End If
End If
rstTwo.MoveNext
Loop
'We want to create an empty row in DataOne, this will show up as an empty entry in our Data Output when we join it to DataThree
If match = False Then
rstDataOne.AddNew
rstDataOne![Compared] = valueOne
rstDataOne.Update
End If
' Set match back to false, and move on to the next entry in the first coloumn
match = False
rstOne.MoveNext
Loop
DoCmd.SetWarnings False
'Opening the query Insert1 joins DataOne to DataThree.
DoCmd.OpenQuery ("Insert1")
' We still have to take care of the unmatched elelments of DataThree. This query sens the unused elements to DataOutPut
DoCmd.RunSQL ("INSERT INTO noMatch (Compared, Identifier2, TableName2, strValueTwo) SELECT " & fieldName & ", " & idField & ", '" & tableTwo & "', strValue FROM " & tableTwo & " WHERE Used = 0 ;")
'What needs to happen here is I need to insert the pieces of noMatch into
' DataOutput, adhereing to the order of Identifier2, without changing the order of Identifier1
DoCmd.SetWarnings True
' Open the output table for the data.
DoCmd.OpenTable ("DataOutPut")
Set rstOne = Nothing
Set rstTwo = Nothing
Set rstDataOne = Nothing
Set db = Nothing
End Sub