【问题标题】:Runtime error while trying to copy records尝试复制记录时出现运行时错误
【发布时间】:2020-10-27 19:48:03
【问题描述】:

在下面的代码中,我试图创建与单个 JobID 相关的所有记录的副本。这是为了修订目的创建具有新 ID 的相同作业。代码是:

Public Function CreateRevisions()

Dim lngOldID As Long    'change from long if text
Dim lngNewID As Long
Dim rsS As Recordset    'source recordset
Dim rsT As Recordset    'target recordset
Dim fld As Field

DoCmd.RunCommand acCmdSaveRecord        'Save the record, to make sure all data is saved in table

lngOldID = Forms!JobQuote!JobID

'Copy the main table

Set rsS = CurrentDb.OpenRecordset("Select * From tblJobDetails where JobID=" & lngOldID, dbOpenSnapshot)
Set rsT = CurrentDb.OpenRecordset("tblJobDetails", dbOpenDynaset, dbAppendOnly)

rsT.AddNew
For Each fld In rsS.Fields
    rsT.Fields(fld.Name) = fld
Next
lngNewID = rsT!JobID
rsT.Update

'Copies Drawings

Set rsS = CurrentDb.OpenRecordset("Select * From tblDrawings where JobID=" & lngOldID, dbOpenSnapshot)
Set rsT = CurrentDb.OpenRecordset("tblDrawings", dbOpenDynaset, dbAppendOnly)

rsT.AddNew
rsT!JobID = lngNewID
For Each fld In rsS.Fields
    If fld.Name <> "JobID" Then
        rsT.Fields(fld.Name) = fld
    End If
Next
rsT.Update

“复制图纸”部分会重复多次,但会针对不同的表格进行。我在 rsT.Fields(fld.Name) = fld 上遇到运行时错误。这是运行时错误64224: Method of 'Value' of object 'Field2' failed

为什么会出现这个错误?

【问题讨论】:

标签: vba ms-access


【解决方案1】:

首先,您可能没有将对象指定为 DAO 对象,并且应该在检索新 ID 之前更新记录。

其次,使用现有的 RecordsetClone 可能更简单、更快。

这是来自工作表单和子表单的实际代码:

Private Sub CopyButton_Click()

    Dim rst         As DAO.Recordset
    Dim rstAdd      As DAO.Recordset
    Dim fld         As DAO.Field
    Dim Count       As Integer
    Dim Item        As Integer
    Dim Bookmark    As Variant
    Dim OldId       As Long
    Dim NewId       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 1.
    ' If a subform is present:
'    Set rstAdd = Me!subChild1.Form.RecordsetClone
    ' If a subform is not present, retrieve records from the child table:
    Set rstAdd = CurrentDb.OpenRecordset("Select * From tblChild1 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
        End With
        rst.MoveNext
    Next

    ' Copy child records 2.
    ' If a subform is present:
    Set rstAdd = Me!subChild2.Form.RecordsetClone
    ' If a subform is not present, retrieve records from the child table:
    ' Set rstAdd = CurrentDb.OpenRecordset("Select * From tblChild2 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
        End With
        rst.MoveNext
    Next

    rst.Close
    rstAdd.Close
    
    ' Move to the new recordcopy.
    Me.Bookmark = Bookmark
    
    Set fld = Nothing
    Set rstAdd = Nothing
    Set rst = Nothing

End Sub

【讨论】:

  • 我很遗憾在.Value = rst.Fields(.Name).Value 上收到错误Invalid arugment。大致相同的行,但现在出现了不同的错误。
  • 您检查过多值字段吗? @Tmyers
  • @Andre 有道理。至少,请仔细检查您的代码,因为发布的答案是经过验证的代码。
  • 我不知道这个术语,因为我对此比较陌生。快速阅读。
  • 我认为问题可能在于我有一个附件字段。这可能是造成它的原因吗?编辑:验证它实际上是附件字段,因为当我删除它时代码工作。我将不得不重新考虑如何处理。
【解决方案2】:

我试过你的代码,除非记录集和字段对象变量被声明为 DAO 类型,否则它不会编译或运行。

考虑不关心记录集类型且不需要字段变量的替代方案:

Dim x As Integer
For x = 0 To rsS.Fields.Count - 1
    rsT(rsS(i).Name) = rsS(i)
Next

【讨论】:

  • 在集合的循环中使用时,fld 将被“设置”为每个循环的集合中的一项,如果您调试循环,IntelliSense 将正常显示。
  • 这是我所期望的,但是当我尝试 OP 的代码时,它不会编译或运行。它在fld.Name 上出错。我尝试将记录集声明为 DAO,但没想到也将字段声明为 DAO。这确实有所作为。修改我的答案和代码是一个有效的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 2017-04-04
  • 2018-05-28
相关资源
最近更新 更多