Just to find out the difference I ran some code to copy the Northwind 2000 database object by object, using a reference to DAO v 3.6 and with the CreateObject method.
The code shown below was run, then the variables changed to Dim dbSrc As DAO.XXX etc.. This gave the following results in milliseconds (ADOX code shown for interest):
Code:
Method         1st Run    2nd Run   3rd run
CreateObject   2377       2172      2184
Reference      1256       1167      1163 
ADOX           7266       6745      6696
So it seems direct reference is almost twice the speed of Create Object,(and about six times faster than ADOX)
VB Code:
  1. Private Sub cmdDAOCopy_Click()
  2.     Dim dbE As Object
  3.     Dim dbSrc As Object
  4.     Dim dbNew As Object
  5.     Dim tdefSrc As Object
  6.     Dim tdefNew As Object
  7.     Dim fdSrc As Object
  8.     Dim fdNew As Object
  9.     Dim ixSrc As Object
  10.     Dim ixNew As Object
  11.     Dim rsSrc As Object
  12.     Dim rsNew As Object
  13.     Dim rlSrc As Object
  14.     Dim rlNew As Object
  15.     Dim qdSrc As Object
  16.     Dim qdNew As Object
  17.     Dim prop As Object
  18.    
  19.     Dim fAccess97 As Boolean
  20.     Dim strSource As String
  21.     Dim strDestination As String
  22.     Dim strPassword As String
  23.     Dim iCt As Integer
  24.     Dim iCount As Integer
  25.     Dim cTimer As clsTimer
  26.     Dim tl As Long
  27.     Dim t1 As Long, t2 As Long
  28.    
  29.     'select database to copy
  30.     With cdlgFile
  31.         .DialogTitle = "Select Database to Copy"
  32.         .Filter = "Access 97/2000 (*.mdb)|*.mdb"
  33.         .CancelError = False
  34.         .InitDir = "C:\My Documents"
  35.         .ShowOpen
  36.     End With
  37.     strSource = cdlgFile.FileName
  38.     If strSource = "" Then
  39.         MsgBox "Cancel clicked"
  40.         Exit Sub
  41.     End If
  42.    
  43.     strPassword = InputBox("Enter password for this database. Leave blank if no password required")
  44.    
  45.     'open database with DAO 3.6 then find correct version
  46.     Set dbE = CreateObject("DAO.DBEngine.36")
  47.     Set dbSrc = dbE.OpenDatabase(strSource, False, False, ";pwd=" & strPassword)
  48.    
  49.     On Error Resume Next
  50.     'loop through properties to find "Connect"
  51.     For Each prop In dbSrc.Properties
  52.         If prop.Name = "Version" Then
  53.             If prop.Value = "3.0" Then
  54.                 fAccess97 = True
  55.             Else
  56.                 fAccess97 = False
  57.             End If
  58.             Exit For
  59.         End If
  60.     Next prop
  61.     On Error GoTo 0
  62.    
  63.     If fAccess97 Then
  64.         'Check if copy is to stay as Access 97 or convert to 2000
  65.         If MsgBox(strSource & vbCrLf & "Is an Access 97 Database. Do you want to convert it to Access 2000 Format?", vbQuestion + vbYesNo) = vbYes Then
  66.             fAccess97 = False
  67.         End If
  68.     End If
  69.     'Select name of database copy
  70.     With cdlgFile
  71.         .DialogTitle = "Save Database as"
  72.         .Filter = "Access 97/2000 (*.mdb)|*.mdb"
  73.         .CancelError = True
  74.         .InitDir = "C:\My Documents"
  75.         .ShowSave
  76.     End With
  77.     strDestination = cdlgFile.FileName
  78.    
  79.     'check if chosen name already exists
  80.     If Dir$(strDestination) <> "" Then
  81.         If MsgBox(strDestination & " already exists. Overwrite?", vbQuestion + vbYesNo) = vbNo Then
  82.             Exit Sub
  83.         Else
  84.             Kill strDestination
  85.         End If
  86.     End If
  87.    
  88.     'start timing...
  89.     Set cTimer = New clsTimer
  90.     cTimer.Reset
  91.    
  92.     Me.Caption = "Creating database..."
  93.     DoEvents
  94.    
  95.     If fAccess97 Then
  96.         'create 97 version
  97.         Set dbNew = dbE.CreateDatabase(strDestination, dbLangGeneral, dbVersion30)
  98.     Else
  99.         'create 2000 version
  100.         Set dbNew = dbE.CreateDatabase(strDestination, dbLangGeneral, dbVersion40)
  101.     End If
  102.    
  103.     'now copy tables
  104.     For Each tdefSrc In dbSrc.TableDefs
  105.         'check if system table
  106.         If InStr(1, tdefSrc.Name, "MSys", vbTextCompare) = 0 Then
  107.             'not a system table
  108.             Set tdefNew = dbNew.CreateTableDef(tdefSrc.Name)
  109.             tdefNew.ValidationRule = tdefSrc.ValidationRule
  110.             tdefNew.ValidationText = tdefSrc.ValidationText
  111.             For Each fdSrc In tdefSrc.Fields
  112.                 'check for replication fields s_GUID, s_Generation, s_Lineage, Gen_XXX
  113.                 If InStr(1, fdSrc.Name, "s_", vbTextCompare) = 0 And InStr(1, fdSrc.Name, "Gen_", vbTextCompare) = 0 Then
  114.                     Set fdNew = tdefNew.CreateField(fdSrc.Name, fdSrc.Type, fdSrc.Size)
  115.                     On Error Resume Next
  116.                     fdNew.Attributes = fdSrc.Attributes
  117.                     fdNew.AllowZeroLength = fdSrc.AllowZeroLength
  118.                     fdNew.DefaultValue = fdSrc.DefaultValue
  119.                     fdNew.Required = fdSrc.Required
  120.                     fdNew.Size = fdSrc.Size
  121.                     tdefNew.Fields.Append fdNew
  122.                     On Error GoTo 0
  123.                 End If
  124.             Next
  125.             'now copy indexes
  126.             For Each ixSrc In tdefSrc.Indexes
  127.                 'Check for replication indices s_GUID, s_Generation
  128.                 If InStr(1, ixSrc.Name, "s_", vbTextCompare) = 0 Then
  129.                     'Don't copy indices set as part of Relation Objects
  130.                     If Not ixSrc.Foreign Then
  131.                         Set ixNew = tdefNew.CreateIndex(ixSrc.Name)
  132.                         ixNew.Clustered = ixSrc.Clustered
  133.                         ixNew.IgnoreNulls = ixSrc.IgnoreNulls
  134.                         ixNew.Primary = ixSrc.Primary
  135.                         ixNew.Required = ixSrc.Required
  136.                         ixNew.Unique = ixSrc.Unique
  137.                         'Add Index field(s)
  138.                         For Each fdSrc In ixSrc.Fields
  139.                             Set fdNew = ixNew.CreateField(fdSrc.Name)
  140.                             fdNew.Attributes = fdSrc.Attributes
  141.                             ixNew.Fields.Append fdNew
  142.                         Next
  143.                         tdefNew.Indexes.Append ixNew
  144.                     End If
  145.                 End If
  146.             Next
  147.             dbNew.TableDefs.Append tdefNew
  148.         End If
  149.     Next
  150.    
  151.     'now copy querydefs
  152.     For Each qdSrc In dbSrc.QueryDefs
  153.         Set qdNew = dbNew.CreateQueryDef(qdSrc.Name, qdSrc.SQL)
  154.         qdNew.Connect = qdSrc.Connect
  155.         qdNew.MaxRecords = qdSrc.MaxRecords
  156.         qdNew.ReturnsRecords = qdSrc.ReturnsRecords
  157.         'Next Line gives error 3219 Invalid operation, but is not needed as added automatically!
  158.         'Nice to have such consistency when dealing with objects!
  159.         'dbSrc.QueryDefs.Append qdNew
  160.     Next qdSrc
  161.    
  162.     'now copy data
  163.     Me.Caption = "Copying Data..."
  164.     DoEvents
  165.     For Each tdefSrc In dbSrc.TableDefs
  166.         If InStr(1, tdefSrc.Name, "MSys", vbTextCompare) = 0 Then
  167.             'not a system table
  168.             Set rsNew = dbNew.OpenRecordset(tdefSrc.Name, dbOpenTable)
  169.             Set rsSrc = dbSrc.OpenRecordset(tdefSrc.Name, dbOpenTable)
  170.            
  171.             If Not rsSrc.BOF Then
  172.                 rsSrc.MoveFirst
  173.                 Do Until rsSrc.EOF
  174.                     rsNew.AddNew
  175.                     For iCt = 0 To rsNew.Fields.Count - 1
  176.                         rsNew.Fields(iCt).Value = rsSrc.Fields(rsNew.Fields(iCt).Name).Value
  177.                     Next
  178.                     rsNew.Update
  179.                     rsSrc.MoveNext
  180.                 Loop
  181.             End If
  182.             rsNew.Close
  183.             rsSrc.Close
  184.         End If
  185.     Next
  186.    
  187.     'now copy relations
  188.     'Does not seem to be a similar method available with ADO...
  189.     For Each rlSrc In dbSrc.Relations
  190.         Set rlNew = dbNew.CreateRelation(rlSrc.Name, rlSrc.Table, rlSrc.ForeignTable, rlSrc.Attributes)
  191.         For Each fdSrc In rlSrc.Fields
  192.             rlNew.Fields.Append rlNew.CreateField(fdSrc.Name)
  193.             rlNew.Fields(fdSrc.Name).ForeignName = rlSrc.Fields(fdSrc.Name).ForeignName
  194.         Next fdSrc
  195.         dbNew.Relations.Append rlNew
  196.     Next rlSrc
  197.     dbNew.Close
  198.     dbSrc.Close
  199.     Set dbE = Nothing
  200.     tl = cTimer.Interval
  201.     Me.Caption = "Time taken " & tl & " ms(" & tl / 1000 & " secs, " & (tl / 1000) / 60 & " mins"
  202.     Set cTimer = Nothing
  203. End Sub
Code for clsTimer
VB Code:
  1. Option Explicit
  2.  
  3. Private Declare Function timeGetTime Lib "winmm.dll" () As Long
  4. Private StartTime As Long
  5. Private Sub Class_Initialize()
  6.     StartTime = timeGetTime()
  7. End Sub
  8. Public Property Get Interval() As Long
  9.    'return time interval in milliseconds
  10.    Interval = timeGetTime() - StartTime
  11. End Property
  12. Public Sub Reset()
  13.    ' Reset starting time.
  14.     StartTime = timeGetTime()
  15. End Sub