[AccessD] DAO rules
Gustav Brock
gustav at cactus.dk
Wed Feb 17 10:21:23 CST 2021
Hi all
I have often promoted DAO rather than lengthy and custom append queries, as the tool to copy a parent record and its child records.
This, I had the chance to expand to also copy subchild records (or grandchildren records if you like) of the child records.
The clever part is, that - apart from the key fields, the subform control name, and the subchild table/query name - specifics like field names are not used:
https://www.experts-exchange.com/questions/29208270/MS-Access-Duplicate-Records-with-Multi-Levels-of-Subforms.html#a43244285
If you can't open the link, code is here:
Private Sub CopyButton_Click()
Dim rst As DAO.Recordset
Dim rstAdd As DAO.Recordset
Dim rstSub As DAO.Recordset
Dim rstSubAdd As DAO.Recordset
Dim fld As DAO.Field
Dim Count As Integer
Dim CountSub As Integer
Dim Item As Integer
Dim ItemSub As Integer
Dim Bookmark As Variant
Dim OldId As Long
Dim NewId As Long
Dim NewSubId As Long
' Copy parent record.
Set rstAdd = Me.RecordsetClone
Set rst = rstAdd.Clone
' Move to current record.
rst.Bookmark = Me.Bookmark
OldId = rst!Id.Value
With rstAdd
.AddNew
For Each fld In .Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
Else
.Value = rst.Fields(.Name).Value
End If
End With
Next
.Update
' Pick Id of the new record.
.MoveLast
NewId = !Id.Value
End With
' Store location of new record.
Bookmark = rstAdd.Bookmark
' Copy child records.
' If a subform is present:
Set rstAdd = Me!subChild.Form.RecordsetClone
' If a subform is not present, retrieve records from the child table:
' Set rstAdd = CurrentDb.OpenRecordset("Select * From tblChild Where FK = " & OldId & "")
Set rst = rstAdd.Clone
If rstAdd.RecordCount > 0 Then
rstAdd.MoveLast
rstAdd.MoveFirst
End If
Count = rstAdd.RecordCount
For Item = 1 To Count
With rstAdd
.AddNew
For Each fld In .Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "FK" Then
' Skip master/child field.
.Value = NewId
Else
.Value = rst.Fields(.Name).Value
End If
End With
Next
.Update
' Pick Id of the new record.
.MoveLast
NewSubId = !Id.Value
End With
' Copy childchild records.
Set rstSubAdd = CurrentDb.OpenRecordset("Select * From tblChildChild Where FK = " & rst!Id.Value & "")
Set rstSub = rstSubAdd.Clone
If rstSubAdd.RecordCount > 0 Then
rstSubAdd.MoveLast
rstSubAdd.MoveFirst
End If
CountSub = rstSubAdd.RecordCount
For ItemSub = 1 To CountSub
With rstSubAdd
.AddNew
For Each fld In .Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "FK" Then
' Skip master/child field.
.Value = NewSubId
Else
.Value = rstSub.Fields(.Name).Value
End If
End With
Next
.Update
End With
rstSub.MoveNext
Next
rst.MoveNext
Next
rstSub.Close
rstSubAdd.Close
rst.Close
rstAdd.Close
' Move to the new recordcopy.
Me.Bookmark = Bookmark
Set fld = Nothing
Set rstSubAdd = Nothing
Set rstSub = Nothing
Set rstAdd = Nothing
Set rst = Nothing
End Sub
/gustav
More information about the AccessD
mailing list