Skip to content

Copying Records and Linked Records

Here’s a good method for copying values from one record to another, including any linked records.

Access Archon #133


Introduction

In Access Archon #51, I described how to copy values from one record to another, using hard-coded control names.  That method does the job, but it requires a lot of editing to make it work for a new form.  And it doesn’t deal with any linked records, such as book authors.  This article describes a more sophisticated (and flexible) method for copying values from one record to another, including any linked records.


Sample Form

The sample database, Copying Records and Linked Records, has a main form, fpriEBookNotes, that display information about ebooks and their authors.  Since a book can have multiple authors, and an author can write multiple books, there is a many-to-many relationship between tblEBooks and tblAuthors, using a linking table (tblEBookAuthors).  A subform on frpiEBookNotes displays the authors for each book; it uses the linking table as its record source.

If you want to copy most (but not all) of the data from a book record to a new record, you need a way to mark the controls whose values should be copied.  I use the handy Tag property of Access controls for this purpose; entering “No Copy” into this property makes the CopyRecord code skip this control.  To copy the author information, the code calls a separate procedure that creates a new record in tblEBookAuthors for each author of the source book, with the AuthorID from the source book and the BookID from the new book.

Figure A shows a book record with two authors; Figure B shows the copy of the record, with data copied from the linked records in the Authors subform, and the cboCategory, cboSource, chkSeries, and cboSeriesName controls (all the other controls have “No Copy” in their Tag properties).


Figure A.  A book record with two authors


Figure B.  A copied book record, with only authors, category and source copied from the source record


VBA Code

The cmdCopyRecord button on fpriEBookNotes calls the CopyRecord procedure listed below:

Private Sub CopyRecord(frm As Access.Form)

 

On Error GoTo ErrorHandler

 

   Dim CopyFields() As Variant

   Dim lngOldBookID As Long

   Dim lngNewBookID As Long

  

   lngCount = CountControls(frm)

   Debug.Print “Number of controls to copy: ” & lngCount

  

   ‘Redimension array with actual number of controls to copy

   ReDim CopyFields(lngCount – 1, 1)

  

   ‘Cycle through all controls on form Detail section
   ‘(except those marked “No Copy”) and save to an array

   lngCount = 0

   lngArrayNo = 0

   lngOldBookID = frm![BookID]

  

   For Each ctl In frm.Section(acDetail).Controls

      strControlName = ctl.Name

      ‘Debug.Print “Control name: ” & strControlName

     

      If InStr(ctl.Tag, “No Copy”) = 0 Then

      

         ‘Check field type and skip those that don’t have values

         lngControlType = ctl.ControlType

        

         Select Case lngControlType

            ‘Controls with values

            Case acTextBox

               GoTo Copy

           

            Case acComboBox

               GoTo Copy

           

            Case acCheckBox

               GoTo Copy

           

            Case acBoundObjectFrame

               GoTo Copy

              

            Case acListBox

               GoTo Copy

          

            Case acOptionGroup

               GoTo Copy

           

            Case acOptionButton

               ‘Check for control source, and only copy from
               ‘option buttons with one (bound option buttons)

               strTest = ctl.ControlSource

               GoTo Copy

              

            Case Else

               ‘No Value property; nothing to copy

               GoTo NoCopy

         End Select

Copy:

         strFieldName = ctl.ControlSource

         varFieldValue = ctl.Value

         Debug.Print strFieldName & ” value: ” & varFieldValue

         CopyFields(lngArrayNo, 0) = strFieldName

         CopyFields(lngArrayNo, 1) = varFieldValue

         lngArrayNo = lngArrayNo + 1

         lngCount = lngCount + 1

NoCopy:

      End If

   Next ctl

 

   Debug.Print “Number of controls to copy: ” & lngCount

  

   ‘Create recordset, add a new record, and copy data to it from array

   Set dbs = CurrentDb

   strTable = “tblEBooks”

  

   Set rst = dbs.OpenRecordset(strTable, dbOpenDynaset)

   With rst

      .AddNew

      For lngArrayCount = 0 To lngCount – 1

         Debug.Print “Processing row ” & lngArrayCount

         strFieldName = CopyFields(lngArrayCount, 0)

         varFieldValue = CopyFields(lngArrayCount, 1)

         Debug.Print “Field name: ” & strFieldName

         Debug.Print “Field value: ” & varFieldValue

         .Fields(strFieldName) = varFieldValue

      Next lngArrayCount

      lngNewBookID = ![BookID]

      .Update

      .Close

   End With

  

   ‘Copy authors to linked table for new book

   Call CopyAuthors(lngOldBookID, lngNewBookID)

  

   ‘Requery form and go to new record

   frm.Requery

   DoCmd.GoToRecord , frm.Name, acLast

  

ErrorHandlerExit:

   Exit Sub

 

ErrorHandler:

   If Err.Number = 2455 Then

      ‘Unbound option button

      Resume NoCopy

   Else

      MsgBox “Error No: ” & Err.Number & “; Description: ” & _

         Err.Description

      Resume ErrorHandlerExit

   End If

 

End Sub

 

Private Sub CopyAuthors(lngOldBookID As Long, lngNewBookID As Long)

 

On Error GoTo ErrorHandler

 

   Dim lngAuthorID As Long

   Dim qdf As DAO.QueryDef

   Dim rstSource As DAO.Recordset

   Dim rstTarget As DAO.Recordset

   Dim strQuery As String

   Dim strSQL As String

   Dim strTable As String

  

   ‘Check whether there are any authors to copy

On Error Resume Next

   strQuery = “qryCopyBooks”

   DoCmd.DeleteObject acQuery, strQuery

 

On Error GoTo ErrorHandler

  

   strSQL = “SELECT * FROM tblEBookAuthors ” _

      & “WHERE BookID = ” & lngOldBookID & “”

   Debug.Print “SQL: ” & strSQL

   Set dbs = CurrentDb

   Set qdf = dbs.CreateQueryDef(strQuery, strSQL)

   lngCount = Nz(DCount(“*”, strQuery))

   Debug.Print “No. of authors: ” & lngCount

   If lngCount = 0 Then

      Debug.Print ” no authors to copy; canceling”

      GoTo ErrorHandlerExit

   End If

  

   ‘Copy authors for new book

   strTable = “tblEBookAuthors”

   Set rstSource = dbs.OpenRecordset(strQuery, dbOpenDynaset)

   Set rstTarget = dbs.OpenRecordset(strTable, dbOpenDynaset)

   Do While Not rstSource.EOF

      lngAuthorID = rstSource![AuthorID]

      rstTarget.AddNew

      rstTarget![BookID] = lngNewBookID

      rstTarget![AuthorID] = lngAuthorID

      rstTarget.Update

      rstSource.MoveNext

   Loop

  

ErrorHandlerExit:

   Exit Sub

 

ErrorHandler:

   MsgBox “Error No: ” & Err.Number & “; Description: ” & Err.Description

   Resume ErrorHandlerExit

 

End Sub

 

The final procedure, CountControls, uses code very similar to the code that iterates through the form controls in the CopyRecord procedure.


References

The code in the sample database needs the following references (in addition to the default references):

Microsoft DAO 3.6 Object Library

If you import code or objects into a database of your own, you may need to set this reference.  The version number may differ, depending on your Office version; check the version you have.  References are set in the References dialog, opened from the VBA window.  For more information on working with references, see Access Archon #107, Working with References.


Supporting Files

The zip file containing this article, in Word format, plus the supporting file, may be downloaded from the Access Archon page of my Web site.  It is accarch133.zip, which is the last entry in the table of Access Archon columns for Access Watch.










Document Name

Document Type

Place in

Copying Records and Linked Records.mdb

Access 2000 database (can also be used in higher versions of Access)

Wherever you want

 

About this author

Office 2024 - all you need to know. Facts & prices for the new Microsoft Office. Do you need it?

Microsoft Office upcoming support end date checklist.