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 :
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 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
Lorsque l'action de duplication est déclenchée, j'obtiens l'erreur suivante :
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
Cette erreur se produit au niveau de la ligne de code :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.
Ca fait 2 jours que je tourne en rond sans trouver d'où vient le pb ni de solution.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 vChildrenRows = vTbElements.Select("IdParent = " & vELRow(0)(vColId).ToString)
Si une ame charitable pouvait m'indiquer la bonne direction, ce serait sympa...
Partager