创建后立即编辑记录

时间:2017-10-12 00:16:27

标签: vba ms-access

对于我的粘贴功能,在某些情况下,我需要能够创建一条记录并在之后立即进行编辑。这是因为我需要知道为AutoNumber字段生成的值。 我得到的错误是“没有AddNew或编辑的更新或取消更新”。我在代码示例中标记了此错误的位置。

我粘贴了我的整个粘贴功能,以防它可能会有所帮助。虽然我不确定如何正确执行的代码位于底部4(***下面的所有内容)。

如果你想确切地知道我想要做什么,请随意阅读帖子的其余部分,尽管它应该足够了。

基本上我要做的是剪贴板中的每条记录,我想复制它 - 复制所有字段的值。但也有例外。感兴趣的是AutoNumber字段,“ESDNodeID”和“ParentID”,它是记录继承的记录的ESDNodeID。

对正在复制的已存在节点的剪贴板(包含ESDNodeID和ParentID)进行排序,以便如果子记录具有父记录,则其父记录是列表中的下一个记录。所以我的想法是我可以使用为记录的id生成的AutoNumber值来找出它的父id(它应该只是它的id + 1,因为它是for循环中的下一个)。

Public Function Paste(nodeID As Long)
  Dim currScenarioID As Long
  Dim i As Long
  Dim saveParentIDs As Collection
  Set saveParentIDs = New Collection
  currScenarioID = Forms("Main")!Scenarios!ScenarioID

  Dim rstSource   As DAO.Recordset
  Dim rstInsert   As DAO.Recordset
  Dim fld         As DAO.Field

  'We want to insert records into the ESDNodes table
  Set rstInsert = CurrentDb.OpenRecordset("ESDNodes")

  'We want to insert a record for each element in the clipboard
  For i = 0 To UBound(clipboard)
     'rstSource represents the record that we want to copy. Should only be 1 as ESDNodeID is unique.
     Set rstSource = CurrentDb.OpenRecordset("SELECT * FROM ESDNodes WHERE ESDNodeID = " & clipboard(i)(0))
     rstSource.MoveFirst
        With rstInsert
           'create a new record
           .AddNew
              'Want to copy all the fields
              For Each fld In rstSource.Fields
                 With fld
                    If .Name = "ESDNodeID" Then
                       'Skip Autonumber field
                    'If the field is the ParentID
                    ElseIf .Name = "ParentID" Then
                       'If the clipboard has a NULL value that means the node selected is the Parent
                       If IsNull(clipboard(i)(1)) Then
                          rstInsert.Fields(.Name).value = nodeID
                       'If the parent ID has already been created for another node, we want to grab that ID

                       ElseIf Contains(saveParentIDs, CStr(clipboard(i)(1))) Then
                          rstInsert.Fields(.Name).value = saveParentIDs(CStr(clipboard(i)(1)))
                       'If neither of these conditions pass, the parentID is handled after the for loop
                       End If
                    'We want the active scenario id
                    ElseIf .Name = "ScenarioID" Then
                       rstInsert.Fields(.Name).value = currScenarioID
                    'Copy all other fields direcly from record
                    Else
                       rstInsert.Fields(.Name).value = .value
                    End If
                 End With
              Next
              'If the parent ID was not set above, that means we have not yet created the record corresponding to its parentID
              'But because of how our clipboard is sorted, it will be the next one in the loop. Meaning that we can create this new record
              'with an empty parentID, and then predict the id of its parent by simply adding 1 to its id

              '*****************
              .Update
              .MoveLast
              If Not IsNull(clipboard(i)(1)) Then
                 If Not Contains(saveParentIDs, CStr(clipboard(i)(1))) Then
                    !parentID = !ESDNodeID + 1 'ERROR HERE
                    saveParentIDs.Add !parentID, CStr(clipboard(i)(1))
                    .Update
                 End If
              End If
              .Close
        End With
  Next i
  loadESDTreeView
End Function

1 个答案:

答案 0 :(得分:1)

在更改现有记录集字段之前,您应该使用方法.Edit

也不要在rstInsert内关闭For,它会在下一行失败。

更多的事情。

可能我没有抓住整个想法,但是如果你在编辑它之前移动到最后一行只是为了阅读ESDNodeID后生成的.AddNew,你就不会这样做。我需要将.Update.MoveLast一起使用,您可以在.AddNew之后立即阅读新ID。

预测自动编号字段值是个坏主意,尤其是在多用户环境中。

数据库完整性非常重要,因此ParentID应该在ESDNodeID上具有外键约束,在这种情况下,数据库不允许您插入不存在的ESDNodeID。尝试检查此过程的逻辑。

相关问题