Bonjour à tous,

Voilà, je ne parviens pas à dupliquer une ligne et ses lignes enfants dans une table hiérarchique.

Contexte :
Dans une bdd Access 2010, une table "tbElements" contient une arborescence d'Elements hiérarchisés gràce à une colonne "Id" (Long / autoincrémenté) et une colonne "IdParent" (Long).
Pour chaque ligne, la colonne "IdParent" contient l' "Id" de la ligne parente (0 si elle est à la racine).

Je souhaite pouvoir dupliquer une ligne avec ou sans ses lignes enfants, selon le choix de l'utilisateur.

Cette table est le datasource d'un Treelist de DevExpress.
Le déclenchement de la copie d'une ligne se fait par drag&drop + touche Ctrl.

Voici la procédure lancée sur l'évènnement Drop :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 
    Friend Sub subElements_Copy(ByVal vNode As TreeListNode,
                                ByVal vTargetNode As TreeListNode)
 
       Try
 
            ' Get Elements data
            Dim vTree As TreeList = frmExplorer.treeExplorer
            Dim vNodeName As String = Convert.ToString(vNode.GetValue(frmExplorer.colGeneralName))
            Dim vNodeType As String = Convert.ToString(vNode.GetValue(frmExplorer.colType))
            Dim vTargetName As String = Convert.ToString(vTargetNode.GetValue(frmExplorer.colGeneralName))
            Dim vTargetType As String = Convert.ToString(vTargetNode.GetValue(frmExplorer.colType))
 
            ' Ask to the user if he wants to perform the copy of the children of
            ' the copied Element also
            Dim vRepCopyChildren As DialogResult
            vRepCopyChildren = XtraMessageBox.Show(
                "You are about to copy the [" & vNodeName & "] " & vNodeType & _
                "into the [" & vTargetName & "] " & vTargetType & " !" & _
                vbCrLf & vbCrLf & "Do you want to copy its sub-Elements too ?",
                "Copy the selected Element into the targeted new Parent Element",
                MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Question)
            If vRepCopyChildren = DialogResult.Cancel Then Exit Sub
 
            vTree.OptionsBehavior.EnableFiltering = False
 
            ' Copy Element with or without its children Elements
            Dim vSourceNodeId As Long = Convert.ToInt64(vNode.GetValue(frmExplorer.colId))
            Dim vTargetNodeId As Long = Convert.ToInt64(vTargetNode.GetValue(frmExplorer.colId))
            Dim vNewNodeId As Long
            If vRepCopyChildren = DialogResult.Yes Then
                ' Copy Element WITH its children Elements
                vNewNodeId = fncDALElements_CopyElement_Recursive(vSourceNodeId, vTargetNodeId, True)
            ElseIf vRepCopyChildren = DialogResult.No Then
                ' Copy Element WITHOUT its children Elements
                vNewNodeId = fncDALElements_CopyElement_Recursive(vSourceNodeId, vTargetNodeId, False)
            End If
 
            ' Refresh treeExplorer datasource
            'frmExplorer.vDS.DS.Tables("tbElements").Rows.Clear()
            'frmExplorer.vDS.DA.Fill(frmExplorer.vDS.DS, "tbElements")
            frmExplorer.treeExplorer.RefreshDataSource()
 
            vTree.OptionsBehavior.EnableFiltering = True
 
            ' Set the new Element Node focused
            Dim vNewNode As TreeListNode = vTree.FindNodeByKeyID(CInt(vNewNodeId))
            vNewNode.Selected = True
 
            ' Display message : Element succesfully copied !
            XtraMessageBox.Show("The [" & vNodeName & "] " & vNodeType & " " & _
                                "has been succesfully copied" & _
                                vbCrLf & "into the [" & vTargetName & "] " & vTargetType & _
                                vbCrLf & "as [" & vNodeName & "]",
                                "Copy an Element",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information)
 
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
 
    End Sub
Et la fonction de duplication (récursive pour les lignes enfants si demandé) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 
    Friend Function fncDALElements_CopyElement_Recursive(ByVal vElementId As Long,
                                                         ByVal vNewParentId As Long,
                                                         ByVal vCopyChildren As Boolean) _
                                                         As Long
 
        Try
 
            Dim vTbElements As DataTable = frmExplorer.vDS.DS.Tables("tbElements")
 
            ' Find the Element row to be copied
            Dim vELRow() As DataRow = vTbElements.Select("Id = " & vElementId)
 
            ' Find the target Parent Element row
            Dim vParRow() As DataRow = vTbElements.Select("Id = " & vNewParentId)
 
            ' Create the new Element row 
            Dim vNewELRow As DataRow = vTbElements.NewRow
 
            ' Copy all of its data from vElRow
            Dim vColumnIndex As Integer
            Dim vColId As Integer
            Dim vColIdParent As Integer
            Dim vColIdProject As Integer
            Dim vColIsAssigned As Integer
            Dim vColGeneralName As Integer
            For Each vColumn As DataColumn In vTbElements.Columns
                vColumnIndex = vColumn.Ordinal
                Select Case vColumn.ColumnName
                    Case "Id"
                        vColId = vColumn.Ordinal
                    Case "IdParent"
                        vColIdParent = vColumn.Ordinal
                    Case "IdProject"
                        vColIdProject = vColumn.Ordinal
                    Case "IsAssigned"
                        vColIsAssigned = vColumn.Ordinal
                    Case "GeneralName"
                        vColGeneralName = vColumn.Ordinal
                End Select
                If vColumn.ColumnName <> "Id" Then
                    vNewELRow(vColumn.ColumnName) = vELRow(0)(vColumnIndex)
                End If
            Next
 
            ' Update some specific data according to vParRow
            'vNewELRow("Id") = DBNull.Value
            vNewELRow("GeneralName") = "Copy of " & Convert.ToString(vELRow(0)(vColGeneralName))
            vNewELRow("IdParent") = vParRow(0)(vColId)
            vNewELRow("IdProject") = vParRow(0)(vColIdProject)
            vNewELRow("IsAssigned") = vParRow(0)(vColIsAssigned)
            vNewELRow("IsStructural") = False
            Dim vTime As Date = Now
            vNewELRow("Date_CreatedOn") = vTime
            vNewELRow("Date_ModifiedOn") = vTime
 
            ' Add vNewElRow into vTbElements
            vTbElements.Rows.Add(vNewELRow)
            frmExplorer.vDS.DA.Update(vTbElements)
            vTbElements.Rows.Clear()
            frmExplorer.vDS.DA.Fill(vTbElements)
 
            ' Get the Id of the newly created Element
            Dim vRows() As DataRow = vTbElements.Select("", "Id DESC")
            Dim vNewRowId As Long = Convert.ToInt64(vRows(0)(vColId))
 
            ' Copy Children Elements if required and exist
            Dim vChildrenRows() As DataRow
            vChildrenRows = vTbElements.Select("IdParent = " & vELRow(0)(vColId).ToString)
            If vCopyChildren And vChildrenRows.Count > 0 Then
                Dim vNewChildElementId As Long
                Dim vChildElementId As Long
                For nRow As Integer = 0 To vChildrenRows.GetUpperBound(0)
                    vChildElementId = Convert.ToInt64(vChildrenRows(nRow)(vColId))
                    vNewChildElementId = fncDALElements_CopyElement_Recursive(vChildElementId, vNewRowId, vCopyChildren)
                Next
            End If
 
            ' Return the Id of the newly created Element
            Return vNewRowId
 
        Catch ex As Exception
            MsgBox(ex.ToString)
            Return Nothing
        End Try
 
    End Function
Lorsque l'action de duplication est déclenchée, j'obtiens l'erreur suivante :
System.Data.RowNotInTableException: cette ligne a été supprimée d'une table et ne contient pas de données. BeginEdit() permettra la création de nouvelles données dans cette ligne.
Cette erreur se produit au niveau de la ligne de code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
vChildrenRows = vTbElements.Select("IdParent = " & vELRow(0)(vColId).ToString)
Ca fait 2 jours que je tourne en rond sans trouver d'où vient le pb ni de solution.

Si une ame charitable pouvait m'indiquer la bonne direction, ce serait sympa...