Duplicate of Main and subform via Insert into in vba does not insert, while in query it works

Viewed 136

All,

I am strugling with a problem for a while now. I am looking everywhere on the internet but did not find a solution yet. I have two tables, a main table (tbl_D_opp_prod_offer) and a detail table (tbl_D_opp_prod_offer_line). A user can select in a userform to create a duplicate of a record in the main form to start changing the new record. Also the associated records of the detail table should be duplicated. This is because sometimes it is faster for a user to grab another line as a template because it is already prefilled. I have simplified the below example.

Main table consists of:
Opp_ID = PK (autonumber)
Project (and several other fields)

Detail table consists of:
Opp_line_ID = PK (autonumber)
Opp_ID = FK (number)
Product (and several other fields)

I have used two ways, one with sql and one with recordsets. Both don't work. When I debug.print the sql route as a new query it works. So I don't get it where it goes wrong. The relationship has Enforce referential integrity, Cascade update and cascade delete. I really hope somebody could help me with this, I am loosing my hair ;-) Because I have stored it in Form class object of the main form, could this be an issue? Or a key violation? How can I change this?

The code I have for the SQL solution:

Public Function duplicate()
    'Find selected record
    DoCmd.SearchForRecord , , , "[Project_ID] = " & "'" & [Forms]![Frm_Opp_prod_offer]!        [lst_Edit_project_ID] & "'"

      Dim OldId As Integer, NewId As Integer

' Read old ID
OldId = Me.Opp_ID

' copy main table records to new record
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdCopy
DoCmd.RunCommand acCmdRecordsGoToNew
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdPaste

' Read new ID
NewId = Me.Opp_ID


' Copy all records from old ID to new ID
       S = "INSERT INTO [tbl_D_opp_prod_offer_line] (Opp_ID, Product) " & _
            "SELECT " & NewId & " As Opp_ID, Product " & _
            "FROM [tbl_D_opp_prod_offer_line] WHERE Opp_ID = " & OldId

    Debug.Print S
       Stop
        ' Hit Ctrl+G, copy SQL from Immediate Window to a new query

        CurrentDb.Execute S, dbFailOnError


      ' Load copied records
        Me!Frm_Opp_prod_offer_line.Form.Requery

    End Function

`

The solution via Recordset:

Sub method2()


      Dim rstSource   As DAO.Recordset
      Dim rstInsert   As DAO.Recordset
      Dim fld         As DAO.Field
      Dim strSQL      As String
      Dim lngLoop     As Long
      Dim lngCount    As Long
      Dim OldId As Integer, NewId As Integer

    'Beginning is same
    'Find selected record
    DoCmd.SearchForRecord , , , "[Project_ID] = " & "'" & [Forms]![Frm_Opp_prod_offer]![lst_Edit_project_ID] & "'"

' Read old ID
OldId = Me.Opp_ID

' copy main table records to new record
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdCopy
DoCmd.RunCommand acCmdRecordsGoToNew
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdPaste

' Read new ID
NewId = Me.Opp_ID

      strSQL = "SELECT * FROM tbl_D_opp_prod_offer_line WHERE Opp_ID = " & OldId

      ' Change this to the RecordsetClone of the subform.
      Set rstInsert = CurrentDb.OpenRecordset(strSQL)


      Set rstSource = rstInsert.Clone
      With rstSource
        lngCount = .RecordCount
        For lngLoop = 1 To lngCount
          With rstInsert
            .AddNew
              For Each fld In rstSource.Fields
                With fld
                  If .Attributes And dbAutoIncrField Then
                    ' Skip Autonumber or GUID field.
                 If .Name = "Opp_ID" Then  ' Name of FK.
                      rstInsert.Fields(.Name).Value = NewId  ' The new ID of the parent.
                           Else
                    ' Copy field content.
                    rstInsert.Fields(.Name).Value = .Value
                  End If
                  End If
                End With
              Next

    .Update
  End With
  .MoveNext
Next
rstInsert.Close
.Close
      End With

      Set rstInsert = Nothing
      Set rstSource = Nothing


End Sub
2 Answers

Once new main record is created on form, must first commit to table before creating dependent records.

Ways to force committing record:

If Me.Dirty Then Me.Dirty = False

RunCommand acCmdSaveRecord

DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

Me.Refresh

Me.Requery
Related