私のペースト機能では、レコードを作成してすぐに後で編集できるようにする必要があります。これは、オートナンバー型フィールドに生成される値を知る必要があるためです。 私が得るエラーは、「AddNewまたはEditなしのUpdateまたはCancelUpdate」です。このエラーがコードサンプルでポップアップする場所をマークしました。レコードを作成した直後に編集する
貼り付け機能全体が貼り付けられている場合があります。私が正しく実行する方法がわからないコードは、最下位4位(***より下のすべて)です。
私がしようとしていることを正確に知りたいのであれば、それが十分でなければならないが、投稿の残りの部分を自由に読むことができます。
私がしようとしていることは、クリップボードの各レコードに対して、すべてのフィールドの値をコピーすることです。しかし、例外があります。対象となるのは、レコードが継承するレコードのESDNodeIDである、「ESDNodeID」および「ParentID」のオートナンバー型フィールドです。
コピー中の既存のノードのクリップボードはソートされているため、子レコードに親レコードがある場合、その親はリスト内の次の子レコードになります。ですから、私の考えは、レコードのidに対して生成されるAutoNumber値を、親ID(forループの次のものであるid + 1でなければなりません)のために見つけることができるということです。
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
ご回答いただきありがとうございます。特に、データベースの完全性についてお聞かせください。私は外来キーの制約が可能であることを知らなかった。アルゴリズムをかなり変更して、はるかにエレガントでParentIDを推測しない再帰的なソリューションを選択しました。 –